mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-26 07:05:52 -05:00
2497 lines
803 KiB
JavaScript
2497 lines
803 KiB
JavaScript
|
/*
|
||
|
Copyright 2018-2019 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.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @description MeshCmd, command line tool for Intel AMT and MeshCentral.
|
||
|
* @author Ylian Saint-Hilaire
|
||
|
* @version v0.2.0
|
||
|
*/
|
||
|
|
||
|
// Debug Stuff
|
||
|
//console.displayFinalizerMessages = 1; // Display objects that have event listeners that are disposed.
|
||
|
//console.displayStreamPipeMessages = 1; // Display stream pipe and un-pipes
|
||
|
//var __gc = setInterval(function () { console.log('GC'); _debugGC() }, 2000); //
|
||
|
|
||
|
|
||
|
var fs = require('fs');
|
||
|
var os = require('os');
|
||
|
var net = require('net');
|
||
|
var http = require('http');
|
||
|
var dgram = require('dgram');
|
||
|
var httpHeaders = require('http-headers');
|
||
|
var tcpserver = null;
|
||
|
var broadcastSockets = {};
|
||
|
var multicastSockets = {};
|
||
|
var discoveryInterval = null;
|
||
|
var membershipIPv4 = '239.255.255.235';
|
||
|
var membershipIPv6 = 'FF02:0:0:0:0:0:0:FE';
|
||
|
var settings = null;
|
||
|
var meshCmdVersion = '***Mesh*Cmd*Version***'; // Dynamically replaced with MeshCentral version
|
||
|
var amtLms = null, amtMei = null, amtMeiState = null;
|
||
|
var wsstack = null, amtstack = null;
|
||
|
var oswsstack = null, osamtstack = null;
|
||
|
var amtMeiTmpState = null;
|
||
|
var SMBiosTables = null;
|
||
|
var globalDebugFlags = 0; // 1 = IDER Debug
|
||
|
var pendingAmtConfigActions = 0;
|
||
|
var RCSMessageProtocolVersion = 1; // RCS Message Protocol Version. Needs to be less than or equal to RCS server Message Protocol Version
|
||
|
|
||
|
// MeshCommander for Firmware (GZIP'ed, Base64) v0.7.8
|
||
|
var Large_IntelAmtWebApp_etag = "zVObfGF4CXPIxvxSUu+3";
|
||
|
var Large_IntelAmtWebApp = "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
|
||
|
var Medium_IntelAmtWebApp_etag = "IeB7H1GRGwkVlI3IGH5z";
|
||
|
var Medium_IntelAmtWebApp = "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
|
||
|
var Small_IntelAmtWebApp_etag = "Ci0RenuglliDcxGQPFS+";
|
||
|
var Small_IntelAmtWebApp = "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
|
||
|
|
||
|
// MeshCommander LMS (GZIP'ed, Base64) v0.7.8
|
||
|
var _IntelAmtWebApp_etag = "N8Wf/McOVX3T6idS+oh9";
|
||
|
var _IntelAmtWebApp = "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
|
||
|
|
||
|
// MeshCommander Local (GZIP'ed, Base64) v0.7.8
|
||
|
var FullSite_IntelAmtLocalWebApp_etag = "PR80FHg+cPmsp2l3pigx";
|
||
|
var FullSite_IntelAmtLocalWebApp = "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
|
||
|
|
||
|
|
||
|
// Check the server certificate fingerprint
|
||
|
function onVerifyServer(clientName, certs) {
|
||
|
if (certs == null) { certs = clientName; } // Temporary thing until we fix duktape
|
||
|
try { for (var i in certs) { if (certs[i].fingerprint.replace(/:/g, '') == settings.serverhttpshash) { return; } } } catch (e) { }
|
||
|
if (settings.serverhttpshash != null) {
|
||
|
console.log('Error: Failed to verify server certificate.');
|
||
|
console.log('Server TLS hash: ' + certs[i].fingerprint.replace(/:/g, ''));
|
||
|
exit(255);
|
||
|
throw 'Invalid server certificate';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Various utility functions
|
||
|
function debug(level, message) { if ((settings.debuglevel != null) && (settings.debuglevel >= level)) { console.log(message); } }
|
||
|
function exit(status) { if (status == null) { status = 0; } try { process.exit(status); } catch (e) { } }
|
||
|
function getInstance(x, y) { for (var i in x) { if (x[i]["InstanceID"] == y) return x[i]; } return null; }
|
||
|
function md5hex(str) { return require('MD5Stream').create().syncHash(str).toString('hex'); }
|
||
|
function guidToStr(g) { return g.substring(6, 8) + g.substring(4, 6) + g.substring(2, 4) + g.substring(0, 2) + "-" + g.substring(10, 12) + g.substring(8, 10) + "-" + g.substring(14, 16) + g.substring(12, 14) + "-" + g.substring(16, 20) + "-" + g.substring(20); }
|
||
|
function parceArguments(argv) { var r = {}; for (var i in argv) { i = parseInt(i); if (argv[i].startsWith('--') == true) { var key = argv[i].substring(2).toLowerCase(), val = true; if (((i + 1) < argv.length) && (argv[i + 1].startsWith('--') == false)) { val = argv[i + 1]; } r[key] = val; } } return r; }
|
||
|
|
||
|
// Convert an object to string with all functions
|
||
|
function objToString(x, p, ret) {
|
||
|
if (ret == undefined) ret = '';
|
||
|
if (p == undefined) p = 0;
|
||
|
if (x == null) { return '[null]'; }
|
||
|
if (p > 8) { return '[...]'; }
|
||
|
if (x == undefined) { return '[undefined]'; }
|
||
|
if (typeof x == 'string') { if (p == 0) return x; return '"' + (x.split('\0')[0]) + '"'; }
|
||
|
if (typeof x == 'buffer') { return '[buffer]'; }
|
||
|
if (typeof x != 'object') { return x; }
|
||
|
var r = '{' + (ret ? '\r\n' : ' ');
|
||
|
for (var i in x) {
|
||
|
if (i != '_ObjectID') { r += (addPad(p + 2, ret) + i + ': ' + objToString(x[i], p + 2, ret) + (ret ? '\r\n' : ' ')); }
|
||
|
}
|
||
|
return r + addPad(p, ret) + '}';
|
||
|
}
|
||
|
|
||
|
// Return p number of spaces
|
||
|
function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ' '; } return r; }
|
||
|
|
||
|
// Parse the incoming arguments
|
||
|
function run(argv) {
|
||
|
if (meshCmdVersion[0] == '*') { meshCmdVersion = ''; } else { meshCmdVersion = ' v' + meshCmdVersion; }
|
||
|
var args = parceArguments(argv);
|
||
|
//console.log(JSON.stringify(argv));
|
||
|
//console.log('addedModules = ' + JSON.stringify(addedModules));
|
||
|
var actionpath = 'meshaction.txt';
|
||
|
if (args.actionfile != null) { actionpath = args.actionfile; }
|
||
|
var actions = ['HELP', 'ROUTE', 'MICROLMS', 'AMTPOWER', 'AMTFEATURES', 'AMTNETWORK', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTINFODEBUG', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTACM', 'AMTDEACTIVATE', 'AMTACMDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG', 'AMTEVENTLOG', 'AMTPRESENCE'];
|
||
|
|
||
|
// Load the action file
|
||
|
var actionfile = null;
|
||
|
try { actionfile = fs.readFileSync(actionpath); } catch (e) { }
|
||
|
if ((actionpath != 'meshaction.txt') && (actionfile == null)) { console.log('Unable to load \"' + actionpath + '\". Create this file or specify the location using --actionfile [filename].'); exit(1); return; }
|
||
|
if (actionfile != null) { try { settings = JSON.parse(actionfile); } catch (e) { console.log(actionpath, e); exit(1); return; } } else { if (argv.length >= 2) { settings = { action: argv[1] } } }
|
||
|
if (settings == null) { settings = {}; }
|
||
|
var settings2 = {}; for (var i in settings) { settings2[i.toLowerCase()] = settings[i]; } settings = settings2;
|
||
|
|
||
|
// Set the arguments
|
||
|
if ((typeof args.action) == 'string') { settings.action = args.action; }
|
||
|
if ((typeof args.localport) == 'string') { settings.localport = parseInt(args.localport); }
|
||
|
if ((typeof args.remotenodeid) == 'string') { settings.remotenodeid = args.remotenodeid; }
|
||
|
if ((typeof args.name) == 'string') { settings.name = args.name; }
|
||
|
if ((typeof args.username) == 'string') { settings.username = args.username; }
|
||
|
if ((typeof args.password) == 'string') { settings.password = args.password; }
|
||
|
if ((typeof args.url) == 'string') { settings.url = args.url; }
|
||
|
if ((typeof args.profile) == 'string') { settings.profile = args.profile; }
|
||
|
if ((typeof args.type) == 'string') { settings.type = args.type; }
|
||
|
if ((typeof args.user) == 'string') { settings.username = args.user; }
|
||
|
if ((typeof args.pass) == 'string') { settings.password = args.pass; }
|
||
|
if ((typeof args.host) == 'string') { settings.hostname = args.host; }
|
||
|
if ((typeof args.hostname) == 'string') { settings.hostname = args.hostname; }
|
||
|
if ((typeof args.serverid) == 'string') { settings.serverid = args.serverid; }
|
||
|
if ((typeof args.serverhttpshash) == 'string') { settings.serverhttpshash = args.serverhttpshash; }
|
||
|
if ((typeof args.remoteport) == 'string') { settings.remoteport = parseInt(args.remoteport); }
|
||
|
if ((typeof args.out) == 'string') { settings.output = args.out; }
|
||
|
if ((typeof args.output) == 'string') { settings.output = args.output; }
|
||
|
if ((typeof args.debug) == 'string') { settings.debuglevel = parseInt(args.debug); }
|
||
|
if ((typeof args.debugflags) == 'string') { globalDebugFlags = parseInt(args.debugflags); }
|
||
|
if ((typeof args.script) == 'string') { settings.script = args.script; }
|
||
|
if ((typeof args.agent) == 'string') { settings.agent = args.agent; }
|
||
|
if ((typeof args.proxy) == 'string') { settings.proxy = args.proxy; }
|
||
|
if ((typeof args.floppy) == 'string') { settings.floppy = args.floppy; }
|
||
|
if ((typeof args.cdrom) == 'string') { settings.cdrom = args.cdrom; }
|
||
|
if ((typeof args.tag) == 'string') { settings.tag = args.tag; }
|
||
|
if ((typeof args.timeout) == 'string') { settings.timeout = parseInt(args.timeout); }
|
||
|
if (args.debug === true) { settings.debuglevel = 1; }
|
||
|
if (args.debug) { try { waitForDebugger(); } catch (e) { } }
|
||
|
if (args.noconsole) { settings.noconsole = true; }
|
||
|
if (args.nocommander) { settings.noconsole = true; }
|
||
|
if (args.lmsdebug) { settings.lmsdebug = true; }
|
||
|
if (args.json) { settings.json = true; }
|
||
|
if (args.tls) { settings.tls = true; }
|
||
|
if ((argv.length > 1) && (actions.indexOf(argv[1].toUpperCase()) >= 0)) { settings.action = argv[1]; }
|
||
|
|
||
|
// Validate meshaction.txt
|
||
|
if (settings.action == null) {
|
||
|
console.log('MeshCentral Command (MeshCmd) ' + meshCmdVersion);
|
||
|
console.log('No action specified, use MeshCmd like this:\r\n');
|
||
|
console.log(' meshcmd [action] [arguments...]\r\n');
|
||
|
console.log('Valid MeshCentral actions:');
|
||
|
console.log(' Route - Map a local TCP port to a remote computer.');
|
||
|
console.log('\r\nValid local actions:');
|
||
|
console.log(' SMBios - Display System Management BIOS tables for this computer.');
|
||
|
console.log(' RawSMBios - Display RAW System Management BIOS tables for this computer.');
|
||
|
console.log(' MicroLMS - Run MicroLMS, allowing local access to Intel AMT.');
|
||
|
console.log(' AmtInfo - Show Intel AMT version and activation state.');
|
||
|
console.log(' AmtVersions - Show all Intel ME version information.');
|
||
|
console.log(' AmtHashes - Show all Intel AMT trusted activation hashes.');
|
||
|
console.log(' AmtCCM - Activate Intel AMT into Client Control Mode.');
|
||
|
console.log(' AmtACM - Activate Intel AMT into Admin Control Mode.');
|
||
|
console.log(' AmtDeactivate - Deactivate Intel AMT if activated in Client Control mode.');
|
||
|
console.log(' AmtAcmDeactivate - Deactivate Intel AMT if activated in Admin Control mode.');
|
||
|
console.log('\r\nValid local or remote actions:');
|
||
|
console.log(' MeshCommander - Launch a local MeshCommander web server.');
|
||
|
console.log(' AmtUUID - Show Intel AMT unique identifier.');
|
||
|
console.log(' AmtEventLog - Show the Intel AMT event log.');
|
||
|
console.log(' AmtAuditLog - Show the Intel AMT audit log.');
|
||
|
console.log(' AmtLoadWebApp - Load MeshCommander in Intel AMT 11.6+ firmware.');
|
||
|
console.log(' AmtClearWebApp - Clear everything from Intel AMT web storage.');
|
||
|
console.log(' AmtStorageState - Show contents of the Intel AMT web storage.');
|
||
|
console.log(' AmtSaveState - Save all Intel AMT WSMAN object to file.');
|
||
|
console.log(' AmtPresence - Heartbeat a local Intel AMT watchdog agent.');
|
||
|
console.log(' AmtPower - Perform remote Intel AMT power operation.');
|
||
|
console.log(' AmtScript - Run .mescript on Intel AMT.');
|
||
|
console.log(' AmtIDER - Mount local disk image to remote computer.');
|
||
|
console.log(' AmtFeatures - Intel AMT features & user consent.');
|
||
|
console.log(' AmtNetwork - Intel AMT network interface settings.');
|
||
|
console.log('\r\nHelp on a specific action using:\r\n');
|
||
|
console.log(' meshcmd help [action]');
|
||
|
exit(1); return;
|
||
|
}
|
||
|
if (settings.action == 'help') {
|
||
|
if (argv.length <= 2) {
|
||
|
actions.shift();
|
||
|
console.log('Help usage:\r\n\r\n MeshCmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.');
|
||
|
exit(1); return;
|
||
|
}
|
||
|
var action = argv[2].toLowerCase();
|
||
|
if (action == 'route') {
|
||
|
console.log("The route action is used along with a MeshCentral account to map a local TCP port to a remote port on any computer on your MeshCentral account. This action requires many arguments, to avoid specifying them all it's best to download the meshaction.txt file from the web site and place it in the current folder. Example usage:\r\n\r\n (Place meshaction.txt file in current folder)\r\n meshcmd route --pass myAccountPassword");
|
||
|
} else if (action == 'smbios') {
|
||
|
console.log("SMBios action will display this computer's system management BIOS information. Example usage:\r\n\r\n meshcmd smbios --out smbios.txt\r\n");
|
||
|
console.log('\r\Optional arguments:\r\n');
|
||
|
console.log(' --output [filename] Optional filename to write the results to.');
|
||
|
} else if (action == 'rawsmbios') {
|
||
|
console.log("RawSMBios action will display this computer's system management BIOS information in raw hexdecimal form. Example usage:\r\n\r\n meshcmd rawsmbios --out smbios.txt\r\n");
|
||
|
console.log('\r\Optional arguments:\r\n');
|
||
|
console.log(' --output [filename] Optional filename to write the results to.');
|
||
|
} else if (action == 'amtinfo') {
|
||
|
console.log('AmtInfo action will get the version and activation state of Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtinfo');
|
||
|
} else if ((action == 'amtversion') || (action == 'amtversions')) {
|
||
|
console.log('AmtVersions will display all version information about Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtversions');
|
||
|
} else if (action == 'amthashes') {
|
||
|
console.log('Amthashes will display all trusted activations hashes for Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd amthashes');
|
||
|
} else if ((action == 'microlms') || (action == 'lms') || (action == 'amtlms')) {
|
||
|
console.log('Starts MicroLMS on this computer, allowing local access to Intel AMT on TCP ports 16992 and 16993 when applicable. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd microlms');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --noconsole MeshCommander for LMS will no be available on port 16994.');
|
||
|
console.log('\r\nRun as a background service:\r\n');
|
||
|
console.log(' microlms install/uninstall/start/stop.');
|
||
|
} else if (action == 'amtccm') {
|
||
|
console.log('AmtCCM will attempt to activate Intel AMT on this computer into client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be in "pre-provisioning" state for this command to work and a administrator password must be provided.');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --password [password] Admin password used to activate Intel AMT.');
|
||
|
console.log('\r\nor:\r\n');
|
||
|
console.log(' --url [wss://server] Url to the activation server.');
|
||
|
console.log(' --tag [string] Optional string sent to the server during activation.');
|
||
|
console.log(' --serverhttpshash [hash] Optional TLS server certificate hash.');
|
||
|
console.log(' --profile [string] Optional profile used for server activation.');
|
||
|
} else if (action == 'amtacm') {
|
||
|
console.log('AmtACM will attempt to activate Intel AMT on this computer into admin control mode (ACM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be in "pre-provisioning" state for this command to work. Example usage:\r\n\r\n meshcmd amtacm --url [url]');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --url [wss://server] The address of the Intel AMT activation server.');
|
||
|
console.log(' --tag [string] Optional string sent to the server during activation.');
|
||
|
console.log(' --serverhttpshash [hash] Optional TLS server certificate hash.');
|
||
|
console.log(' --profile [string] Optional profile used for server activation.');
|
||
|
} else if (action == 'amtdeactivate') {
|
||
|
console.log('AmtDeactivate will attempt to deactivate Intel AMT on this computer when in client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be activated in client control mode for this command to work. Example usage:\r\n\r\n meshcmd amtdeactivate');
|
||
|
} else if (action == 'amtacmdeactivate') {
|
||
|
console.log('AmtACMDeactivate will attempt to deactivate Intel AMT on this computer when in admin control mode (ACM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be activated in admin control mode for this command to work. Example usage:\r\n\r\n meshcmd amtacmdeactivate');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log(' --type [partial/full] Specifies to perform partial or full unprovision.');
|
||
|
} else if (action == 'amtuuid') {
|
||
|
console.log('AmtUUID action will get the unique identifier of the local or remote Intel AMT computer. By default, the local UUID is obtained unless a host is specified. Intel AMT must be activated for this command to work. Example usage:\r\n\r\n meshcmd amtuuid --host 1.2.3.4 --user admin --pass mypassword --tls');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
} else if ((action == 'amtloadwebapp') || (action == 'amtloadsmallwebapp') || (action == 'amtloadlargewebapp') || (action == 'amtclearwebapp') || (action == 'amtstoragestate')) {
|
||
|
console.log('AmtLoadWebApp action will load MeshCommander into Intel AMT 11.6 or higher. If the computer is in ACM mode, MeshCommander will replace the default index.htm on HTTP/16992 or HTTPS/16993. If Intel AMT is in CCM mode, MeshCommander will be installed alongside the default web page and will be accessible in the "Web Applications" section. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtloadwebapp --host 1.2.3.4 --user admin --pass mypassword --tls');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
} else if (action == 'amtclearwebstorage') {
|
||
|
console.log('AmtClearWebStorage will clear the web storage of Intel AMT, removing any loaded firmware version of MeshCommander. This command can clear the local or a remote Intel AMT computer. By default, the local computer storage is cleared unless a host is specified. Intel AMT must be activated for this command to work. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtclearwebstorage --host 1.2.3.4 --user admin --pass mypassword --tls');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
} else if (action == 'amtstoragestate') {
|
||
|
console.log('AmtStorageState will display the content of the web storage of Intel AMT including any loaded firmware version of MeshCommander. This command can read the storage state of a local or remote Intel AMT computer. By default, the local computer storage state is displayed unless a host is specified. Intel AMT must be activated for this command to work. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtstoragestate --host 1.2.3.4 --user admin --pass mypassword --tls');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
} else if (action == 'amtsavestate') {
|
||
|
console.log('AmtSaveState action will fetch all the entire state of Intel AMT and save it as a JSON file. This action will take multiple minutes to perform. The command will fetch the local computer state unless host is specified. Intel AMT must be ativated for this command to work. Example usage:\r\n\r\n meshcmd amtsavestate --host 1.2.3.4 --user admin --pass mypassword --tls --output state.json');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --output [filename] The output file for the Intel AMT state in JSON format.');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
} else if (action == 'amtpresence') {
|
||
|
console.log('AmtPresence will heartbeat a local Intel AMT watchdog agent. Example usage:\r\n\r\n meshcmd amtpresence --agent B4B6A24C-255E-A75C-F5E8-B00B4D946AA7');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log(' --agent [uuid] The unique identifier of the watchdog agent.');
|
||
|
} else if (action == 'amtscript') {
|
||
|
console.log('AmtScript will run a .mescript file on the local or remote Intel AMT. Script files can be built using the MeshCommander script editor and be used to setup or perform actions on Intel AMT. Example usage:\r\n\r\n meshcmd amtscript --script myscript.mescript --host 1.2.3.4 --user admin --pass mypassword --tls');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --script [filename] The script file to run on Intel AMT.');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
} else if (action == 'amtpower') {
|
||
|
console.log('AmtPower will get current pwoer state or send a reboot command to a remote Intel AMT device. Example usage:\r\n\r\n meshcmd amtpower --reset --host 1.2.3.4 --user admin --pass mypassword --tls');
|
||
|
console.log('\r\nRequired arguments:\r\n');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log('\r\nOptional arguments:\r\n');
|
||
|
console.log(' --reset, --poweron, --poweroff, --powercycle, --sleep, --hibernate');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
} else if (action == 'amtnetwork') {
|
||
|
console.log('AmtNetwork is used to get/set Intel AMT network interface configuration. Example usage:\r\n\r\n meshcmd amtnetwork --host 1.2.3.4 --user admin --pass mypassword --dhcp');
|
||
|
console.log('\r\nRequired arguments:\r\n');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log('\r\nOptional arguments:\r\n');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
console.log(' --ipsync [0 or 1] Change the wired IPSync setting on Intel AMT 7+');
|
||
|
console.log(' --dhcp Change IPv4 wired interface to DHCP mode');
|
||
|
console.log(' --static Change IPv4 wired interface to static IP mode');
|
||
|
console.log(' --ip [1.2.3.4] Static IPv4 address (required)');
|
||
|
console.log(' --subnet [1.2.3.4] Static IPv4 subnet mask');
|
||
|
console.log(' --gateway [1.2.3.4] Static IPv4 default gateway');
|
||
|
console.log(' --dns [1.2.3.4] Primary DNS IPv4 address');
|
||
|
console.log(' --dns2 [1.2.3.4] Secondary DNS IPv4 address');
|
||
|
} else if (action == 'amtfeatures') {
|
||
|
console.log('AmtFeatures is used to get/set Intel AMT feature configuration. Example usage:\r\n\r\n meshcmd amtfeatures --host 1.2.3.4 --user admin --pass mypassword --tls --redir 1');
|
||
|
console.log('\r\nRequired arguments:\r\n');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log('\r\nOptional arguments:\r\n');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
console.log(' --consent [none/kvm/all] Set Intel AMT user consent feature.');
|
||
|
console.log(' --redir [0/1] Set Intel AMT redirection port feature.');
|
||
|
console.log(' --kvm [0/1] Set Intel AMT KVM feature.');
|
||
|
console.log(' --sol [0/1] Set Intel AMT Serial-over-LAN feature.');
|
||
|
console.log(' --ider [0/1] Set Intel AMT IDE redirection feature.');
|
||
|
} else if (action == 'meshcommander') {
|
||
|
console.log('This action launched a local web server that hosts MeshCommander, a Intel AMT management console.');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --localport [port] Local port used for the web server, 3000 is default.');
|
||
|
console.log('\r\nRun as a background service:\r\n');
|
||
|
console.log(' meshcommander install/uninstall/start/stop.');
|
||
|
} else if (action == 'amteventlog') {
|
||
|
console.log('AmtEventLog action will fetch the local or remote event log. Example usage:\r\n\r\n meshcmd amteventlog --host 1.2.3.4 --user admin --pass mypassword --tls --output events.txt');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --output [filename] The output file for the Intel AMT event log.');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
console.log(' --json Output as a JSON format.');
|
||
|
} else if (action == 'amtauditlog') {
|
||
|
console.log('AmtAuditLog action will fetch the local or remote audit log. If used localy, no username/password is required. Example usage:\r\n\r\n meshcmd amtauditlog --host 1.2.3.4 --user admin --pass mypassword --tls --output audit.json');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --output [filename] The output file for the Intel AMT audit log.');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
console.log(' --json Output as a JSON format.');
|
||
|
} else if (action == 'amtider') {
|
||
|
console.log('AmtIDER will mount a local disk images to a remote Intel AMT computer. Example usage:\r\n\r\n meshcmd amtider --host 1.2.3.4 --user admin --pass mypassword --tls --floppy disk.img --cdrom disk.iso');
|
||
|
console.log('\r\nPossible arguments:\r\n');
|
||
|
console.log(' --host [hostname] The IP address or DNS name of Intel AMT.');
|
||
|
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||
|
console.log(' --pass [password] The Intel AMT login password.');
|
||
|
console.log(' --tls Specifies that TLS must be used.');
|
||
|
console.log(' --floppy [file] Specifies .img file to be mounted as a flppy disk.');
|
||
|
console.log(' --cdrom [file] Specifies .img file to be mounted as a CDROM disk.');
|
||
|
console.log(' --timeout [seconds] Optional, disconnect after number of seconds without disk read.');
|
||
|
} else {
|
||
|
actions.shift();
|
||
|
console.log('Invalid action, usage:\r\n\r\n meshcmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.');
|
||
|
}
|
||
|
exit(1); return;
|
||
|
}
|
||
|
settings.action = settings.action.toLowerCase();
|
||
|
debug(1, "Settings: " + JSON.stringify(settings));
|
||
|
|
||
|
// Setup the proxy if needed
|
||
|
if ((typeof settings.proxy) == 'string') {
|
||
|
var proxy = settings.proxy.split(':'), proxyport = (proxy.length == 2) ? parseInt(proxy[1]) : 0;
|
||
|
if ((proxy.length != 2) || (proxy[0].length < 1) || (proxyport < 1) || (proxyport > 65535)) { console.log('Invalid \"proxy\" specified, use --proxy [hostname]:[port].'); exit(1); return; }
|
||
|
try { require('global-tunnel').initialize({ host: proxy[0], port: proxyport }); } catch (ex) { console.log(ex); exit(1); return; }
|
||
|
console.log('Proxy set to ' + proxy[0] + ':' + proxyport);
|
||
|
}
|
||
|
|
||
|
if (settings.action == 'smbios') {
|
||
|
// Display SM BIOS tables in raw form
|
||
|
SMBiosTables = require('smbios');
|
||
|
SMBiosTables.get(function (data) {
|
||
|
var r = SMBiosTables.parse(data);
|
||
|
var out = objToString(r, 0, '\r\n');
|
||
|
if (settings.output == null) { console.log(out); } else { var file = fs.openSync(settings.output, 'w'); fs.writeSync(file, Buffer.from(out, 'utf8')); fs.closeSync(file); }
|
||
|
exit(1);
|
||
|
});
|
||
|
} else if (settings.action == 'rawsmbios') {
|
||
|
// Display SM BIOS tables in raw form
|
||
|
SMBiosTables = require('smbios');
|
||
|
SMBiosTables.get(function (data) {
|
||
|
var out = '';
|
||
|
for (var i in data) { var header = false; for (var j in data[i]) { if (data[i][j].length > 0) { if (header == false) { out += ('Table type #' + i + ((SMBiosTables.smTableTypes[i] == null) ? '' : (', ' + SMBiosTables.smTableTypes[i]))) + '\r\n'; header = true; } out += (' ' + data[i][j].toString('hex')) + '\r\n'; } } }
|
||
|
if (settings.output == null) { console.log(out); } else { var file = fs.openSync(settings.output, 'w'); fs.writeSync(file, Buffer.from(out, 'utf8')); fs.closeSync(file); }
|
||
|
exit(1);
|
||
|
});
|
||
|
} else if (settings.action == 'route') {
|
||
|
// MeshCentral Router, port map local TCP port to a remote computer
|
||
|
if ((settings.localport == null) || (typeof settings.localport != 'number') || (settings.localport < 0) || (settings.localport > 65535)) { console.log('No or invalid \"localPort\" specified, use --localport [localport].'); exit(1); return; }
|
||
|
if ((settings.remotenodeid == null) || (typeof settings.remotenodeid != 'string')) { console.log('No or invalid \"remoteNodeId\" specified.'); exit(1); return; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { console.log('No or invalid \"username\" specified, use --username [username].'); exit(1); return; }
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.serverid == null) || (typeof settings.serverid != 'string') || (settings.serverid.length != 96)) { console.log('No or invalid \"serverId\" specified.'); exit(1); return; }
|
||
|
if ((settings.serverhttpshash == null) || (typeof settings.serverhttpshash != 'string') || (settings.serverhttpshash.length != 96)) { console.log('No or invalid \"serverHttpsHash\" specified.'); exit(1); return; }
|
||
|
if ((settings.remoteport == null) || (typeof settings.remoteport != 'number') || (settings.remoteport < 0) || (settings.remoteport > 65535)) { console.log('No or invalid \"remotePort\" specified, use --remoteport [remoteport].'); exit(1); return; }
|
||
|
if (settings.serverurl != null) { startRouter(); } else { discoverMeshServer(); } // Start MeshCentral Router
|
||
|
} else if ((settings.action == 'amtloadwebapp') || (settings.action == 'amtloadsmallwebapp') || (settings.action == 'amtloadlargewebapp') || (settings.action == 'amtclearwebapp') || (settings.action == 'amtstoragestate')) { // Intel AMT Web Application Actions
|
||
|
// Intel AMT 11.6+ Load MeshCommander into firmware
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
settings.protocol = 'http:';
|
||
|
settings.localport = 16992;
|
||
|
debug(1, "Settings: " + JSON.stringify(settings));
|
||
|
digest = require('http-digest').create(settings.username, settings.password);
|
||
|
digest.http = require('http');
|
||
|
if (settings.action == 'amtstoragestate') {
|
||
|
getAmtStorage(function (statusCode, data) { if (statusCode == 200) { console.log("Storage State: " + JSON.stringify(data, null, 2)); exit(); return; } else { console.log("Unable to read storage state."); exit(); return; } });
|
||
|
} else {
|
||
|
if (settings.action == 'amtloadwebapp') { settings.webapp = Medium_IntelAmtWebApp; }
|
||
|
else if (settings.action == 'amtloadsmallwebapp') { settings.webapp = Small_IntelAmtWebApp; }
|
||
|
else if (settings.action == 'amtloadlargewebapp') { settings.webapp = Large_IntelAmtWebApp; }
|
||
|
else if (settings.action == 'amtclearwebapp') { settings.webapp = null; }
|
||
|
nextStepStorageUpload();
|
||
|
}
|
||
|
} else if ((settings.action == 'amtversion') || (settings.action == 'amtversions') || (settings.action == 'amtver')) {
|
||
|
// Display Intel AMT versions
|
||
|
var amtMeiModule, amtMei;
|
||
|
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
|
||
|
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||
|
amtMei.getVersion(function (val) {
|
||
|
console.log("MEI Version = " + val.BiosVersion.toString());
|
||
|
for (var version in val.Versions) { console.log(val.Versions[version].Description + " = " + val.Versions[version].Version); }
|
||
|
exit(1); return;
|
||
|
});
|
||
|
} else if (settings.action == 'amthashes') {
|
||
|
// Display Intel AMT list of trusted hashes
|
||
|
var amtMeiModule, amtMei;
|
||
|
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
|
||
|
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||
|
amtMei.getHashHandles(function (handles) {
|
||
|
exitOnCount = handles.length;
|
||
|
for (var i = 0; i < handles.length; ++i) {
|
||
|
this.getCertHashEntry(handles[i], function (result) {
|
||
|
console.log(result.name + ', (' + (result.isDefault ? 'Default' : '') + (result.isActive ? ', Active' : ', Disabled') + ')\r\n ' + result.hashAlgorithmStr + ': ' + result.certificateHash);
|
||
|
if (--exitOnCount == 0) { exit(1); }
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
} else if (settings.action == 'netinfo') {
|
||
|
// Display network information
|
||
|
var interfaces = require('os').networkInterfaces();
|
||
|
console.log(JSON.stringify(interfaces, 2, ' '));
|
||
|
exit(0); return;
|
||
|
} else if (settings.action == 'amtinfo') {
|
||
|
// Display Intel AMT version and activation state
|
||
|
mestate = {};
|
||
|
var amtMeiModule, amtMei;
|
||
|
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
|
||
|
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||
|
amtMei.getVersion(function (result) { if (result) { for (var version in result.Versions) { if (result.Versions[version].Description == 'AMT') { mestate.ver = result.Versions[version].Version; } } } });
|
||
|
amtMei.getProvisioningState(function (result) { if (result) { mestate.ProvisioningState = result; } });
|
||
|
amtMei.getProvisioningMode(function (result) { if (result) { mestate.ProvisioningMode = result; } });
|
||
|
amtMei.getEHBCState(function (result) { if (result) { mestate.ehbc = result; } });
|
||
|
amtMei.getControlMode(function (result) { if (result) { mestate.controlmode = result; } });
|
||
|
amtMei.getMACAddresses(function (result) { if (result) { mestate.mac = result; } });
|
||
|
amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } });
|
||
|
amtMei.getLanInterfaceSettings(1, function (result) { if (result) { mestate.net1 = result; } });
|
||
|
amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } });
|
||
|
amtMei.getDnsSuffix(function (result) {
|
||
|
if (result) { mestate.dns = result; }
|
||
|
if (mestate.ver && mestate.ProvisioningState && mestate.ProvisioningMode) {
|
||
|
var str = 'Intel AMT v' + mestate.ver;
|
||
|
if (mestate.ProvisioningState.stateStr == 'PRE') { str += ', pre-provisioning state'; }
|
||
|
else if (mestate.ProvisioningState.stateStr == 'IN') { str += ', in-provisioning state'; }
|
||
|
else if (mestate.ProvisioningState.stateStr == 'POST') {
|
||
|
if (mestate.ProvisioningMode) {
|
||
|
if (mestate.controlmode) {
|
||
|
if (mestate.ProvisioningMode.modeStr == 'ENTERPRISE') { str += ', activated in ' + ["none", "client control mode", "admin control mode", "remote assistance mode"][mestate.controlmode.controlMode]; } else { str += ', activated in ' + mestate.ProvisioningMode.modeStr; }
|
||
|
} else {
|
||
|
str += ', activated in ' + mestate.ProvisioningMode.modeStr;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if ((mestate.ehbc) && (mestate.ehbc.EHBC == true)) { str += ', EHBC enabled'; }
|
||
|
str += '.';
|
||
|
if (mestate.net0 != null) { str += '\r\nWired ' + ((mestate.net0.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net0.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net0.mac + (mestate.net0.address == '0.0.0.0' ? '' : (', ' + mestate.net0.address)); }
|
||
|
if (mestate.net1 != null) { str += '\r\nWireless ' + ((mestate.net1.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net1.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net1.mac + (mestate.net1.address == '0.0.0.0' ? '' : (', ' + mestate.net1.address)); }
|
||
|
if ((mestate.ProvisioningState.stateStr != 'POST') && (mestate.net0 != null) && (mestate.net0.enabled == 1)) {
|
||
|
if (mestate.dns != null) {
|
||
|
// Intel AMT has a trusted DNS suffix set, use that one.
|
||
|
str += '\r\nTrusted DNS suffix: ' + mestate.dns;
|
||
|
} else {
|
||
|
// Look for the DNS suffix for the Intel AMT Ethernet interface
|
||
|
var fqdn = null, interfaces = require('os').networkInterfaces();
|
||
|
for (var i in interfaces) {
|
||
|
for (var j in interfaces[i]) {
|
||
|
if ((interfaces[i][j].mac == mestate.net0.mac) && (interfaces[i][j].fqdn != null) && (interfaces[i][j].fqdn != '')) { fqdn = interfaces[i][j].fqdn; }
|
||
|
}
|
||
|
}
|
||
|
if (fqdn != null) { str += '\r\nDNS suffix: ' + fqdn; }
|
||
|
}
|
||
|
}
|
||
|
console.log(str + '.');
|
||
|
} else {
|
||
|
console.log('Intel(R) AMT not supported.');
|
||
|
}
|
||
|
exit(1);
|
||
|
});
|
||
|
} else if (settings.action == 'amtinfodebug') {
|
||
|
// Display Intel AMT version and activation state
|
||
|
mestate = {};
|
||
|
var amtMeiModule, amtMei;
|
||
|
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
|
||
|
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||
|
amtMei.getVersion(function (result) { console.log('getVersion: ' + JSON.stringify(result)); });
|
||
|
amtMei.getProvisioningState(function (result) { console.log('getProvisioningState: ' + JSON.stringify(result)); });
|
||
|
amtMei.getProvisioningMode(function (result) { console.log('getProvisioningMode: ' + JSON.stringify(result)); });
|
||
|
amtMei.getEHBCState(function (result) { if (result) { console.log('getEHBCState: ' + JSON.stringify(result)); } });
|
||
|
amtMei.getControlMode(function (result) { if (result) { console.log('getControlMode: ' + JSON.stringify(result)); } });
|
||
|
amtMei.getMACAddresses(function (result) { if (result) { console.log('getMACAddresses: ' + JSON.stringify(result)); } });
|
||
|
amtMei.getLanInterfaceSettings(0, function (result) { console.log('getLanInterfaceSettings0: ' + JSON.stringify(result)); });
|
||
|
amtMei.getLanInterfaceSettings(1, function (result) { console.log('getLanInterfaceSettings1: ' + JSON.stringify(result)); });
|
||
|
amtMei.getUuid(function (result) { console.log('getUuid: ' + JSON.stringify(result)); });
|
||
|
amtMei.getDnsSuffix(function (result) { console.log('getDnsSuffix: ' + JSON.stringify(result)); exit(1); });
|
||
|
} else if (settings.action == 'amtsavestate') {
|
||
|
// Save the entire state of Intel AMT info a JSON file
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
if ((settings.output == null) || (typeof settings.output != 'string') || (settings.output == '')) { console.log('No or invalid \"output\" file specified, use --output [filename].'); exit(1); return; }
|
||
|
settings.protocol = 'http:';
|
||
|
settings.localport = 16992;
|
||
|
debug(1, "Settings: " + JSON.stringify(settings));
|
||
|
saveEntireAmtState();
|
||
|
} else if ((settings.action == 'microlms') || (settings.action == 'amtlms') || (settings.action == 'lms')) {
|
||
|
// Start Intel AMT MicroLMS
|
||
|
startLms(function (state) {
|
||
|
console.log(['MicroLMS did not start. Must run as administrator or LMS already active.', 'MicroLMS started.', 'MicroLMS started, MeshCommander on HTTP/16994.', 'MEI error'][state]);
|
||
|
if (((state == 0) || (state == 3)) && (settings.noconsole === true)) { exit(0); } else { console.log('Press ctrl-c to exit.'); }
|
||
|
}, settings.noconsole !== true);
|
||
|
} else if (settings.action == 'amtpresence') {
|
||
|
// Heartbeat a Intel AMT watchdog
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
if ((settings.agent == null) || (typeof settings.agent != 'string') || (settings.agent == '')) { console.log('No or invalid \"agent\" specified, use --agent [agent].'); exit(1); return; }
|
||
|
performAmtAgentPresence();
|
||
|
} else if (settings.action == 'amtscript') {
|
||
|
// Start running a MEScript
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
if ((settings.script == null) || (typeof settings.script != 'string') || (settings.script == '')) { if (mescriptJSON != '') { settings.scriptjson = mescriptJSON; } else { console.log('No or invalid \"script\" file specified, use --script [filename].'); exit(1); return; } }
|
||
|
startMeScript();
|
||
|
} else if (settings.action == 'amtuuid') {
|
||
|
// Start running
|
||
|
if (settings.hostname != null) {
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
}
|
||
|
settings.protocol = 'http:';
|
||
|
settings.localport = 16992;
|
||
|
debug(1, "Settings: " + JSON.stringify(settings));
|
||
|
getAmtUuid();
|
||
|
} else if (settings.action == 'amtccm') {
|
||
|
// Start activation to CCM
|
||
|
if (((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) && ((settings.url == null) || (typeof settings.url != 'string') || (settings.url == ''))) { console.log('No or invalid parameters specified, use --password [password] or --url [url].'); exit(1); return; }
|
||
|
if ((typeof settings.profile != 'string') || (settings.profile == '')) { settings.profile = null; }
|
||
|
settings.protocol = 'http:';
|
||
|
settings.localport = 16992;
|
||
|
debug(1, "Settings: " + JSON.stringify(settings));
|
||
|
if (settings.password != null) { activeToCCM(); } else { activeToACM(); }
|
||
|
} else if (settings.action == 'amtacm') {
|
||
|
// Start activation to ACM
|
||
|
if ((settings.url == null) || (typeof settings.url != 'string') || (settings.url == '')) { console.log('No activation server URL specified, use --url [url].'); exit(1); return; }
|
||
|
if ((typeof settings.profile != 'string') || (settings.profile == '')) { settings.profile = null; }
|
||
|
debug(1, "Settings: " + JSON.stringify(settings));
|
||
|
activeToACM();
|
||
|
} else if (settings.action == 'amtdiscover') {
|
||
|
// Intel AMT server discovery, tell the server the state of Intel AMT.
|
||
|
if ((settings.url == null) || (typeof settings.url != 'string') || (settings.url == '')) { console.log('No activation server URL specified, use --url [url].'); exit(1); return; }
|
||
|
debug(1, "Settings: " + JSON.stringify(settings));
|
||
|
activeToACM();
|
||
|
} else if (settings.action == 'amtdeactivate') {
|
||
|
// Deactivate CCM
|
||
|
debug(1, "Settings: " + JSON.stringify(settings));
|
||
|
deactivateCCM();
|
||
|
} else if (settings.action == 'amtacmdeactivate') {
|
||
|
// Deactivate ACM
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.type == null) || (typeof settings.type != 'string') || (settings.type == '')) { console.log('Unprovisioning \"type\" must be specified, use --type [partial/full].'); exit(1); return; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
if (settings.hostname == null) { settings.hostname = '127.0.0.1'; }
|
||
|
if (settings.tls == null) { settings.tls = false; }
|
||
|
debug(1, "Settings: " + JSON.stringify(settings));
|
||
|
deactivateACM();
|
||
|
} else if (settings.action == 'meshcommander') { // Start MeshCommander
|
||
|
startMeshCommander();
|
||
|
//} else if (settings.action == 'amtdisable') { // Disable AMT Network Interface
|
||
|
// amtDisable();
|
||
|
} else if (settings.action == 'amtauditlog') { // Read the Intel AMT audit log
|
||
|
if (settings.hostname != null) {
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
} else { settings.hostname = '127.0.0.1'; }
|
||
|
readAmtAuditLog();
|
||
|
} else if (settings.action == 'amteventlog') { // Read the Intel AMT audit log
|
||
|
if (settings.hostname == null) { settings.hostname = '127.0.0.1'; }
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
readAmtEventLog();
|
||
|
} else if (settings.action == 'amtider') { // Remote mount IDER image
|
||
|
if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { console.log('No or invalid \"hostname\" specified, use --hostname [password].'); exit(1); return; }
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
if ((settings.floppy == null) || (typeof settings.floppy != 'string') || (settings.floppy == '')) { settings.floppy = null; }
|
||
|
if ((settings.cdrom == null) || (typeof settings.cdrom != 'string') || (settings.cdrom == '')) { settings.cdrom = null; }
|
||
|
if ((settings.floppy == null) && (settings.cdrom == null)) { console.log('No or invalid \"floppy\" or \"cdrom\" specified, use --floppy [file] or --cdrom [file].'); exit(1); return; }
|
||
|
performIder();
|
||
|
} else if (settings.action == 'amtnetwork') { // Perform remote Intel AMT wired IPv4 configuration operation
|
||
|
if (settings.hostname == null) { settings.hostname = '127.0.0.1'; }
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
performAmtNetConfig(args);
|
||
|
} else if (settings.action == 'amtfeatures') { // Perform remote Intel AMT feature configuration operation
|
||
|
if (settings.hostname == null) { settings.hostname = '127.0.0.1'; }
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
performAmtFeatureConfig(args);
|
||
|
} else if (settings.action == 'amtpower') { // Perform remote Intel AMT power operation
|
||
|
if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { console.log('No or invalid \"hostname\" specified, use --hostname [host].'); exit(1); return; }
|
||
|
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||
|
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||
|
|
||
|
/*
|
||
|
2 = Power On
|
||
|
3 = Sleep - Light
|
||
|
4 = Sleep - Deep
|
||
|
5 = Power Cycle (Off Soft)
|
||
|
6 = Power Off - Hard
|
||
|
7 = Hibernate
|
||
|
8 = Power Off - Soft
|
||
|
9 = Power Cycle (Off Hard)
|
||
|
10 = Master Bus Reset
|
||
|
11 = Diagnostic Interrupt (NMI)
|
||
|
12 = Power Off - Soft Graceful
|
||
|
13 = Power Off - Hard Graceful
|
||
|
14 = Master Bus Reset Graceful
|
||
|
15 = Power Cycle (Off - Soft Graceful)
|
||
|
16 = Power Cycle (Off - Hard Graceful)
|
||
|
*/
|
||
|
|
||
|
settings.poweraction = 0;
|
||
|
if (args.poweron) { settings.poweraction = 2; }
|
||
|
if (args.sleep) { settings.poweraction = 3; }
|
||
|
if (args.powercycle) { settings.poweraction = 5; }
|
||
|
if (args.poweroff) { settings.poweraction = 6; }
|
||
|
if (args.hibernate) { settings.poweraction = 7; }
|
||
|
if (args.reset) { settings.poweraction = 10; }
|
||
|
//if (settings.poweraction == 0) { console.log('No power action, specify --poweron, --sleep, --powercycle, --poweroff, --hibernate, --reset.'); exit(1); return; }
|
||
|
performAmtPowerAction();
|
||
|
} else {
|
||
|
console.log('Invalid \"action\" specified.'); exit(1); return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Intel AMT Agent Presence
|
||
|
//
|
||
|
|
||
|
function performAmtAgentPresence() { startLms(function () { tempWatchdogTimer = setTimeout(performAmtAgentPresenceRegister, 3000); }); }
|
||
|
|
||
|
function performAmtAgentPresenceRegister() {
|
||
|
// Setup the Intel AMT WSMAN stack
|
||
|
tempWatchdogTimer = null;
|
||
|
var transport = require('amt-wsman-duk');
|
||
|
var wsman = require('amt-wsman');
|
||
|
var amt = require('amt');
|
||
|
wsstack = new wsman(transport, '127.0.0.1', settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
|
||
|
amtstack = new amt(wsstack);
|
||
|
|
||
|
// Register the watchdog
|
||
|
watchdog = { DeviceID: Buffer.from(guidToStr(settings.agent.split('-').join('')).split('-').join(''), 'hex').toString('base64'), Retry: 0 };
|
||
|
amtstack.AMT_AgentPresenceWatchdog_RegisterAgent(performAmtAgentPresenceRegisterRetry, watchdog, watchdog.Seq, { 'DeviceID': watchdog.DeviceID });
|
||
|
}
|
||
|
|
||
|
// Called after the agent is registered
|
||
|
function performAmtAgentPresenceRegisterRetry(stack, name, response, status, watchdog) {
|
||
|
if ((status == 200) && (response.Body.SessionSequenceNumber) && (response.Body.TimeoutInterval)) {
|
||
|
console.log('Asserting presence of the watchdog...');
|
||
|
watchdog.Seq = response.Body.SessionSequenceNumber;
|
||
|
watchdog.Interval = response.Body.TimeoutInterval * 800;
|
||
|
watchdog.Retry = 0;
|
||
|
tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval);
|
||
|
} else {
|
||
|
debug(1, 'Failed to register, status = ' + status);
|
||
|
watchdog.Retry++;
|
||
|
if (watchdog.Retry < 5) {
|
||
|
tempWatchdogTimer = setTimeout(function () { amtstack.AMT_AgentPresenceWatchdog_RegisterAgent(performAmtAgentPresenceRegisterRetry, watchdog, watchdog.Seq, { 'DeviceID': watchdog.DeviceID }); }, 1000);
|
||
|
} else {
|
||
|
console.log('Failed to register this watchdog.');
|
||
|
process.exit(0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Start a new agent assert
|
||
|
function performAmtAgentPresenceAssert() {
|
||
|
watchdog.Seq++;
|
||
|
amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceAssertRetry, watchdog, 0, { 'DeviceID': watchdog.DeviceID });
|
||
|
}
|
||
|
|
||
|
// Called after the agent is asserted
|
||
|
function performAmtAgentPresenceAssertRetry(stack, name, response, status, watchdog) {
|
||
|
if (status == 200) {
|
||
|
debug(1, 'Succesful assert, sequence = ' + watchdog.Seq);
|
||
|
watchdog.Retry = 0;
|
||
|
tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval);
|
||
|
} else {
|
||
|
debug(1, 'Failed to assert, status = ' + status);
|
||
|
watchdog.Retry++;
|
||
|
if (watchdog.Retry < 5) {
|
||
|
amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceAssertRetry, watchdog, 0, { 'DeviceID': watchdog.DeviceID });
|
||
|
} else {
|
||
|
console.log('Failed to assert presence on this watchdog.');
|
||
|
process.exit(0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function performAmtAgentPresenceEx5(stack, name, response, status, watchdog) {
|
||
|
console.log('b', status, watchdog);
|
||
|
if (status == 200) {
|
||
|
watchdog.Retry = 0;
|
||
|
} else {
|
||
|
watchdog.Retry++;
|
||
|
if (watchdog.Retry < 5) {
|
||
|
amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceEx4, watchdog, 0, { 'DeviceID': watchdog.DeviceID });
|
||
|
} else {
|
||
|
console.log('Failed to assert presence on this watchdog.');
|
||
|
process.exit(0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Intel AMT Event Log
|
||
|
//
|
||
|
|
||
|
function readAmtEventLog() {
|
||
|
// See if MicroLMS needs to be started
|
||
|
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) {
|
||
|
settings.noconsole = true; startLms(readAmtEventLogEx);
|
||
|
} else {
|
||
|
readAmtEventLogEx(9999);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function readAmtEventLogEx(x) {
|
||
|
if (x == 9999) {
|
||
|
var transport = require('amt-wsman-duk');
|
||
|
var wsman = require('amt-wsman');
|
||
|
var amt = require('amt');
|
||
|
wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
|
||
|
amtstack = new amt(wsstack);
|
||
|
amtstack.GetMessageLog(readAmtEventLogEx2);
|
||
|
} else {
|
||
|
osamtstack.GetMessageLog(readAmtEventLogEx2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function readAmtEventLogEx2(stack, messages) {
|
||
|
if (messages == null) {
|
||
|
console.log('Unable to get event log.');
|
||
|
} else {
|
||
|
var out = '';
|
||
|
if (settings.json) {
|
||
|
out = JSON.stringify(messages, 4, ' ');
|
||
|
} else {
|
||
|
for (var i in messages) { out += messages[i].Time + ', ' + messages[i].EntityStr + ', ' + messages[i].Desc + '\r\n'; }
|
||
|
}
|
||
|
if (settings.output == null) { console.log(out); } else {
|
||
|
var file = fs.openSync(settings.output, 'w');
|
||
|
fs.writeSync(file, Buffer.from(out));
|
||
|
fs.closeSync(file);
|
||
|
}
|
||
|
}
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Intel AMT Audit Log
|
||
|
//
|
||
|
|
||
|
function readAmtAuditLog() {
|
||
|
// See if MicroLMS needs to be started
|
||
|
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) {
|
||
|
settings.noconsole = true; startLms(readAmtAuditLogEx);
|
||
|
} else {
|
||
|
readAmtAuditLogEx(9999);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function readAmtAuditLogEx(x) {
|
||
|
if (x == 9999) {
|
||
|
var transport = require('amt-wsman-duk');
|
||
|
var wsman = require('amt-wsman');
|
||
|
var amt = require('amt');
|
||
|
wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
|
||
|
amtstack = new amt(wsstack);
|
||
|
amtstack.GetAuditLog(readAmtAuditLogEx2);
|
||
|
} else {
|
||
|
osamtstack.GetAuditLog(readAmtAuditLogEx2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function readAmtAuditLogEx2(stack, response, status) {
|
||
|
if (status != 200) {
|
||
|
console.log('Unable to get audit log, status = ' + status + '.');
|
||
|
} else {
|
||
|
var out = '';
|
||
|
if (settings.json) {
|
||
|
out = JSON.stringify(response, 4, ' ');
|
||
|
} else {
|
||
|
for (var i in response) {
|
||
|
var name = ((response[i].Initiator != '') ? (response[i].Initiator + ': ') : '')
|
||
|
out += (response[i].Time + ' - ' + name + response[i].Event + '\r\n');
|
||
|
}
|
||
|
}
|
||
|
if (settings.output == null) { console.log(out); } else {
|
||
|
var file = fs.openSync(settings.output, 'w');
|
||
|
fs.writeSync(file, Buffer.from(out));
|
||
|
fs.closeSync(file);
|
||
|
}
|
||
|
}
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Disable AMT Network
|
||
|
//
|
||
|
|
||
|
//function amtDisable() {
|
||
|
// settings.noconsole = true;
|
||
|
// startLms(amtDisableEx);
|
||
|
//}
|
||
|
|
||
|
//function amtDisableEx(stack, response, status) {
|
||
|
// //console.log(osamtstack);
|
||
|
// osamtstack.Get('AMT_EthernetPortSettings', function (stack, name, response, status) {
|
||
|
// console.log(response.Body);
|
||
|
// });
|
||
|
//}
|
||
|
|
||
|
//
|
||
|
// MeshCommander local web server
|
||
|
//
|
||
|
|
||
|
function startMeshCommander() {
|
||
|
if (settings.localport == null) { settings.localport = 3000; }
|
||
|
|
||
|
// Start the web server
|
||
|
var http = require('http');
|
||
|
webServer = http.createServer();
|
||
|
webServer.listen(settings.localport);
|
||
|
webServer.wsList = {};
|
||
|
webServer.wsListIndex = 0;
|
||
|
webServer.on('upgrade', function (req, socket, head) {
|
||
|
//console.log("WebSocket for " + req.url.split('?')[0]);
|
||
|
switch (req.url.split('?')[0]) {
|
||
|
case '/webrelay.ashx': // MeshCommander relay channel
|
||
|
var ws = socket.upgradeWebSocket();
|
||
|
socket.ws = ws;
|
||
|
ws.wsIndex = ++webServer.wsListIndex;
|
||
|
webServer.wsList[ws.wsIndex] = ws; // Keep a reference so the websocket and forwarder don't get disposed.
|
||
|
ws.pause();
|
||
|
|
||
|
// We got a new web socket connection, initiate a TCP connection to the target Intel AMT host/port.
|
||
|
var webargs = parseUrlArguments(req.url);
|
||
|
if (webargs.p) { webargs.p = parseInt(webargs.p); }
|
||
|
if (webargs.tls) { webargs.tls = parseInt(webargs.tls); }
|
||
|
if (webargs.tls1only) { webargs.tls1only = parseInt(webargs.tls1only); }
|
||
|
if (webargs.port) { webargs.port = parseInt(webargs.port); }
|
||
|
debug(1, 'Opening web socket connection to ' + webargs.host + ':' + webargs.port + '.');
|
||
|
//console.log('Opening web socket connection to ' + webargs.host + ':' + webargs.port + '.');
|
||
|
if (webargs.tls == 0) {
|
||
|
// If this is TCP (without TLS) set a normal TCP socket
|
||
|
var net = require('net');
|
||
|
ws.forwardclient = net.connect({ host: webargs.host, port: webargs.port })
|
||
|
ws.forwardclient.on('connect', function () { debug(1, 'Connected TCP to ' + webargs.host + ':' + webargs.port + '.'); this.pipe(this.ws, { end: false }); this.ws.pipe(this, { end: false }); });
|
||
|
ws.forwardclient.on('error', function () { debug(1, 'TCP connection error to ' + webargs.host + ':' + webargs.port + '.'); try { this.ws.end(); } catch (e) { } });
|
||
|
ws.forwardclient.ws = ws;
|
||
|
} else {
|
||
|
// If TLS is going to be used, setup a TLS socket
|
||
|
var tls = require('tls');
|
||
|
var tlsoptions = { host: webargs.host, port: webargs.port, secureProtocol: ((webargs.tls1only == 1) ? 'TLSv1_method' : 'SSLv23_method'), rejectUnauthorized: false };
|
||
|
ws.forwardclient = tls.connect(tlsoptions, function () { debug(1, 'Connected TLS to ' + webargs.host + ':' + webargs.port + '.'); this.pipe(this.ws, { end: false }); this.ws.pipe(this, { end: false }); });
|
||
|
ws.forwardclient.on('error', function () { debug(1, 'TLS connection error to ' + webargs.host + ':' + webargs.port + '.'); try { this.ws.end(); } catch (e) { } });
|
||
|
ws.forwardclient.ws = ws;
|
||
|
}
|
||
|
|
||
|
// Handle pipe closure
|
||
|
ws.on('end', function () { debug(1, 'Disconnected from ' + webargs.host + ':' + webargs.port + '.'); try { this.forwardclient.end(); } catch (e) { } delete webServer.wsList[this.wsIndex]; });
|
||
|
ws.forwardclient.on('end', function () { try { this.ws.end(); } catch (e) { } });
|
||
|
|
||
|
break;
|
||
|
default:
|
||
|
socket.end();
|
||
|
break;
|
||
|
}
|
||
|
});
|
||
|
webServer.on('request', function (req, rsp) {
|
||
|
//console.log("WebRequest for " + req.url.split('?')[0]);
|
||
|
switch (req.url.split('?')[0]) {
|
||
|
case '/': // Serve MeshCommander Web Application
|
||
|
var meshcommander = null;
|
||
|
try { meshcommander = fs.readFileSync('meshcommander.htm'); } catch (e) { }
|
||
|
if (meshcommander != null) {
|
||
|
rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Transfer-Encoding': 'chunked' });
|
||
|
rsp.end(meshcommander);
|
||
|
} else {
|
||
|
rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Content-Encoding': 'gzip', 'Transfer-Encoding': 'chunked', ETag: FullSite_IntelAmtLocalWebApp_etag });
|
||
|
rsp.end(Buffer.from(FullSite_IntelAmtLocalWebApp, 'base64'));
|
||
|
}
|
||
|
break;
|
||
|
default: // Unknown request
|
||
|
rsp.statusCode = 404;
|
||
|
rsp.statusMessage = "Not Found";
|
||
|
rsp.end();
|
||
|
break;
|
||
|
}
|
||
|
});
|
||
|
console.log('MeshCommander running on HTTP port ' + settings.localport + '.');
|
||
|
console.log('Press ctrl-c to exit.');
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Deactivate Intel AMT CCM
|
||
|
//
|
||
|
|
||
|
// When called, this will use MEI to deactivate Intel AMT when it's in CCM mode. Simply calls "unprovision" on MEI and checks the return code.
|
||
|
function deactivateCCM() {
|
||
|
var amtMeiModule, amtMei;
|
||
|
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
|
||
|
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||
|
amtMei.unprovision(1, function (status) { if (status == 0) { console.log('Success'); } else { console.log('Error ' + status); } exit(1); });
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Activate Intel AMT to CCM
|
||
|
//
|
||
|
|
||
|
function activeToCCM() {
|
||
|
// See if MicroLMS needs to be started and setup the $$OsAdmin wsman stack
|
||
|
settings.noconsole = true;
|
||
|
startLms(activeToCCMEx); // TODO: Fix this so that it works even if LMS already running.
|
||
|
}
|
||
|
|
||
|
function activeToCCMEx(state) {
|
||
|
osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], activeToCCMEx2);
|
||
|
}
|
||
|
|
||
|
function activeToCCMEx2(stack, name, responses, status) {
|
||
|
if (status != 200) { console.log('Failed to fetch activation status, status ' + status); exit(1); }
|
||
|
else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { console.log('Client control mode activation not allowed'); exit(1); }
|
||
|
else { osamtstack.IPS_HostBasedSetupService_Setup(2, md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + settings.password).substring(0, 32), null, null, null, null, activeToCCMEx3); }
|
||
|
}
|
||
|
|
||
|
function activeToCCMEx3(stack, name, responses, status) {
|
||
|
if (status != 200) { console.log('Failed to activate, status ' + status); }
|
||
|
else if (responses.Body.ReturnValue != 0) { console.log('Client control mode activation failed: ' + responses.Body.ReturnValueStr); }
|
||
|
else { console.log('Success'); exit(0); }
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// Deactivate Intel AMT ACM
|
||
|
//
|
||
|
|
||
|
// When called, this will use MEI to deactivate Intel AMT when it's in ACM mode. Calls "unprovision" on MEI and checks the return code.
|
||
|
function deactivateACM() {
|
||
|
settings.noconsole = true;
|
||
|
startLms(deactivateACMEx);
|
||
|
}
|
||
|
|
||
|
function deactivateACMEx() {
|
||
|
var transport = require('amt-wsman-duk');
|
||
|
var wsman = require('amt-wsman');
|
||
|
var amt = require('amt');
|
||
|
wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
|
||
|
amtstack = new amt(wsstack);
|
||
|
amtstack.Get("AMT_SetupAndConfigurationService", function (stack, name, responses, status) {
|
||
|
if (status !== 200) {
|
||
|
console.log('Command not allowed. Status: ' + status);
|
||
|
exit(1);
|
||
|
} else {
|
||
|
var sacs = responses.Body;
|
||
|
if (sacs.ZeroTouchConfigurationEnabled == true) { sacs.ZeroTouchConfigurationEnabled = true; }
|
||
|
amtstack.Put("AMT_SetupAndConfigurationService", sacs, function (stack, name, responses, status) {
|
||
|
if (settings.type == 'full') {
|
||
|
amtstack.AMT_SetupAndConfigurationService_Unprovision(2, function (stack, name, responses, status) {
|
||
|
if (status != 200) { console.log('Failed to fully unconfigure AMT, status ' + status); exit(1); }
|
||
|
else if (responses.Body.ReturnValue != 0) { console.log('Unprovision failed: ' + responses.Body.ReturnValueStr); exit(1); }
|
||
|
else { console.log('AMT fully unprovisioned.'); exit(0); }
|
||
|
});
|
||
|
} else {
|
||
|
console.log('Only full unprovision is currently supported.');
|
||
|
exit(0);
|
||
|
}
|
||
|
//} else if (settings.type == 'partial') {
|
||
|
// amtstack.AMT_SetupAndConfigurationService_PartialUnprovision(null, function (stack, name, responses, status) {
|
||
|
// if (status != 200) { console.log('Failed to partially unconfigure AMT, status ' + status); exit(1); }
|
||
|
// else if (responses.Body.ReturnValue != 0) { console.log('Unprovision failed: ' + responses.Body.ReturnValueStr); exit(1); }
|
||
|
// else { console.log('AMT partially unprovisioned.'); exit(0); }
|
||
|
// });
|
||
|
//}
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get Intel AMT activation hashes
|
||
|
//
|
||
|
|
||
|
var trustedHashes = null;
|
||
|
function getTrustedHashes(amtMei, func, tag) {
|
||
|
if (trustedHashes != null) { func(tag); }
|
||
|
trustedHashes = [];
|
||
|
amtMei.getHashHandles(function (handles) {
|
||
|
var exitOnCount = handles.length;
|
||
|
for (var i = 0; i < handles.length; ++i) {
|
||
|
this.getCertHashEntry(handles[i], function (result) {
|
||
|
if (result.isActive == 1) { trustedHashes.push(result.certificateHash.toLowerCase()); }
|
||
|
if (--exitOnCount == 0) { func(tag); }
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Activate Intel AMT to with server (ACM or CCM)
|
||
|
//
|
||
|
|
||
|
function activeToACM() {
|
||
|
console.log('Starting Intel AMT activation attempt...');
|
||
|
settings.noconsole = true;
|
||
|
|
||
|
// Display Intel AMT version and activation state
|
||
|
mestate = {};
|
||
|
var amtMeiModule, amtMei;
|
||
|
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
|
||
|
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||
|
amtMei.getProvisioningState(function (result) { if (result) { mestate.ProvisioningState = result; } });
|
||
|
amtMei.getVersion(function (val) { mestate.vers = {}; if (val != null) { for (var version in val.Versions) { mestate.vers[val.Versions[version].Description] = val.Versions[version].Version; } } });
|
||
|
amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } });
|
||
|
amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } });
|
||
|
amtMei.getControlMode(function (result) { if (result != null) { mestate.controlMode = result.controlMode; } }); // controlMode: 0 = NoActivated, 1 = CCM, 2 = ACM
|
||
|
amtMei.getDnsSuffix(function (result) {
|
||
|
if ((mestate.vers == null) || (mestate.vers['AMT'] == null)) { console.log("Unable to get Intel AMT version."); exit(100); return; }
|
||
|
if (mestate.ProvisioningState == null) { console.log("Unable to read Intel AMT activation state."); exit(100); return; }
|
||
|
if ((settings.action != 'amtdiscover') && (mestate.controlMode == 2)) { console.log("Intel AMT already activation in admin control mode."); exit(100); return; }
|
||
|
if (mestate.uuid == null) { console.log("Unable to get Intel AMT UUID."); exit(100); return; }
|
||
|
var fqdn = null;
|
||
|
if ((mestate.net0 == null) && (meinfo.net0.enabled != 0)) { console.log("No Intel AMT wired interface, can't perform ACM activation."); exit(100); return; }
|
||
|
if (result) { fqdn = result; } // If Intel AMT has a trusted DNS suffix set, use that one.
|
||
|
else {
|
||
|
// Look for the DNS suffix for the Intel AMT Ethernet interface
|
||
|
var interfaces = require('os').networkInterfaces();
|
||
|
for (var i in interfaces) {
|
||
|
for (var j in interfaces[i]) {
|
||
|
if ((interfaces[i][j].mac == mestate.net0.mac) && (interfaces[i][j].fqdn != null) && (interfaces[i][j].fqdn != '')) { fqdn = interfaces[i][j].fqdn; }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (fqdn != null) {
|
||
|
settings.fqdn = fqdn;
|
||
|
settings.uuid = mestate.uuid;
|
||
|
getTrustedHashes(amtMei, function () { startLms(getFwNonce, amtMei); });
|
||
|
} else {
|
||
|
console.log("Trusted DNS suffix not set, can't perform ACM activation."); exit(100); return;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Gets the FWNonce from AMT and saves it to a file.
|
||
|
function getFwNonce() {
|
||
|
osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], function (stack, name, responses, status) {
|
||
|
if (status != 200) { console.log("Unable to get firmware activation nonce, status=" + status); exit(100); return; }
|
||
|
var fwNonce = responses['IPS_HostBasedSetupService'].response['ConfigurationNonce'];
|
||
|
var digestRealm = responses['AMT_GeneralSettings'].response['DigestRealm'];
|
||
|
var allowedModes = responses['IPS_HostBasedSetupService'].response['AllowedControlModes']; // 1 = CCM, 2 = ACM
|
||
|
activeToACMEx(fwNonce, settings.fqdn, digestRealm, settings.uuid, allowedModes);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Connect to the activation server and perform ACM activation
|
||
|
function activeToACMEx(fwNonce, dnsSuffix, digestRealm, uuid, allowedModes) {
|
||
|
console.log('FQDN: ' + dnsSuffix);
|
||
|
console.log('UUID: ' + uuid);
|
||
|
console.log('Realm: ' + digestRealm);
|
||
|
console.log('Nonce: ' + fwNonce);
|
||
|
console.log('Connecting to ' + settings.url);
|
||
|
|
||
|
// Establish WebSocket connection to activation server
|
||
|
var options = http.parseUri(settings.url);
|
||
|
options.checkServerIdentity = onVerifyServer;
|
||
|
options.rejectUnauthorized = false;
|
||
|
var connection = http.request(options);
|
||
|
connection.on('upgrade', function (response, socket) {
|
||
|
settings.xxsocket = socket;
|
||
|
console.log('Connected, requesting activation...');
|
||
|
socket.on('end', function () { console.log('Connection closed'); exit(0); });
|
||
|
socket.on('error', function () { console.log('Connection error'); exit(100); });
|
||
|
socket.on('data', function (data) {
|
||
|
// Parse and check the response
|
||
|
var cmd = null;
|
||
|
try { cmd = JSON.parse(data); } catch (ex) { console.log('Unable to parse server response: ' + data); exit(100); return; }
|
||
|
if (typeof cmd != 'object') { console.log('Invalid server response: ' + cmd); exit(100); return; }
|
||
|
if (typeof cmd.errorText == 'string') { console.log('Server error: ' + cmd.errorText); exit(100); return; }
|
||
|
switch (cmd.action) {
|
||
|
case 'acmactivate': {
|
||
|
// Server responded with ACM activation response
|
||
|
if (typeof cmd.signature != 'string') { console.log('Invalid server signature'); exit(100); return; }
|
||
|
if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; }
|
||
|
if (typeof cmd.nonce != 'string') { console.log('Invalid server nonce'); exit(100); return; }
|
||
|
if (typeof cmd.certs != 'object') { console.log('Invalid server certificates'); exit(100); return; }
|
||
|
settings.xxprofileScript = cmd.profileScript;
|
||
|
settings.xxrawpassword = cmd.rawpassword;
|
||
|
|
||
|
cmd.index = 0;
|
||
|
// If we are in CCM mode, deactivate.
|
||
|
if (mestate.controlMode == 1) {
|
||
|
amtMei.unprovision(1, function (status) {
|
||
|
if (status == 0) {
|
||
|
console.log('Intel AMT CCM deactivated, holding 10 seconds...');
|
||
|
// We are ready to go, perform ACM activation.
|
||
|
settings.xxTimer = setTimeout(function () { performAcmActivation(cmd, AcmActivationCompleted); }, 10000);
|
||
|
} else {
|
||
|
console.log('Intel AMT CCM deactivation error ' + status); exit(1); return;
|
||
|
}
|
||
|
});
|
||
|
} else {
|
||
|
// We are ready to go, perform ACM activation.
|
||
|
performAcmActivation(cmd, AcmActivationCompleted);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case 'ccmactivate': {
|
||
|
// Server responded with CCM activation response
|
||
|
if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; }
|
||
|
settings.xxprofileScript = cmd.profileScript;
|
||
|
settings.xxrawpassword = cmd.rawpassword;
|
||
|
|
||
|
// If we are already in CCM mode, deactivate.
|
||
|
if (mestate.controlMode == 1) {
|
||
|
amtMei.unprovision(1, function (status) {
|
||
|
if (status == 0) {
|
||
|
console.log('Intel AMT CCM deactivated, holding 10 seconds...');
|
||
|
// We are ready to go, perform CCM activation.
|
||
|
settings.xxTimer = setTimeout(function () { osamtstack.IPS_HostBasedSetupService_Setup(2, cmd.password, null, null, null, null, performCcmActivation); }, 10000);
|
||
|
} else {
|
||
|
console.log('Intel AMT CCM deactivation error ' + status); exit(1); return;
|
||
|
}
|
||
|
});
|
||
|
} else {
|
||
|
// We are ready to go, perform CCM activation.
|
||
|
osamtstack.IPS_HostBasedSetupService_Setup(2, cmd.password, null, null, null, null, performCcmActivation);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case 'amtdiscover': {
|
||
|
console.log('Done.');
|
||
|
exit(0);
|
||
|
break;
|
||
|
}
|
||
|
default: {
|
||
|
console.log('Invalid server response, command: ' + cmd.action); exit(100);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var action = 'acmactivate';
|
||
|
if (settings.action == 'amtccm') { action = 'ccmactivate'; }
|
||
|
if (settings.action == 'amtdiscover') { action = 'amtdiscover'; }
|
||
|
socket.write({ client: 'meshcmd', version: 1, action: action, fqdn: dnsSuffix, realm: digestRealm, nonce: fwNonce, uuid: uuid, profile: settings.profile, hashes: trustedHashes, tag: settings.tag, name: settings.name, ver: mestate.vers['AMT'], build: mestate.vers['Build Number'], modes: allowedModes, currentMode: mestate.controlMode });
|
||
|
});
|
||
|
connection.end();
|
||
|
}
|
||
|
|
||
|
function performCcmActivation(stack, name, responses, status) {
|
||
|
if (status != 200) {
|
||
|
settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-failed', uuid: mestate.uuid });
|
||
|
console.log('Failed to activate, status ' + status);
|
||
|
} else if (responses.Body.ReturnValue != 0) {
|
||
|
settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-failed', uuid: mestate.uuid });
|
||
|
console.log('Intel AMT CCM activation failed: ' + responses.Body.ReturnValueStr);
|
||
|
} else {
|
||
|
settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'ccmactivate-success', uuid: mestate.uuid });
|
||
|
if ((settings.xxprofileScript !== null) && (settings.xxrawpassword != null)) {
|
||
|
console.log("Intel AMT CCM activation success, applying profile...");
|
||
|
settings.scriptjson = settings.xxprofileScript;
|
||
|
settings.password = settings.xxrawpassword; // This is only going to work if the server sends the raw password
|
||
|
settings.username = 'admin';
|
||
|
startMeScriptEx(function () { console.log('Intel AMT profile applied.'); socket.end(); exit(0); }, stack);
|
||
|
return;
|
||
|
} else {
|
||
|
console.log('Intel AMT CCM activation success.');
|
||
|
settings.xxsocket.end();
|
||
|
exit(0);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
settings.xxsocket.end();
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
function AcmActivationCompleted(result) {
|
||
|
if (result == false) {
|
||
|
console.log('Intel AMT ACM activation failed.');
|
||
|
settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'acmactivate-failed', uuid: mestate.uuid });
|
||
|
settings.xxsocket.end();
|
||
|
exit(1);
|
||
|
} else {
|
||
|
if ((settings.xxprofileScript !== null) && (settings.xxrawpassword != null)) {
|
||
|
console.log('Intel AMT ACM activation success, applying profile...');
|
||
|
settings.scriptjson = settings.xxprofileScript;
|
||
|
settings.password = settings.xxrawpassword; // This is only going to work if the server sends the raw password
|
||
|
settings.username = 'admin';
|
||
|
startMeScriptEx(function () { console.log('Intel AMT profile applied.'); settings.xxsocket.end(); exit(0); }, stack);
|
||
|
} else {
|
||
|
console.log('Intel AMT ACM activation success.');
|
||
|
settings.xxsocket.write({ client: 'meshcmd', version: 1, action: 'acmactivate-success', uuid: mestate.uuid });
|
||
|
settings.xxsocket.end();
|
||
|
exit(0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Recursive function to inject the provisioning certificates into AMT in the proper order and completes ACM activation
|
||
|
function performAcmActivation(acmdata, func) {
|
||
|
var leaf = (acmdata.index == 0), root = (acmdata.index == (acmdata.certs.length - 1));
|
||
|
if ((acmdata.index < acmdata.certs.length) && (acmdata.certs[acmdata.index] != null)) {
|
||
|
osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(acmdata.certs[acmdata.index], leaf, root, function (stack, name, responses, status) {
|
||
|
if (status !== 200) { console.log('AddNextCertInChain error, status=' + status); exit(1); return; }
|
||
|
else if (responses['Body']['ReturnValue'] !== 0) { console.log('AddNextCertInChain error: ' + responses['Body']['ReturnValue']); exit(1); return; }
|
||
|
else { acmdata.index++; performAcmActivation(acmdata, func); }
|
||
|
});
|
||
|
} else {
|
||
|
//console.log(acmdata.password, acmdata.nonce, acmdata.signature);
|
||
|
osamtstack.IPS_HostBasedSetupService_AdminSetup(2, acmdata.password, acmdata.nonce, 2, acmdata.signature,
|
||
|
function (stack, name, responses, status) {
|
||
|
if (status !== 200) { console.log('Error, AdminSetup status: ' + status); }
|
||
|
else if (responses['Body']['ReturnValue'] != 0) { console.log('Error, AdminSetup return value: ' + responses['Body']['ReturnValue']); }
|
||
|
func((status == 200) && (responses['Body']['ReturnValue'] == 0));
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get AMT UUID
|
||
|
//
|
||
|
|
||
|
// Called to get the UUID of Intel AMT, start by setting up MicroLMS if we are doing the operation on the local computer
|
||
|
function getAmtUuid() {
|
||
|
if (settings.hostname == null) {
|
||
|
var amtMeiModule, amtMei;
|
||
|
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
|
||
|
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||
|
amtMei.getUuid(function (result) { if ((result == null) || (result.uuid == null)) { console.log('Failed.'); } else { console.log(result.uuid); } exit(1); });
|
||
|
} else {
|
||
|
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { settings.noconsole = true; startLms(getAmtUuidEx); return; } else { getAmtUuidEx(); }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Fetch the computer's UUID by fetching the CIM_ComputerSystemPackage WSMAN object.
|
||
|
function getAmtUuidEx() {
|
||
|
var transport = require('amt-wsman-duk');
|
||
|
var wsman = require('amt-wsman');
|
||
|
var amt = require('amt');
|
||
|
wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
|
||
|
amtstack = new amt(wsstack);
|
||
|
amtstack.Get("CIM_ComputerSystemPackage", function (obj, name, response, xstatus, tag) {
|
||
|
if (xstatus == 200) { console.log("GUID: " + guidToStr(response.Body.PlatformGUID.toLowerCase())); } else { console.log("Intel AMT is not available or not activated."); } exit(1);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Run MESCRIPT
|
||
|
//
|
||
|
|
||
|
// Run a .mescript targeting local or remote Intel AMT.
|
||
|
function startMeScript() {
|
||
|
// See if MicroLMS needs to be started
|
||
|
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { settings.noconsole = true; startLms(startMeScriptEx); return; } else { startMeScriptEx(); }
|
||
|
}
|
||
|
|
||
|
function startMeScriptEx(callback, amtstack) {
|
||
|
//console.log('Running script...');
|
||
|
var transport = require('amt-wsman-duk');
|
||
|
var wsman = require('amt-wsman');
|
||
|
var amt = require('amt');
|
||
|
if (!wsstack) { wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); }
|
||
|
if (!amtstack) { amtstack = new amt(wsstack); }
|
||
|
//IntelAmtEntireStateProgress = 101;
|
||
|
//amtstack.onProcessChanged = onWsmanProcessChanged;
|
||
|
|
||
|
var scriptData = null;
|
||
|
if (settings.script != null) {
|
||
|
try { scriptData = fs.readFileSync(settings.script); } catch (e) { console.log('Unable to read script file (1): ' + settings.script + '.'); exit(1); return; }
|
||
|
} else {
|
||
|
scriptData = settings.scriptjson;
|
||
|
}
|
||
|
if (scriptData == null) { console.log('Unable to read script file (2): ' + settings.script + '.'); exit(1); return; }
|
||
|
try { scriptData = JSON.parse(scriptData); } catch (e) { console.log('Unable to read script file (3): ' + settings.script + '.'); exit(1); return; }
|
||
|
if (scriptData.mescript == null) { console.log('Unable to read script file (4): ' + settings.script + '.'); exit(1); return; }
|
||
|
var scriptData = Buffer.from(scriptData.mescript, 'base64');
|
||
|
|
||
|
var scriptModule = require('amt-script');
|
||
|
var script = scriptModule.setup(scriptData, {})
|
||
|
script.amtstack = amtstack;
|
||
|
script.start();
|
||
|
script.onCompleted = function () { if (callback) { callback(); } exit(1); }
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// FETCH ALL INTEL AMT STATE
|
||
|
//
|
||
|
|
||
|
function saveEntireAmtState2() {
|
||
|
console.log('Fetching all Intel AMT state, this may take a few minutes...');
|
||
|
var transport = require('amt-wsman-duk');
|
||
|
var wsman = require('amt-wsman');
|
||
|
var amt = require('amt');
|
||
|
wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
|
||
|
amtstack = new amt(wsstack);
|
||
|
amtstack.onProcessChanged = onWsmanProcessChanged;
|
||
|
//var AllWsman = "AMT_GeneralSystemDefenseCapabilities".split(',');
|
||
|
var AllWsman = "AMT_8021xCredentialContext,AMT_8021XProfile,AMT_ActiveFilterStatistics,AMT_AgentPresenceCapabilities,AMT_AgentPresenceInterfacePolicy,AMT_AgentPresenceService,AMT_AgentPresenceWatchdog,AMT_AgentPresenceWatchdogAction,AMT_AlarmClockService,IPS_AlarmClockOccurrence,AMT_AssetTable,AMT_AssetTableService,AMT_AuditLog,AMT_AuditPolicyRule,AMT_AuthorizationService,AMT_BootCapabilities,AMT_BootSettingData,AMT_ComplexFilterEntryBase,AMT_CRL,AMT_CryptographicCapabilities,AMT_EACCredentialContext,AMT_EndpointAccessControlService,AMT_EnvironmentDetectionInterfacePolicy,AMT_EnvironmentDetectionSettingData,AMT_EthernetPortSettings,AMT_EventLogEntry,AMT_EventManagerService,AMT_EventSubscriber,AMT_FilterEntryBase,AMT_FilterInSystemDefensePolicy,AMT_GeneralSettings,AMT_GeneralSystemDefenseCapabilities,AMT_Hdr8021Filter,AMT_HeuristicPacketFilterInterfacePolicy,AMT_HeuristicPacketFilterSettings,AMT_HeuristicPacketFilterStatistics,AMT_InterfacePolicy,AMT_IPHeadersFilter,AMT_KerberosSettingData,AMT_ManagementPresenceRemoteSAP,AMT_MessageLog,AMT_MPSUsernamePassword,AMT_NetworkFilter,AMT_NetworkPortDefaultSystemDefensePolicy,AMT_NetworkPortSystemDefenseCapabilities,AMT_NetworkPortSystemDefensePolicy,AMT_PCIDevice,AMT_PETCapabilities,AMT_PETFilterForTarget,AMT_PETFilterSetting,AMT_ProvisioningCertificateHash,AMT_PublicKeyCertificate,AMT_PublicKeyManagementCapabilities,AMT_PublicKeyManagementService,AMT_PublicPrivateKeyPair,AMT_RedirectionService,AMT_RemoteAccessCapabilities,AMT_RemoteAccessCredentialContext,AMT_RemoteAccessPolicyAppliesToMPS,AMT_RemoteAccessPolicyRule,AMT_RemoteAccessService,AMT_SetupAndConfigurationService,AMT_SNMPEventSubscriber,AMT_StateTransitionCondition,AMT_SystemDefensePolicy,AMT_SystemDefensePolicyInService,AMT_SystemDefenseService,AMT_SystemPowerScheme,AMT_ThirdPartyDataStorageAdministrationService,AMT_ThirdPartyDataStorageService,AMT_TimeSynchronizationService,AMT_TLSCredentialContext,AMT_TLSProtocolEndpoint,AMT_TLSProtocolEndpointCollection,AMT_TLSSettingData,AMT_TrapTargetForService,AMT_UserInitiatedConnectionService,AMT_WebUIService,AMT_WiFiPortConfigurationService,CIM_AbstractIndicationSubscription,CIM_Account,CIM_AccountManagementCapabilities,CIM_AccountManagementService,CIM_AccountOnSystem,CIM_AdminDomain,CIM_AlertIndication,CIM_AssignedIdentity,CIM_AssociatedPowerManagementService,CIM_AuthenticationService,CIM_AuthorizationService,CIM_BIOSElement,CIM_BIOSFeature,CIM_BIOSFeatureBIOSElements,CIM_BootConfigSetting,CIM_BootService,CIM_BootSettingData,CIM_BootSourceSetting,CIM_Capabilities,CIM_Card,CIM_Chassis,CIM_Chip,CIM_Collection,CIM_Component,CIM_ComputerSystem,CIM_ComputerSystemPackage,CIM_ConcreteComponent,CIM_ConcreteDependency,CIM_Controller,CIM_CoolingDevice,CIM_Credential,CIM_CredentialContext,CIM_CredentialManagementService,CIM_Dependency,CIM_DeviceSAPImplementation,CIM_ElementCapabilities,CIM_ElementConformsToProfile,CIM_ElementLocation,CIM_ElementSettingData,CIM_ElementSoftwareIdentity,CIM_ElementStatisticalData,CIM_EnabledLogicalElement,CIM_EnabledLogicalElementCapabilities,CIM_EthernetPort,CIM_Fan,CIM_FilterCollection,CIM_FilterCollectionSubscription,CIM_HostedAccessPoint,CIM_HostedDependency,CIM_HostedService,CIM_Identity,CIM_IEEE8021xCapabilities,CIM_IEEE8021xSettings,CIM_Indication,CIM_IndicationService,CIM_InstalledSoftwareIdentity,CIM_KVMRedirectionSAP,CIM_LANEndpoint,CIM_ListenerDestination,CIM_ListenerDestinationWSManagement,CIM_Location,CIM_Log,CIM_LogEntry,CIM_LogicalDevice,CIM_LogicalElement,CIM_LogicalPort,CIM_LogicalPortCapabilities,CIM_LogManagesRecord,CIM_ManagedCredential,CIM_ManagedElement,CIM_ManagedSystemElement,CIM_MediaAccessDevice,CIM_MemberOfCollection,CIM_Memory,CIM_MessageLog,CIM_NetworkPort,CIM_NetworkPortCapabilities,CIM_NetworkPortConfigurationService,CIM_OrderedComponent,CIM_OwningCollectionElement,CIM_OwningJobElement,CIM_PCIController,CIM_PhysicalComponent,CIM_PhysicalElement,CIM_PhysicalElementLocation,CIM_PhysicalFrame,CIM_PhysicalMemory,CIM_PhysicalPackage,CIM_Policy,CIM_PolicyAction,CIM_PolicyCondition,CIM_PolicyInSystem,CIM_PolicyRule,CIM_PolicyR
|
||
|
IntelAmtEntireStateProgress = 101;
|
||
|
IntelAmtEntireStateCalls = 3;
|
||
|
IntelAmtEntireState = { 'localtime': Date(), 'utctime': new Date().toUTCString(), 'isotime': new Date().toISOString() };
|
||
|
amtstack.BatchEnum(null, AllWsman, saveEntireAmtStateOk2, null, true);
|
||
|
amtstack.GetAuditLog(saveEntireAmtStateOk3);
|
||
|
amtstack.GetMessageLog(saveEntireAmtStateOk4);
|
||
|
|
||
|
}
|
||
|
|
||
|
// Save the entire Intel AMT state
|
||
|
function saveEntireAmtState() {
|
||
|
// See if MicroLMS needs to be started
|
||
|
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) {
|
||
|
settings.noconsole = true;
|
||
|
startLms().then(saveEntireAmtState2);
|
||
|
}
|
||
|
else {
|
||
|
saveEntireAmtState2();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function onWsmanProcessChanged(a, b) { var x = Math.floor((a * 100) / b); if (x < IntelAmtEntireStateProgress) { IntelAmtEntireStateProgress = x; console.log((100 - x) + '%'); } }
|
||
|
function saveEntireAmtStateOk2(stack, name, responses, status) { if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); exit(2); } IntelAmtEntireState['wsmanenums'] = responses; saveEntireAmtStateDone(); }
|
||
|
function saveEntireAmtStateOk3(stack, messages, status) { if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); exit(2); } IntelAmtEntireState['auditlog'] = messages; saveEntireAmtStateDone(); }
|
||
|
function saveEntireAmtStateOk4(stack, messages, tag, status) { if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); exit(2); } IntelAmtEntireState['eventlog'] = messages; saveEntireAmtStateDone(); }
|
||
|
|
||
|
// Called when the entire state of Intel AMT is fetched.
|
||
|
function saveEntireAmtStateDone() {
|
||
|
if (--IntelAmtEntireStateCalls != 0) return;
|
||
|
var out = fs.openSync(settings.output, 'w');
|
||
|
fs.writeSync(out, Buffer.from(JSON.stringify(IntelAmtEntireState)));
|
||
|
fs.closeSync(out);
|
||
|
console.log('Done, results written to ' + settings.output + '.');
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// FETCH ALL INTEL AMT MEI STATE
|
||
|
//
|
||
|
|
||
|
// Get Intel AMT information using MEI
|
||
|
// TODO: If this call is called many time at once, it's going to cause issues.
|
||
|
var getAmtInfoFetching = null;
|
||
|
var getAmtInfoFetchingTimer = null;
|
||
|
function getAmtInfo(func, tag) {
|
||
|
if (amtMei == null) { if (func != null) { func(null, tag); } return; }
|
||
|
if (getAmtInfoFetching != null) { getAmtInfoFetching.push({ f: func, t: tag }); return; }
|
||
|
getAmtInfoFetching = [{ f: func, t: tag }];
|
||
|
amtMeiTmpState = { Flags: 0, TrustedHashes: [] }; // Flags: 1=EHBC, 2=CCM, 4=ACM
|
||
|
getAmtInfoFetchingTimer = setTimeout(function () {
|
||
|
// MEI failed to respond, break out and reset everthing.
|
||
|
for (var i in getAmtInfoFetching) { if (getAmtInfoFetching[i].f != null) { getAmtInfoFetching[i].f(amtMeiTmpState, getAmtInfoFetching[i].t); } }
|
||
|
getAmtInfoFetching = null;
|
||
|
getAmtInfoFetchingTimer = null;
|
||
|
var amtMeiModule, amtMei;
|
||
|
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
|
||
|
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||
|
}, 3000);
|
||
|
amtMei.getProtocolVersion(function (result) { if (result != null) { amtMeiTmpState.MeiVersion = result; } });
|
||
|
amtMei.getVersion(function (val) {
|
||
|
amtMeiTmpState.Versions = {};
|
||
|
if (val != null) {
|
||
|
for (var version in val.Versions) { amtMeiTmpState.Versions[val.Versions[version].Description] = val.Versions[version].Version; }
|
||
|
amtMei.getProvisioningMode(function (result) { if (result != null) { amtMeiTmpState.ProvisioningMode = result.mode; } });
|
||
|
amtMei.getProvisioningState(function (result) { if (result != null) { amtMeiTmpState.ProvisioningState = result.state; } });
|
||
|
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; } } });
|
||
|
//amtMei.getMACAddresses(function (result) { if (result != null) { amtMeiTmpState.mac = result; } });
|
||
|
amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } });
|
||
|
amtMei.getHashHandles(function (handles) {
|
||
|
exitOnCount = handles.length;
|
||
|
for (var i = 0; i < handles.length; ++i) {
|
||
|
amtMei.getCertHashEntry(handles[i], function (result) {
|
||
|
amtMeiTmpState.TrustedHashes.push({ Active: result.isActive, Default: result.isDefault, HashAlgorithm: result.hashAlgorithm, Name: result.name, Hash: result.certificateHash });
|
||
|
if (--exitOnCount == 0) {
|
||
|
amtMeiTmpState.Notifications = lmsNotifications; amtMeiState = amtMeiTmpState;
|
||
|
for (var i in getAmtInfoFetching) { if (getAmtInfoFetching[i].f != null) { getAmtInfoFetching[i].f(amtMeiTmpState, getAmtInfoFetching[i].t); } }
|
||
|
getAmtInfoFetching = null;
|
||
|
clearTimeout(getAmtInfoFetchingTimer);
|
||
|
getAmtInfoFetchingTimer = null;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
} else {
|
||
|
amtMeiState = amtMeiTmpState;
|
||
|
amtMeiState.ProvisioningMode = -858993460;
|
||
|
amtMeiState.TrustedHashes = {};
|
||
|
amtMeiState.Notifications = lmsNotifications;
|
||
|
//console.log('getAmtInfo3', JSON.stringify(amtMeiState));
|
||
|
if (func != null) { func(amtMeiState, tag); }
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// MicroLMS
|
||
|
//
|
||
|
|
||
|
var lmsControlSockets = {};
|
||
|
var lmsControlSocketsNextId = 1;
|
||
|
var lmsNotifications = [];
|
||
|
var amtLms = null;
|
||
|
var promise = require('promise');
|
||
|
|
||
|
function startLms(func, lmscommander, tag) {
|
||
|
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
|
||
|
var lme_heci = null
|
||
|
try { lme_heci = require('amt-lme'); } catch (ex) { }
|
||
|
if (lme_heci == null) { if (func != null) { func(0, tag); } this.promise._res(); return; }
|
||
|
|
||
|
//var amtLms = null;
|
||
|
var http = require('http');
|
||
|
|
||
|
console.log('Setting up MEI...');
|
||
|
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
|
||
|
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||
|
//console.log("PTHI Connected.");
|
||
|
|
||
|
console.log('Setting up LME...');
|
||
|
amtLms = new lme_heci({ debug: settings.lmsdebug });
|
||
|
amtLms.promise = ret;
|
||
|
amtLms.on('error', function (e) {
|
||
|
//console.log('LME connection failed', e);
|
||
|
if (lmscommander === true) { //settings.noconsole !== true) {
|
||
|
startMeshCommanderLms();
|
||
|
//console.log("LMS started, MeshCommander on HTTP/16994.");
|
||
|
tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 2, tag); }, 100);
|
||
|
} else {
|
||
|
//console.log('LME connection failed: ' + JSON.stringify(e));
|
||
|
tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 0, tag); }, 100);
|
||
|
}
|
||
|
this.promise._res();
|
||
|
});
|
||
|
amtLms.on('notify', function (data, options, str, code) {
|
||
|
if (code == 'iAMT0052-3') {
|
||
|
kvmGetData();
|
||
|
} else if (str != null) {
|
||
|
var notify = { date: Date.now(), str: str, code: code };
|
||
|
lmsNotifications.push(notify);
|
||
|
while (lmsNotifications.length > 100) { lmsNotifications.shift(); }
|
||
|
var notifyBuf = Buffer.concat([Buffer.from('0900', 'hex'), Buffer.from(JSON.stringify(notify))]) // Add a notification
|
||
|
for (var i in lmsControlSockets) { lmsControlSockets[i].write(notifyBuf); }
|
||
|
}
|
||
|
});
|
||
|
//console.log('LME Connecting...');
|
||
|
amtLms.on('bind', function (mapping) {
|
||
|
if (mapping[16992]) { this.removeAllListeners('bind'); } else { return; }
|
||
|
//console.log('LMS Bounded');
|
||
|
amtLms.connected = true;
|
||
|
this.promise._res();
|
||
|
|
||
|
//console.log("LME Connected.");
|
||
|
if (settings.noconsole !== true) {
|
||
|
startMeshCommanderLms();
|
||
|
//console.log("LMS started, MeshCommander on HTTP/16994.");
|
||
|
tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 2, tag); }, 100);
|
||
|
//console.logReferenceCount(tempTimer);
|
||
|
} else {
|
||
|
//console.log("LMS started.");
|
||
|
tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 1, tag); }, 100);
|
||
|
//console.logReferenceCount(tempTimer);
|
||
|
}
|
||
|
|
||
|
});
|
||
|
return (ret);
|
||
|
}
|
||
|
|
||
|
function startMeshCommanderLms() {
|
||
|
|
||
|
amtLms.meshCommander = http.createServer();
|
||
|
amtLms.meshCommander.listen(16994);
|
||
|
amtLms.meshCommander.on('upgrade', function (req, socket, head) {
|
||
|
//console.log("WebSocket for " + req.url.split('?')[0]);
|
||
|
switch (req.url.split('?')[0]) {
|
||
|
case '/lms.ashx': // MeshCommander control channel (PTHI)
|
||
|
socket.ws = socket.upgradeWebSocket();
|
||
|
socket.ws.on('data', processLmsControlData);
|
||
|
socket.ws.on('end', function () { if (lmsControlSockets[this.id]) { delete lmsControlSockets[this.id]; /*console.log('removeControl', JSON.stringify(lmsControlSockets));*/ } });
|
||
|
var id = lmsControlSocketsNextId++;
|
||
|
lmsControlSockets[id] = socket.ws;
|
||
|
socket.ws.id = id;
|
||
|
//socket.ws.write(Buffer.concat([Buffer.from('0900', 'hex'), Buffer.from(JSON.stringify(lmsNotifications))])); // Send out full list of notifications
|
||
|
//console.log('addControl', JSON.stringify(lmsControlSockets));
|
||
|
break;
|
||
|
case '/webrelay.ashx': // MeshCommander data channel (LME)
|
||
|
socket.ws = socket.upgradeWebSocket();
|
||
|
if (amtLms.connected == true) {
|
||
|
// Route traffic directly into MicroLMS
|
||
|
amtLms.bindDuplexStream(socket.ws, 'IPv4', 16992);
|
||
|
} else {
|
||
|
// Route traffic to real LMS service
|
||
|
var net = require('net');
|
||
|
socket.relay = net.connect({ host: '127.0.0.1', port: 16992 })
|
||
|
socket.relay.on('connect', function () {
|
||
|
socket.ws.on('data', function (data) { socket.relay.write(data); });
|
||
|
socket.ws.on('end', function () { socket.relay.end(); });
|
||
|
});
|
||
|
socket.relay.on('data', function (data) { socket.ws.write(data); });
|
||
|
socket.relay.on('close', function () { socket.ws.end(); });
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
socket.end();
|
||
|
break;
|
||
|
}
|
||
|
});
|
||
|
amtLms.meshCommander.on('request', function (req, rsp) {
|
||
|
//console.log("WebRequest for " + req.url.split('?')[0]);
|
||
|
switch (req.url.split('?')[0]) {
|
||
|
case '/': // Serve MeshCommander Web Application for LMS
|
||
|
var lmscommander = null;
|
||
|
try { lmscommander = fs.readFileSync('lmscommander.htm'); } catch (e) { }
|
||
|
if (lmscommander != null) {
|
||
|
rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Transfer-Encoding': 'chunked' });
|
||
|
rsp.end(lmscommander);
|
||
|
} else {
|
||
|
rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Content-Encoding': 'gzip', 'Transfer-Encoding': 'chunked', ETag: _IntelAmtWebApp_etag });
|
||
|
rsp.end(Buffer.from(_IntelAmtWebApp, "base64"));
|
||
|
}
|
||
|
break;
|
||
|
default: // Unknown request
|
||
|
rsp.statusCode = 404;
|
||
|
rsp.statusMessage = "Not Found";
|
||
|
rsp.end();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function setupMeiOsAdmin(func, state, tag) {
|
||
|
if (amtMei == null) {
|
||
|
if (func) { func(state, tag); }
|
||
|
} else {
|
||
|
amtMei.getLocalSystemAccount(function (x) {
|
||
|
var transport = require('amt-wsman-duk');
|
||
|
var wsman = require('amt-wsman');
|
||
|
var amt = require('amt');
|
||
|
oswsstack = new wsman(transport, '127.0.0.1', 16992, x.user, x.pass, false);
|
||
|
osamtstack = new amt(oswsstack);
|
||
|
if (func) { func(state, tag); }
|
||
|
|
||
|
//var AllWsman = "CIM_SoftwareIdentity,IPS_SecIOService,IPS_ScreenSettingData,IPS_ProvisioningRecordLog,IPS_HostBasedSetupService,IPS_HostIPSettings,IPS_IPv6PortSettings".split(',');
|
||
|
//osamtstack.BatchEnum(null, AllWsman, startLmsWsmanResponse, null, true);
|
||
|
//*************************************
|
||
|
|
||
|
// Setup KVM data channel if this is Intel AMT 12 or above
|
||
|
amtMei.getVersion(function (x) {
|
||
|
var amtver = null;
|
||
|
try { for (var i in x.Versions) { if (x.Versions[i].Description == 'AMT') amtver = parseInt(x.Versions[i].Version.split('.')[0]); } } catch (e) { }
|
||
|
if ((amtver != null) && (amtver >= 12)) {
|
||
|
kvmGetData('skip'); // Clear any previous data, this is a dummy read to about handling old data.
|
||
|
tempTimer = setInterval(function () { kvmGetData(); }, 2000); // Start polling for KVM data.
|
||
|
kvmSetData(JSON.stringify({ action: 'restart', ver: 1 })); // Send a restart command to advise the console if present that MicroLMS just started.
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function kvmGetData(tag) {
|
||
|
osamtstack.IPS_KVMRedirectionSettingData_DataChannelRead(kvmDataGetResponse, tag);
|
||
|
}
|
||
|
|
||
|
function kvmDataGetResponse(stack, name, response, status, tag) {
|
||
|
if ((tag != 'skip') && (status == 200) && (response.Body.ReturnValue == 0)) {
|
||
|
var val = null;
|
||
|
try { val = Buffer.from(response.Body.DataMessage, 'base64').toString(); } catch (e) { return }
|
||
|
if (val != null) { kvmProcessData(response.Body.RealmsBitmap, response.Body.MessageId, val); }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var webRtcDesktop = null;
|
||
|
function kvmProcessData(realms, messageId, val) {
|
||
|
var data = null;
|
||
|
try { data = JSON.parse(val) } catch (e) { }
|
||
|
if ((data != null) && (data.action)) {
|
||
|
if (data.action == 'present') { kvmSetData(JSON.stringify({ action: 'present', ver: 1, platform: process.platform })); }
|
||
|
if (data.action == 'offer') {
|
||
|
webRtcDesktop = {};
|
||
|
var rtc = require('ILibWebRTC');
|
||
|
webRtcDesktop.webrtc = rtc.createConnection();
|
||
|
webRtcDesktop.webrtc.on('connected', function () { });
|
||
|
webRtcDesktop.webrtc.on('disconnected', function () { webRtcCleanUp(); });
|
||
|
webRtcDesktop.webrtc.on('dataChannel', function (rtcchannel) {
|
||
|
webRtcDesktop.rtcchannel = rtcchannel;
|
||
|
var kvmmodule = require('meshDesktop');
|
||
|
webRtcDesktop.kvm = kvmmodule.getRemoteDesktopStream();
|
||
|
webRtcDesktop.kvm.pipe(webRtcDesktop.rtcchannel, { dataTypeSkip: 1, end: false });
|
||
|
webRtcDesktop.rtcchannel.on('end', function () { webRtcCleanUp(); });
|
||
|
webRtcDesktop.rtcchannel.on('data', function (x) { kvmCtrlData(this, x); });
|
||
|
webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm, { dataTypeSkip: 1, end: false });
|
||
|
//webRtcDesktop.kvm.on('end', function () { console.log('WebRTC DataChannel closed2'); webRtcCleanUp(); });
|
||
|
//webRtcDesktop.rtcchannel.on('data', function (data) { console.log('WebRTC data: ' + data); });
|
||
|
});
|
||
|
kvmSetData(JSON.stringify({ action: 'answer', ver: 1, sdp: webRtcDesktop.webrtc.setOffer(data.sdp) }));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Polyfill path.join
|
||
|
var path = {
|
||
|
join: function () {
|
||
|
var x = [];
|
||
|
for (var i in arguments) {
|
||
|
var w = arguments[i];
|
||
|
if (w != null) {
|
||
|
while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
|
||
|
if (i != 0) {
|
||
|
while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); }
|
||
|
}
|
||
|
x.push(w);
|
||
|
}
|
||
|
}
|
||
|
if (x.length == 0) return '/';
|
||
|
return x.join('/');
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Get a formated response for a given directory path
|
||
|
function getDirectoryInfo(reqpath) {
|
||
|
var response = { path: reqpath, dir: [] };
|
||
|
if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) {
|
||
|
// List all the drives in the root, or the root itself
|
||
|
var results = null;
|
||
|
try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
|
||
|
//console.log('a', objToString(results, 0, ' '));
|
||
|
if (results != null) {
|
||
|
for (var i = 0; i < results.length; ++i) {
|
||
|
var drive = { n: results[i].name, t: 1 };
|
||
|
if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons.
|
||
|
response.dir.push(drive);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
// List all the files and folders in this path
|
||
|
if (reqpath == '') { reqpath = '/'; }
|
||
|
var xpath = path.join(reqpath, '*');
|
||
|
var results = null;
|
||
|
|
||
|
try { results = fs.readdirSync(xpath); } catch (e) { }
|
||
|
if (results != null) {
|
||
|
for (var i = 0; i < results.length; ++i) {
|
||
|
if ((results[i] != '.') && (results[i] != '..')) {
|
||
|
var stat = null, p = path.join(reqpath, results[i]);
|
||
|
try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date
|
||
|
if ((stat != null) && (stat != undefined)) {
|
||
|
if (stat.isDirectory() == true) {
|
||
|
response.dir.push({ n: results[i], t: 2, d: stat.mtime });
|
||
|
} else {
|
||
|
response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime });
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return response;
|
||
|
}
|
||
|
|
||
|
// Process KVM control channel data
|
||
|
function kvmCtrlData(channel, cmd) {
|
||
|
if (cmd.length > 0 && cmd.charCodeAt(0) != 123) {
|
||
|
// This is upload data
|
||
|
if (this.fileupload != null) {
|
||
|
cmd = Buffer.from(cmd, 'base64');
|
||
|
var header = cmd.readUInt32BE(0);
|
||
|
if ((header == 0x01000000) || (header == 0x01000001)) {
|
||
|
fs.writeSync(this.fileupload.fp, cmd.slice(4));
|
||
|
channel.write({ action: 'upload', sub: 'ack', reqid: this.fileupload.reqid });
|
||
|
if (header == 0x01000001) { fs.closeSync(this.fileupload.fp); this.fileupload = null; } // Close the file
|
||
|
}
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
//console.log('KVM Ctrl Data', cmd);
|
||
|
|
||
|
try { cmd = JSON.parse(cmd); } catch (ex) { console.error('Invalid JSON: ' + cmd); return; }
|
||
|
if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
|
||
|
switch (cmd.action) {
|
||
|
case 'ping': {
|
||
|
// This is a keep alive
|
||
|
channel.write({ action: 'pong' });
|
||
|
break;
|
||
|
}
|
||
|
case 'ls': {
|
||
|
/*
|
||
|
// Close the watcher if required
|
||
|
var samepath = ((this.httprequest.watcher != undefined) && (cmd.path == this.httprequest.watcher.path));
|
||
|
if ((this.httprequest.watcher != undefined) && (samepath == false)) {
|
||
|
//console.log('Closing watcher: ' + this.httprequest.watcher.path);
|
||
|
//this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!!
|
||
|
delete this.httprequest.watcher;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
// Send the folder content to the browser
|
||
|
var response = getDirectoryInfo(cmd.path);
|
||
|
if (cmd.reqid != undefined) { response.reqid = cmd.reqid; }
|
||
|
channel.write(response);
|
||
|
|
||
|
/*
|
||
|
// Start the directory watcher
|
||
|
if ((cmd.path != '') && (samepath == false)) {
|
||
|
var watcher = fs.watch(cmd.path, onFileWatcher);
|
||
|
watcher.tunnel = this.httprequest;
|
||
|
watcher.path = cmd.path;
|
||
|
this.httprequest.watcher = watcher;
|
||
|
//console.log('Starting watcher: ' + this.httprequest.watcher.path);
|
||
|
}
|
||
|
*/
|
||
|
break;
|
||
|
}
|
||
|
case 'mkdir': {
|
||
|
// Create a new empty folder
|
||
|
fs.mkdirSync(cmd.path);
|
||
|
break;
|
||
|
}
|
||
|
case 'rm': {
|
||
|
// Remove many files or folders
|
||
|
for (var i in cmd.delfiles) {
|
||
|
var fullpath = path.join(cmd.path, cmd.delfiles[i]);
|
||
|
try { fs.unlinkSync(fullpath); } catch (e) { console.log(e); }
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case 'rename': {
|
||
|
// Rename a file or folder
|
||
|
var oldfullpath = path.join(cmd.path, cmd.oldname);
|
||
|
var newfullpath = path.join(cmd.path, cmd.newname);
|
||
|
try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); }
|
||
|
break;
|
||
|
}
|
||
|
case 'download': {
|
||
|
// Download a file, to browser
|
||
|
var sendNextBlock = 0;
|
||
|
if (cmd.sub == 'start') { // Setup the download
|
||
|
if (this.filedownload != null) { channel.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||
|
this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
|
||
|
try { this.filedownload.f = fs.openSync(this.filedownload.path, 'rbN'); } catch (e) { channel.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||
|
if (this.filedownload) { channel.write({ action: 'download', sub: 'start', id: cmd.id }); }
|
||
|
} else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands
|
||
|
if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; }
|
||
|
}
|
||
|
// Send the next download block(s)
|
||
|
while (sendNextBlock > 0) {
|
||
|
sendNextBlock--;
|
||
|
var buf = Buffer.alloc(4096);
|
||
|
var len = fs.readSync(this.filedownload.f, buf, 4, 4092, null);
|
||
|
this.filedownload.ptr += len;
|
||
|
if (len < 4092) { buf.writeInt32BE(0x01000001, 0); fs.closeSync(this.filedownload.f); delete this.filedownload; sendNextBlock = 0; } else { buf.writeInt32BE(0x01000000, 0); }
|
||
|
channel.write(buf.slice(0, len + 4).toString('base64')); // Write as Base64
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case 'upload': {
|
||
|
// Upload a file, from browser
|
||
|
if (cmd.sub == 'start') { // Start the upload
|
||
|
if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); }
|
||
|
if (!cmd.path || !cmd.name) break;
|
||
|
this.fileupload = { reqid: cmd.reqid };
|
||
|
var filepath = path.join(cmd.path, cmd.name);
|
||
|
try { this.fileupload.fp = fs.openSync(filepath, 'wbN'); } catch (e) { }
|
||
|
if (this.fileupload.fp) { channel.write({ action: 'upload', sub: 'start', reqid: this.fileupload.reqid }); } else { this.fileupload = null; channel.write({ action: 'upload', sub: 'error', reqid: this.fileupload.reqid }); }
|
||
|
}
|
||
|
else if (cmd.sub == 'cancel') { // Stop the upload
|
||
|
if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); this.fileupload = null; }
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case 'copy': {
|
||
|
// Copy a bunch of files from scpath to dspath
|
||
|
for (var i in cmd.names) {
|
||
|
var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
|
||
|
if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case 'move': {
|
||
|
// Move a bunch of files from scpath to dspath
|
||
|
for (var i in cmd.names) {
|
||
|
var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
|
||
|
if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
// Unknown action, ignore it.
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function webRtcCleanUp() {
|
||
|
if (webRtcDesktop == null) return;
|
||
|
if (webRtcDesktop.rtcchannel) {
|
||
|
try { webRtcDesktop.rtcchannel.close(); } catch (e) { }
|
||
|
try { webRtcDesktop.rtcchannel.removeAllListeners('data'); } catch (e) { }
|
||
|
try { webRtcDesktop.rtcchannel.removeAllListeners('end'); } catch (e) { }
|
||
|
delete webRtcDesktop.rtcchannel;
|
||
|
}
|
||
|
if (webRtcDesktop.webrtc) {
|
||
|
try { webRtcDesktop.webrtc.close(); } catch (e) { }
|
||
|
try { webRtcDesktop.webrtc.removeAllListeners('connected'); } catch (e) { }
|
||
|
try { webRtcDesktop.webrtc.removeAllListeners('disconnected'); } catch (e) { }
|
||
|
try { webRtcDesktop.webrtc.removeAllListeners('dataChannel'); } catch (e) { }
|
||
|
delete webRtcDesktop.webrtc;
|
||
|
}
|
||
|
if (webRtcDesktop.kvm) {
|
||
|
try { webRtcDesktop.kvm.end(); } catch (e) { }
|
||
|
delete webRtcDesktop.kvm;
|
||
|
}
|
||
|
webRtcDesktop = null;
|
||
|
}
|
||
|
|
||
|
function kvmSetData(x) {
|
||
|
osamtstack.IPS_KVMRedirectionSettingData_DataChannelWrite(Buffer.from(x).toString('base64'), function () { });
|
||
|
}
|
||
|
|
||
|
function startLmsWsmanResponse(stack, name, responses, status) {
|
||
|
if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); }
|
||
|
else if (status != 200) { console.log('ERROR: Unable to get object from Intel(R) AMT, status = ' + status + '.'); }
|
||
|
else {
|
||
|
//console.log(JSON.stringify(responses), status);
|
||
|
var amtlogicalelements = responses["CIM_SoftwareIdentity"].responses;
|
||
|
if (amtlogicalelements.length > 0) {
|
||
|
var v = getInstance(amtlogicalelements, "AMT")["VersionString"];
|
||
|
amtversion = parseInt(v.split('.')[0]);
|
||
|
amtversionmin = parseInt(v.split('.')[1]);
|
||
|
//console.log(amtversion, amtversionmin);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// Process commands in the LMS control channel
|
||
|
// Command 9 is add a notification.
|
||
|
function processLmsControlData(data) {
|
||
|
if (data.length < 2) return;
|
||
|
var cmdid = data.readUInt16LE(0);
|
||
|
switch (cmdid) {
|
||
|
case 1: // Request basic Intel AMT information (CMD = 1)
|
||
|
{ getAmtInfo(function (meinfo, socket) { meinfo.LoginMode = 2; socket.write(Buffer.concat([Buffer.from('0100', 'hex'), Buffer.from(JSON.stringify(meinfo))])); }, this); break; }
|
||
|
case 2: // Intel AMT MEI Unprovision (CMD = 2)
|
||
|
{ if (data.length < 6) break; amtMei.unprovision(data.readUInt32LE(2), function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(2, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
|
||
|
case 3: // Intel AMT MEI GetLocalSystemAccount (CMD = 3)
|
||
|
{ amtMei.getLocalSystemAccount(function (account, socket) { socket.write(Buffer.concat([Buffer.from('030000000000', 'hex'), account.raw])); }, this); break; }
|
||
|
case 4: // Instruct Intel AMT to start remote configuration (CMD = 4)
|
||
|
{ amtMei.startConfiguration(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
|
||
|
case 5: // Instruct Intel AMT to stop remote configuration (CMD = 5)
|
||
|
{ amtMei.stopConfiguration(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
|
||
|
case 6: // Instruct Intel AMT connect CIRA (CMD = 6)
|
||
|
{ amtMei.openUserInitiatedConnection(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
|
||
|
case 7: // Instruct Intel AMT disconnect CIRA (CMD = 7)
|
||
|
{ amtMei.closeUserInitiatedConnection(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
|
||
|
case 8: // Get Intel AMT CIRA State (CMD = 8)
|
||
|
{ amtMei.getRemoteAccessConnectionStatus(function (state, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(8, 0); data.writeUInt32LE(state.status, 2); socket.write(Buffer.concat([data, state.raw])); }, this); break; }
|
||
|
default:
|
||
|
// Unknown action, ignore it.
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// MeshCentral TCP port router
|
||
|
//
|
||
|
|
||
|
function startRouter() {
|
||
|
tcpserver = net.createServer(OnTcpClientConnected);
|
||
|
tcpserver.on('error', function (e) { console.log('ERROR: ' + JSON.stringify(e)); exit(0); return; });
|
||
|
tcpserver.listen(settings.localport, function () {
|
||
|
// We started listening.
|
||
|
if (settings.remotename == null) {
|
||
|
console.log('Redirecting local port ' + settings.localport + ' to remote port ' + settings.remoteport + '.');
|
||
|
} else {
|
||
|
console.log('Redirecting local port ' + settings.localport + ' to ' + settings.remotename + ':' + settings.remoteport + '.');
|
||
|
}
|
||
|
console.log('Press ctrl-c to exit.');
|
||
|
|
||
|
// If settings has a "cmd", run it now.
|
||
|
//process.exec("notepad.exe");
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Called when a TCP connect is received on the local port. Launch a tunnel.
|
||
|
function OnTcpClientConnected(c) {
|
||
|
try {
|
||
|
// 'connection' listener
|
||
|
debug(1, 'Client connected');
|
||
|
c.on('end', function () { disconnectTunnel(this, this.websocket, 'Client closed'); });
|
||
|
c.pause();
|
||
|
try {
|
||
|
options = http.parseUri(settings.serverurl + '?user=' + settings.username + '&pass=' + settings.password + '&nodeid=' + settings.remotenodeid + '&tcpport=' + settings.remoteport);
|
||
|
} catch (e) { console.log('Unable to parse \"serverUrl\".'); process.exit(1); return; }
|
||
|
options.checkServerIdentity = onVerifyServer;
|
||
|
options.rejectUnauthorized = false;
|
||
|
c.websocket = http.request(options);
|
||
|
c.websocket.tcp = c;
|
||
|
c.websocket.tunneling = false;
|
||
|
c.websocket.upgrade = OnWebSocket;
|
||
|
c.websocket.on('error', function (e) { console.log('ERROR: ' + JSON.stringify(e)); });
|
||
|
c.websocket.end();
|
||
|
} catch (e) { debug(2, e); }
|
||
|
}
|
||
|
|
||
|
// Disconnect both TCP & WebSocket connections and display a message.
|
||
|
function disconnectTunnel(tcp, ws, msg) {
|
||
|
if (ws != null) { try { ws.end(); } catch (e) { debug(2, e); } }
|
||
|
if (tcp != null) { try { tcp.end(); } catch (e) { debug(2, e); } }
|
||
|
debug(1, 'Tunnel disconnected: ' + msg);
|
||
|
}
|
||
|
|
||
|
// Called when the web socket gets connected
|
||
|
function OnWebSocket(msg, s, head) {
|
||
|
debug(1, 'Websocket connected');
|
||
|
s.on('data', function (msg) {
|
||
|
if (this.parent.tunneling == false) {
|
||
|
msg = msg.toString();
|
||
|
if ((msg == 'c') || (msg == 'cr')) {
|
||
|
this.parent.tunneling = true; this.pipe(this.parent.tcp); this.parent.tcp.pipe(this); debug(1, 'Tunnel active');
|
||
|
} else if ((msg.length > 6) && (msg.substring(0, 6) == 'error:')) {
|
||
|
console.log(msg.substring(6));
|
||
|
disconnectTunnel(this.tcp, this, msg.substring(6));
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
s.on('error', function (msg) { disconnectTunnel(this.tcp, this, 'Websocket error'); });
|
||
|
s.on('close', function (msg) { disconnectTunnel(this.tcp, this, 'Websocket closed'); });
|
||
|
s.parent = this;
|
||
|
}
|
||
|
|
||
|
// Try to discover the location of the mesh server
|
||
|
function discoverMeshServer() { console.log('Looking for server...'); discoveryInterval = setInterval(discoverMeshServerOnce, 5000); discoverMeshServerOnce(); }
|
||
|
|
||
|
// Try to discover the location of the mesh server only once
|
||
|
function discoverMeshServerOnce() {
|
||
|
var interfaces = os.networkInterfaces();
|
||
|
for (var adapter in interfaces) {
|
||
|
if (interfaces.hasOwnProperty(adapter)) {
|
||
|
for (var i = 0; i < interfaces[adapter].length; ++i) {
|
||
|
var addr = interfaces[adapter][i];
|
||
|
multicastSockets[i] = dgram.createSocket({ type: (addr.family == "IPv4" ? "udp4" : "udp6") });
|
||
|
multicastSockets[i].bind({ address: addr.address, exclusive: false });
|
||
|
if (addr.family == "IPv4") {
|
||
|
try {
|
||
|
multicastSockets[i].addMembership(membershipIPv4);
|
||
|
//multicastSockets[i].setMulticastLoopback(true);
|
||
|
multicastSockets[i].once('message', OnMulticastMessage);
|
||
|
multicastSockets[i].send(settings.serverid, 16989, membershipIPv4);
|
||
|
} catch (e) { }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Called when a multicast packet is received
|
||
|
function OnMulticastMessage(msg, rinfo) {
|
||
|
var m = msg.toString().split('|');
|
||
|
if ((m.length == 3) && (m[0] == 'MeshCentral2') && (m[1] == settings.serverid)) {
|
||
|
settings.serverurl = m[2].replace('%s', rinfo.address).replace('/agent.ashx', '/meshrelay.ashx');
|
||
|
console.log('Found server at ' + settings.serverurl + '.');
|
||
|
if (discoveryInterval != null) { clearInterval(discoveryInterval); discoveryInterval = null; }
|
||
|
startRouter();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// PUSH MESHCOMMANDER INTO FIRMWARE
|
||
|
//
|
||
|
|
||
|
function nextStepStorageUpload() {
|
||
|
debug(3, "nextStepStorageUpload");
|
||
|
getAmtStorage(function (statusCode, data) {
|
||
|
if (statusCode == 200) {
|
||
|
debug(2, "getAmtStorage: " + JSON.stringify(data, null, 2));
|
||
|
if ((data['content'] != null) && (data['content']['index.htm'] != null)) { nextStepStorageUpload3('index.htm'); }
|
||
|
else if ((data['content'] != null) && (data['content']['logon.htm'] != null)) { nextStepStorageUpload3('logon.htm'); }
|
||
|
else if ((data['content'] != null) && (data['content']['logon.htm'] != null)) { nextStepStorageUpload3('logon.htm'); }
|
||
|
else { nextStepStorageUpload2('index.htm', null); }
|
||
|
} else {
|
||
|
console.log("Unable to read storage state.");
|
||
|
exit();
|
||
|
return;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function nextStepStorageUpload2(uploadName, linkName) {
|
||
|
debug(3, "nextStepStorageUpload2");
|
||
|
if (settings.webapp == null) { console.log("Done."); exit(); return; } else {
|
||
|
console.log("Uploading MeshCommander...");
|
||
|
pushToStorage(uploadName, linkName, Buffer.from(settings.webapp, 'base64'), function (statusCode) {
|
||
|
if (statusCode == 500) { console.log("Error, check that computer is powered on."); exit(); return; }
|
||
|
if (statusCode != 200) {
|
||
|
if (uploadName == 'index.htm') {
|
||
|
nextStepStorageUpload2('mesh/commander/console', 'MeshCommander');
|
||
|
} else {
|
||
|
console.log("Unable to upload MeshCommander, status = " + statusCode + "."); exit(); return;
|
||
|
}
|
||
|
} else {
|
||
|
console.log("Verifying MeshCommander...");
|
||
|
verifyStorage(uploadName, Buffer.from(settings.webapp, 'base64'), function (verified) {
|
||
|
if (verified == true) { console.log('Done.'); } else { console.log('MeshCommander verification failed.'); }
|
||
|
exit(); return;
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function nextStepStorageUpload3(deleteName) {
|
||
|
console.log("Deleting " + deleteName + " from storage...");
|
||
|
deleteStorage(deleteName, function (statusCode) {
|
||
|
if (statusCode == 500) { console.log("Error, check that computer is powered on."); exit(); return; }
|
||
|
if (statusCode == 200) { nextStepStorageUpload(); } else { console.log("Unable to delete " + deleteName + "."); exit(); return; }
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Fetch the Intel AMT storage document
|
||
|
function getAmtStorage(func, noretry) {
|
||
|
var req = digest.request({ protocol: settings.protocol, method: "GET", host: settings.hostname, path: "/amt-storage/", port: settings.localport },
|
||
|
function (response) {
|
||
|
if (response.statusCode != 200) { console.log("Unable to connect to Intel(R) AMT."); func(response.statusCode, null); }
|
||
|
response.on('data', function (chunk) { if (response.acc == null) { response.acc = chunk; } else { response.acc += chunk; } });
|
||
|
response.on('end', function () {
|
||
|
var data = response.acc.toString(), len, data2, amtstorage = null;
|
||
|
data = data.split('\t').join('').split('\r').join('').split('\n').join('');
|
||
|
try {
|
||
|
do { len = data.length; data2 = data; data = data2.replace('": ', '":'); } while (data != data2); // Remove all zero's, this is needed because firmware sometimes returns garbage we must fix.
|
||
|
do { len = data.length; data2 = data; data = data2.replace('\x00', ''); } while (data != data2); // Remove all zero's, this is needed because firmware sometimes returns garbage we must fix.
|
||
|
do { len = data.length; data2 = data; data = data2.replace('\x22\x01\x22', '\x22\x22'); } while (data != data2); // "\x01", this is needed because firmware sometimes returns garbage we must fix.
|
||
|
var xopen = data.split("{").length, xclose = data.split("}").length, xadd = '';
|
||
|
while (xopen > xclose) { data += '}'; xclose++; } // Close any missing close brackets
|
||
|
amtstorage = JSON.parse(data);
|
||
|
} catch (e) { console.log("Error: Unable to parse Intel AMT response: " + data, e); func(null); }
|
||
|
if (func != null) { func(response.statusCode, amtstorage); }
|
||
|
});
|
||
|
});
|
||
|
req.on('error', function (e) { console.log("Error occured: " + JSON.stringify(e)); if (noretry == true) { if (func != null) { func(null); } } else { getAmtStorage(func, true); } });
|
||
|
req.end();
|
||
|
}
|
||
|
|
||
|
// Fetch the Intel AMT storage document
|
||
|
function pushToStorage(name, linkname, data, func, ptr) {
|
||
|
if (ptr == null) { ptr = 0; }
|
||
|
var req = digest.request({ protocol: settings.protocol, method: "PUT", host: settings.hostname, path: ("/amt-storage/" + name + ((ptr != 0) ? '?append=' : '')), port: settings.localport });
|
||
|
req.on('error', function (e) { console.log("Error occured: " + JSON.stringify(e)); if (func != null) { func(null); } });
|
||
|
req.on('response', function (response) {
|
||
|
debug(1, 'Chunk Done', data.length, ptr);
|
||
|
if ((response.statusCode == 200) && (ptr < data.length)) { pushToStorage(name, linkname, data, func, ptr); } else { if (func != null) { func(response.statusCode); } }
|
||
|
});
|
||
|
var header = (ptr > 0) ? '<metadata></metadata>' : '<metadata><headers><h>Content-Encoding:gzip</h><h>Content-Type:text/html</h></headers>' + ((linkname != null) ? ('<link>' + linkname + '</link>') : '') + '</metadata>';
|
||
|
var blocklen = ((data.length - ptr) > (7000 - header.length)) ? (7000 - header.length) : (data.length - ptr);
|
||
|
req.write(Buffer.concat([new Buffer(header), data.slice(ptr, ptr + blocklen)]));
|
||
|
ptr += blocklen;
|
||
|
req.end();
|
||
|
}
|
||
|
|
||
|
// Fetch the Intel AMT storage document
|
||
|
function verifyStorage(name, data, func) {
|
||
|
var req = digest.request({ protocol: settings.protocol, method: "GET", host: settings.hostname, path: ("/amt-storage/" + name), port: settings.localport });
|
||
|
req.on('error', function (e) { console.log("Verify error occured: " + JSON.stringify(e)); if (func != null) { func(null); } });
|
||
|
req.on('response', function (response) {
|
||
|
response.ptr = 0;
|
||
|
response.ok = true;
|
||
|
response.on('data', function (data2) { if (data2.toString('hex') != data.slice(response.ptr, response.ptr + data2.length).toString('hex')) { response.ok = false; console.log('Verifiy failed (' + response.ptr + ', ' + data2.length + ').'); } response.ptr += data2.length; });
|
||
|
response.on('end', function () { if (func != null) { func(response.ok); } });
|
||
|
});
|
||
|
req.end();
|
||
|
}
|
||
|
|
||
|
// Fetch the Intel AMT storage document
|
||
|
function deleteStorage(name, func, noretry) {
|
||
|
var req = digest.request({ protocol: settings.protocol, method: "DELETE", host: settings.hostname, path: "/amt-storage/" + name, port: settings.localport });
|
||
|
req.on('error', function (e) { if ((e == 'Error: Socket was unexpectedly closed') && (noretry != true)) { deleteStorage(name, func, true); } else { if (func != null) { if (e.statusCode) { func(e.statusCode); } else { func(null); } } } });
|
||
|
req.on('response', function (response) { if (func != null) { func(response.statusCode); } });
|
||
|
req.end();
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// IDER
|
||
|
//
|
||
|
|
||
|
ider = null;
|
||
|
iderIdleTimer = null;
|
||
|
|
||
|
// Perform IDER
|
||
|
function performIder() {
|
||
|
if ((settings.floppy != null) && fs.existsSync(settings.floppy) == false) { console.log("Unable to floppy image file: " + settings.floppy); process.exit(); return; }
|
||
|
if ((settings.cdrom != null) && fs.existsSync(settings.cdrom) == false) { console.log("Unable to CDROM image file: " + settings.cdrom); process.exit(); return; }
|
||
|
try {
|
||
|
var sfloppy = null, scdrom = null;
|
||
|
if (settings.floppy) { try { if (sfloppy = fs.statSync(settings.floppy)) { sfloppy.file = fs.openSync(settings.floppy, 'rbN'); } } catch (ex) { console.log(ex); process.exit(1); return; } }
|
||
|
if (settings.cdrom) { try { scdrom = fs.statSync(settings.cdrom); if (scdrom) { scdrom.file = fs.openSync(settings.cdrom, 'rbN'); } } catch (ex) { console.log(ex); process.exit(1); return; } }
|
||
|
|
||
|
ider = require('amt-redir-duk')(require('amt-ider')());
|
||
|
ider.onStateChanged = onIderStateChange;
|
||
|
ider.m.floppy = sfloppy;
|
||
|
ider.m.cdrom = scdrom;
|
||
|
ider.m.iderStart = 1; // OnReboot = 0, Graceful = 1, Now = 2
|
||
|
ider.m.debug = (settings.debuglevel > 0);
|
||
|
if (settings.timeout > 0) { ider.m.sectorStats = iderSectorStats; }
|
||
|
//ider.digestRealmMatch = wsstack.comm.digestRealm;
|
||
|
//ider.tlsv1only = amtstack.wsman.comm.tlsv1only;
|
||
|
ider.Start(settings.hostname, (settings.tls == true) ? 16995 : 16994, settings.username ? 'admin' : settings.username, settings.password, settings.tls);
|
||
|
} catch (ex) { console.log(ex); }
|
||
|
}
|
||
|
|
||
|
function onIderStateChange(stack, state) { console.log(['Disconnected', 'Connecting...', 'Connected...', 'Started IDER...'][state]); }
|
||
|
|
||
|
function iderSectorStats(mode, dev, mediaBlocks, lba, len) {
|
||
|
if (iderIdleTimer != null) { clearTimeout(iderIdleTimer); }
|
||
|
iderIdleTimer = setTimeout(function () { console.log('Idle timeout'); process.exit(1); }, 1000 * settings.timeout);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Intel AMT IPv4 wired configuration
|
||
|
//
|
||
|
|
||
|
function performAmtNetConfig(args) {
|
||
|
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) {
|
||
|
settings.noconsole = true; startLms(performAmtNetConfig0, false, args);
|
||
|
} else {
|
||
|
performAmtNetConfig0(1, args);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function performAmtNetConfig0(state, args) {
|
||
|
var transport = require('amt-wsman-duk');
|
||
|
var wsman = require('amt-wsman');
|
||
|
var amt = require('amt');
|
||
|
wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
|
||
|
amtstack = new amt(wsstack);
|
||
|
amtstack.BatchEnum(null, ['AMT_EthernetPortSettings'], performAmtNetConfig1, args);
|
||
|
}
|
||
|
|
||
|
function performAmtNetConfig1(stack, name, response, status, args) {
|
||
|
if (status == 200) {
|
||
|
// Set wired and wireless interfaces
|
||
|
var amtwirelessif = -1;
|
||
|
var amtwiredif = -1;
|
||
|
for (var y in response['AMT_EthernetPortSettings'].responses) {
|
||
|
var z = response['AMT_EthernetPortSettings'].responses[y];
|
||
|
if (z['WLANLinkProtectionLevel'] || (y == 1)) { amtwirelessif = y; } // Set the wireless interface, this seems to cover new wireless only computers and older computers with dual interfaces.
|
||
|
if (y == 0) { if ((amtwirelessif != y) && (z["MACAddress"] != "00-00-00-00-00-00")) { amtwiredif = y; } } // On computers with only wireless, the wired interface will have a null MAC
|
||
|
}
|
||
|
|
||
|
// Check if configuration change is required
|
||
|
if (args) {
|
||
|
var docall = false;
|
||
|
var x = JSON.parse(JSON.stringify(response['AMT_EthernetPortSettings'].responses[amtwiredif]));
|
||
|
var y = response['AMT_EthernetPortSettings'].responses[amtwiredif];
|
||
|
delete x["IpSyncEnabled"];
|
||
|
delete x["LinkIsUp"];
|
||
|
delete x["LinkPolicy"];
|
||
|
delete x["MACAddress"];
|
||
|
delete x["SharedDynamicIP"];
|
||
|
delete x["SharedMAC"];
|
||
|
delete x["SharedStaticIp"];
|
||
|
|
||
|
if ((y['IpSyncEnabled'] == false) && (args.ipsync === '1')) { x['IpSyncEnabled'] = true; docall = true; }
|
||
|
if ((y['IpSyncEnabled'] == true) && (args.ipsync === '0')) { x['IpSyncEnabled'] = false; docall = true; }
|
||
|
if (args.dhcp && (amtwiredif != -1) && (response['AMT_EthernetPortSettings'].responses[amtwiredif].DHCPEnabled == false)) {
|
||
|
// Change to DHCP
|
||
|
x['DHCPEnabled'] = true;
|
||
|
docall = true;
|
||
|
}
|
||
|
else if (args.static && (amtwiredif != -1) && (response['AMT_EthernetPortSettings'].responses[amtwiredif].DHCPEnabled == true)) {
|
||
|
// Change to STATIC
|
||
|
x['DHCPEnabled'] = false;
|
||
|
if (args.ip) { x["IPAddress"] = args.ip; } else { console.log('Missing IPv4 address, use --ip 1.2.3.4'); process.exit(1); }
|
||
|
if (args.subnet) { x["SubnetMask"] = args.subnet; } else { console.log('Missing IPv4 subnet, use --subnet 255.255.255.0'); process.exit(1); }
|
||
|
if (args.gateway) { x["DefaultGateway"] = args.gateway; }
|
||
|
if (args.dns) { x["PrimaryDNS"] = args.dns; }
|
||
|
if (args.dns2) { x["SecondaryDNS"] = args.dns2; }
|
||
|
docall = true;
|
||
|
}
|
||
|
if (docall) {
|
||
|
if (x["DHCPEnabled"] == true) {
|
||
|
delete x["IPAddress"];
|
||
|
delete x["DefaultGateway"];
|
||
|
delete x["PrimaryDNS"];
|
||
|
delete x["SecondaryDNS"];
|
||
|
delete x["SubnetMask"];
|
||
|
}
|
||
|
pendingAmtConfigActions++;
|
||
|
//console.log(JSON.stringify(x, 4, ' '));
|
||
|
amtstack.Put("AMT_EthernetPortSettings", x, function (stack, name, response, status) { if (status != 200) { console.log('Error, status ' + status + '.'); } if (--pendingAmtConfigActions == 0) { performAmtNetConfig0(); } }, null, 0, x);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pendingAmtConfigActions == 0) {
|
||
|
var maxlen = 0;
|
||
|
if (amtwiredif != -1) { for (var i in response['AMT_EthernetPortSettings'].responses[amtwiredif]) { if (i.length > maxlen) { maxlen = i.length; } } }
|
||
|
if (amtwirelessif != -1) { for (var i in response['AMT_EthernetPortSettings'].responses[amtwirelessif]) { if (i.length > maxlen) { maxlen = i.length; } } }
|
||
|
|
||
|
if (amtwiredif != -1) { // Wired
|
||
|
var z = response['AMT_EthernetPortSettings'].responses[amtwiredif];
|
||
|
console.log('--WIRED---');
|
||
|
for (var i in z) {
|
||
|
if (['ElementName', 'InstanceID'].indexOf(i) == -1) {
|
||
|
var name = i;
|
||
|
while (name.length < maxlen) { name += ' '; }
|
||
|
console.log(name + ' : ' + z[i]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (amtwirelessif != -1) { // Wireless
|
||
|
var z = response['AMT_EthernetPortSettings'].responses[amtwirelessif];
|
||
|
console.log('--WIRELESS---');
|
||
|
for (var i in z) {
|
||
|
if (['ElementName', 'InstanceID'].indexOf(i) == -1) {
|
||
|
var name = i;
|
||
|
while (name.length < maxlen) { name += ' '; }
|
||
|
console.log(name + ' : ' + z[i]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
process.exit(0);
|
||
|
}
|
||
|
} else {
|
||
|
console.log('Error, status ' + status + '.');
|
||
|
process.exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Intel AMT feature configuration action
|
||
|
//
|
||
|
|
||
|
function performAmtFeatureConfig(args) {
|
||
|
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) {
|
||
|
settings.noconsole = true; startLms(performAmtFeatureConfig0, false, args);
|
||
|
} else {
|
||
|
performAmtFeatureConfig0(1, args);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function performAmtFeatureConfig0(state, args) {
|
||
|
var transport = require('amt-wsman-duk');
|
||
|
var wsman = require('amt-wsman');
|
||
|
var amt = require('amt');
|
||
|
wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
|
||
|
amtstack = new amt(wsstack);
|
||
|
amtstack.BatchEnum(null, ['*IPS_OptInService', '*AMT_RedirectionService', '*CIM_KVMRedirectionSAP'], performAmtFeatureConfig1, args);
|
||
|
}
|
||
|
|
||
|
function performAmtFeatureConfig1(stack, name, response, status, args) {
|
||
|
if (status == 200) {
|
||
|
// User consent
|
||
|
var optinrequired = response['IPS_OptInService'].response["OptInRequired"];
|
||
|
if (args) {
|
||
|
if ((args.userconsent == 'none') && (optinrequired != 0)) {
|
||
|
pendingAmtConfigActions++;
|
||
|
response['IPS_OptInService'].response["OptInRequired"] = 0;
|
||
|
amtstack.Put("IPS_OptInService", response['IPS_OptInService'].response, function (stack, name, response, status) { if (--pendingAmtConfigActions == 0) { performAmtFeatureConfig0(); } });
|
||
|
}
|
||
|
else if ((args.userconsent == 'kvm') && (optinrequired != 1)) {
|
||
|
pendingAmtConfigActions++;
|
||
|
response['IPS_OptInService'].response["OptInRequired"] = 1;
|
||
|
amtstack.Put("IPS_OptInService", response['IPS_OptInService'].response, function (stack, name, response, status) { if (--pendingAmtConfigActions == 0) { performAmtFeatureConfig0(); } });
|
||
|
}
|
||
|
else if ((args.userconsent == 'all') && (optinrequired != 0xFFFFFFFF)) {
|
||
|
pendingAmtConfigActions++;
|
||
|
response['IPS_OptInService'].response["OptInRequired"] = 0xFFFFFFFF;
|
||
|
amtstack.Put("IPS_OptInService", response['IPS_OptInService'].response, function (stack, name, response, status) { if (--pendingAmtConfigActions == 0) { performAmtFeatureConfig0(); } });
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Redirection ports
|
||
|
var redirportchange = false;
|
||
|
var redirchange = false;
|
||
|
var redir = (response['AMT_RedirectionService'].response["ListenerEnabled"] == true);
|
||
|
|
||
|
var sol = ((response['AMT_RedirectionService'].response["EnabledState"] & 2) != 0);
|
||
|
var ider = ((response['AMT_RedirectionService'].response["EnabledState"] & 1) != 0);
|
||
|
if (args) {
|
||
|
if ((redir == false) && ((args.redir == 'enabled') || (args.redir == 1))) { response['AMT_RedirectionService'].response["ListenerEnabled"] = true; redirportchange = true; }
|
||
|
if ((redir == true) && ((args.redir == 'disabled') || (args.redir == 0))) { response['AMT_RedirectionService'].response["ListenerEnabled"] = false; redirportchange = true; }
|
||
|
if ((sol == false) && ((args.sol == 'enabled') || (args.sol == 1))) { sol = true; redirchange = true; }
|
||
|
if ((sol == true) && ((args.sol == 'disabled') || (args.sol == 0))) { sol = false; redirchange = true; }
|
||
|
if ((ider == false) && ((args.ider == 'enabled') || (args.ider == 1))) { ider = true; redirchange = true; }
|
||
|
if ((ider == true) && ((args.ider == 'disabled') || (args.ider == 0))) { ider = false; redirchange = true; }
|
||
|
if (redirportchange) { pendingAmtConfigActions++; amtstack.Put("AMT_RedirectionService", response['AMT_RedirectionService'].response, function (stack, name, response, status) { if (--pendingAmtConfigActions == 0) { performAmtFeatureConfig0(); } }); }
|
||
|
if (redirchange) { pendingAmtConfigActions++; amtstack.AMT_RedirectionService_RequestStateChange((32768 + ((ider ? 1 : 0) + (sol ? 2 : 0))), function (stack, name, response, status) { if (--pendingAmtConfigActions == 0) { performAmtFeatureConfig0(); } }); }
|
||
|
}
|
||
|
|
||
|
// KVM
|
||
|
var kvm = false;
|
||
|
var kvmchange = false;
|
||
|
if (response['CIM_KVMRedirectionSAP'] != null) {
|
||
|
kvm = ((response['CIM_KVMRedirectionSAP'].response["EnabledState"] == 6 && response['CIM_KVMRedirectionSAP'].response["RequestedState"] == 2) || response['CIM_KVMRedirectionSAP'].response["EnabledState"] == 2 || response['CIM_KVMRedirectionSAP'].response["EnabledState"] == 6);
|
||
|
if (args) {
|
||
|
if ((kvm == false) && ((args.kvm == 'enabled') || (args.kvm == 1))) { kvm = true; kvmchange = true; }
|
||
|
if ((kvm == true) && ((args.kvm == 'disabled') || (args.kvm == 0))) { kvm = false; kvmchange = true; }
|
||
|
if (kvmchange) { pendingAmtConfigActions++; amtstack.CIM_KVMRedirectionSAP_RequestStateChange(kvm ? 2 : 3, 0, function (stack, name, response, status) { if (--pendingAmtConfigActions == 0) { performAmtFeatureConfig0(); } }); }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pendingAmtConfigActions == 0) {
|
||
|
if (optinrequired == 0) { console.log('User Consent : None'); }
|
||
|
else if (optinrequired == 1) { console.log('User Consent : KVM'); }
|
||
|
else if (optinrequired == 0xFFFFFFFF) { console.log('User Consent : All'); }
|
||
|
else { console.log('User Consent : ' + optinrequired); }
|
||
|
console.log('Redirection Port : ' + (redir ? 'Enabled' : 'Disabled'));
|
||
|
console.log('Serial-over-LAN : ' + (sol ? 'Enabled' : 'Disabled'));
|
||
|
console.log('IDE Redirection : ' + (ider ? 'Enabled' : 'Disabled'));
|
||
|
if (response['CIM_KVMRedirectionSAP'] != null) { console.log('Remote desktop (KVM) : ' + (kvm ? 'Enabled' : 'Disabled')); }
|
||
|
process.exit(0);
|
||
|
}
|
||
|
} else {
|
||
|
console.log('Error, status ' + status + '.');
|
||
|
process.exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Intel AMT Remote Power Action
|
||
|
//
|
||
|
|
||
|
function performAmtPowerAction() {
|
||
|
var transport = require('amt-wsman-duk');
|
||
|
var wsman = require('amt-wsman');
|
||
|
var amt = require('amt');
|
||
|
wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
|
||
|
amtstack = new amt(wsstack);
|
||
|
if (settings.poweraction != 0) {
|
||
|
// Set the power state
|
||
|
amtstack.RequestPowerStateChange(settings.poweraction, performAmtPowerActionEx);
|
||
|
} else {
|
||
|
// Get the power state
|
||
|
amtstack.Get("CIM_AssociatedPowerManagementService", performAmtPowerActionEx2, 0, 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function performAmtPowerActionEx(stack, name, response, status) {
|
||
|
if (status == 200) {
|
||
|
console.log(response.Body.ReturnValueStr.split('_').join(' '));
|
||
|
process.exit(0);
|
||
|
} else {
|
||
|
console.log('Error, status ' + status + '.');
|
||
|
process.exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var DMTFPowerStates = ["", "", "Power on", "Light sleep", "Deep sleep", "Power cycle (Soft off)", "Off - Hard", "Hibernate (Off soft)", "Soft off", "Power cycle (Off-hard)", "Master bus reset", "Diagnostic interrupt (NMI)", "Not applicable", "Off - Soft graceful", "Off - Hard graceful", "Master bus reset graceful", "Power cycle (Off - Soft graceful)", "Power cycle (Off - Hard graceful)", "Diagnostic interrupt (INIT)"];
|
||
|
function performAmtPowerActionEx2(stack, name, response, status) {
|
||
|
if (status == 200) {
|
||
|
var powerNumber = parseInt(response.Body.PowerState);
|
||
|
if ((powerNumber >= DMTFPowerStates.length) && (powerNumber > 1)) {
|
||
|
console.log('Unknown power state: ' + response.Body.PowerState);
|
||
|
} else {
|
||
|
console.log('Current power state: ' + DMTFPowerStates[powerNumber]);
|
||
|
}
|
||
|
process.exit(0);
|
||
|
} else {
|
||
|
console.log('Error, status ' + status + '.');
|
||
|
process.exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Startup
|
||
|
//
|
||
|
|
||
|
// Parse URL arguments
|
||
|
function parseUrlArguments(url) {
|
||
|
var r = {}, x = url.split('?');
|
||
|
if (x.length < 2) return r;
|
||
|
x = x[1].split('&');
|
||
|
for (var i in x) { var j = x[i].indexOf('='); if (j > 0) { r[x[i].substring(0, j).toLowerCase()] = x[i].substring(j + 1); } }
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
// Remove a element from a array
|
||
|
function removeItemFromArray(array, element) {
|
||
|
var index = array.indexOf(element);
|
||
|
if (index !== -1) { array.splice(index, 1); }
|
||
|
}
|
||
|
|
||
|
// Run MeshCmd, but before we do, we need to see if what type of service we are going to be
|
||
|
var serviceName = null;
|
||
|
var serviceOpSpecified = 0;
|
||
|
var serviceInstall = 0;
|
||
|
|
||
|
for (var i in process.argv) {
|
||
|
if (process.argv[i].toLowerCase() == 'install') { serviceInstall = 1 } else if (process.argv[i].toLowerCase() == 'uninstall') { serviceInstall = -1 }
|
||
|
if ((process.argv[i].toLowerCase() == 'microlms') || (process.argv[i].toLowerCase() == 'amtlms') || (process.argv[i].toLowerCase() == 'lms')) { serviceName = 'MicroLMS'; break; }
|
||
|
if ((process.argv[i].toLowerCase() == 'meshcommander') || (process.argv[i].toLowerCase() == 'commander')) { serviceName = 'MeshCommander'; break; }
|
||
|
}
|
||
|
|
||
|
if (serviceName == null) {
|
||
|
for (var i in process.argv) {
|
||
|
if ((process.argv[i].toLowerCase() == 'install') || (process.argv[i].toLowerCase() == 'uninstall')) {
|
||
|
console.log('In order to install/uninstall, a service type must be specified.');
|
||
|
process.exit();
|
||
|
}
|
||
|
}
|
||
|
if (process.execPath.includes('MicroLMS')) { serviceName = 'MicroLMS'; }
|
||
|
else if (process.execPath.includes('MeshCommander')) { serviceName = 'MeshCommander'; }
|
||
|
else { serviceName = 'not_a_service'; }
|
||
|
}
|
||
|
|
||
|
if (serviceInstall == 0) {
|
||
|
run(process.argv);
|
||
|
} else {
|
||
|
var serviceHost = require('service-host');
|
||
|
var meshcmdService = new serviceHost({ name: serviceName, startType: 'AUTO_START' });
|
||
|
|
||
|
// Called when the background service is started.
|
||
|
meshcmdService.on('serviceStart', function onStart() {
|
||
|
console.setDestination(console.Destinations.DISABLED); // Disable console.log().
|
||
|
if (process.execPath.includes('MicroLMS')) { run([process.execPath, 'microlms']); } //
|
||
|
else if (process.execPath.includes('MeshCommander')) { run([process.execPath, 'meshcommander']); }
|
||
|
else { console.log('Aborting Service Start, because unknown binary: ' + process.execPath); process.exit(1); }
|
||
|
});
|
||
|
|
||
|
// Called when the background service is stopping
|
||
|
meshcmdService.on('serviceStop', function onStop() { console.log('Stopping service'); process.exit(); }); // The console.log() is for debugging, will be ignored unless "console.setDestination()" is set.
|
||
|
|
||
|
// Called when the executable is not running as a service, run normally.
|
||
|
meshcmdService.on('normalStart', function onNormalStart() { try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); } });
|
||
|
meshcmdService.run();
|
||
|
}
|