diff --git a/agents/MeshCmd-signed.exe b/agents/MeshCmd-signed.exe index f42d8115..474b06c6 100644 Binary files a/agents/MeshCmd-signed.exe and b/agents/MeshCmd-signed.exe differ diff --git a/agents/MeshCmd64-signed.exe b/agents/MeshCmd64-signed.exe index c7ff3c56..64a65689 100644 Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ diff --git a/agents/meshcmd.js b/agents/meshcmd.js index fb2bd492..748d0093 100644 --- a/agents/meshcmd.js +++ b/agents/meshcmd.js @@ -91,7 +91,7 @@ function run(argv) { //console.log('addedModules = ' + JSON.stringify(addedModules)); var actionpath = 'meshaction.txt'; if (args.actionfile != null) { actionpath = args.actionfile; } - var actions = ['HELP', 'ROUTE', 'AMTLMS', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER']; + var actions = ['HELP', 'ROUTE', 'AMTLMS', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG']; // Load the action file var actionfile = null; @@ -142,6 +142,7 @@ function run(argv) { 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(' 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.'); @@ -230,6 +231,14 @@ function run(argv) { 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.'); + } 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 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 { actions.shift(); console.log('Invalid action, usage:\r\n\r\n meshcmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.'); @@ -373,15 +382,61 @@ function run(argv) { // Deactivate CCM debug(1, "Settings: " + JSON.stringify(settings)); deactivateCCM(); - } else if (settings.action == 'meshcommander') { - // Start MeshCommander + } else if (settings.action == 'meshcommander') { // Start MeshCommander startMeshCommander(); + } 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 { console.log('Invalid \"action\" specified.'); exit(1); return; } } +// +// 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 = ''; + 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, new Buffer(out, 'utf8')); fs.closeSync(file); } + } + exit(1); +} + + // // MeshCommander local web server // @@ -397,27 +452,18 @@ function startMeshCommander() { 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; ws.pause(); - // When data is received from the web socket, forward the data into the associated TCP connection. - // If the TCP connection is pending, buffer up the data until it connects. - ws.on('data', function (data) { - //console.log('Data relay --> ' + data.length + ': ' + data.toString() + '\r\n'); - ws.forwardclient.write(data); // Forward data to the associated TCP connection. - }); - - // If the web socket is closed, close the associated TCP connection. - ws.on('close', function (req) { - //console.log('Closed websocket.'); - if (ws.forwardclient) { try { ws.forwardclient.destroy(); } catch (e) { } } - }); - // 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); } @@ -429,36 +475,16 @@ function startMeshCommander() { // 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 () { this.pipe(this.ws); this.ws.pipe(this); }); ws.forwardclient.ws = ws; - ws.forwardclient.on('connect', function () { this.ws.resume(); }); } 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 () { this.ws.resume(); }); + ws.forwardclient = tls.connect(tlsoptions, function () { this.pipe(this.ws); this.ws.pipe(this); }); ws.forwardclient.ws = ws; } - // When we receive data on the TCP connection, forward it back into the web socket connection. - ws.forwardclient.on('data', function (data) { - //console.log('Data relay <-- ' + data.length + ': ' + data.toString() + '\r\n'); - try { this.ws.write(data); } catch (e) { } - }); - - // If the TCP connection closes, disconnect the associated web socket. - ws.forwardclient.on('close', function () { - //console.log('TCP/TLS disconnected.'); - try { this.ws.end(); } catch (e) { } - try { this.end(); } catch (e) { } - }); - - // If the TCP connection causes an error, disconnect the associated web socket. - ws.forwardclient.on('error', function (err) { - //console.log('TCP/TLS disconnected with error', err); - try { this.ws.end(); } catch (e) { } - try { this.end(); } catch (e) { } - }); - break; default: socket.end(); @@ -1129,5 +1155,11 @@ function parseUrlArguments(url) { return r; } +// Remove a element from a array +function removeItemFromArray(array, element) { + const index = array.indexOf(element); + if (index !== -1) { array.splice(index, 1); } +} + // Run MeshCmd try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); } diff --git a/agents/meshcore.js b/agents/meshcore.js index 0d35d854..6626932d 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -75,10 +75,10 @@ function createMeshCore(agent) { // Try to load up the MEI module try { var amtMeiLib = require('amt-mei'); - amtMeiConnected = 1; amtMei = new amtMeiLib(); amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; sendPeriodicServerUpdate(); }); - amtMei.on('connect', function () { amtMeiConnected = 2; sendPeriodicServerUpdate(); }); + amtMeiConnected = 2; + //amtMei.on('connect', function () { amtMeiConnected = 2; sendPeriodicServerUpdate(); }); } catch (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; } // Try to load up the WIFI scanner @@ -869,11 +869,11 @@ function createMeshCore(agent) { break; } case 'selfinfo': { // Return self information block - buildSelfInfo(function (info) { sendConsoleText(objToString(info, 0, ' '), sessionid); }); + buildSelfInfo(function (info) { sendConsoleText(objToString(info, 0, ' ', true), sessionid); }); break; } case 'args': { // Displays parsed command arguments - response = 'args ' + objToString(args, 0, ' '); + response = 'args ' + objToString(args, 0, ' ', true); break; } case 'print': { // Print a message on the mesh agent console, does nothing when running in the background @@ -1045,7 +1045,7 @@ function createMeshCore(agent) { case 'amt': { // Show Intel AMT status getAmtInfo(function (state) { var resp = 'Intel AMT not detected.'; - if (state != null) { resp = objToString(state, 0, ' '); } + if (state != null) { resp = objToString(state, 0, ' ', true); } sendConsoleText(resp, sessionid); }); break; @@ -1053,7 +1053,11 @@ function createMeshCore(agent) { case 'netinfo': { // Show network interface information //response = objToString(mesh.NetInfo, 0, ' '); var interfaces = require('os').networkInterfaces(); - response = objToString(interfaces, 0, ' '); + response = objToString(interfaces, 0, ' ', true); + break; + } + case 'netinfo2': { // Show network interface information + response = objToString(mesh.NetInfo, 0, ' ', true); break; } case 'wakeonlan': { // Send wake-on-lan @@ -1215,7 +1219,7 @@ function createMeshCore(agent) { amtMei.getVersion(function (val) { amtMeiTmpState.Versions = {}; for (var version in val.Versions) { amtMeiTmpState.Versions[val.Versions[version].Description] = val.Versions[version].Version; } }); amtMei.getProvisioningMode(function (result) { amtMeiTmpState.ProvisioningMode = result.mode; }); amtMei.getProvisioningState(function (result) { amtMeiTmpState.ProvisioningState = result.state; }); - amtMei.getEHBCState(function (result) { if (result.EHBC == true) { amtMeiTmpState.Flags += 1; } }); + amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } }); amtMei.getControlMode(function (result) { if (result.controlMode == 1) { amtMeiTmpState.Flags += 2; } if (result.controlMode == 2) { amtMeiTmpState.Flags += 4; } }); //amtMei.getMACAddresses(function (result) { amtMeiTmpState.mac = result; }); amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } if (func != null) { func(amtMeiTmpState); } }); diff --git a/agents/modules_meshcmd/amt-mei.js b/agents/modules_meshcmd/amt-mei.js index fa87cfc5..d1c50808 100644 --- a/agents/modules_meshcmd/amt-mei.js +++ b/agents/modules_meshcmd/amt-mei.js @@ -18,7 +18,6 @@ var Q = require('queue'); function amt_heci() { var emitterUtils = require('events').inherits(this); emitterUtils.createEvent('error'); - emitterUtils.createEvent('connect'); var heci = require('heci'); diff --git a/agents/modules_meshcmd/amt.js b/agents/modules_meshcmd/amt.js index 166fddaf..632b7312 100644 --- a/agents/modules_meshcmd/amt.js +++ b/agents/modules_meshcmd/amt.js @@ -633,7 +633,7 @@ function AmtStackCreateService(wsmanStack) { 2003: 'Security Audit Log Enabled', 2004: 'Security Audit Log Exported', 2005: 'Security Audit Log Recovered', - 2100: 'Intel® ME Time Set', + 2100: 'Intel(R) ME Time Set', 2200: 'TCPIP Parameters Set', 2201: 'Host Name Set', 2202: 'Domain Name Set', @@ -742,12 +742,12 @@ function AmtStackCreateService(wsmanStack) { } if (x['InitiatorType'] == 2) { // Local - x['Initiator'] = 'Local'; + x['Initiator'] = 'Local'; ptr = 5; } if (x['InitiatorType'] == 3) { // KVM Default Port - x['Initiator'] = 'KVM Default Port'; + x['Initiator'] = 'KVM Default Port'; ptr = 5; } diff --git a/agents/modules_meshcore/amt-lme.js b/agents/modules_meshcore/amt-lme.js index f7a8f468..a70960bc 100644 --- a/agents/modules_meshcore/amt-lme.js +++ b/agents/modules_meshcore/amt-lme.js @@ -290,11 +290,8 @@ function lme_heci(options) { var notify = null; try { notify = xmlParser.ParseWsman(httpData); } catch (e) { } - // Translate the event - var notifyString = _lmsNotifyToString(notify); - // Event the http data - if (notify != null) { this.LMS.emit('notify', notify, channel.options, notifyString); } + if (notify != null) { this.LMS.emit('notify', notify, channel.options, _lmsNotifyToString(notify), _lmsNotifyToCode(notify)); } // Send channel close var buffer = Buffer.alloc(5); @@ -437,6 +434,13 @@ function parseHttp(httpData) { return null; } +function _lmsNotifyToCode(notify) { + if ((notify == null) || (notify.Body == null) || (notify.Body.MessageID == null)) return null; + var msgid = notify.Body.MessageID; + try { msgid += '-' + notify.Body.MessageArguments[0]; } catch (e) { } + return msgid; +} + function _lmsNotifyToString(notify) { if ((notify == null) || (notify.Body == null) || (notify.Body.MessageID == null)) return null; var msgid = notify.Body.MessageID; @@ -520,7 +524,7 @@ var lmsEvents = { "iAMT0055-0": "User Notification Alert - Provisioning state change notification - Pre-configuration.", "iAMT0055-1": "User Notification Alert - Provisioning state change notification - In configuration.", "iAMT0055-2": "User Notification Alert - Provisioning state change notification - Post-configuration.", - "iAMT0055-3": "User Notification Alert - Provisioning state change notification - unprovision process has started.", + "iAMT0055-3": "User Notification Alert - Provisioning state change notification - Unprovision process has started.", "iAMT0056": "User Notification Alert - System Defense change notification.", "iAMT0057": "User Notification Alert - Network State change notification.", "iAMT0058": "User Notification Alert - Remote Access change notification.", diff --git a/agents/modules_meshcore/amt-mei.js b/agents/modules_meshcore/amt-mei.js index fa87cfc5..ffe504c5 100644 --- a/agents/modules_meshcore/amt-mei.js +++ b/agents/modules_meshcore/amt-mei.js @@ -18,24 +18,20 @@ var Q = require('queue'); function amt_heci() { var emitterUtils = require('events').inherits(this); emitterUtils.createEvent('error'); - emitterUtils.createEvent('connect'); var heci = require('heci'); this._ObjectID = "pthi"; this._rq = new Q(); - this._setupPTHI = function _setupPTHI() - { + this._setupPTHI = function _setupPTHI() { this._amt = heci.create(); this._amt.BiosVersionLen = 65; this._amt.UnicodeStringLen = 20; this._amt.Parent = this; this._amt.on('error', function _amtOnError(e) { this.Parent.emit('error', e); }); - this._amt.on('connect', function _amtOnConnect() - { - this.on('data', function _amtOnData(chunk) - { + this._amt.on('connect', function _amtOnConnect() { + this.on('data', function _amtOnData(chunk) { //console.log("Received: " + chunk.length + " bytes"); var header = this.Parent.getCommand(chunk); //console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse); @@ -47,14 +43,12 @@ function amt_heci() { params.unshift(header); callback.apply(this.Parent, params); - if(this.Parent._rq.isEmpty()) - { + if (this.Parent._rq.isEmpty()) { // No More Requests, we can close PTHI this.Parent._amt.disconnect(); this.Parent._amt = null; } - else - { + else { // Send the next request this.write(this.Parent._rq.peekQueue().send); } @@ -79,10 +73,9 @@ function amt_heci() { var header = Buffer.from('010100000000000000000000', 'hex'); header.writeUInt32LE(arguments[0] | 0x04000000, 4); header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8); - this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args , send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]]))}); + this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args, send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]])) }); - if(!this._amt) - { + if (!this._amt) { this._setupPTHI(); this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 }); } @@ -94,7 +87,7 @@ function amt_heci() { this.sendCommand(26, null, function (header, fn, opt) { if (header.Status == 0) { var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, this._amt.BiosVersionLen), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4); - for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen) ; ++i) { + for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen); ++i) { val.Versions[i] = { Description: v.slice(2, v.readUInt16LE(0) + 2).toString(), Version: v.slice(4 + this._amt.UnicodeStringLen, 4 + this._amt.UnicodeStringLen + v.readUInt16LE(2 + this._amt.UnicodeStringLen)).toString() }; v = v.slice(4 + (2 * this._amt.UnicodeStringLen)); } diff --git a/views/default.handlebars b/views/default.handlebars index 3d3b242d..4388178b 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -563,15 +563,7 @@