diff --git a/agents/MeshCmd-signed.exe b/agents/MeshCmd-signed.exe index b4e37588..728078b3 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 aaee20d6..1539f1bf 100644 Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ diff --git a/agents/MeshService-signed.exe b/agents/MeshService-signed.exe index a46f9bd9..7ed930ce 100644 Binary files a/agents/MeshService-signed.exe and b/agents/MeshService-signed.exe differ diff --git a/agents/MeshService.exe b/agents/MeshService.exe index 41f1142e..bfe38e5c 100644 Binary files a/agents/MeshService.exe and b/agents/MeshService.exe differ diff --git a/agents/MeshService64-signed.exe b/agents/MeshService64-signed.exe index c1bc727c..245e2595 100644 Binary files a/agents/MeshService64-signed.exe and b/agents/MeshService64-signed.exe differ diff --git a/agents/MeshService64.exe b/agents/MeshService64.exe index 83f6b819..9a661d42 100644 Binary files a/agents/MeshService64.exe and b/agents/MeshService64.exe differ diff --git a/agents/meshcmd.js b/agents/meshcmd.js index af54659d..c5d511ff 100644 --- a/agents/meshcmd.js +++ b/agents/meshcmd.js @@ -1532,7 +1532,7 @@ if (serviceName == null) { if (serviceInstall == 0) { run(process.argv); } else { - var serviceHost = require('serviceHost'); + var serviceHost = require('service-host'); var meshcmdService = new serviceHost({ name: serviceName, startType: 'AUTO_START' }); // Called when the background service is started. diff --git a/agents/meshcore.js b/agents/meshcore.js index 364c8305..523b31b5 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -14,12 +14,59 @@ See the License for the specific language governing permissions and limitations under the License. */ + +function borderController() +{ + this.container = null; + this.Start = function Start(user) + { + if (this.container == null) { + if (process.platform == 'win32') { + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.SessionId }); + } + else { + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.uid }); + } + this.container.addModule('monitor-info', getJSModule('monitor-info')); + this.container.addModule('monitor-border', getJSModule('monitor-border')); + this.container.addModule('promise', getJSModule('promise')); + this.container.ExecuteString("var border = require('monitor-border'); border.Start();"); + } + } + this.Stop = function Stop() + { + if (this.container != null) + { + this._container = this.container; + this._container.parent = this; + this.container = null; + + this._container.once('exit', function () { this.parent._container = null; }); + this._container.exit(); + } + } +} + function createMeshCore(agent) { var obj = {}; + require('events').EventEmitter.call(obj, true).createEvent('loggedInUsers_Updated'); + obj.on('loggedInUsers_Updated', function () + { + var users = [] + for(var i = 0; i < obj.loggedInUsers.length; ++i) + { + users.push((obj.loggedInUsers[i].Domain ? (obj.loggedInUsers[i].Domain + '\\') : '') + obj.loggedInUsers[i].Username); + } + sendConsoleText('LogOn Status Changed. Active Users => [' + users.join(', ') + ']'); + }); + obj.borderManager = new borderController(); + // MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent. obj.meshCoreInfo = "MeshCore v5"; obj.meshCoreCapabilities = 14; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript + obj.loggedInUsers = []; + var meshServerConnectionState = 0; var tunnels = {}; var lastSelfInfo = null; @@ -863,9 +910,36 @@ function createMeshCore(agent) { var response = null; switch (cmd) { case 'help': { // Displays available commands - response = 'Available commands: help, info, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock.'; + response = 'Available commands: help, info, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, border.'; break; } + case 'border': + { + if ((args['_'].length == 1) && (args['_'][0] == 'on')) { + if (obj.loggedInUsers.length > 0) { + obj.borderManager.Start(obj.loggedInUsers[0]); + response = 'Border blinking is on.'; + } else { + response = 'Cannot turn on border blinking, no logged in users.'; + } + } else if ((args['_'].length == 1) && (args['_'][0] == 'off')) { + obj.borderManager.Stop(); + response = 'Border blinking is off.'; + } else { + response = 'Proper usage: border "on|off"'; // Display correct command usage + } + } + break; + case 'users': + { + var retList = []; + for(var i = 0; i < obj.loggedInUsers.length; ++i) + { + retList.push((obj.loggedInUsers[i].Domain ? (obj.loggedInUsers[i].Domain + '\\') : '') + obj.loggedInUsers[i].Username); + } + response = 'Active Users => [' + retList.join(', ') + ']'; + } + break; case 'toast': { if (process.platform == 'win32') { if (args['_'].length < 1) { response = 'Proper usage: toast "message"'; } else { @@ -878,8 +952,8 @@ function createMeshCore(agent) { break; } case 'setdebug': { - if (args['_'].length < 1) { response = 'Proper usage: setdebug (target), 0 = StdOut, 1 = This Console, * = All Consoles, 2 = WebLog, 3 = Disabled'; } // Display usage - else { if (args['_'][0] == '*') { console.setDestination(1); } else { console.setDestination(parseInt(args['_'][0]), sessionid); } } + if (args['_'].length < 1) { response = 'Proper usage: setdebug (target), 0 = Disabled, 1 = StdOut, 2 = This Console, * = All Consoles, 4 = WebLog, 8 = Logfile'; } // Display usage + else { if (args['_'][0] == '*') { console.setDestination(2); } else { console.setDestination(parseInt(args['_'][0]), sessionid); } } break; } case 'ps': { @@ -1373,6 +1447,16 @@ function createMeshCore(agent) { sendPeriodicServerUpdate(true); // Send the server update } + require('user-sessions').on('changed', function onUserSessionChanged() + { + require('user-sessions').enumerateUsers().then(function (users) + { + obj.loggedInUsers = users.Active; + obj.emit('loggedInUsers_Updated'); + }); + }); + + require('user-sessions').emit('changed'); //console.log('Stopping.'); //process.exit(); } diff --git a/agents/modules_meshcmd/serviceHost.js b/agents/modules_meshcmd/service-host.js similarity index 63% rename from agents/modules_meshcmd/serviceHost.js rename to agents/modules_meshcmd/service-host.js index ebe0c7c3..7bfe0e49 100644 --- a/agents/modules_meshcmd/serviceHost.js +++ b/agents/modules_meshcmd/service-host.js @@ -1,24 +1,61 @@ +/* +Copyright 2018 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. +*/ + var SERVICE_WIN32 = 0x00000010 | 0x00000020; var SERVICE_STATE = { STOPPED: 0x00000001, SERVICE_START_PENDING: 0x00000002, SERVICE_STOP_PENDING: 0x00000003, RUNNING: 0x00000004 }; -var SERVICE_ACCEPT = { SERVICE_ACCEPT_STOP: 0x00000001, SERVICE_ACCEPT_SHUTDOWN: 0x00000004 }; -var SERVICE_CONTROL = { SERVICE_CONTROL_SHUTDOWN: 0x00000005, SERVICE_CONTROL_STOP: 0x00000001 }; +var SERVICE_ACCEPT = { SERVICE_ACCEPT_STOP: 0x00000001, SERVICE_ACCEPT_SHUTDOWN: 0x00000004, SERVICE_ACCEPT_POWEREVENT: 0x00000040, SERVICE_ACCEPT_SESSIONCHANGE: 0x00000080 }; + +var SERVICE_CONTROL = { SERVICE_CONTROL_SHUTDOWN: 0x00000005, SERVICE_CONTROL_STOP: 0x00000001, SERVICE_CONTROL_POWEREVENT: 0x0000000D, SERVICE_CONTROL_SESSIONCHANGE: 0x0000000E}; +var SESSION_CHANGE_TYPE = +{ + WTS_CONSOLE_CONNECT: 0x1, + WTS_CONSOLE_DISCONNECT: 0x2, + WTS_REMOTE_CONNECT: 0x3, + WTS_REMOTE_DISCONNECT: 0x4, + WTS_SESSION_LOGON: 0x5, + WTS_SESSION_LOGOFF: 0x6, + WTS_SESSION_LOCK: 0x7, + WTS_SESSION_UNLOCK: 0x8, + WTS_SESSION_REMOTE_CONTROL: 0x9, + WTS_SESSION_CREATE: 0xa, + WTS_SESSION_TERMINATE: 0xb +}; + + var NO_ERROR = 0; -var serviceManager = require('serviceManager'); +var serviceManager = require('service-manager'); -function serviceHost(serviceName) { - this._ObjectID = 'serviceHost'; +function serviceHost(serviceName) +{ + this._ObjectID = 'service-host'; var emitterUtils = require('events').inherits(this); emitterUtils.createEvent('serviceStart'); emitterUtils.createEvent('serviceStop'); emitterUtils.createEvent('normalStart'); + emitterUtils.createEvent('session'); + emitterUtils.createEvent('powerStateChange'); - if (process.platform == 'win32') { + if (process.platform == 'win32') + { this.GM = require('_GenericMarshal'); this.Advapi = this.GM.CreateNativeProxy('Advapi32.dll'); this.Advapi.CreateMethod({ method: 'StartServiceCtrlDispatcherA', threadDispatch: 1 }); - this.Advapi.CreateMethod('RegisterServiceCtrlHandlerA'); + this.Advapi.CreateMethod('RegisterServiceCtrlHandlerExA'); this.Advapi.CreateMethod('SetServiceStatus'); this.Kernel32 = this.GM.CreateNativeProxy('Kernel32.dll'); this.Kernel32.CreateMethod('GetLastError'); @@ -31,7 +68,8 @@ function serviceHost(serviceName) { this._ServiceMain = this.GM.GetGenericGlobalCallback(2); this._ServiceMain.Parent = this; this._ServiceMain.GM = this.GM; - this._ServiceMain.on('GlobalCallback', function onGlobalCallback(argc, argv) { + this._ServiceMain.on('GlobalCallback', function onGlobalCallback(argc, argv) + { //ToDo: Check to make sure this is for us this.Parent._ServiceStatus = this.GM.CreateVariable(28); @@ -48,8 +86,9 @@ function serviceHost(serviceName) { // Initialise service status this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_WIN32); this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.SERVICE_STOPPED, 4); - this.Parent._ServiceStatusHandle = this.Parent.Advapi.RegisterServiceCtrlHandlerA(this.Parent._ServiceName, this.Parent._ServiceControlHandler); - if (this.Parent._ServiceStatusHandle.Val == 0) { + this.Parent._ServiceStatusHandle = this.Parent.Advapi.RegisterServiceCtrlHandlerExA(this.Parent._ServiceName, this.Parent._ServiceControlHandler, this.Parent.GM.StashObject(this.Parent._ServiceControlHandler)); + if(this.Parent._ServiceStatusHandle.Val == 0) + { process.exit(1); } @@ -59,11 +98,12 @@ function serviceHost(serviceName) { // Service running this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.RUNNING, 4); - this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_ACCEPT.SERVICE_ACCEPT_STOP, 8); + this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_ACCEPT.SERVICE_ACCEPT_STOP | SERVICE_ACCEPT.SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT.SERVICE_ACCEPT_SESSIONCHANGE, 8); this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus); this.Parent.Ole32.CoInitializeEx(0, 2); - this.Parent.on('~', function OnServiceHostFinalizer() { + this.Parent.on('~', function OnServiceHostFinalizer() + { var GM = require('_GenericMarshal'); var Advapi = GM.CreateNativeProxy('Advapi32.dll'); Advapi.CreateMethod('SetServiceStatus'); @@ -82,22 +122,39 @@ function serviceHost(serviceName) { this.Ole32.CoUninitialize(); }); + this.Parent.emit('serviceStart'); }); - this._ServiceControlHandler = this.GM.GetGenericGlobalCallback(1); + this._ServiceControlHandler = this.GM.GetGenericGlobalCallback(4); this._ServiceControlHandler.Parent = this; this._ServiceControlHandler.GM = this.GM; - this._ServiceControlHandler.on('GlobalCallback', function onServiceControlHandler(code) { - switch (code.Val) { - case SERVICE_CONTROL.SERVICE_CONTROL_SHUTDOWN: - case SERVICE_CONTROL.SERVICE_CONTROL_STOP: - this.Parent.emit('serviceStop'); - return; - default: - break; - } + this._ServiceControlHandler.on('GlobalCallback', function onServiceControlHandler(code, eventType, eventData, context) + { + var j = this.Parent.GM.UnstashObject(context); + if (j != null && j == this) + { + switch (code.Val) + { + case SERVICE_CONTROL.SERVICE_CONTROL_SHUTDOWN: + case SERVICE_CONTROL.SERVICE_CONTROL_STOP: + this.Parent.emit('serviceStop'); + return; + case SERVICE_CONTROL.SERVICE_CONTROL_SESSIONCHANGE: + var sessionId = eventData.Deref(4, 4).toBuffer().readUInt32LE(); + switch(eventType.Val) + { + case SESSION_CHANGE_TYPE.WTS_SESSION_LOGON: + case SESSION_CHANGE_TYPE.WTS_SESSION_LOGOFF: + require('user-sessions').emit('changed'); + break; + } + break; + default: + break; + } - this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus); + this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus); + } }); } @@ -106,42 +163,54 @@ function serviceHost(serviceName) { { throw ('Must specify either ServiceName or Options'); } - if (!this._ServiceOptions.servicePath) { + if (!this._ServiceOptions.servicePath) + { this._ServiceOptions.servicePath = process.execPath; } - - this.run = function run() { + + this.run = function run() + { var serviceOperation = 0; - for (var i = 0; i < process.argv.length; ++i) { - switch (process.argv[i].toLowerCase()) { - case 'install': + for(var i = 0; i 0 && tokens[x]) { tokenList.push(tokens[x]); } + if (i > 0 && tokens[x]) { tokenList.push(tokens[x]);} } - if ((i > 0) && (tokenList[key.PID])) { - retVal[tokenList[key.PID]] = { user: tokenList[key.USER], cmd: tokenList[key.COMMAND] }; + if(i>0) + { + if (tokenList[key.PID]) + { + retVal.push({ pid: tokenList[key.PID], user: tokenList[key.USER], command: tokenList[key.COMMAND] }); + } } } - if (this.callback) { + if (this.callback) + { this.args.unshift(retVal); this.callback.apply(this.parent, this.args); } @@ -81,18 +99,25 @@ function processManager() { break; } }; - this.getProcessInfo = function getProcessInfo(pid) { - switch (process.platform) { + this.getProcessInfo = function getProcessInfo(pid) + { + switch(process.platform) + { default: throw ('getProcessInfo() not supported for ' + process.platform); + break; case 'linux': - var status = require('fs').readFileSync('/proc/' + pid + '/status'), info = {}, lines = status.toString().split('\n'); - for (var i in lines) { + var status = require('fs').readFileSync('/proc/' + pid + '/status'); + var info = {}; + var lines = status.toString().split('\n'); + for(var i in lines) + { var tokens = lines[i].split(':'); if (tokens.length > 1) { tokens[1] = tokens[1].trim(); } info[tokens[0]] = tokens[1]; } return (info); + break; } }; } diff --git a/agents/modules_meshcore/promise.js b/agents/modules_meshcore/promise.js new file mode 100644 index 00000000..e764a630 --- /dev/null +++ b/agents/modules_meshcore/promise.js @@ -0,0 +1,185 @@ +/* +Copyright 2018 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. +*/ + +var refTable = {}; + +function Promise(promiseFunc) +{ + this._ObjectID = 'promise'; + this._internal = { promise: this, func: promiseFunc, completed: false, errors: false, completedArgs: [] }; + require('events').EventEmitter.call(this._internal); + this._internal.on('_eventHook', function (eventName, eventCallback) + { + //console.log('hook', eventName, 'errors/' + this.errors + ' completed/' + this.completed); + var r = null; + + if (eventName == 'resolved' && !this.errors && this.completed) + { + r = eventCallback.apply(this, this.completedArgs); + if(r!=null) + { + this.emit_returnValue('resolved', r); + } + } + if (eventName == 'rejected' && this.errors && this.completed) + { + eventCallback.apply(this, this.completedArgs); + } + if (eventName == 'settled' && this.completed) + { + eventCallback.apply(this, []); + } + }); + this._internal.resolver = function _resolver() + { + _resolver._self.errors = false; + _resolver._self.completed = true; + _resolver._self.completedArgs = []; + var args = ['resolved']; + if (this.emit_returnValue && this.emit_returnValue('resolved') != null) + { + _resolver._self.completedArgs.push(this.emit_returnValue('resolved')); + args.push(this.emit_returnValue('resolved')); + } + else + { + for (var a in arguments) + { + _resolver._self.completedArgs.push(arguments[a]); + args.push(arguments[a]); + } + } + _resolver._self.emit.apply(_resolver._self, args); + _resolver._self.emit('settled'); + }; + this._internal.rejector = function _rejector() + { + _rejector._self.errors = true; + _rejector._self.completed = true; + _rejector._self.completedArgs = []; + var args = ['rejected']; + for (var a in arguments) + { + _rejector._self.completedArgs.push(arguments[a]); + args.push(arguments[a]); + } + + _rejector._self.emit.apply(_rejector._self, args); + _rejector._self.emit('settled'); + }; + this.catch = function(func) + { + this._internal.once('settled', func); + } + this.finally = function (func) + { + this._internal.once('settled', func); + }; + this.then = function (resolved, rejected) + { + if (resolved) { this._internal.once('resolved', resolved); } + if (rejected) { this._internal.once('rejected', rejected); } + + var retVal = new Promise(function (r, j) { }); + + this._internal.once('resolved', retVal._internal.resolver); + this._internal.once('rejected', retVal._internal.rejector); + return (retVal); + }; + + this._internal.resolver._self = this._internal; + this._internal.rejector._self = this._internal;; + + try + { + promiseFunc.call(this, this._internal.resolver, this._internal.rejector); + } + catch(e) + { + this._internal.errors = true; + this._internal.completed = true; + this._internal.completedArgs = [e]; + this._internal.emit('rejected', e); + this._internal.emit('settled'); + } + + if(!this._internal.completed) + { + // Save reference of this object + refTable[this._internal._hashCode()] = this._internal; + this._internal.once('settled', function () { refTable[this._hashCode()] = null; }); + } +} + +Promise.resolve = function resolve() +{ + var retVal = new Promise(function (r, j) { }); + var args = []; + for (var i in arguments) + { + args.push(arguments[i]); + } + retVal._internal.resolver.apply(retVal._internal, args); + return (retVal); +}; +Promise.reject = function reject() { + var retVal = new Promise(function (r, j) { }); + var args = []; + for (var i in arguments) { + args.push(arguments[i]); + } + retVal._internal.rejector.apply(retVal._internal, args); + return (retVal); +}; +Promise.all = function all(promiseList) +{ + var ret = new Promise(function (res, rej) + { + this.__rejector = rej; + this.__resolver = res; + this.__promiseList = promiseList; + this.__done = false; + this.__count = 0; + }); + + for (var i in promiseList) + { + promiseList[i].then(function () + { + // Success + if(++ret.__count == ret.__promiseList.length) + { + ret.__done = true; + ret.__resolver(ret.__promiseList); + } + }, function (arg) + { + // Failure + if(!ret.__done) + { + ret.__done = true; + ret.__rejector(arg); + } + }); + } + if (promiseList.length == 0) + { + ret.__resolver(promiseList); + } + return (ret); +}; + +module.exports = Promise; \ No newline at end of file diff --git a/agents/modules_meshcore/user-sessions.js b/agents/modules_meshcore/user-sessions.js index d8fe2d96..4672596e 100644 --- a/agents/modules_meshcore/user-sessions.js +++ b/agents/modules_meshcore/user-sessions.js @@ -16,9 +16,27 @@ limitations under the License. function UserSessions() { - this._ObjectID = 'UserSessions'; + this._ObjectID = 'user-sessions'; + require('events').EventEmitter.call(this, true).createEvent('changed'); - if (process.platform == 'win32') { + this.enumerateUsers = function enumerateUsers() + { + var promise = require('promise'); + var p = new promise(function (res, rej) + { + this.__resolver = res; + this.__rejector = rej; + }); + p.__handler = function __handler(users) + { + p.__resolver(users); + }; + this.Current(p.__handler); + return (p); + } + + if (process.platform == 'win32') + { this._marshal = require('_GenericMarshal'); this._kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll'); this._kernel32.CreateMethod('GetLastError'); @@ -77,7 +95,7 @@ function UserSessions() return (retVal); }; - this.Current = function Current() + this.Current = function Current(cb) { var retVal = {}; var pinfo = this._marshal.CreatePointer(); @@ -102,36 +120,152 @@ function UserSessions() this._wts.WTSFreeMemory(pinfo.Deref()); - Object.defineProperty(retVal, 'connected', { value: showActiveOnly(retVal) }); + Object.defineProperty(retVal, 'Active', { value: showActiveOnly(retVal) }); + if (cb) { cb(retVal); } return (retVal); }; } else { - this.Current = function Current() + this.Self = function Self() + { + var promise = require('promise'); + var p = new promise(function (res, rej) + { + this.__resolver = res; this.__rejector = rej; + this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u']); + this.__child.promise = this; + this.__child.stdout._txt = ''; + this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); }); + this.__child.on('exit', function (code) + { + try + { + parseInt(this.stdout._txt); + } + catch (e) + { + this.promise.__rejector('invalid uid'); + return; + } + + var id = parseInt(this.stdout._txt); + this.promise.__resolver(id); + }); + }); + return (p); + }; + this.Current = function Current(cb) { var retVal = {}; - var emitterUtils = require('events').inherits(retVal); - emitterUtils.createEvent('logon'); + retVal._ObjectID = 'UserSession' + Object.defineProperty(retVal, '_callback', { value: cb }); + Object.defineProperty(retVal, '_child', { value: require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']) }); - retVal._child = require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']); retVal._child.Parent = retVal; retVal._child._txt = ''; retVal._child.on('exit', function (code) { var lines = this._txt.split('\n'); var sessions = []; + var users = {}; + for(var i in lines) { if (lines[i]) { - console.log(getTokens(lines[i])); - var user = lines[i].substring(0, lines[i].indexOf(' ')); - sessions.push(user); + var tokens = getTokens(lines[i]); + var s = { Username: tokens[0], SessionId: tokens[1] } + if (tokens[3].includes('still logged in')) + { + s.State = 'Active'; + } + else + { + s.LastActive = tokens[3]; + } + + sessions.push(s); } } sessions.pop(); - console.log(sessions); + + + var usernames = {}; + var promises = []; + + for (var i in sessions) + { + if (sessions[i].Username != 'reboot') + { + users[sessions[i].SessionId] = sessions[i]; + if(usernames[sessions[i].Username] == null) + { + usernames[sessions[i].Username] = -1; + } + } + } + + try + { + require('promise'); + } + catch(e) + { + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) }); + if (this.Parent._callback) { this.Parent._callback.call(this.Parent, users); } + return; + } + + var promise = require('promise'); + for (var n in usernames) + { + var p = new promise(function (res, rej) + { + this.__username = n; + this.__resolver = res; this.__rejector = rej; + this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u', n]); + this.__child.promise = this; + this.__child.stdout._txt = ''; + this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); }); + this.__child.on('exit', function (code) + { + try + { + parseInt(this.stdout._txt); + } + catch(e) + { + this.promise.__rejector('invalid uid'); + return; + } + + var id = parseInt(this.stdout._txt); + this.promise.__resolver(id); + }); + }); + promises.push(p); + } + promise.all(promises).then(function (plist) + { + // Done + var table = {}; + for(var i in plist) + { + table[plist[i].__username] = plist[i]._internal.completedArgs[0]; + } + for(var i in users) + { + users[i].uid = table[users[i].Username]; + } + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) }); + if (retVal._callback) { retVal._callback.call(retVal, users); } + }, function (reason) + { + // Failed + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) }); + if (retVal._callback) { retVal._callback.call(retVal, users); } + }); }); retVal._child.stdout.Parent = retVal._child; retVal._child.stdout.on('data', function (chunk) { this.Parent._txt += chunk.toString(); }); @@ -145,7 +279,7 @@ function showActiveOnly(source) var retVal = []; for (var i in source) { - if (source[i].State == 'Active' || source[i].State == 'Connected') + if (source[i].State == 'Active') { retVal.push(source[i]); } @@ -159,8 +293,13 @@ function getTokens(str) columns.push(str.substring(0, (i=str.indexOf(' ')))); while (str[++i] == ' '); - columns.push(str.substring(i, str.substring(i).indexOf(' ') + i)); - + columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i))); + while (str[++i] == ' '); + columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i))); + while (str[++i] == ' '); + var status = str.substring(i).trim(); + columns.push(status); + return (columns); } diff --git a/agents/modules_meshcore_backup/amt-lme.js b/agents/modules_meshcore_backup/amt-lme.js new file mode 100644 index 00000000..a7bb12ec --- /dev/null +++ b/agents/modules_meshcore_backup/amt-lme.js @@ -0,0 +1,893 @@ +/* +Copyright 2018 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. +*/ + + +var MemoryStream = require('MemoryStream'); +var lme_id = 0; // Our next channel identifier +var lme_port_offset = 0; // Debug: Set this to "-100" to bind to 16892 & 16893 and IN_ADDRANY. This is for LMS debugging. +var xmlParser = require('amt-xml'); + +// Documented in: https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/HTMLDocuments/MPSDocuments/Intel%20AMT%20Port%20Forwarding%20Protocol%20Reference%20Manual.pdf +var APF_DISCONNECT = 1; +var APF_SERVICE_REQUEST = 5; +var APF_SERVICE_ACCEPT = 6; +var APF_USERAUTH_REQUEST = 50; +var APF_USERAUTH_FAILURE = 51; +var APF_USERAUTH_SUCCESS = 52; +var APF_GLOBAL_REQUEST = 80; +var APF_REQUEST_SUCCESS = 81; +var APF_REQUEST_FAILURE = 82; +var APF_CHANNEL_OPEN = 90; +var APF_CHANNEL_OPEN_CONFIRMATION = 91; +var APF_CHANNEL_OPEN_FAILURE = 92; +var APF_CHANNEL_WINDOW_ADJUST = 93; +var APF_CHANNEL_DATA = 94; +var APF_CHANNEL_CLOSE = 97; +var APF_PROTOCOLVERSION = 192; + +function lme_object() { + this.ourId = ++lme_id; + this.amtId = -1; + this.LME_CHANNEL_STATUS = 'LME_CS_FREE'; + this.txWindow = 0; + this.rxWindow = 0; + this.localPort = 0; + this.errorCount = 0; +} + +function stream_bufferedWrite() { + var emitterUtils = require('events').inherits(this); + this.buffer = []; + this._readCheckImmediate = undefined; + this._ObjectID = "bufferedWriteStream"; + // Writable Events + emitterUtils.createEvent('close'); + emitterUtils.createEvent('drain'); + emitterUtils.createEvent('error'); + emitterUtils.createEvent('finish'); + emitterUtils.createEvent('pipe'); + emitterUtils.createEvent('unpipe'); + + // Readable Events + emitterUtils.createEvent('readable'); + this.isEmpty = function () { + return (this.buffer.length == 0); + }; + this.isWaiting = function () { + return (this._readCheckImmediate == undefined); + }; + this.write = function (chunk) { + for (var args in arguments) { if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; } } + var tmp = Buffer.alloc(chunk.length); + chunk.copy(tmp); + this.buffer.push({ offset: 0, data: tmp }); + this.emit('readable'); + return (this.buffer.length == 0 ? true : false); + }; + this.read = function () { + var size = arguments.length == 0 ? undefined : arguments[0]; + var bytesRead = 0; + var list = []; + while ((size == undefined || bytesRead < size) && this.buffer.length > 0) { + var len = this.buffer[0].data.length - this.buffer[0].offset; + var offset = this.buffer[0].offset; + + if (len > (size - bytesRead)) { + // Only reading a subset + list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead)); + this.buffer[0].offset += (size - bytesRead); + bytesRead += (size - bytesRead); + } else { + // Reading the entire thing + list.push(this.buffer[0].data.slice(offset)); + bytesRead += len; + this.buffer.shift(); + } + } + this._readCheckImmediate = setImmediate(function (buffered) { + buffered._readCheckImmediate = undefined; + if (buffered.buffer.length == 0) { + buffered.emit('drain'); // Drained + } else { + buffered.emit('readable'); // Not drained + } + }, this); + return (Buffer.concat(list)); + }; +} + + +function lme_heci(options) { + var emitterUtils = require('events').inherits(this); + emitterUtils.createEvent('error'); + emitterUtils.createEvent('connect'); + emitterUtils.createEvent('notify'); + emitterUtils.createEvent('bind'); + + if ((options != null) && (options.debug == true)) { lme_port_offset = -100; } // LMS debug mode + + var heci = require('heci'); + this.INITIAL_RXWINDOW_SIZE = 4096; + + this._ObjectID = "lme"; + this._LME = heci.create(); + this._LME._binded = {}; + this._LME.LMS = this; + this._LME.on('error', function (e) { this.LMS.emit('error', e); }); + this._LME.on('connect', function () { + this.on('data', function (chunk) { + // this = HECI + var cmd = chunk.readUInt8(0); + //console.log('LME Command ' + cmd + ', ' + chunk.length + ' byte(s).'); + + switch (cmd) { + default: + console.log('Unhandled LME Command ' + cmd + ', ' + chunk.length + ' byte(s).'); + break; + case APF_SERVICE_REQUEST: + var nameLen = chunk.readUInt32BE(1); + var name = chunk.slice(5, nameLen + 5); + //console.log("Service Request for: " + name); + if (name == 'pfwd@amt.intel.com' || name == 'auth@amt.intel.com') { + var outBuffer = Buffer.alloc(5 + nameLen); + outBuffer.writeUInt8(6, 0); + outBuffer.writeUInt32BE(nameLen, 1); + outBuffer.write(name.toString(), 5); + this.write(outBuffer); + //console.log('Answering APF_SERVICE_REQUEST'); + } else { + //console.log('UNKNOWN APF_SERVICE_REQUEST'); + } + break; + case APF_GLOBAL_REQUEST: + var nameLen = chunk.readUInt32BE(1); + var name = chunk.slice(5, nameLen + 5).toString(); + + switch (name) { + case 'tcpip-forward': + var len = chunk.readUInt32BE(nameLen + 6); + var port = chunk.readUInt32BE(nameLen + 10 + len); + //console.log("[" + chunk.length + "/" + len + "] APF_GLOBAL_REQUEST for: " + name + " on port " + port); + if (this[name] == undefined) { this[name] = {}; } + if (this[name][port] != null) { // Close the existing binding + for (var i in this.sockets) { + var channel = this.sockets[i]; + if (channel.localPort == port) { this.sockets[i].end(); delete this.sockets[i]; } // Close this socket + } + } + if (this[name][port] == null) + { // Bind a new server socket if not already present + this[name][port] = require('net').createServer(); + this[name][port].HECI = this; + if (lme_port_offset == 0) { + this[name][port].listen({ port: port, host: '127.0.0.1' }); // Normal mode + } else { + this[name][port].listen({ port: (port + lme_port_offset) }); // Debug mode + } + this[name][port].on('connection', function (socket) { + //console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort); + this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort - lme_port_offset); + }); + this._binded[port] = true; + this.LMS.emit('bind', this._binded); + } + var outBuffer = Buffer.alloc(5); + outBuffer.writeUInt8(81, 0); + outBuffer.writeUInt32BE(port, 1); + this.write(outBuffer); + break; + case 'cancel-tcpip-forward': + var outBuffer = Buffer.alloc(1); + outBuffer.writeUInt8(APF_REQUEST_SUCCESS, 0); + this.write(outBuffer); + break; + case 'udp-send-to@amt.intel.com': + var outBuffer = Buffer.alloc(1); + outBuffer.writeUInt8(APF_REQUEST_FAILURE, 0); + this.write(outBuffer); + break; + default: + //console.log("Unknown APF_GLOBAL_REQUEST for: " + name); + break; + } + break; + case APF_CHANNEL_OPEN_CONFIRMATION: + var rChannel = chunk.readUInt32BE(1); + var sChannel = chunk.readUInt32BE(5); + var wSize = chunk.readUInt32BE(9); + //console.log('rChannel/' + rChannel + ', sChannel/' + sChannel + ', wSize/' + wSize); + if (this.sockets[rChannel] != undefined) { + this.sockets[rChannel].lme.amtId = sChannel; + this.sockets[rChannel].lme.rxWindow = wSize; + this.sockets[rChannel].lme.txWindow = wSize; + this.sockets[rChannel].lme.LME_CHANNEL_STATUS = 'LME_CS_CONNECTED'; + //console.log('LME_CS_CONNECTED'); + this.sockets[rChannel].bufferedStream = new stream_bufferedWrite(); + this.sockets[rChannel].bufferedStream.socket = this.sockets[rChannel]; + this.sockets[rChannel].bufferedStream.on('readable', function () { + if (this.socket.lme.txWindow > 0) { + var buffer = this.read(this.socket.lme.txWindow); + var packet = Buffer.alloc(9 + buffer.length); + packet.writeUInt8(APF_CHANNEL_DATA, 0); + packet.writeUInt32BE(this.socket.lme.amtId, 1); + packet.writeUInt32BE(buffer.length, 5); + buffer.copy(packet, 9); + this.socket.lme.txWindow -= buffer.length; + this.socket.HECI.write(packet); + } + }); + this.sockets[rChannel].bufferedStream.on('drain', function () { + this.socket.resume(); + }); + this.sockets[rChannel].on('data', function (chunk) { + if (!this.bufferedStream.write(chunk)) { this.pause(); } + }); + this.sockets[rChannel].on('end', function () { + var outBuffer = Buffer.alloc(5); + outBuffer.writeUInt8(APF_CHANNEL_CLOSE, 0); + outBuffer.writeUInt32BE(this.lme.amtId, 1); + this.HECI.write(outBuffer); + }); + this.sockets[rChannel].resume(); + } + + break; + case APF_PROTOCOLVERSION: + var major = chunk.readUInt32BE(1); + var minor = chunk.readUInt32BE(5); + var reason = chunk.readUInt32BE(9); + var outBuffer = Buffer.alloc(93); + outBuffer.writeUInt8(192, 0); + outBuffer.writeUInt32BE(1, 1); + outBuffer.writeUInt32BE(0, 5); + outBuffer.writeUInt32BE(reason, 9); + //console.log('Answering PROTOCOL_VERSION'); + this.write(outBuffer); + break; + case APF_CHANNEL_WINDOW_ADJUST: + var rChannelId = chunk.readUInt32BE(1); + var bytesToAdd = chunk.readUInt32BE(5); + if (this.sockets[rChannelId] != undefined) { + this.sockets[rChannelId].lme.txWindow += bytesToAdd; + if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) { + this.sockets[rChannelId].bufferedStream.emit('readable'); + } + } else { + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST'); + } + break; + case APF_CHANNEL_DATA: + var rChannelId = chunk.readUInt32BE(1); + var dataLen = chunk.readUInt32BE(5); + var data = chunk.slice(9, 9 + dataLen); + if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) { + this.sockets[rChannelId].pendingBytes.push(data.length); + this.sockets[rChannelId].write(data, function () { + var written = this.pendingBytes.shift(); + //console.log('adjust', this.lme.amtId, written); + var outBuffer = Buffer.alloc(9); + outBuffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0); + outBuffer.writeUInt32BE(this.lme.amtId, 1); + outBuffer.writeUInt32BE(written, 5); + this.HECI.write(outBuffer); + }); + } else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) { + var channel = this.insockets[rChannelId]; + if (channel.data == null) { channel.data = data.toString(); } else { channel.data += data.toString(); } + channel.rxWindow += dataLen; + //console.log('IN DATA', channel.rxWindow, channel.data.length, dataLen, channel.amtId, data.toString()); + var httpData = parseHttp(channel.data); + if ((httpData != null) || (channel.data.length >= 8000)) { + // Parse the WSMAN + var notify = null; + try { notify = xmlParser.ParseWsman(httpData); } catch (e) { } + + // Event the http data + if (notify != null) { this.LMS.emit('notify', notify, channel.options, _lmsNotifyToString(notify), _lmsNotifyToCode(notify)); } + + // Send channel close + var buffer = Buffer.alloc(5); + buffer.writeUInt8(APF_CHANNEL_CLOSE, 0); + buffer.writeUInt32BE(amtId, 1); + this.write(buffer); + } else { + if (channel.rxWindow > 6000) { + // Send window adjust + var buffer = Buffer.alloc(9); + buffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0); + buffer.writeUInt32BE(channel.amtId, 1); + buffer.writeUInt32BE(channel.rxWindow, 5); + this.write(buffer); + channel.rxWindow = 0; + } + } + } else { + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA'); + } + break; + case APF_CHANNEL_OPEN_FAILURE: + var rChannelId = chunk.readUInt32BE(1); + var reasonCode = chunk.readUInt32BE(5); + if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) { + this.sockets[rChannelId].end(); + delete this.sockets[rChannelId]; + } else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) { + delete this.insockets[rChannelId]; + } else { + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_OPEN_FAILURE'); + } + break; + case APF_CHANNEL_CLOSE: + var rChannelId = chunk.readUInt32BE(1); + if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) { + this.sockets[rChannelId].end(); + var amtId = this.sockets[rChannelId].lme.amtId; + var buffer = Buffer.alloc(5); + delete this.sockets[rChannelId]; + + buffer.writeUInt8(APF_CHANNEL_CLOSE, 0); // ???????????????????????????? + buffer.writeUInt32BE(amtId, 1); + this.write(buffer); + } else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) { + delete this.insockets[rChannelId]; + // Should I send a close back???? + } else { + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE'); + } + break; + case APF_CHANNEL_OPEN: + var nameLen = chunk.readUInt32BE(1); + var name = chunk.slice(5, nameLen + 5).toString(); + var channelSender = chunk.readUInt32BE(nameLen + 5); + var initialWindowSize = chunk.readUInt32BE(nameLen + 9); + var hostToConnectLen = chunk.readUInt32BE(nameLen + 17); + var hostToConnect = chunk.slice(nameLen + 21, nameLen + 21 + hostToConnectLen).toString(); + var portToConnect = chunk.readUInt32BE(nameLen + 21 + hostToConnectLen); + var originatorIpLen = chunk.readUInt32BE(nameLen + 25 + hostToConnectLen); + var originatorIp = chunk.slice(nameLen + 29 + hostToConnectLen, nameLen + 29 + hostToConnectLen + originatorIpLen).toString(); + var originatorPort = chunk.readUInt32BE(nameLen + 29 + hostToConnectLen + originatorIpLen); + //console.log('APF_CHANNEL_OPEN', name, channelSender, initialWindowSize, 'From: ' + originatorIp + ':' + originatorPort, 'To: ' + hostToConnect + ':' + portToConnect); + + if (this.insockets == null) { this.insockets = {}; } + var ourId = ++lme_id; + var insocket = new lme_object(); + insocket.ourId = ourId; + insocket.amtId = channelSender; + insocket.txWindow = initialWindowSize; + insocket.rxWindow = 0; + insocket.options = { target: hostToConnect, targetPort: portToConnect, source: originatorIp, sourcePort: originatorPort }; + this.insockets[ourId] = insocket; + + var buffer = Buffer.alloc(17); + buffer.writeUInt8(APF_CHANNEL_OPEN_CONFIRMATION, 0); + buffer.writeUInt32BE(channelSender, 1); // Intel AMT sender channel + buffer.writeUInt32BE(ourId, 5); // Our receiver channel id + buffer.writeUInt32BE(4000, 9); // Initial Window Size + buffer.writeUInt32BE(0xFFFFFFFF, 13); // Reserved + this.write(buffer); + + //var buffer = Buffer.alloc(17); + //buffer.writeUInt8(APF_CHANNEL_OPEN_FAILURE, 0); + //buffer.writeUInt32BE(channelSender, 1); // Intel AMT sender channel + //buffer.writeUInt32BE(2, 5); // Reason code + //buffer.writeUInt32BE(0, 9); // Reserved + //buffer.writeUInt32BE(0, 13); // Reserved + //this.write(buffer); + //console.log('Sent APF_CHANNEL_OPEN_FAILURE', channelSender); + + break; + } + }); + this.LMS.emit('connect'); + this.resume(); + + }); + + this.bindDuplexStream = function (duplexStream, remoteFamily, localPort) { + var socket = duplexStream; + //console.log('New [' + remoteFamily + '] Virtual Connection/' + socket.localPort); + socket.pendingBytes = []; + socket.HECI = this._LME; + socket.LMS = this; + socket.lme = new lme_object(); + socket.lme.Socket = socket; + socket.localPort = localPort; + var buffer = new MemoryStream(); + buffer.writeUInt8(0x5A); + buffer.writeUInt32BE(15); + buffer.write('forwarded-tcpip'); + buffer.writeUInt32BE(socket.lme.ourId); + buffer.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE); + buffer.writeUInt32BE(0xFFFFFFFF); + for (var i = 0; i < 2; ++i) { + if (remoteFamily == 'IPv6') { + buffer.writeUInt32BE(3); + buffer.write('::1'); + } else { + buffer.writeUInt32BE(9); + buffer.write('127.0.0.1'); + } + buffer.writeUInt32BE(localPort); + } + this._LME.write(buffer.buffer); + if (this._LME.sockets == undefined) { this._LME.sockets = {}; } + this._LME.sockets[socket.lme.ourId] = socket; + socket.pause(); + }; + + this._LME.connect(heci.GUIDS.LME, { noPipeline: 0 }); +} + +function parseHttp(httpData) { + var i = httpData.indexOf('\r\n\r\n'); + if ((i == -1) || (httpData.length < (i + 2))) { return null; } + var headers = require('http-headers')(httpData.substring(0, i), true); + var contentLength = parseInt(headers['content-length']); + if (httpData.length >= contentLength + i + 4) { return httpData.substring(i + 4, i + 4 + contentLength); } + 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; + try { msgid += '-' + notify.Body.MessageArguments[0]; } catch (e) { } + if (lmsEvents[msgid]) { return lmsEvents[msgid]; } + return null; +} + +var lmsEvents = { + "iAMT0001": "System Defense Policy %1s triggered.", + "iAMT0002": "Agent Presence Agent %1s not started.", + "iAMT0003": "Agent Presence Agent %1s stopped.", + "iAMT0004": "Agent Presence Agent %1s running.", + "iAMT0005": "Agent Presence Agent %1s expired.", + "iAMT0006": "Agent Presence Agent %1s suspended.", + "iAMT0007": "Host software attempt to disable AMT Network link detected.", + "iAMT0008": "Host software attempt to disable AMT Network link detected -- Host Network link blocked.", + "iAMT0009": "AMT clock or FLASH wear-out protection disabled.", + "iAMT0010": "Intel(R) AMT Network Interface %1s heuristics defense slow threshold trespassed.", + "iAMT0011": "Intel(R) AMT Network Interface %1s heuristics defense fast threshold trespassed.", + "iAMT0012": "Intel(R) AMT Network Interface %1s heuristics defense factory defined threshold trespassed.", + "iAMT0013": "Intel(R) AMT Network Interface %1s heuristics defense Encounter timeout expired.", + "iAMT0014": "General certificate error.", + "iAMT0015": "Certificate expired.", + "iAMT0016": "No trusted root certificate.", + "iAMT0017": "Not configured to work with server certificate.", + "iAMT0018": "Certificate revoked.", + "iAMT0019": "RSA exponent too large.", + "iAMT0020": "RSA modulus too large.", + "iAMT0021": "Unsupported digest.", + "iAMT0022": "Distinguished name too long.", + "iAMT0023": "Key usage missing.", + "iAMT0024": "General SSL handshake error.", + "iAMT0025": "General 802.1x error.", + "iAMT0026": "AMT Diagnostic AlertEAC error - General NAC error.", + "iAMT0027": "AMT Diagnostic AlertEAC error - attempt to get a NAC posture while AMT NAC is disabled.", + "iAMT0028": "AMT Diagnostic AlertEAC error - attempt to get a posture of an unsupported type.", + "iAMT0029": "Audit log storage is 50% full.", + "iAMT0030": "Audit log storage is 75% full.", + "iAMT0031": "Audit log storage is 85% full.", + "iAMT0032": "Audit log storage is 95% full.", + "iAMT0033": "Audit log storage is full.", + "iAMT0034": "Firmware Update Event - Partial.", + "iAMT0035": "Firmware Update Event - Failure.", + "iAMT0036": "Remote connectivity initiated.", + "iAMT0037": "ME Presence event.", + "iAMT0038-0": "AMT is being unprovisioned using BIOS command.", + "iAMT0038-1": "AMT is being unprovisioned using Local MEI command.", + "iAMT0038-2": "AMT is being unprovisioned using Local WS-MAN/SOAP command.", + "iAMT0038-3": "AMT is being unprovisioned using Remote WS-MAN/SOAP command.", + "iAMT0039": "HW Asset Error.", + "iAMT0050": "User Notification Alert - General Notification.", + "iAMT0050-16": "User Notification Alert - Circuit Breaker notification (CB Drop TX filter hit.).", + "iAMT0050-17": "User Notification Alert - Circuit Breaker notification (CB Rate Limit TX filter hit.).", + "iAMT0050-18": "User Notification Alert - Circuit Breaker notification (CB Drop RX filter hit.).", + "iAMT0050-19": "User Notification Alert - Circuit Breaker notification (CB Rate Limit RX filter hit.).", + "iAMT0050-32": "User Notification Alert - EAC notification.", + "iAMT0050-48": "User Notification Alert - Remote diagnostics - (Remote Redirection session started - SOL).", + "iAMT0050-49": "User Notification Alert - Remote diagnostics - (Remote Redirection session stopped - SOL).", + "iAMT0050-50": "User Notification Alert - Remote diagnostics. (Remote Redirection session started - IDE-R).", + "iAMT0050-51": "User Notification Alert - Remote diagnostics. (Remote Redirection session stopped - IDE-R).", + "iAMT0050-66": "User Notification Alert - WLAN notification (Host profile mismatch - Management Interface ignored).", + "iAMT0050-67": "User Notification Alert - WLAN notification (Management device overrides host radio).", + "iAMT0050-68": "User Notification Alert - WLAN notification (Host profile security mismatch).", + "iAMT0050-69": "User Notification Alert - WLAN notification (Management device relinquishes control over host Radio).", + "iAMT0051": "User Notification Alert - SecIo event.", + "iAMT0051-0": "User Notification Alert - SecIo event semaphore at host.", + "iAMT0051-1": "User Notification Alert - semaphore at ME.", + "iAMT0051-2": "User Notification Alert - SecIo event - semaphore timeout.", + "iAMT0052": "User Notification Alert - KVM session event.", + "iAMT0052-0": "User Notification Alert - KVM session requested.", + "iAMT0052-1": "User Notification Alert - KVM session started.", + "iAMT0052-2": "User Notification Alert - KVM session stopped.", + "iAMT0052-3": "User Notification Alert - KVM data channel.", + "iAMT0053": "User Notification Alert - RCS notification.", + "iAMT0053-50": "User Notification Alert - RCS notification (HW button pressed. Connection initiated automatically).", + "iAMT0053-52": "User Notification Alert - RCS notification (HW button pressed. Connection wasn't initiated automatically).", + "iAMT0053-53": "User Notification Alert - RCS notification (Contracts updated).", + "iAMT0054": "User Notification Alert - WLAN notification. Wireless Profile sync enablement state changed.", + "iAMT0055": "User Notification Alert - Provisioning state change notification.", + "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.", + "iAMT0056": "User Notification Alert - System Defense change notification.", + "iAMT0057": "User Notification Alert - Network State change notification.", + "iAMT0058": "User Notification Alert - Remote Access change notification.", + "iAMT0058-1": "User Notification Alert - Remote Access change notification - tunnel is closed.", + //"iAMT0058-1": "User Notification Alert - Remote Access change notification - tunnel is open.", // TODO + "iAMT0059": "User Notification Alert - KVM enabled event.", + "iAMT0059-0": "User Notification Alert - KVM enabled event - KVM disabled.", + "iAMT0059-1": "User Notification Alert - KVM enabled event - KVM enabled (both from MEBx and PTNI).", + "iAMT0060": "User Notification Alert - SecIO configuration event.", + "iAMT0061": "ME FW reset occurred.", + "iAMT0062": "User Notification Alert - IpSyncEnabled event.", + "iAMT0062-0": "User Notification Alert - IpSyncEnabled event - IpSync disabled.", + "iAMT0062-1": "User Notification Alert - IpSyncEnabled event - IpSync enabled.", + "iAMT0063": "User Notification Alert - HTTP Proxy sync enabled event.", + "iAMT0063-0": "User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync disabled.", + "iAMT0063-1": "User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync enabled.", + "iAMT0064": "User Notification Alert - User Consent event.", + "iAMT0064-1": "User Notification Alert - User Consent event - User Consent granted.", + "iAMT0064-2": "User Notification Alert - User Consent event - User Consent ended.", + "iAMT0067-0": "Graceful Remote Control Operation - Shutdown.", + "iAMT0067-1": "Graceful Remote Control Operation - Reset.", + "iAMT0067-2": "Graceful Remote Control Operation - Hibernate.", + "iAMT0068-0": "Link Protection Notification - No link protection.", + "iAMT0068-1": "Link Protection Notification - Passive link protection.", + "iAMT0068-2": "Link Protection Notification - High link protection.", + "iAMT0069-0": "Local Time Sync Enablement Notification - Local Time Sync Disabled.", + "iAMT0069-1": "Local Time Sync Enablement Notification - Local Time Sync Enabled.", + "iAMT0070": "Host Reset Triggered by WD Expiration Notification.", + "PLAT0004": "The chassis %1s was opened.", + "PLAT0005": "The chassis %1s was closed.", + "PLAT0006": "The drive bay %1s was opened.", + "PLAT0007": "The drive bay %1s was closed.", + "PLAT0008": "The I/O card area %1s was opened.", + "PLAT0009": "The I/O card area %1s was closed.", + "PLAT0010": "The processor area %1s was opened.", + "PLAT0011": "The processor area %1s was closed.", + "PLAT0012": "The LAN %1s has been disconnected.", + "PLAT0013": "The LAN %1s has been connected.", + "PLAT0016": "The permission to insert package %1s has been granted.", + "PLAT0017": "The permission to insert package %1s has been removed.", + "PLAT0018": "The fan card area %1s is open.", + "PLAT0019": "The fan card area %1s is closed.", + "PLAT0022": "The computer system %1s has detected a secure mode violation.", + "PLAT0024": "The computer system %1s has detected a pre-boot user password violation.", + "PLAT0026": "The computer system %1s has detected a pre-boot setup password violation.", + "PLAT0028": "The computer system %1s has detected a network boot password violation.", + "PLAT0030": "The computer system %1s has detected a password violation.", + "PLAT0032": "The management controller %1s has detected an out-of-band password violation.", + "PLAT0034": "The processor %1s has been added.", + "PLAT0035": "The processor %1s has been removed.", + "PLAT0036": "An over-temperature condition has been detected on the processor %1s.", + "PLAT0037": "An over-temperature condition has been removed on the processor %1s.", + "PLAT0038": "The processor %1s is operating in a degraded State.", + "PLAT0039": "The processor %1s is no longer operating in a degraded State.", + "PLAT0040": "The processor %1s has failed.", + "PLAT0042": "The processor %1s has failed.", + "PLAT0044": "The processor %1s has failed.", + "PLAT0046": "The processor %1s has failed.", + "PLAT0048": "The processor %1s has failed.", + "PLAT0060": "The processor %1s has been enabled.", + "PLAT0061": "The processor %1s has been disabled.", + "PLAT0062": "The processor %1s has a configuration mismatch.", + "PLAT0064": "A terminator has been detected on the processor %1s.", + "PLAT0084": "The Power Supply %1s has been added.", + "PLAT0085": "The Power Supply %1s has been removed.", + "PLAT0086": "The Power Supply %1s has failed.", + "PLAT0088": "Failure predicted on power supply %1s.", + "PLAT0096": "The input to power supply %1s has been lost or fallen out of range.", + "PLAT0098": "The power supply %1s is operating in an input state that is out of range.", + "PLAT0099": "The power supply %1s has returned to a normal input state.", + "PLAT0100": "The power supply %1s has lost input.", + "PLAT0104": "The power supply %1s has a configuration mismatch.", + "PLAT0106": "Power supply %1s has been disabled.", + "PLAT0107": "Power supply %1s has been enabled.", + "PLAT0108": "Power supply %1s has been power cycled.", + "PLAT0110": "Power supply %1s has encountered an error during power down.", + "PLAT0112": "Power supply %1s has lost power.", + "PLAT0114": "Soft power control has failed for power supply %1s.", + "PLAT0116": "Power supply %1s has failed.", + "PLAT0118": "Failure predicted on power supply %1s.", + "PLAT0120": "Memory subsystem failure.", + "PLAT0122": "DIMM missing.", + "PLAT0124": "Memory error detected & corrected for DIMM %1s.", + "PLAT0128": "Memory DIMM %1s added.", + "PLAT0129": "Memory DIMM %1s removed.", + "PLAT0130": "Memory DIMM %1s enabled.", + "PLAT0131": "Memory DIMM %1s disabled.", + "PLAT0134": "Memory parity error for DIMM %1s.", + "PLAT0136": "Memory scrub failure for DIMM %1s.", + "PLAT0138": "Memory uncorrectable error detected for DIMM %1s.", + "PLAT0140": "Memory sparing initiated for DIMM %1s.", + "PLAT0141": "Memory sparing concluded for DIMM %1s.", + "PLAT0142": "Memory DIMM %1s Throttled.", + "PLAT0144": "Memory logging limit reached for DIMM %1s.", + "PLAT0145": "Memory logging limit removed for DIMM %1s.", + "PLAT0146": "An over-temperature condition has been detected on the Memory DIMM %1s.", + "PLAT0147": "An over-temperature condition has been removed on the Memory DIMM %1s.", + "PLAT0162": "The drive %1s has been added.", + "PLAT0163": "The drive %1s has been removed.", + "PLAT0164": "The drive %1s has been disabled due to a detected fault.", + "PLAT0167": "The drive %1s has been enabled.", + "PLAT0168": "Failure predicted on drive %1s.", + "PLAT0170": "Hot spare enabled for %1s.", + "PLAT0171": "Hot spare disabled for %1s.", + "PLAT0172": "Consistency check has begun for %1s.", + "PLAT0173": "Consistency check completed for %1s.", + "PLAT0174": "Array %1s is in critical condition.", + "PLAT0176": "Array %1s has failed.", + "PLAT0177": "Array %1s has been restored.", + "PLAT0178": "Rebuild in progress for array %1s.", + "PLAT0179": "Rebuild completed for array %1s.", + "PLAT0180": "Rebuild Aborted for array %1s.", + "PLAT0184": "The system %1s encountered a POST error.", + "PLAT0186": "The system %1s encountered a firmware hang.", + "PLAT0188": "The system %1s encountered firmware progress.", + "PLAT0192": "The log %1s has been disabled.", + "PLAT0193": "The log %1s has been enabled.", + "PLAT0194": "The log %1s has been disabled.", + "PLAT0195": "The log %1s has been enabled.", + "PLAT0196": "The log %1s has been disabled.", + "PLAT0198": "The log %1s has been enabled.", + "PLAT0200": "The log %1s has been cleared.", + "PLAT0202": "The log %1s is full.", + "PLAT0203": "The log %1s is no longer full.", + "PLAT0204": "The log %1s is almost full.", + "PLAT0208": "The log %1s has a configuration error.", + "PLAT0210": "The system %1s has been reconfigured.", + "PLAT0212": "The system %1s has encountered an OEM system boot event.", + "PLAT0214": "The system %1s has encountered an unknown system hardware fault.", + "PLAT0216": "The system %1s has generated an auxiliary log entry.", + "PLAT0218": "The system %1s has executed a PEF action.", + "PLAT0220": "The system %1s has synchronized the system clock.", + "PLAT0222": "A diagnostic interrupt has occurred on system %1s.", + "PLAT0224": "A bus timeout has occurred on system %1s.", + "PLAT0226": "An I/O channel check NMI has occurred on system %1s.", + "PLAT0228": "A software NMI has occurred on system %1s.", + "PLAT0230": "System %1s has recovered from an NMI.", + "PLAT0232": "A PCI PERR has occurred on system %1s.", + "PLAT0234": "A PCI SERR has occurred on system %1s.", + "PLAT0236": "An EISA fail safe timeout occurred on system %1s.", + "PLAT0238": "A correctable bus error has occurred on system %1s.", + "PLAT0240": "An uncorrectable bus error has occurred on system %1s.", + "PLAT0242": "A fatal NMI error has occurred on system %1s.", + "PLAT0244": "A fatal bus error has occurred on system %1s.", + "PLAT0246": "A bus on system %1s is operating in a degraded state.", + "PLAT0247": "A bus on system %1s is no longer operating in a degraded state.", + "PLAT0248": "The power button %1s has been pressed.", + "PLAT0249": "The power button %1s has been released.", + "PLAT0250": "The sleep button %1s has been pressed.", + "PLAT0251": "The sleep button %1s has been released.", + "PLAT0252": "The reset button %1s has been pressed.", + "PLAT0253": "The reset button %1s has been released.", + "PLAT0254": "The latch to %1s has been opened.", + "PLAT0255": "The latch to %1s has been closed.", + "PLAT0256": "The service request %1s has been enabled.", + "PLAT0257": "The service request %1s has been completed.", + "PLAT0258": "Power control of system %1s has failed.", + "PLAT0262": "The network port %1s has been connected.", + "PLAT0263": "The network port %1s has been disconnected.", + "PLAT0266": "The connector %1s has encountered a configuration error.", + "PLAT0267": "The connector %1s configuration error has been repaired.", + "PLAT0272": "Power on for system %1s.", + "PLAT0274": "Power cycle hard requested for system %1s.", + "PLAT0276": "Power cycle soft requested for system %1s.", + "PLAT0278": "PXE boot requested for system %1s.", + "PLAT0280": "Diagnostics boot requested for system %1s.", + "PLAT0282": "System restart requested for system %1s.", + "PLAT0284": "System restart begun for system %1s.", + "PLAT0286": "No bootable media available for system %1s.", + "PLAT0288": "Non-bootable media selected for system %1s.", + "PLAT0290": "PXE server not found for system %1s.", + "PLAT0292": "User timeout on boot for system %1s.", + "PLAT0296": "System %1s boot from floppy initiated.", + "PLAT0298": "System %1s boot from local drive initiated.", + "PLAT0300": "System %1s boot from PXE on network port initiated.", + "PLAT0302": "System %1s boot diagnostics initiated.", + "PLAT0304": "System %1s boot from CD initiated.", + "PLAT0306": "System %1s boot from ROM initiated.", + "PLAT0312": "System %1s boot initiated.", + "PLAT0320": "Critical stop during OS load on system %1s.", + "PLAT0322": "Run-time critical stop on system %1s.", + "PLAT0324": "OS graceful stop on system %1s.", + "PLAT0326": "OS graceful shutdown begun on system %1s.", + "PLAT0327": "OS graceful shutdown completed on system %1s.", + "PLAT0328": "Agent not responding on system %1s.", + "PLAT0329": "Agent has begun responding on system %1s.", + "PLAT0330": "Fault in slot on system %1s.", + "PLAT0331": "Fault condition removed on system %1s.", + "PLAT0332": "Identifying slot on system %1s.", + "PLAT0333": "Identify stopped on slot for system %1s.", + "PLAT0334": "Package installed in slot for system %1s.", + "PLAT0336": "Slot empty system %1s.", + "PLAT0338": "Slot in system %1s is ready for installation.", + "PLAT0340": "Slot in system %1s is ready for removal.", + "PLAT0342": "Power is off on slot of system %1s.", + "PLAT0344": "Power is on for slot of system %1s.", + "PLAT0346": "Removal requested for slot of system %1s.", + "PLAT0348": "Interlock activated on slot of system %1s.", + "PLAT0349": "Interlock de-asserted on slot of system %1s.", + "PLAT0350": "Slot disabled on system %1s.", + "PLAT0351": "Slot enabled on system %1s.", + "PLAT0352": "Slot of system %1s holds spare.", + "PLAT0353": "Slot of system %1s no longer holds spare.", + "PLAT0354": "Computer system %1s enabled.", + "PLAT0356": "Computer system %1s is in sleep - light mode.", + "PLAT0358": "Computer system %1s is in hibernate.", + "PLAT0360": "Computer system %1s is in standby.", + "PLAT0362": "Computer system %1s is in soft off mode.", + "PLAT0364": "Computer system %1s is in hard off mode.", + "PLAT0366": "Computer system %1s is sleeping.", + "PLAT0368": "Watchdog timer expired for %1s.", + "PLAT0370": "Reboot of system initiated by watchdog %1s.", + "PLAT0372": "Powering off system initiated by watchdog %1s.", + "PLAT0374": "Power cycle of system initiated by watchdog %1s.", + "PLAT0376": "Watchdog timer interrupt occurred for %1s.", + "PLAT0378": "A page alert has been generated for system %1s.", + "PLAT0380": "A LAN alert has been generated for system %1s.", + "PLAT0382": "An event trap has been generated for system %1s.", + "PLAT0384": "An SNMP trap has been generated for system %1s.", + "PLAT0390": "%1s detected as present.", + "PLAT0392": "%1s detected as absent.", + "PLAT0394": "%1s has been disabled.", + "PLAT0395": "%1s has been enabled.", + "PLAT0396": "Heartbeat lost for LAN %1s.", + "PLAT0397": "Heartbeat detected for LAN %1s.", + "PLAT0398": "Sensor %1s is unavailable or degraded on management system.", + "PLAT0399": "Sensor %1s has returned to normal on management system.", + "PLAT0400": "Controller %1s is unavailable or degraded on management system.", + "PLAT0401": "Controller %1s has returned to normal on management system.", + "PLAT0402": "Management system %1s is off-line.", + "PLAT0404": "Management system %1s is disabled.", + "PLAT0405": "Management system %1s is enabled.", + "PLAT0406": "Sensor %1s has failed on management system.", + "PLAT0408": "FRU %1s has failed on management system.", + "PLAT0424": "The battery %1s is critically low.", + "PLAT0427": "The battery %1s is no longer critically low.", + "PLAT0430": "The battery %1s has been removed from unit.", + "PLAT0431": "The battery %1s has been added.", + "PLAT0432": "The battery %1s has failed.", + "PLAT0434": "Session audit is deactivated on system %1s.", + "PLAT0435": "Session audit is activated on system %1s.", + "PLAT0436": "A hardware change occurred on system %1s.", + "PLAT0438": "A firmware or software change occurred on system %1s.", + "PLAT0440": "A hardware incompatibility was detected on system %1s.", + "PLAT0442": "A firmware or software incompatibility was detected on system %1s.", + "PLAT0444": "Invalid or unsupported hardware was detected on system %1s.", + "PLAT0446": "Invalid or unsupported firmware or software was detected on system %1s.", + "PLAT0448": "A successful hardware change was detected on system %1s.", + "PLAT0450": "A successful software or firmware change was detected on system %1s.", + "PLAT0464": "FRU %1s not installed on system.", + "PLAT0465": "FRU %1s installed on system.", + "PLAT0466": "Activation requested for FRU %1s on system.", + "PLAT0467": "FRU %1s on system is active.", + "PLAT0468": "Activation in progress for FRU %1s on system.", + "PLAT0470": "Deactivation request for FRU %1s on system.", + "PLAT0471": "FRU %1s on system is in standby or \"hot spare\" state.", + "PLAT0472": "Deactivation in progress for FRU %1s on system.", + "PLAT0474": "Communication lost with FRU %1s on system.", + "PLAT0476": "Numeric sensor %1s going low (lower non-critical).", + "PLAT0478": "Numeric sensor %1s going high (lower non-critical).", + "PLAT0480": "Numeric sensor %1s going low (lower critical).", + "PLAT0482": "Numeric sensor %1s going high (lower critical).", + "PLAT0484": "Numeric sensor %1s going low (lower non-recoverable).", + "PLAT0486": "Numeric sensor %1s going high (lower non-critical).", + "PLAT0488": "Numeric sensor %1s going low (upper non-critical).", + "PLAT0490": "Numeric sensor %1s going high (upper non-critical).", + "PLAT0492": "Numeric sensor %1s going low (upper critical).", + "PLAT0494": "Numeric sensor %1s going high (upper critical).", + "PLAT0496": "Numeric sensor %1s going low (upper non-recoverable).", + "PLAT0498": "Numeric sensor %1s going high (upper non-recoverable).", + "PLAT0500": "Sensor %1s has transitioned to idle.", + "PLAT0502": "Sensor %1s has transitioned to active.", + "PLAT0504": "Sensor %1s has transitioned to busy.", + "PLAT0508": "Sensor %1s has asserted.", + "PLAT0509": "Sensor %1s has de-asserted.", + "PLAT0510": "Sensor %1s is asserting predictive failure.", + "PLAT0511": "Sensor %1s is de-asserting predictive failure.", + "PLAT0512": "Sensor %1s has indicated limit exceeded.", + "PLAT0513": "Sensor %1s has indicated limit no longer exceeded.", + "PLAT0514": "Sensor %1s has indicated performance met.", + "PLAT0516": "Sensor %1s has indicated performance lags.", + "PLAT0518": "Sensor %1s has transitioned to normal state.", + "PLAT0520": "Sensor %1s has transitioned from normal to non-critical state.", + "PLAT0522": "Sensor %1s has transitioned to critical from a less severe state.", + "PLAT0524": "Sensor %1s has transitioned to non-recoverable from a less severe state.", + "PLAT0526": "Sensor %1s has transitioned to non-critical from a more severe state.", + "PLAT0528": "Sensor %1s has transitioned to critical from a non-recoverable state.", + "PLAT0530": "Sensor %1s has transitioned to non-recoverable.", + "PLAT0532": "Sensor %1s indicates a monitor state.", + "PLAT0534": "Sensor %1s has an informational state.", + "PLAT0536": "Device %1s has been added.", + "PLAT0537": "Device %1s has been removed from unit.", + "PLAT0538": "Device %1s has been enabled.", + "PLAT0539": "Device %1s has been disabled.", + "PLAT0540": "Sensor %1s has indicated a running state.", + "PLAT0544": "Sensor %1s has indicated a power off state.", + "PLAT0546": "Sensor %1s has indicated an on-line state.", + "PLAT0548": "Sensor %1s has indicated an off-line state.", + "PLAT0550": "Sensor %1s has indicated an off-duty state.", + "PLAT0552": "Sensor %1s has indicated a degraded state.", + "PLAT0554": "Sensor %1s has indicated a power save state.", + "PLAT0556": "Sensor %1s has indicated an install error.", + "PLAT0558": "Redundancy %1s has been lost.", + "PLAT0560": "Redundancy %1s has been reduced.", + "PLAT0561": "Redundancy %1s has been restored.", + "PLAT0562": "%1s has transitioned to a D0 power state.", + "PLAT0564": "%1s has transitioned to a D1 power state.", + "PLAT0566": "%1s has transitioned to a D2 power state.", + "PLAT0568": "%1s has transitioned to a D3 power state.", + "PLAT0720": "The System %1s encountered firmware progress - memory initialization entry.", + "PLAT0721": "The System %1s encountered firmware progress - memory initialization exit.", + "PLAT0722": "The System %1s encountered firmware progress - hard drive initialization entry.", + "PLAT0723": "The System %1s encountered firmware progress - hard drive initialization exit.", + "PLAT0724": "The System %1s encountered firmware progress - user authentication.", + "PLAT0728": "The System %1s encountered firmware progress - USR resource configuration entry.", + "PLAT0729": "The System %1s encountered firmware progress - USR resource configuration exit.", + "PLAT0730": "The System %1s encountered firmware progress - PCI recource configuration entry.", + "PLAT0731": "The System %1s encountered firmware progress - PCI recource configuration exit.", + "PLAT0732": "The System %1s encountered firmware progress - Option ROM initialization entry.", + "PLAT0733": "The System %1s encountered firmware progress - Option ROM initialization entry exit.", + "PLAT0734": "The System %1s encountered firmware progress -video initialization entry entry.", + "PLAT0735": "The System %1s encountered firmware progress - video initialization entry exit.", + "PLAT0736": "The System %1s encountered firmware progress - cache initialization entry.", + "PLAT0737": "The System %1s encountered firmware progress - cache initialization exit.", + "PLAT0738": "The System %1s encountered firmware progress - keyboard controller initialization entry.", + "PLAT0739": "The System %1s encountered firmware progress - keyboard controller initialization exit.", + "PLAT0740": "The System %1s encountered firmware progress - motherboard initialization entry.", + "PLAT0741": "The System %1s encountered firmware progress - motherboard initialization exit.", + "PLAT0742": "The System %1s encountered firmware progress - floppy disk initialization entry.", + "PLAT0743": "The System %1s encountered firmware progress - floppy disk initialization exit.", + "PLAT0744": "The System %1s encountered firmware progress - keyboard test entry.", + "PLAT0745": "The System %1s encountered firmware progress - keyboard test exit.", + "PLAT0746": "The System %1s encountered firmware progress - pointing device test entry.", + "PLAT0747": "The System %1s encountered firmware progress - pointing device test exit.", + "PLAT0750": "The System %1s encountered firmware progress - dock enable entry.", + "PLAT0751": "The System %1s encountered firmware progress - dock enable exit.", + "PLAT0752": "The System %1s encountered firmware progress - dock disable entry.", + "PLAT0753": "The System %1s encountered firmware progress - dock disable exit.", + "PLAT0760": "The System %1s encountered firmware progress - start OS boot process.", + "PLAT0762": "The System %1s encountered firmware progress - call OS wake vector.", + "PLAT0764": "The System %1s encountered firmware progress - unrecoverable keyboard failure.", + "PLAT0766": "The System %1s encountered firmware progress - no video device detected.", + "PLAT0768": "The System %1s encountered firmware progress - SMART alert detected on drive.", + "PLAT0770": "The System %1s encountered firmware progress - unrecoverable boot device failure.", + "PLAT0789": "Corrupt BIOS detected.", + "PLAT0790": "The System %1s encountered PCI configuration failure.", + "PLAT0791": "The System %1s encountered a video subsystem failure.", + "PLAT0792": "The System %1s encountered a storage subsystem failure.", + "PLAT0793": "The System %1s encountered a USB subsystem failure.", + "PLAT0794": "The System %1s has detected no memory in the system.", + "PLAT0795": "The System %1s encountered a motherboard failure.", + "PLAT0796": "The System %1s encountered a memory Regulator Voltage Bad.", + "PLAT0797": "%1s PCI reset is not deasserting.", + "PLAT0798": "%1s Non-Motherboard Regulator Failure.", + "PLAT0799": "%1s Power Supply Cable failure.", + "PLAT0800": "%1s Motherboard regulator failure.", + "PLAT0801": "%1s System component compatibility mismatch." +} + +module.exports = lme_heci; diff --git a/agents/modules_meshcore_backup/amt-mei.js b/agents/modules_meshcore_backup/amt-mei.js new file mode 100644 index 00000000..a6f0b17b --- /dev/null +++ b/agents/modules_meshcore_backup/amt-mei.js @@ -0,0 +1,387 @@ +/* +Copyright 2018 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. +*/ + +var Q = require('queue'); +function amt_heci() { + var emitterUtils = require('events').inherits(this); + emitterUtils.createEvent('error'); + + var heci = require('heci'); + + this._ObjectID = "pthi"; + this._rq = new Q(); + 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) + { + //console.log("Received: " + chunk.length + " bytes"); + var header = this.Parent.getCommand(chunk); + //console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse); + + var user = this.Parent._rq.deQueue(); + var params = user.optional; + var callback = user.func; + + params.unshift(header); + callback.apply(this.Parent, params); + + if(this.Parent._rq.isEmpty()) + { + // No More Requests, we can close PTHI + this.Parent._amt.disconnect(); + this.Parent._amt = null; + } + else + { + // Send the next request + this.write(this.Parent._rq.peekQueue().send); + } + }); + + // Start sending requests + this.write(this.Parent._rq.peekQueue().send); + }); + }; + function trim(x) { var y = x.indexOf('\0'); if (y >= 0) { return x.substring(0, y); } else { return x; } } + this.getCommand = function getCommand(chunk) { + var command = chunk.length == 0 ? (this._rq.peekQueue().cmd | 0x800000) : chunk.readUInt32LE(4); + var ret = { IsResponse: (command & 0x800000) == 0x800000 ? true : false, Command: (command & 0x7FFFFF), Status: chunk.length != 0 ? chunk.readUInt32LE(12) : -1, Data: chunk.length != 0 ? chunk.slice(16) : null }; + return (ret); + }; + + this.sendCommand = function sendCommand() { + if (arguments.length < 3 || typeof (arguments[0]) != 'number' || typeof (arguments[1]) != 'object' || typeof (arguments[2]) != 'function') { throw ('invalid parameters'); } + var args = []; + for (var i = 3; i < arguments.length; ++i) { args.push(arguments[i]); } + + 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]]))}); + + if(!this._amt) + { + this._setupPTHI(); + this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 }); + } + } + + this.getVersion = function getVersion(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } + 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).toString(), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4); + 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)); + } + if (val.BiosVersion.indexOf('\0') > 0) { val.BiosVersion = val.BiosVersion.substring(0, val.BiosVersion.indexOf('\0')); } + opt.unshift(val); + } else { + opt.unshift(null); + } + fn.apply(this, opt); + }, callback, optional); + }; + + // Fill the left with zeros until the string is of a given length + function zeroLeftPad(str, len) { + if ((len == null) && (typeof (len) != 'number')) { return null; } + if (str == null) str = ''; // If null, this is to generate zero leftpad string + var zlp = ''; + for (var i = 0; i < len - str.length; i++) { zlp += '0'; } + return zlp + str; + } + + this.getUuid = function getUuid(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(0x5c, null, function (header, fn, opt) { + if (header.Status == 0) { + var result = {}; + result.uuid = [zeroLeftPad(header.Data.readUInt32LE(0).toString(16), 8), + zeroLeftPad(header.Data.readUInt16LE(4).toString(16), 4), + zeroLeftPad(header.Data.readUInt16LE(6).toString(16), 4), + zeroLeftPad(header.Data.readUInt16BE(8).toString(16), 4), + zeroLeftPad(header.Data.slice(10).toString('hex').toLowerCase(), 12)].join('-'); + opt.unshift(result); + } else { + opt.unshift(null); + } + fn.apply(this, opt); + }, callback, optional); + }; + + this.getProvisioningState = function getProvisioningState(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(17, null, function (header, fn, opt) { + if (header.Status == 0) { + var result = {}; + result.state = header.Data.readUInt32LE(0); + if (result.state < 3) { result.stateStr = ["PRE", "IN", "POST"][result.state]; } + opt.unshift(result); + } else { + opt.unshift(null); + } + fn.apply(this, opt); + }, callback, optional); + }; + this.getProvisioningMode = function getProvisioningMode(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(8, null, function (header, fn, opt) { + if (header.Status == 0) { + var result = {}; + result.mode = header.Data.readUInt32LE(0); + if (result.mode < 4) { result.modeStr = ["NONE", "ENTERPRISE", "SMALL_BUSINESS", "REMOTE_ASSISTANCE"][result.mode]; } + result.legacy = header.Data.readUInt32LE(4) == 0 ? false : true; + opt.unshift(result); + } else { + opt.unshift(null); + } + fn.apply(this, opt); + }, callback, optional); + }; + this.getEHBCState = function getEHBCState(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(132, null, function (header, fn, opt) { + if (header.Status == 0) { + opt.unshift({ EHBC: header.Data.readUInt32LE(0) != 0 }); + } else { + opt.unshift(null); + } + fn.apply(this, opt); + }, callback, optional); + }; + this.getControlMode = function getControlMode(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(107, null, function (header, fn, opt) { + if (header.Status == 0) { + var result = {}; + result.controlMode = header.Data.readUInt32LE(0); + if (result.controlMode < 3) { result.controlModeStr = ["NONE_RPAT", "CLIENT", "ADMIN", "REMOTE_ASSISTANCE"][result.controlMode]; } + opt.unshift(result); + } else { + opt.unshift(null); + } + fn.apply(this, opt); + }, callback, optional); + }; + this.getMACAddresses = function getMACAddresses(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(37, null, function (header, fn, opt) { + if (header.Status == 0) { + opt.unshift({ DedicatedMAC: header.Data.slice(0, 6).toString('hex:'), HostMAC: header.Data.slice(6, 12).toString('hex:') }); + } else { opt.unshift({ DedicatedMAC: null, HostMAC: null }); } + fn.apply(this, opt); + }, callback, optional); + }; + this.getDnsSuffix = function getDnsSuffix(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(54, null, function (header, fn, opt) { + if (header.Status == 0) { + var resultLen = header.Data.readUInt16LE(0); + if (resultLen > 0) { opt.unshift(header.Data.slice(2, 2 + resultLen).toString()); } else { opt.unshift(null); } + } else { + opt.unshift(null); + } + fn.apply(this, opt); + }, callback, optional); + }; + this.getHashHandles = function getHashHandles(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(0x2C, null, function (header, fn, opt) { + var result = []; + if (header.Status == 0) { + var resultLen = header.Data.readUInt32LE(0); + for (var i = 0; i < resultLen; ++i) { + result.push(header.Data.readUInt32LE(4 + (4 * i))); + } + } + opt.unshift(result); + fn.apply(this, opt); + }, callback, optional); + }; + this.getCertHashEntry = function getCertHashEntry(handle, callback) { + var optional = []; + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); } + + var data = new Buffer(4); + data.writeUInt32LE(handle, 0); + + this.sendCommand(0x2D, data, function (header, fn, opt) { + if (header.Status == 0) { + var result = {}; + result.isDefault = header.Data.readUInt32LE(0); + result.isActive = header.Data.readUInt32LE(4); + result.hashAlgorithm = header.Data.readUInt8(72); + if (result.hashAlgorithm < 4) { + result.hashAlgorithmStr = ["MD5", "SHA1", "SHA256", "SHA512"][result.hashAlgorithm]; + result.hashAlgorithmSize = [16, 20, 32, 64][result.hashAlgorithm]; + result.certificateHash = header.Data.slice(8, 8 + result.hashAlgorithmSize).toString('hex'); + } + result.name = header.Data.slice(73 + 2, 73 + 2 + header.Data.readUInt16LE(73)).toString(); + opt.unshift(result); + } else { + opt.unshift(null); + } + fn.apply(this, opt); + }, callback, optional); + }; + this.getCertHashEntries = function getCertHashEntries(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } + + this.getHashHandles(function (handles, fn, opt) { + var entries = []; + this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles); + }, callback, optional); + }; + + this._getHashEntrySink = function _getHashEntrySink(result, fn, opt, entries, handles) { + entries.push(result); + if (handles.length > 0) { + this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles); + } else { + opt.unshift(entries); + fn.apply(this, opt); + } + } + this.getLocalSystemAccount = function getLocalSystemAccount(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt) { + if (header.Data.length == 68) { opt.unshift({ user: trim(header.Data.slice(0, 33).toString()), pass: trim(header.Data.slice(33, 67).toString()), raw: header.Data }); } else { opt.unshift(null); } + fn.apply(this, opt); + }, callback, optional); + } + this.getLanInterfaceSettings = function getLanInterfaceSettings(index, callback) + { + var optional = []; + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); } + var ifx = Buffer.alloc(4); + ifx.writeUInt32LE(index); + this.sendCommand(0x48, ifx, function onGetLanInterfaceSettings(header, fn, opt) + { + if(header.Status == 0) + { + var info = {}; + info.enabled = header.Data.readUInt32LE(0); + info.dhcpEnabled = header.Data.readUInt32LE(8); + switch(header.Data[12]) + { + case 1: + info.dhcpMode = 'ACTIVE' + break; + case 2: + info.dhcpMode = 'PASSIVE' + break; + default: + info.dhcpMode = 'UNKNOWN'; + break; + } + info.mac = header.Data.slice(14).toString('hex:'); + + var addr = header.Data.readUInt32LE(4); + info.address = ((addr >> 24) & 255) + '.' + ((addr >> 16) & 255) + '.' + ((addr >> 8) & 255) + '.' + (addr & 255); + opt.unshift(info); + fn.apply(this, opt); + } + else + { + opt.unshift(null); + fn.apply(this, opt); + } + }, callback, optional); + + }; + this.unprovision = function unprovision(mode, callback) { + var optional = []; + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); } + var data = new Buffer(4); + data.writeUInt32LE(mode, 0); + this.sendCommand(16, data, function (header, fn, opt) { + opt.unshift(header.Status); + fn.apply(this, opt); + }, callback, optional); + } + this.startConfiguration = function startConfiguration() { + var optional = []; + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(0x29, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional); + } + this.stopConfiguration = function stopConfiguration() { + var optional = []; + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(0x5E, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional); + } + this.openUserInitiatedConnection = function openUserInitiatedConnection() { + var optional = []; + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(0x44, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional); + } + this.closeUserInitiatedConnection = function closeUnserInitiatedConnected() { + var optional = []; + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(0x45, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional); + } + this.getRemoteAccessConnectionStatus = function getRemoteAccessConnectionStatus() { + var optional = []; + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); } + this.sendCommand(0x46, data, function (header, fn, opt) { + if (header.Status == 0) { + var hostname = v.slice(14, header.Data.readUInt16LE(12) + 14).toString() + opt.unshift({ status: header.Status, networkStatus: header.Data.readUInt32LE(0), remoteAccessStatus: header.Data.readUInt32LE(4), remoteAccessTrigger: header.Data.readUInt32LE(8), mpsHostname: hostname, raw: header.Data }); + } else { + opt.unshift({ status: header.Status }); + } + fn.apply(this, opt); + }, callback, optional); + } + this.getProtocolVersion = function getProtocolVersion(callback) { + var optional = []; + for (var i = 1; i < arguments.length; ++i) { opt.push(arguments[i]); } + + heci.doIoctl(heci.IOCTL.HECI_VERSION, Buffer.alloc(5), Buffer.alloc(5), function (status, buffer, self, fn, opt) { + if (status == 0) { + var result = buffer.readUInt8(0).toString() + '.' + buffer.readUInt8(1).toString() + '.' + buffer.readUInt8(2).toString() + '.' + buffer.readUInt16BE(3).toString(); + opt.unshift(result); + fn.apply(self, opt); + } + else { + opt.unshift(null); + fn.apply(self, opt); + } + }, this, callback, optional); + } +} + +module.exports = amt_heci; \ No newline at end of file diff --git a/agents/modules_meshcore_backup/amt-scanner.js b/agents/modules_meshcore_backup/amt-scanner.js new file mode 100644 index 00000000..d82b6d8c --- /dev/null +++ b/agents/modules_meshcore_backup/amt-scanner.js @@ -0,0 +1,105 @@ +/* +Copyright 2018 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 Meshcentral Intel AMT Local Scanner +* @author Ylian Saint-Hilaire & Joko Sastriawan +* @version v0.0.1 +*/ + +// Construct a Intel AMT Scanner object + +function AMTScanner() { + var emitterUtils = require('events').inherits(this); + emitterUtils.createEvent('found'); + + this.dgram = require('dgram'); + + this.buildRmcpPing = function (tag) { + var packet = Buffer.from('06000006000011BE80000000', 'hex'); + packet[9] = tag; + return packet; + }; + + this.parseRmcpPacket = function (server, data, rinfo, func) { + if (data == null || data.length < 20) return; + var res = {}; + if (((data[12] == 0) || (data[13] != 0) || (data[14] != 1) || (data[15] != 0x57)) && (data[21] & 32)) { + res.servertag = data[9]; + res.minorVersion = data[18] & 0x0F; + res.majorVersion = (data[18] >> 4) & 0x0F; + res.provisioningState = data[19] & 0x03; // Pre = 0, In = 1, Post = 2 + + var openPort = (data[16] * 256) + data[17]; + var dualPorts = ((data[19] & 0x04) != 0) ? true : false; + res.openPorts = [openPort]; + res.address = rinfo.address; + if (dualPorts == true) { res.openPorts = [16992, 16993]; } + if (func !== undefined) { + func(server, res); + } + } + } + + this.parseIPv4Range = function (range) { + if (range == undefined || range == null) return null; + var x = range.split('-'); + if (x.length == 2) { return { min: this.parseIpv4Addr(x[0]), max: this.parseIpv4Addr(x[1]) }; } + x = range.split('/'); + if (x.length == 2) { + var ip = this.parseIpv4Addr(x[0]), masknum = parseInt(x[1]), mask = 0; + if (masknum <= 16 || masknum > 32) return null; + masknum = 32 - masknum; + for (var i = 0; i < masknum; i++) { mask = (mask << 1); mask++; } + return { min: ip & (0xFFFFFFFF - mask), max: (ip & (0xFFFFFFFF - mask)) + mask }; + } + x = this.parseIpv4Addr(range); + if (x == null) return null; + return { min: x, max: x }; + }; + + // Parse IP address. Takes a + this.parseIpv4Addr = function (addr) { + var x = addr.split('.'); + if (x.length == 4) { return (parseInt(x[0]) << 24) + (parseInt(x[1]) << 16) + (parseInt(x[2]) << 8) + (parseInt(x[3]) << 0); } + return null; + } + + // IP address number to string + this.IPv4NumToStr = function (num) { + return ((num >> 24) & 0xFF) + '.' + ((num >> 16) & 0xFF) + '.' + ((num >> 8) & 0xFF) + '.' + (num & 0xFF); + } + + this.scan = function (rangestr, timeout) { + var iprange = this.parseIPv4Range(rangestr); + var rmcp = this.buildRmcpPing(0); + var server = this.dgram.createSocket({ type: 'udp4' }); + server.parent = this; + server.scanResults = []; + server.on('error', function (err) { console.log('Error:' + err); }); + server.on('message', function (msg, rinfo) { if (rinfo.size > 4) { this.parent.parseRmcpPacket(this, msg, rinfo, function (s, res) { s.scanResults.push(res); }) }; }); + server.on('listening', function () { for (var i = iprange.min; i <= iprange.max; i++) { server.send(rmcp, 623, server.parent.IPv4NumToStr(i)); } }); + server.bind({ address: '0.0.0.0', port: 0, exclusive: true }); + var tmout = setTimeout(function cb() { + //console.log("Server closed"); + server.close(); + server.parent.emit('found', server.scanResults); + delete server; + }, timeout); + }; +} + +module.exports = AMTScanner; diff --git a/agents/modules_meshcore_backup/amt-wsman-duk.js b/agents/modules_meshcore_backup/amt-wsman-duk.js new file mode 100644 index 00000000..7df52f1c --- /dev/null +++ b/agents/modules_meshcore_backup/amt-wsman-duk.js @@ -0,0 +1,148 @@ +/* +Copyright 2018 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 WSMAN communication using duktape http +* @author Ylian Saint-Hilaire +* @version v0.2.0c +*/ + +// Construct a WSMAN communication object +function CreateWsmanComm(/*host, port, user, pass, tls, extra*/) +{ + var obj = {}; + obj.PendingAjax = []; // List of pending AJAX calls. When one frees up, another will start. + obj.ActiveAjaxCount = 0; // Number of currently active AJAX calls + obj.MaxActiveAjaxCount = 1; // Maximum number of activate AJAX calls at the same time. + obj.FailAllError = 0; // Set this to non-zero to fail all AJAX calls with that error status, 999 causes responses to be silent. + obj.digest = null; + obj.RequestCount = 0; + obj.requests = {}; + + if (arguments.length == 1 && typeof(arguments[0] == 'object')) + { + obj.host = arguments[0].host; + obj.port = arguments[0].port; + obj.authToken = arguments[0].authToken; + obj.tls = arguments[0].tls; + } + else + { + obj.host = arguments[0]; + obj.port = arguments[1]; + obj.user = arguments[2]; + obj.pass = arguments[3]; + obj.tls = arguments[4]; + } + + + // Private method + // pri = priority, if set to 1, the call is high priority and put on top of the stack. + obj.PerformAjax = function (postdata, callback, tag, pri, url, action) { + if ((obj.ActiveAjaxCount == 0 || ((obj.ActiveAjaxCount < obj.MaxActiveAjaxCount) && (obj.challengeParams != null))) && obj.PendingAjax.length == 0) { + // There are no pending AJAX calls, perform the call now. + obj.PerformAjaxEx(postdata, callback, tag, url, action); + } else { + // If this is a high priority call, put this call in front of the array, otherwise put it in the back. + if (pri == 1) { obj.PendingAjax.unshift([postdata, callback, tag, url, action]); } else { obj.PendingAjax.push([postdata, callback, tag, url, action]); } + } + } + + // Private method + obj.PerformNextAjax = function () { + if (obj.ActiveAjaxCount >= obj.MaxActiveAjaxCount || obj.PendingAjax.length == 0) return; + var x = obj.PendingAjax.shift(); + obj.PerformAjaxEx(x[0], x[1], x[2], x[3], x[4]); + obj.PerformNextAjax(); + } + + // Private method + obj.PerformAjaxEx = function (postdata, callback, tag, url, action) { + if (obj.FailAllError != 0) { if (obj.FailAllError != 999) { obj.gotNextMessagesError({ status: obj.FailAllError }, 'error', null, [postdata, callback, tag]); } return; } + if (!postdata) postdata = ""; + //console.log("SEND: " + postdata); // DEBUG + + // We are in a DukTape environement + if (obj.digest == null) + { + if (obj.authToken) + { + obj.digest = require('http-digest').create({ authToken: obj.authToken }); + } + else + { + obj.digest = require('http-digest').create(obj.user, obj.pass); + } + obj.digest.http = require('http'); + } + var request = { protocol: (obj.tls == 1 ? 'https:' : 'http:'), method: 'POST', host: obj.host, path: '/wsman', port: obj.port, rejectUnauthorized: false, checkServerIdentity: function (cert) { console.log('checkServerIdentity', JSON.stringify(cert)); } }; + var req = obj.digest.request(request); + req.reqid = obj.RequestCount++; + obj.requests[req.reqid] = req; // Keep a reference to the request object so it does not get disposed. + //console.log('Request ' + (obj.RequestCount++)); + req.on('error', function (e) { delete obj.requests[this.reqid]; obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); }); + req.on('response', function (response) { + response.reqid = this.reqid; + //console.log('Response: ' + response.statusCode); + if (response.statusCode != 200) { + //console.log('ERR:' + JSON.stringify(response)); + obj.gotNextMessagesError({ status: response.statusCode }, 'error', null, [postdata, callback, tag]); + } else { + response.acc = ''; + response.on('data', function (data2) { this.acc += data2; }); + response.on('end', function () { delete obj.requests[this.reqid]; obj.gotNextMessages(response.acc, 'success', { status: response.statusCode }, [postdata, callback, tag]); }); + } + }); + + // Send POST body, this work with binary. + req.end(postdata); + obj.ActiveAjaxCount++; + return req; + } + + // AJAX specific private method + obj.pendingAjaxCall = []; + + // Private method + obj.gotNextMessages = function (data, status, request, callArgs) { + obj.ActiveAjaxCount--; + if (obj.FailAllError == 999) return; + //console.log("RECV: " + data); // DEBUG + if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; } + if (request.status != 200) { callArgs[1](null, request.status, callArgs[2]); return; } + callArgs[1](data, 200, callArgs[2]); + obj.PerformNextAjax(); + } + + // Private method + obj.gotNextMessagesError = function (request, status, errorThrown, callArgs) { + obj.ActiveAjaxCount--; + if (obj.FailAllError == 999) return; + if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; } + //if (status != 200) { console.log("ERROR, status=" + status + "\r\n\r\nreq=" + callArgs[0]); } // Debug: Display the request & response if something did not work. + if (obj.FailAllError != 999) { callArgs[1]({ Header: { HttpError: request.status } }, request.status, callArgs[2]); } + obj.PerformNextAjax(); + } + + // Cancel all pending queries with given status + obj.CancelAllQueries = function (s) { + while (obj.PendingAjax.length > 0) { var x = obj.PendingAjax.shift(); x[1](null, s, x[2]); } + } + + return obj; +} + +module.exports = CreateWsmanComm; diff --git a/agents/modules_meshcore_backup/amt-wsman.js b/agents/modules_meshcore_backup/amt-wsman.js new file mode 100644 index 00000000..5552917b --- /dev/null +++ b/agents/modules_meshcore_backup/amt-wsman.js @@ -0,0 +1,211 @@ +/* +Copyright 2018 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 Intel(r) AMT WSMAN Stack +* @author Ylian Saint-Hilaire +* @version v0.2.0 +*/ + +// Construct a MeshServer object +function WsmanStackCreateService(/*CreateWsmanComm, host, port, user, pass, tls, extra*/) +{ + var obj = {_ObjectID: 'WSMAN'}; + //obj.onDebugMessage = null; // Set to a function if you want to get debug messages. + obj.NextMessageId = 1; // Next message number, used to label WSMAN calls. + obj.Address = '/wsman'; + obj.xmlParser = require('amt-xml'); + + if (arguments.length == 1 && typeof (arguments[0] == 'object')) + { + var CreateWsmanComm = arguments[0].transport; + if (CreateWsmanComm) { obj.comm = new CreateWsmanComm(arguments[0]); } + } + else + { + var CreateWsmanComm = arguments[0]; + if (CreateWsmanComm) { obj.comm = new CreateWsmanComm(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]); } + } + + obj.PerformAjax = function PerformAjax(postdata, callback, tag, pri, namespaces) { + if (namespaces == null) namespaces = ''; + obj.comm.PerformAjax('
' + postdata, function (data, status, tag) { + if (status != 200) { callback(obj, null, { Header: { HttpError: status } }, status, tag); return; } + var wsresponse = obj.xmlParser.ParseWsman(data); + if (!wsresponse || wsresponse == null) { callback(obj, null, { Header: { HttpError: status } }, 601, tag); } else { callback(obj, wsresponse.Header["ResourceURI"], wsresponse, 200, tag); } + }, tag, pri); + } + + // Private method + //obj.Debug = function (msg) { /*console.log(msg);*/ } + + // Cancel all pending queries with given status + obj.CancelAllQueries = function CancelAllQueries(s) { obj.comm.CancelAllQueries(s); } + + // Get the last element of a URI string + obj.GetNameFromUrl = function (resuri) { + var x = resuri.lastIndexOf("/"); + return (x == -1)?resuri:resuri.substring(x + 1); + } + + // Perform a WSMAN Subscribe operation + obj.ExecSubscribe = function ExecSubscribe(resuri, delivery, url, callback, tag, pri, selectors, opaque, user, pass) { + var digest = "", digest2 = "", opaque = ""; + if (user != null && pass != null) { digest = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken' + user + '' + pass + ''; digest2 = ''; } + if (opaque != null) { opaque = '' + opaque + ''; } + if (delivery == 'PushWithAck') { delivery = 'dmtf.org/wbem/wsman/1/wsman/PushWithAck'; } else if (delivery == 'Push') { delivery = 'xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push'; } + var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous" + _PutObjToSelectorsXml(selectors) + digest + '
' + url + '' + opaque + '' + digest2 + ''; + obj.PerformAjax(data + "
", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:m="http://x.com"'); + } + + // Perform a WSMAN UnSubscribe operation + obj.ExecUnSubscribe = function ExecUnSubscribe(resuri, callback, tag, pri, selectors) { + var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous" + _PutObjToSelectorsXml(selectors) + ''; + obj.PerformAjax(data + "", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"'); + } + + // Perform a WSMAN PUT operation + obj.ExecPut = function ExecPut(resuri, putobj, callback, tag, pri, selectors) { + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Put" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60.000S" + _PutObjToSelectorsXml(selectors) + '' + _PutObjToBodyXml(resuri, putobj); + obj.PerformAjax(data + "", callback, tag, pri); + } + + // Perform a WSMAN CREATE operation + obj.ExecCreate = function ExecCreate(resuri, putobj, callback, tag, pri, selectors) { + var objname = obj.GetNameFromUrl(resuri); + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Create" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S" + _PutObjToSelectorsXml(selectors) + ""; + for (var n in putobj) { data += "" + putobj[n] + "" } + obj.PerformAjax(data + "", callback, tag, pri); + } + + // Perform a WSMAN DELETE operation + obj.ExecDelete = function ExecDelete(resuri, putobj, callback, tag, pri) { + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S" + _PutObjToSelectorsXml(putobj) + ""; + obj.PerformAjax(data, callback, tag, pri); + } + + // Perform a WSMAN GET operation + obj.ExecGet = function ExecGet(resuri, callback, tag, pri) { + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S", callback, tag, pri); + } + + // Perform a WSMAN method call operation + obj.ExecMethod = function ExecMethod(resuri, method, args, callback, tag, pri, selectors) { + var argsxml = ""; + for (var i in args) { if (args[i] != null) { if (Array.isArray(args[i])) { for (var x in args[i]) { argsxml += "" + args[i][x] + ""; } } else { argsxml += "" + args[i] + ""; } } } + obj.ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors); + } + + // Perform a WSMAN method call operation. The arguments are already formatted in XML. + obj.ExecMethodXml = function ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors) { + obj.PerformAjax(resuri + "/" + method + "" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S" + _PutObjToSelectorsXml(selectors) + "" + argsxml + "", callback, tag, pri); + } + + // Perform a WSMAN ENUM operation + obj.ExecEnum = function ExecEnum(resuri, callback, tag, pri) { + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S", callback, tag, pri); + } + + // Perform a WSMAN PULL operation + obj.ExecPull = function ExecPull(resuri, enumctx, callback, tag, pri) { + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull" + obj.Address + "" + resuri + "" + (obj.NextMessageId++) + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S" + enumctx + "99999999", callback, tag, pri); + } + + function _PutObjToBodyXml(resuri, putObj) { + if (!resuri || putObj == null) return ''; + var objname = obj.GetNameFromUrl(resuri); + var result = ''; + + for (var prop in putObj) { + if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue; + if (putObj[prop] == null || typeof putObj[prop] === 'function') continue; + if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) { + result += '' + putObj[prop].Address + '' + putObj[prop]['ReferenceParameters']["ResourceURI"] + ''; + var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector']; + if (Array.isArray(selectorArray)) { + for (var i=0; i< selectorArray.length; i++) { + result += '' + selectorArray[i]['Value'] + ''; + } + } + else { + result += '' + selectorArray['Value'] + ''; + } + result += ''; + } + else { + if (Array.isArray(putObj[prop])) { + for (var i = 0; i < putObj[prop].length; i++) { + result += '' + putObj[prop][i].toString() + ''; + } + } else { + result += '' + putObj[prop].toString() + ''; + } + } + } + + result += ''; + return result; + } + + /* + convert + { @Name: 'InstanceID', @AttrName: 'Attribute Value'} + into + ' Name="InstanceID" AttrName="Attribute Value" ' + */ + function _ObjectToXmlAttributes(objWithAttributes) { + if(!objWithAttributes) return ''; + var result = ' '; + for (var propName in objWithAttributes) { + if (!objWithAttributes.hasOwnProperty(propName) || propName.indexOf('@') !== 0) continue; + result += propName.substring(1) + '="' + objWithAttributes[propName] + '" '; + } + return result; + } + + function _PutObjToSelectorsXml(selectorSet) { + if (!selectorSet) return ''; + if (typeof selectorSet == 'string') return selectorSet; + if (selectorSet['InstanceID']) return "" + selectorSet['InstanceID'] + ""; + var result = ''; + for(var propName in selectorSet) { + if (!selectorSet.hasOwnProperty(propName)) continue; + result += ''; + if (selectorSet[propName]['ReferenceParameters']) { + result += ''; + result += '' + selectorSet[propName]['Address'] + '' + selectorSet[propName]['ReferenceParameters']['ResourceURI'] + ''; + var selectorArray = selectorSet[propName]['ReferenceParameters']['SelectorSet']['Selector']; + if (Array.isArray(selectorArray)) { + for (var i = 0; i < selectorArray.length; i++) { + result += '' + selectorArray[i]['Value'] + ''; + } + } else { + result += '' + selectorArray['Value'] + ''; + } + result += ''; + } else { + result += selectorSet[propName]; + } + result += ''; + } + result += ''; + return result; + } + + return obj; +} + +module.exports = WsmanStackCreateService; diff --git a/agents/modules_meshcore_backup/amt-xml.js b/agents/modules_meshcore_backup/amt-xml.js new file mode 100644 index 00000000..605d8baf --- /dev/null +++ b/agents/modules_meshcore_backup/amt-xml.js @@ -0,0 +1,183 @@ +/* +Copyright 2018 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. +*/ + +// Parse XML and return JSON +module.exports.ParseWsman = function (xml) { + try { + if (!xml.childNodes) xml = _turnToXml(xml); + var r = { Header: {} }, header = xml.getElementsByTagName("Header")[0], t; + if (!header) header = xml.getElementsByTagName("a:Header")[0]; + if (!header) return null; + for (var i = 0; i < header.childNodes.length; i++) { + var child = header.childNodes[i]; + r.Header[child.localName] = child.textContent; + } + var body = xml.getElementsByTagName("Body")[0]; + if (!body) body = xml.getElementsByTagName("a:Body")[0]; + if (!body) return null; + if (body.childNodes.length > 0) { + t = body.childNodes[0].localName; + if (t.indexOf("_OUTPUT") == t.length - 7) { t = t.substring(0, t.length - 7); } + r.Header['Method'] = t; + r.Body = _ParseWsmanRec(body.childNodes[0]); + } + return r; + } catch (e) { + console.log("Unable to parse XML: " + xml); + return null; + } +} + +// Private method +function _ParseWsmanRec(node) { + var data, r = {}; + for (var i = 0; i < node.childNodes.length; i++) { + var child = node.childNodes[i]; + if ((child.childElementCount == null) || (child.childElementCount == 0)) { data = child.textContent; } else { data = _ParseWsmanRec(child); } + if (data == 'true') data = true; // Convert 'true' into true + if (data == 'false') data = false; // Convert 'false' into false + if ((parseInt(data) + '') === data) data = parseInt(data); // Convert integers + + var childObj = data; + if ((child.attributes != null) && (child.attributes.length > 0)) { + childObj = { 'Value': data }; + for (var j = 0; j < child.attributes.length; j++) { + childObj['@' + child.attributes[j].name] = child.attributes[j].value; + } + } + + if (r[child.localName] instanceof Array) { r[child.localName].push(childObj); } + else if (r[child.localName] == null) { r[child.localName] = childObj; } + else { r[child.localName] = [r[child.localName], childObj]; } + } + return r; +} + +function _PutObjToBodyXml(resuri, putObj) { + if (!resuri || putObj == null) return ''; + var objname = obj.GetNameFromUrl(resuri); + var result = ''; + + for (var prop in putObj) { + if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue; + if (putObj[prop] == null || typeof putObj[prop] === 'function') continue; + if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) { + result += '' + putObj[prop].Address + '' + putObj[prop]['ReferenceParameters']["ResourceURI"] + ''; + var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector']; + if (Array.isArray(selectorArray)) { + for (var i = 0; i < selectorArray.length; i++) { + result += '' + selectorArray[i]['Value'] + ''; + } + } + else { + result += '' + selectorArray['Value'] + ''; + } + result += ''; + } + else { + if (Array.isArray(putObj[prop])) { + for (var i = 0; i < putObj[prop].length; i++) { + result += '' + putObj[prop][i].toString() + ''; + } + } else { + result += '' + putObj[prop].toString() + ''; + } + } + } + + result += ''; + return result; +} + +// This is a drop-in replacement to _turnToXml() that works without xml parser dependency. +try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : null); } }); } catch (ex) { } +function _treeBuilder() { + this.tree = []; + this.push = function (element) { this.tree.push(element); }; + this.pop = function () { var element = this.tree.pop(); if (this.tree.length > 0) { var x = this.tree.peek(); x.childNodes.push(element); x.childElementCount = x.childNodes.length; } return (element); }; + this.peek = function () { return (this.tree.peek()); } + this.addNamespace = function (prefix, namespace) { this.tree.peek().nsTable[prefix] = namespace; if (this.tree.peek().attributes.length > 0) { for (var i = 0; i < this.tree.peek().attributes; ++i) { var a = this.tree.peek().attributes[i]; if (prefix == '*' && a.name == a.localName) { a.namespace = namespace; } else if (prefix != '*' && a.name != a.localName) { var pfx = a.name.split(':')[0]; if (pfx == prefix) { a.namespace = namespace; } } } } } + this.getNamespace = function (prefix) { for (var i = this.tree.length - 1; i >= 0; --i) { if (this.tree[i].nsTable[prefix] != null) { return (this.tree[i].nsTable[prefix]); } } return null; } +} +function _turnToXml(text) { if (text == null) return null; return ({ childNodes: [_turnToXmlRec(text)], getElementsByTagName: _getElementsByTagName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS }); } +function _getElementsByTagNameNS(ns, name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name && (node.namespace == ns || ns == '*')) { ret.push(node); } }); return ret; } +function _getElementsByTagName(name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name) { ret.push(node); } }); return ret; } +function _getChildElementsByTagName(name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name) { ret.push(this.childNodes[node]); } } } return (ret); } +function _getChildElementsByTagNameNS(ns, name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name && (ns == '*' || this.childNodes[node].namespace == ns)) { ret.push(this.childNodes[node]); } } } return (ret); } +function _xmlTraverseAllRec(nodes, func) { for (var i in nodes) { func(nodes[i]); if (nodes[i].childNodes) { _xmlTraverseAllRec(nodes[i].childNodes, func); } } } +function _turnToXmlRec(text) { + var elementStack = new _treeBuilder(), lastElement = null, x1 = text.split('<'), ret = [], element = null, currentElementName = null; + for (var i in x1) { + var x2 = x1[i].split('>'), x3 = x2[0].split(' '), elementName = x3[0]; + if ((elementName.length > 0) && (elementName[0] != '?')) { + if (elementName[0] != '/') { + var attributes = [], localName, localname2 = elementName.split(' ')[0].split(':'), localName = (localname2.length > 1) ? localname2[1] : localname2[0]; + Object.defineProperty(attributes, "get", + { + value: function () { + if (arguments.length == 1) { + for (var a in this) { if (this[a].name == arguments[0]) { return (this[a]); } } + } + else if (arguments.length == 2) { + for (var a in this) { if (this[a].name == arguments[1] && (arguments[0] == '*' || this[a].namespace == arguments[0])) { return (this[a]); } } + } + else { + throw ('attributes.get(): Invalid number of parameters'); + } + } + }); + elementStack.push({ name: elementName, localName: localName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS, getChildElementsByTagNameNS: _getChildElementsByTagNameNS, attributes: attributes, childNodes: [], nsTable: {} }); + // Parse Attributes + if (x3.length > 0) { + var skip = false; + for (var j in x3) { + if (x3[j] == '/') { + // This is an empty Element + elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':'))); + elementStack.peek().textContent = ''; + lastElement = elementStack.pop(); + skip = true; + break; + } + var k = x3[j].indexOf('='); + if (k > 0) { + var attrName = x3[j].substring(0, k); + var attrValue = x3[j].substring(k + 2, x3[j].length - 1); + var attrNS = elementStack.getNamespace('*'); + + if (attrName == 'xmlns') { + elementStack.addNamespace('*', attrValue); + attrNS = attrValue; + } else if (attrName.startsWith('xmlns:')) { + elementStack.addNamespace(attrName.substring(6), attrValue); + } else { + var ax = attrName.split(':'); + if (ax.length == 2) { attrName = ax[1]; attrNS = elementStack.getNamespace(ax[0]); } + } + var x = { name: attrName, value: attrValue } + if (attrNS != null) x.namespace = attrNS; + elementStack.peek().attributes.push(x); + } + } + if (skip) { continue; } + } + elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':'))); + if (x2[1]) { elementStack.peek().textContent = x2[1]; } + } else { lastElement = elementStack.pop(); } + } + } + return lastElement; +} diff --git a/agents/modules_meshcore_backup/amt.js b/agents/modules_meshcore_backup/amt.js new file mode 100644 index 00000000..e0dbe0aa --- /dev/null +++ b/agents/modules_meshcore_backup/amt.js @@ -0,0 +1,1019 @@ +/* +Copyright 2018 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @fileoverview Intel(r) AMT Communication StackXX +* @author Ylian Saint-Hilaire +* @version v0.2.0b +*/ + +/** + * Construct a AmtStackCreateService object, this ia the main Intel AMT communication stack. + * @constructor + */ +function AmtStackCreateService(wsmanStack) { + var obj = new Object(); + obj._ObjectID = 'AMT' + obj.wsman = wsmanStack; + obj.pfx = ["http://intel.com/wbem/wscim/1/amt-schema/1/", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/", "http://intel.com/wbem/wscim/1/ips-schema/1/"]; + obj.PendingEnums = []; + obj.PendingBatchOperations = 0; + obj.ActiveEnumsCount = 0; + obj.MaxActiveEnumsCount = 1; // Maximum number of enumerations that can be done at the same time. + obj.onProcessChanged = null; + var _MaxProcess = 0; + var _LastProcess = 0; + + // Return the number of pending actions + obj.GetPendingActions = function () { return (obj.PendingEnums.length * 2) + (obj.ActiveEnumsCount) + obj.wsman.comm.PendingAjax.length + obj.wsman.comm.ActiveAjaxCount + obj.PendingBatchOperations; } + + // Private Method, Update the current processing status, this gives the application an idea of what progress is being done by the WSMAN stack + function _up() { + var x = obj.GetPendingActions(); + if (_MaxProcess < x) _MaxProcess = x; + if (obj.onProcessChanged != null && _LastProcess != x) { + //console.log("Process Old=" + _LastProcess + ", New=" + x + ", PEnums=" + obj.PendingEnums.length + ", AEnums=" + obj.ActiveEnumsCount + ", PAjax=" + obj.wsman.comm.PendingAjax.length + ", AAjax=" + obj.wsman.comm.ActiveAjaxCount + ", PBatch=" + obj.PendingBatchOperations); + _LastProcess = x; + obj.onProcessChanged(x, _MaxProcess); + } + if (x == 0) _MaxProcess = 0; + } + + // Perform a WSMAN "SUBSCRIBE" operation. + obj.Subscribe = function Subscribe(name, delivery, url, callback, tag, pri, selectors, opaque, user, pass) { obj.wsman.ExecSubscribe(obj.CompleteName(name), delivery, url, function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri, selectors, opaque, user, pass); _up(); } + + // Perform a WSMAN "UNSUBSCRIBE" operation. + obj.UnSubscribe = function UnSubscribe(name, callback, tag, pri, selectors) { obj.wsman.ExecUnSubscribe(obj.CompleteName(name), function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri, selectors); _up(); } + + // Perform a WSMAN "GET" operation. + obj.Get = function Get(name, callback, tag, pri) { obj.wsman.ExecGet(obj.CompleteName(name), function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri); _up(); } + + // Perform a WSMAN "PUT" operation. + obj.Put = function Put(name, putobj, callback, tag, pri, selectors) { obj.wsman.ExecPut(obj.CompleteName(name), putobj, function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri, selectors); _up(); } + + // Perform a WSMAN "CREATE" operation. + obj.Create = function Create(name, putobj, callback, tag, pri) { obj.wsman.ExecCreate(obj.CompleteName(name), putobj, function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri); _up(); } + + // Perform a WSMAN "DELETE" operation. + obj.Delete = function Delete(name, putobj, callback, tag, pri) { obj.wsman.ExecDelete(obj.CompleteName(name), putobj, function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, response, xstatus, tag); }, 0, pri); _up(); } + + // Perform a WSMAN method call operation. + obj.Exec = function Exec(name, method, args, callback, tag, pri, selectors) { obj.wsman.ExecMethod(obj.CompleteName(name), method, args, function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, obj.CompleteExecResponse(response), xstatus, tag); }, 0, pri, selectors); _up(); } + + // Perform a WSMAN method call operation. + obj.ExecWithXml = function ExecWithXml(name, method, args, callback, tag, pri, selectors) { obj.wsman.ExecMethodXml(obj.CompleteName(name), method, execArgumentsToXml(args), function (ws, resuri, response, xstatus) { _up(); callback.call(obj, obj, name, obj.CompleteExecResponse(response), xstatus, tag); }, 0, pri, selectors); _up(); } + + // Perform a WSMAN "ENUMERATE" operation. + obj.Enum = function Enum(name, callback, tag, pri) { + if (obj.ActiveEnumsCount < obj.MaxActiveEnumsCount) { + obj.ActiveEnumsCount++; obj.wsman.ExecEnum(obj.CompleteName(name), function (ws, resuri, response, xstatus, tag0) { _up(); _EnumStartSink(name, response, callback, resuri, xstatus, tag0); }, tag, pri); + } else { + obj.PendingEnums.push([name, callback, tag, pri]); + } + _up(); + } + + // Private method + function _EnumStartSink(name, response, callback, resuri, status, tag, pri) { + if (status != 200) { callback.call(obj, obj, name, null, status, tag); _EnumDoNext(1); return; } + if (response == null || response.Header["Method"] != "EnumerateResponse" || !response.Body["EnumerationContext"]) { callback.call(obj, obj, name, null, 603, tag); _EnumDoNext(1); return; } + var enumctx = response.Body["EnumerationContext"]; + obj.wsman.ExecPull(resuri, enumctx, function (ws, resuri, response, xstatus) { _EnumContinueSink(name, response, callback, resuri, [], xstatus, tag, pri); }); + } + + // Private method + function _EnumContinueSink(name, response, callback, resuri, items, status, tag, pri) { + if (status != 200) { callback.call(obj, obj, name, null, status, tag); _EnumDoNext(1); return; } + if (response == null || response.Header["Method"] != "PullResponse") { callback.call(obj, obj, name, null, 604, tag); _EnumDoNext(1); return; } + for (var i in response.Body["Items"]) { + if (response.Body["Items"][i] instanceof Array) { + for (var j in response.Body["Items"][i]) { items.push(response.Body["Items"][i][j]); } + } else { + items.push(response.Body["Items"][i]); + } + } + if (response.Body["EnumerationContext"]) { + var enumctx = response.Body["EnumerationContext"]; + obj.wsman.ExecPull(resuri, enumctx, function (ws, resuri, response, xstatus) { _EnumContinueSink(name, response, callback, resuri, items, xstatus, tag, 1); }); + } else { + _EnumDoNext(1); + callback.call(obj, obj, name, items, status, tag); + _up(); + } + } + + // Private method + function _EnumDoNext(dec) { + obj.ActiveEnumsCount -= dec; + if (obj.ActiveEnumsCount >= obj.MaxActiveEnumsCount || obj.PendingEnums.length == 0) return; + var x = obj.PendingEnums.shift(); + obj.Enum(x[0], x[1], x[2]); + _EnumDoNext(0); + } + + // Perform a batch of WSMAN "ENUM" operations. + obj.BatchEnum = function (batchname, names, callback, tag, continueOnError, pri) { + obj.PendingBatchOperations += (names.length * 2); + _BatchNextEnum(batchname, Clone(names), callback, tag, {}, continueOnError, pri); _up(); + } + + function Clone(v) { return JSON.parse(JSON.stringify(v)); } + + // Request each enum in the batch, stopping if something does not return status 200 + function _BatchNextEnum(batchname, names, callback, tag, results, continueOnError, pri) { + obj.PendingBatchOperations -= 2; + var n = names.shift(), f = obj.Enum; + if (n[0] == '*') { f = obj.Get; n = n.substring(1); } // If the name starts with a star, do a GET instead of an ENUM. This will reduce round trips. + //console.log((f == obj.Get?'Get ':'Enum ') + n); + // Perform a GET/ENUM action + f(n, function (stack, name, responses, status, tag0) { + tag0[2][name] = { response: (responses==null?null:responses.Body), responses: responses, status: status }; + if (tag0[1].length == 0 || status == 401 || (continueOnError != true && status != 200 && status != 400)) { obj.PendingBatchOperations -= (names.length * 2); _up(); callback.call(obj, obj, batchname, tag0[2], status, tag); } + else { _up(); _BatchNextEnum(batchname, names, callback, tag, tag0[2], pri); } + }, [batchname, names, results], pri); + _up(); + } + + // Perform a batch of WSMAN "GET" operations. + obj.BatchGet = function (batchname, names, callback, tag, pri) { + _FetchNext({ name: batchname, names: names, callback: callback, current: 0, responses: {}, tag: tag, pri: pri }); _up(); + } + + // Private method + function _FetchNext(batch) { + if (batch.names.length <= batch.current) { + batch.callback.call(obj, obj, batch.name, batch.responses, 200, batch.tag); + } else { + obj.wsman.ExecGet(obj.CompleteName(batch.names[batch.current]), function (ws, resuri, response, xstatus) { _Fetched(batch, response, xstatus); }, batch.pri); + batch.current++; + } + _up(); + } + + // Private method + function _Fetched(batch, response, status) { + if (response == null || status != 200) { + batch.callback.call(obj, obj, batch.name, null, status, batch.tag); + } else { + batch.responses[response.Header["Method"]] = response; + _FetchNext(batch); + } + } + + // Private method + obj.CompleteName = function(name) { + if (name.indexOf("AMT_") == 0) return obj.pfx[0] + name; + if (name.indexOf("CIM_") == 0) return obj.pfx[1] + name; + if (name.indexOf("IPS_") == 0) return obj.pfx[2] + name; + } + + obj.CompleteExecResponse = function (resp) { + if (resp && resp != null && resp.Body && (resp.Body["ReturnValue"] != undefined)) { resp.Body.ReturnValueStr = obj.AmtStatusToStr(resp.Body["ReturnValue"]); } + return resp; + } + + obj.RequestPowerStateChange = function (PowerState, callback_func) { + obj.CIM_PowerManagementService_RequestPowerStateChange(PowerState, "
http://schemas.xmlsoap.org/ws/2004/08/addressing
http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystemCIM_ComputerSystemManagedSystem", null, null, callback_func); + } + + obj.SetBootConfigRole = function (Role, callback_func) { + obj.CIM_BootService_SetBootConfigRole("
http://schemas.xmlsoap.org/ws/2004/08/addressing
http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_BootConfigSettingIntel(r) AMT: Boot Configuration 0", Role, callback_func); + } + + // Cancel all pending queries with given status + obj.CancelAllQueries = function (s) { + obj.wsman.CancelAllQueries(s); + } + + // Auto generated methods + obj.AMT_AgentPresenceWatchdog_RegisterAgent = function (callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "RegisterAgent", {}, callback_func, tag, pri, selectors); } + obj.AMT_AgentPresenceWatchdog_AssertPresence = function (SequenceNumber, callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func, tag, pri, selectors); } + obj.AMT_AgentPresenceWatchdog_AssertShutdown = function (SequenceNumber, callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func, tag, pri, selectors); } + //obj.AMT_AgentPresenceWatchdog_RegisterAgent = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdog", "RegisterAgent", {}, callback_func); } + //obj.AMT_AgentPresenceWatchdog_AssertPresence = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func); } + //obj.AMT_AgentPresenceWatchdog_AssertShutdown = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func); } + obj.AMT_AgentPresenceWatchdog_AddAction = function (OldState, NewState, EventOnTransition, ActionSd, ActionEac, callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "AddAction", { "OldState": OldState, "NewState": NewState, "EventOnTransition": EventOnTransition, "ActionSd": ActionSd, "ActionEac": ActionEac }, callback_func, tag, pri, selectors); } + obj.AMT_AgentPresenceWatchdog_DeleteAllActions = function (callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "DeleteAllActions", {}, callback_func, tag, pri, selectors); } + obj.AMT_AgentPresenceWatchdogAction_GetActionEac = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdogAction", "GetActionEac", {}, callback_func); } + obj.AMT_AgentPresenceWatchdogVA_RegisterAgent = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "RegisterAgent", {}, callback_func); } + obj.AMT_AgentPresenceWatchdogVA_AssertPresence = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func); } + obj.AMT_AgentPresenceWatchdogVA_AssertShutdown = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func); } + obj.AMT_AgentPresenceWatchdogVA_AddAction = function (OldState, NewState, EventOnTransition, ActionSd, ActionEac, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AddAction", { "OldState": OldState, "NewState": NewState, "EventOnTransition": EventOnTransition, "ActionSd": ActionSd, "ActionEac": ActionEac }, callback_func); } + obj.AMT_AgentPresenceWatchdogVA_DeleteAllActions = function (_method_dummy, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "DeleteAllActions", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_AlarmClockService_AddAlarm = function AlarmClockService_AddAlarm(alarmInstance, callback_func) + { + var id = alarmInstance.InstanceID; + var nm = alarmInstance.ElementName; + var start = alarmInstance.StartTime.Datetime; + var interval = alarmInstance.Interval ? alarmInstance.Interval.Datetime : undefined; + var doc = alarmInstance.DeleteOnCompletion; + var tpl = "" + id + "" + nm + "" + start + "" + ((interval!=undefined)?("" + interval + ""):"") + "" + doc + "" + obj.wsman.ExecMethodXml(obj.CompleteName("AMT_AlarmClockService"), "AddAlarm", tpl, callback_func); + }; + obj.AMT_AuditLog_ClearLog = function (callback_func) { obj.Exec("AMT_AuditLog", "ClearLog", {}, callback_func); } + obj.AMT_AuditLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_AuditLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.AMT_AuditLog_ReadRecords = function (StartIndex, callback_func, tag) { obj.Exec("AMT_AuditLog", "ReadRecords", { "StartIndex": StartIndex }, callback_func, tag); } + obj.AMT_AuditLog_SetAuditLock = function (LockTimeoutInSeconds, Flag, Handle, callback_func) { obj.Exec("AMT_AuditLog", "SetAuditLock", { "LockTimeoutInSeconds": LockTimeoutInSeconds, "Flag": Flag, "Handle": Handle }, callback_func); } + obj.AMT_AuditLog_ExportAuditLogSignature = function (SigningMechanism, callback_func) { obj.Exec("AMT_AuditLog", "ExportAuditLogSignature", { "SigningMechanism": SigningMechanism }, callback_func); } + obj.AMT_AuditLog_SetSigningKeyMaterial = function (SigningMechanismType, SigningKey, LengthOfCertificates, Certificates, callback_func) { obj.Exec("AMT_AuditLog", "SetSigningKeyMaterial", { "SigningMechanismType": SigningMechanismType, "SigningKey": SigningKey, "LengthOfCertificates": LengthOfCertificates, "Certificates": Certificates }, callback_func); } + obj.AMT_AuditPolicyRule_SetAuditPolicy = function (Enable, AuditedAppID, EventID, PolicyType, callback_func) { obj.Exec("AMT_AuditPolicyRule", "SetAuditPolicy", { "Enable": Enable, "AuditedAppID": AuditedAppID, "EventID": EventID, "PolicyType": PolicyType }, callback_func); } + obj.AMT_AuditPolicyRule_SetAuditPolicyBulk = function (Enable, AuditedAppID, EventID, PolicyType, callback_func) { obj.Exec("AMT_AuditPolicyRule", "SetAuditPolicyBulk", { "Enable": Enable, "AuditedAppID": AuditedAppID, "EventID": EventID, "PolicyType": PolicyType }, callback_func); } + obj.AMT_AuthorizationService_AddUserAclEntryEx = function (DigestUsername, DigestPassword, KerberosUserSid, AccessPermission, Realms, callback_func) { obj.Exec("AMT_AuthorizationService", "AddUserAclEntryEx", { "DigestUsername": DigestUsername, "DigestPassword": DigestPassword, "KerberosUserSid": KerberosUserSid, "AccessPermission": AccessPermission, "Realms": Realms }, callback_func); } + obj.AMT_AuthorizationService_EnumerateUserAclEntries = function (StartIndex, callback_func) { obj.Exec("AMT_AuthorizationService", "EnumerateUserAclEntries", { "StartIndex": StartIndex }, callback_func); } + obj.AMT_AuthorizationService_GetUserAclEntryEx = function (Handle, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "GetUserAclEntryEx", { "Handle": Handle }, callback_func, tag); } + obj.AMT_AuthorizationService_UpdateUserAclEntryEx = function (Handle, DigestUsername, DigestPassword, KerberosUserSid, AccessPermission, Realms, callback_func) { obj.Exec("AMT_AuthorizationService", "UpdateUserAclEntryEx", { "Handle": Handle, "DigestUsername": DigestUsername, "DigestPassword": DigestPassword, "KerberosUserSid": KerberosUserSid, "AccessPermission": AccessPermission, "Realms": Realms }, callback_func); } + obj.AMT_AuthorizationService_RemoveUserAclEntry = function (Handle, callback_func) { obj.Exec("AMT_AuthorizationService", "RemoveUserAclEntry", { "Handle": Handle }, callback_func); } + obj.AMT_AuthorizationService_SetAdminAclEntryEx = function (Username, DigestPassword, callback_func) { obj.Exec("AMT_AuthorizationService", "SetAdminAclEntryEx", { "Username": Username, "DigestPassword": DigestPassword }, callback_func); } + obj.AMT_AuthorizationService_GetAdminAclEntry = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminAclEntry", {}, callback_func); } + obj.AMT_AuthorizationService_GetAdminAclEntryStatus = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminAclEntryStatus", {}, callback_func); } + obj.AMT_AuthorizationService_GetAdminNetAclEntryStatus = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminNetAclEntryStatus", {}, callback_func); } + obj.AMT_AuthorizationService_SetAclEnabledState = function (Handle, Enabled, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "SetAclEnabledState", { "Handle": Handle, "Enabled": Enabled }, callback_func, tag); } + obj.AMT_AuthorizationService_GetAclEnabledState = function (Handle, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "GetAclEnabledState", { "Handle": Handle }, callback_func, tag); } + obj.AMT_EndpointAccessControlService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.AMT_EndpointAccessControlService_GetPosture = function (PostureType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetPosture", { "PostureType": PostureType }, callback_func); } + obj.AMT_EndpointAccessControlService_GetPostureHash = function (PostureType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetPostureHash", { "PostureType": PostureType }, callback_func); } + obj.AMT_EndpointAccessControlService_UpdatePostureState = function (UpdateType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "UpdatePostureState", { "UpdateType": UpdateType }, callback_func); } + obj.AMT_EndpointAccessControlService_GetEacOptions = function (callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetEacOptions", {}, callback_func); } + obj.AMT_EndpointAccessControlService_SetEacOptions = function (EacVendors, PostureHashAlgorithm, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "SetEacOptions", { "EacVendors": EacVendors, "PostureHashAlgorithm": PostureHashAlgorithm }, callback_func); } + obj.AMT_EnvironmentDetectionSettingData_SetSystemDefensePolicy = function (Policy, callback_func) { obj.Exec("AMT_EnvironmentDetectionSettingData", "SetSystemDefensePolicy", { "Policy": Policy }, callback_func); } + obj.AMT_EnvironmentDetectionSettingData_EnableVpnRouting = function (Enable, callback_func) { obj.Exec("AMT_EnvironmentDetectionSettingData", "EnableVpnRouting", { "Enable": Enable }, callback_func); } + obj.AMT_EthernetPortSettings_SetLinkPreference = function (LinkPreference, Timeout, callback_func) { obj.Exec("AMT_EthernetPortSettings", "SetLinkPreference", { "LinkPreference": LinkPreference, "Timeout": Timeout }, callback_func); } + obj.AMT_HeuristicPacketFilterStatistics_ResetSelectedStats = function (SelectedStatistics, callback_func) { obj.Exec("AMT_HeuristicPacketFilterStatistics", "ResetSelectedStats", { "SelectedStatistics": SelectedStatistics }, callback_func); } + obj.AMT_KerberosSettingData_GetCredentialCacheState = function (callback_func) { obj.Exec("AMT_KerberosSettingData", "GetCredentialCacheState", {}, callback_func); } + obj.AMT_KerberosSettingData_SetCredentialCacheState = function (Enable, callback_func) { obj.Exec("AMT_KerberosSettingData", "SetCredentialCacheState", { "Enable": Enable }, callback_func); } + obj.AMT_MessageLog_CancelIteration = function (IterationIdentifier, callback_func) { obj.Exec("AMT_MessageLog", "CancelIteration", { "IterationIdentifier": IterationIdentifier }, callback_func); } + obj.AMT_MessageLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_MessageLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.AMT_MessageLog_ClearLog = function (callback_func) { obj.Exec("AMT_MessageLog", "ClearLog", { }, callback_func); } + obj.AMT_MessageLog_GetRecords = function (IterationIdentifier, MaxReadRecords, callback_func, tag) { obj.Exec("AMT_MessageLog", "GetRecords", { "IterationIdentifier": IterationIdentifier, "MaxReadRecords": MaxReadRecords }, callback_func, tag); } + obj.AMT_MessageLog_GetRecord = function (IterationIdentifier, PositionToNext, callback_func) { obj.Exec("AMT_MessageLog", "GetRecord", { "IterationIdentifier": IterationIdentifier, "PositionToNext": PositionToNext }, callback_func); } + obj.AMT_MessageLog_PositionAtRecord = function (IterationIdentifier, MoveAbsolute, RecordNumber, callback_func) { obj.Exec("AMT_MessageLog", "PositionAtRecord", { "IterationIdentifier": IterationIdentifier, "MoveAbsolute": MoveAbsolute, "RecordNumber": RecordNumber }, callback_func); } + obj.AMT_MessageLog_PositionToFirstRecord = function (callback_func, tag) { obj.Exec("AMT_MessageLog", "PositionToFirstRecord", {}, callback_func, tag); } + obj.AMT_MessageLog_FreezeLog = function (Freeze, callback_func) { obj.Exec("AMT_MessageLog", "FreezeLog", { "Freeze": Freeze }, callback_func); } + obj.AMT_PublicKeyManagementService_AddCRL = function (Url, SerialNumbers, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddCRL", { "Url": Url, "SerialNumbers": SerialNumbers }, callback_func); } + obj.AMT_PublicKeyManagementService_ResetCRLList = function (_method_dummy, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "ResetCRLList", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_PublicKeyManagementService_AddCertificate = function (CertificateBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddCertificate", { "CertificateBlob": CertificateBlob }, callback_func); } + obj.AMT_PublicKeyManagementService_AddTrustedRootCertificate = function (CertificateBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddTrustedRootCertificate", { "CertificateBlob": CertificateBlob }, callback_func); } + obj.AMT_PublicKeyManagementService_AddKey = function (KeyBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddKey", { "KeyBlob": KeyBlob }, callback_func); } + obj.AMT_PublicKeyManagementService_GeneratePKCS10Request = function (KeyPair, DNName, Usage, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GeneratePKCS10Request", { "KeyPair": KeyPair, "DNName": DNName, "Usage": Usage }, callback_func); } + obj.AMT_PublicKeyManagementService_GeneratePKCS10RequestEx = function (KeyPair, SigningAlgorithm, NullSignedCertificateRequest, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GeneratePKCS10RequestEx", { "KeyPair": KeyPair, "SigningAlgorithm": SigningAlgorithm, "NullSignedCertificateRequest": NullSignedCertificateRequest }, callback_func); } + obj.AMT_PublicKeyManagementService_GenerateKeyPair = function (KeyAlgorithm, KeyLength, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GenerateKeyPair", { "KeyAlgorithm": KeyAlgorithm, "KeyLength": KeyLength }, callback_func); } + obj.AMT_RedirectionService_RequestStateChange = function (RequestedState, callback_func) { obj.Exec("AMT_RedirectionService", "RequestStateChange", { "RequestedState": RequestedState }, callback_func); } + obj.AMT_RedirectionService_TerminateSession = function (SessionType, callback_func) { obj.Exec("AMT_RedirectionService", "TerminateSession", { "SessionType": SessionType }, callback_func); } + obj.AMT_RemoteAccessService_AddMpServer = function (AccessInfo, InfoFormat, Port, AuthMethod, Certificate, Username, Password, CN, callback_func) { obj.Exec("AMT_RemoteAccessService", "AddMpServer", { "AccessInfo": AccessInfo, "InfoFormat": InfoFormat, "Port": Port, "AuthMethod": AuthMethod, "Certificate": Certificate, "Username": Username, "Password": Password, "CN": CN }, callback_func); } + obj.AMT_RemoteAccessService_AddRemoteAccessPolicyRule = function (Trigger, TunnelLifeTime, ExtendedData, MpServer, callback_func) { obj.Exec("AMT_RemoteAccessService", "AddRemoteAccessPolicyRule", { "Trigger": Trigger, "TunnelLifeTime": TunnelLifeTime, "ExtendedData": ExtendedData, "MpServer": MpServer }, callback_func); } + obj.AMT_RemoteAccessService_CloseRemoteAccessConnection = function (_method_dummy, callback_func) { obj.Exec("AMT_RemoteAccessService", "CloseRemoteAccessConnection", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_SetupAndConfigurationService_CommitChanges = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "CommitChanges", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_SetupAndConfigurationService_Unprovision = function (ProvisioningMode, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "Unprovision", { "ProvisioningMode": ProvisioningMode }, callback_func); } + obj.AMT_SetupAndConfigurationService_PartialUnprovision = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "PartialUnprovision", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_SetupAndConfigurationService_ResetFlashWearOutProtection = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "ResetFlashWearOutProtection", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_SetupAndConfigurationService_ExtendProvisioningPeriod = function (Duration, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "ExtendProvisioningPeriod", { "Duration": Duration }, callback_func); } + obj.AMT_SetupAndConfigurationService_SetMEBxPassword = function (Password, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "SetMEBxPassword", { "Password": Password }, callback_func); } + obj.AMT_SetupAndConfigurationService_SetTLSPSK = function (PID, PPS, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "SetTLSPSK", { "PID": PID, "PPS": PPS }, callback_func); } + obj.AMT_SetupAndConfigurationService_GetProvisioningAuditRecord = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetProvisioningAuditRecord", {}, callback_func); } + obj.AMT_SetupAndConfigurationService_GetUuid = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetUuid", {}, callback_func); } + obj.AMT_SetupAndConfigurationService_GetUnprovisionBlockingComponents = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetUnprovisionBlockingComponents", {}, callback_func); } + obj.AMT_SetupAndConfigurationService_GetProvisioningAuditRecordV2 = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetProvisioningAuditRecordV2", {}, callback_func); } + obj.AMT_SystemDefensePolicy_GetTimeout = function (callback_func) { obj.Exec("AMT_SystemDefensePolicy", "GetTimeout", {}, callback_func); } + obj.AMT_SystemDefensePolicy_SetTimeout = function (Timeout, callback_func) { obj.Exec("AMT_SystemDefensePolicy", "SetTimeout", { "Timeout": Timeout }, callback_func); } + obj.AMT_SystemDefensePolicy_UpdateStatistics = function (NetworkInterface, ResetOnRead, callback_func, tag, pri, selectors) { obj.Exec("AMT_SystemDefensePolicy", "UpdateStatistics", { "NetworkInterface": NetworkInterface, "ResetOnRead": ResetOnRead }, callback_func, tag, pri, selectors); } + obj.AMT_SystemPowerScheme_SetPowerScheme = function (callback_func, schemeInstanceId, tag) { obj.Exec("AMT_SystemPowerScheme", "SetPowerScheme", {}, callback_func, tag, 0, { "InstanceID": schemeInstanceId }); } + obj.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch = function (callback_func, tag) { obj.Exec("AMT_TimeSynchronizationService", "GetLowAccuracyTimeSynch", {}, callback_func, tag); } + obj.AMT_TimeSynchronizationService_SetHighAccuracyTimeSynch = function (Ta0, Tm1, Tm2, callback_func, tag) { obj.Exec("AMT_TimeSynchronizationService", "SetHighAccuracyTimeSynch", { "Ta0": Ta0, "Tm1": Tm1, "Tm2": Tm2 }, callback_func, tag); } + obj.AMT_UserInitiatedConnectionService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_UserInitiatedConnectionService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.AMT_WebUIService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func, tag) { obj.Exec("AMT_WebUIService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func, tag); } + obj.AMT_WiFiPortConfigurationService_AddWiFiSettings = function (WiFiEndpoint, WiFiEndpointSettingsInput, IEEE8021xSettingsInput, ClientCredential, CACredential, callback_func) { obj.ExecWithXml("AMT_WiFiPortConfigurationService", "AddWiFiSettings", { "WiFiEndpoint": WiFiEndpoint, "WiFiEndpointSettingsInput": WiFiEndpointSettingsInput, "IEEE8021xSettingsInput": IEEE8021xSettingsInput, "ClientCredential": ClientCredential, "CACredential": CACredential }, callback_func); } + obj.AMT_WiFiPortConfigurationService_UpdateWiFiSettings = function (WiFiEndpointSettings, WiFiEndpointSettingsInput, IEEE8021xSettingsInput, ClientCredential, CACredential, callback_func) { obj.ExecWithXml("AMT_WiFiPortConfigurationService", "UpdateWiFiSettings", { "WiFiEndpointSettings": WiFiEndpointSettings, "WiFiEndpointSettingsInput": WiFiEndpointSettingsInput, "IEEE8021xSettingsInput": IEEE8021xSettingsInput, "ClientCredential": ClientCredential, "CACredential": CACredential }, callback_func); } + obj.AMT_WiFiPortConfigurationService_DeleteAllITProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllITProfiles", { "_method_dummy": _method_dummy }, callback_func); } + obj.AMT_WiFiPortConfigurationService_DeleteAllUserProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllUserProfiles", { "_method_dummy": _method_dummy }, callback_func); } + obj.CIM_Account_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Account", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_AccountManagementService_CreateAccount = function (System, AccountTemplate, callback_func) { obj.Exec("CIM_AccountManagementService", "CreateAccount", { "System": System, "AccountTemplate": AccountTemplate }, callback_func); } + obj.CIM_BootConfigSetting_ChangeBootOrder = function (Source, callback_func) { obj.Exec("CIM_BootConfigSetting", "ChangeBootOrder", { "Source": Source }, callback_func); } + obj.CIM_BootService_SetBootConfigRole = function (BootConfigSetting, Role, callback_func) { obj.Exec("CIM_BootService", "SetBootConfigRole", { "BootConfigSetting": BootConfigSetting, "Role": Role }, callback_func, 0, 1); } + obj.CIM_Card_ConnectorPower = function (Connector, PoweredOn, callback_func) { obj.Exec("CIM_Card", "ConnectorPower", { "Connector": Connector, "PoweredOn": PoweredOn }, callback_func); } + obj.CIM_Card_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_Card", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); } + obj.CIM_Chassis_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_Chassis", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); } + obj.CIM_Fan_SetSpeed = function (DesiredSpeed, callback_func) { obj.Exec("CIM_Fan", "SetSpeed", { "DesiredSpeed": DesiredSpeed }, callback_func); } + obj.CIM_KVMRedirectionSAP_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_KVMRedirectionSAP", "RequestStateChange", { "RequestedState": RequestedState/*, "TimeoutPeriod": TimeoutPeriod */}, callback_func); } + obj.CIM_MediaAccessDevice_LockMedia = function (Lock, callback_func) { obj.Exec("CIM_MediaAccessDevice", "LockMedia", { "Lock": Lock }, callback_func); } + obj.CIM_MediaAccessDevice_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_MediaAccessDevice", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_MediaAccessDevice_Reset = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "Reset", {}, callback_func); } + obj.CIM_MediaAccessDevice_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_MediaAccessDevice", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_MediaAccessDevice_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_MediaAccessDevice", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_MediaAccessDevice_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_MediaAccessDevice", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_MediaAccessDevice_SaveProperties = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "SaveProperties", {}, callback_func); } + obj.CIM_MediaAccessDevice_RestoreProperties = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "RestoreProperties", {}, callback_func); } + obj.CIM_MediaAccessDevice_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_MediaAccessDevice", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_PhysicalFrame_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_PhysicalFrame", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); } + obj.CIM_PhysicalPackage_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_PhysicalPackage", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); } + obj.CIM_PowerManagementService_RequestPowerStateChange = function (PowerState, ManagedElement, Time, TimeoutPeriod, callback_func) { obj.Exec("CIM_PowerManagementService", "RequestPowerStateChange", { "PowerState": PowerState, "ManagedElement": ManagedElement, "Time": Time, "TimeoutPeriod": TimeoutPeriod }, callback_func, 0, 1); } + obj.CIM_PowerSupply_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_PowerSupply", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_PowerSupply_Reset = function (callback_func) { obj.Exec("CIM_PowerSupply", "Reset", {}, callback_func); } + obj.CIM_PowerSupply_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_PowerSupply", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_PowerSupply_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_PowerSupply", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_PowerSupply_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_PowerSupply", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_PowerSupply_SaveProperties = function (callback_func) { obj.Exec("CIM_PowerSupply", "SaveProperties", {}, callback_func); } + obj.CIM_PowerSupply_RestoreProperties = function (callback_func) { obj.Exec("CIM_PowerSupply", "RestoreProperties", {}, callback_func); } + obj.CIM_PowerSupply_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_PowerSupply", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_Processor_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Processor", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_Processor_Reset = function (callback_func) { obj.Exec("CIM_Processor", "Reset", {}, callback_func); } + obj.CIM_Processor_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Processor", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_Processor_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Processor", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_Processor_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Processor", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_Processor_SaveProperties = function (callback_func) { obj.Exec("CIM_Processor", "SaveProperties", {}, callback_func); } + obj.CIM_Processor_RestoreProperties = function (callback_func) { obj.Exec("CIM_Processor", "RestoreProperties", {}, callback_func); } + obj.CIM_Processor_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Processor", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_RecordLog_ClearLog = function (callback_func) { obj.Exec("CIM_RecordLog", "ClearLog", {}, callback_func); } + obj.CIM_RecordLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_RecordLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_RedirectionService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_RedirectionService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_Sensor_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Sensor", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_Sensor_Reset = function (callback_func) { obj.Exec("CIM_Sensor", "Reset", {}, callback_func); } + obj.CIM_Sensor_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Sensor", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_Sensor_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Sensor", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_Sensor_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Sensor", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_Sensor_SaveProperties = function (callback_func) { obj.Exec("CIM_Sensor", "SaveProperties", {}, callback_func); } + obj.CIM_Sensor_RestoreProperties = function (callback_func) { obj.Exec("CIM_Sensor", "RestoreProperties", {}, callback_func); } + obj.CIM_Sensor_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Sensor", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_StatisticalData_ResetSelectedStats = function (SelectedStatistics, callback_func) { obj.Exec("CIM_StatisticalData", "ResetSelectedStats", { "SelectedStatistics": SelectedStatistics }, callback_func); } + obj.CIM_Watchdog_KeepAlive = function (callback_func) { obj.Exec("CIM_Watchdog", "KeepAlive", {}, callback_func); } + obj.CIM_Watchdog_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Watchdog", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_Watchdog_Reset = function (callback_func) { obj.Exec("CIM_Watchdog", "Reset", {}, callback_func); } + obj.CIM_Watchdog_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Watchdog", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_Watchdog_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Watchdog", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_Watchdog_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Watchdog", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_Watchdog_SaveProperties = function (callback_func) { obj.Exec("CIM_Watchdog", "SaveProperties", {}, callback_func); } + obj.CIM_Watchdog_RestoreProperties = function (callback_func) { obj.Exec("CIM_Watchdog", "RestoreProperties", {}, callback_func); } + obj.CIM_Watchdog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Watchdog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.CIM_WiFiPort_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_WiFiPort", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); } + obj.CIM_WiFiPort_Reset = function (callback_func) { obj.Exec("CIM_WiFiPort", "Reset", {}, callback_func); } + obj.CIM_WiFiPort_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_WiFiPort", "EnableDevice", { "Enabled": Enabled }, callback_func); } + obj.CIM_WiFiPort_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_WiFiPort", "OnlineDevice", { "Online": Online }, callback_func); } + obj.CIM_WiFiPort_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_WiFiPort", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); } + obj.CIM_WiFiPort_SaveProperties = function (callback_func) { obj.Exec("CIM_WiFiPort", "SaveProperties", {}, callback_func); } + obj.CIM_WiFiPort_RestoreProperties = function (callback_func) { obj.Exec("CIM_WiFiPort", "RestoreProperties", {}, callback_func); } + obj.CIM_WiFiPort_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_WiFiPort", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.IPS_HostBasedSetupService_Setup = function (NetAdminPassEncryptionType, NetworkAdminPassword, McNonce, Certificate, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "Setup", { "NetAdminPassEncryptionType": NetAdminPassEncryptionType, "NetworkAdminPassword": NetworkAdminPassword, "McNonce": McNonce, "Certificate": Certificate, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); } + obj.IPS_HostBasedSetupService_AddNextCertInChain = function (NextCertificate, IsLeafCertificate, IsRootCertificate, callback_func) { obj.Exec("IPS_HostBasedSetupService", "AddNextCertInChain", { "NextCertificate": NextCertificate, "IsLeafCertificate": IsLeafCertificate, "IsRootCertificate": IsRootCertificate }, callback_func); } + obj.IPS_HostBasedSetupService_AdminSetup = function (NetAdminPassEncryptionType, NetworkAdminPassword, McNonce, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "AdminSetup", { "NetAdminPassEncryptionType": NetAdminPassEncryptionType, "NetworkAdminPassword": NetworkAdminPassword, "McNonce": McNonce, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); } + obj.IPS_HostBasedSetupService_UpgradeClientToAdmin = function (McNonce, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "UpgradeClientToAdmin", { "McNonce": McNonce, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); } + obj.IPS_HostBasedSetupService_DisableClientControlMode = function (_method_dummy, callback_func) { obj.Exec("IPS_HostBasedSetupService", "DisableClientControlMode", { "_method_dummy": _method_dummy }, callback_func); } + obj.IPS_KVMRedirectionSettingData_TerminateSession = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "TerminateSession", {}, callback_func); } + obj.IPS_KVMRedirectionSettingData_DataChannelRead = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelRead", {}, callback_func); } + obj.IPS_KVMRedirectionSettingData_DataChannelWrite = function (Data, callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelWrite", { "DataMessage": Data }, callback_func); } + obj.IPS_OptInService_StartOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "StartOptIn", {}, callback_func); } + obj.IPS_OptInService_CancelOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "CancelOptIn", {}, callback_func); } + obj.IPS_OptInService_SendOptInCode = function (OptInCode, callback_func) { obj.Exec("IPS_OptInService", "SendOptInCode", { "OptInCode": OptInCode }, callback_func); } + obj.IPS_OptInService_StartService = function (callback_func) { obj.Exec("IPS_OptInService", "StartService", {}, callback_func); } + obj.IPS_OptInService_StopService = function (callback_func) { obj.Exec("IPS_OptInService", "StopService", {}, callback_func); } + obj.IPS_OptInService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_OptInService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.IPS_ProvisioningRecordLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_ProvisioningRecordLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + obj.IPS_ProvisioningRecordLog_ClearLog = function (_method_dummy, callback_func) { obj.Exec("IPS_ProvisioningRecordLog", "ClearLog", { "_method_dummy": _method_dummy }, callback_func); } + obj.IPS_SecIOService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_SecIOService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); } + + obj.AmtStatusToStr = function (code) { if (obj.AmtStatusCodes[code]) return obj.AmtStatusCodes[code]; else return "UNKNOWN_ERROR" } + obj.AmtStatusCodes = { + 0x0000: "SUCCESS", + 0x0001: "INTERNAL_ERROR", + 0x0002: "NOT_READY", + 0x0003: "INVALID_PT_MODE", + 0x0004: "INVALID_MESSAGE_LENGTH", + 0x0005: "TABLE_FINGERPRINT_NOT_AVAILABLE", + 0x0006: "INTEGRITY_CHECK_FAILED", + 0x0007: "UNSUPPORTED_ISVS_VERSION", + 0x0008: "APPLICATION_NOT_REGISTERED", + 0x0009: "INVALID_REGISTRATION_DATA", + 0x000A: "APPLICATION_DOES_NOT_EXIST", + 0x000B: "NOT_ENOUGH_STORAGE", + 0x000C: "INVALID_NAME", + 0x000D: "BLOCK_DOES_NOT_EXIST", + 0x000E: "INVALID_BYTE_OFFSET", + 0x000F: "INVALID_BYTE_COUNT", + 0x0010: "NOT_PERMITTED", + 0x0011: "NOT_OWNER", + 0x0012: "BLOCK_LOCKED_BY_OTHER", + 0x0013: "BLOCK_NOT_LOCKED", + 0x0014: "INVALID_GROUP_PERMISSIONS", + 0x0015: "GROUP_DOES_NOT_EXIST", + 0x0016: "INVALID_MEMBER_COUNT", + 0x0017: "MAX_LIMIT_REACHED", + 0x0018: "INVALID_AUTH_TYPE", + 0x0019: "AUTHENTICATION_FAILED", + 0x001A: "INVALID_DHCP_MODE", + 0x001B: "INVALID_IP_ADDRESS", + 0x001C: "INVALID_DOMAIN_NAME", + 0x001D: "UNSUPPORTED_VERSION", + 0x001E: "REQUEST_UNEXPECTED", + 0x001F: "INVALID_TABLE_TYPE", + 0x0020: "INVALID_PROVISIONING_STATE", + 0x0021: "UNSUPPORTED_OBJECT", + 0x0022: "INVALID_TIME", + 0x0023: "INVALID_INDEX", + 0x0024: "INVALID_PARAMETER", + 0x0025: "INVALID_NETMASK", + 0x0026: "FLASH_WRITE_LIMIT_EXCEEDED", + 0x0027: "INVALID_IMAGE_LENGTH", + 0x0028: "INVALID_IMAGE_SIGNATURE", + 0x0029: "PROPOSE_ANOTHER_VERSION", + 0x002A: "INVALID_PID_FORMAT", + 0x002B: "INVALID_PPS_FORMAT", + 0x002C: "BIST_COMMAND_BLOCKED", + 0x002D: "CONNECTION_FAILED", + 0x002E: "CONNECTION_TOO_MANY", + 0x002F: "RNG_GENERATION_IN_PROGRESS", + 0x0030: "RNG_NOT_READY", + 0x0031: "CERTIFICATE_NOT_READY", + 0x0400: "DISABLED_BY_POLICY", + 0x0800: "NETWORK_IF_ERROR_BASE", + 0x0801: "UNSUPPORTED_OEM_NUMBER", + 0x0802: "UNSUPPORTED_BOOT_OPTION", + 0x0803: "INVALID_COMMAND", + 0x0804: "INVALID_SPECIAL_COMMAND", + 0x0805: "INVALID_HANDLE", + 0x0806: "INVALID_PASSWORD", + 0x0807: "INVALID_REALM", + 0x0808: "STORAGE_ACL_ENTRY_IN_USE", + 0x0809: "DATA_MISSING", + 0x080A: "DUPLICATE", + 0x080B: "EVENTLOG_FROZEN", + 0x080C: "PKI_MISSING_KEYS", + 0x080D: "PKI_GENERATING_KEYS", + 0x080E: "INVALID_KEY", + 0x080F: "INVALID_CERT", + 0x0810: "CERT_KEY_NOT_MATCH", + 0x0811: "MAX_KERB_DOMAIN_REACHED", + 0x0812: "UNSUPPORTED", + 0x0813: "INVALID_PRIORITY", + 0x0814: "NOT_FOUND", + 0x0815: "INVALID_CREDENTIALS", + 0x0816: "INVALID_PASSPHRASE", + 0x0818: "NO_ASSOCIATION", + 0x081B: "AUDIT_FAIL", + 0x081C: "BLOCKING_COMPONENT", + 0x0821: "USER_CONSENT_REQUIRED", + 0x1000: "APP_INTERNAL_ERROR", + 0x1001: "NOT_INITIALIZED", + 0x1002: "LIB_VERSION_UNSUPPORTED", + 0x1003: "INVALID_PARAM", + 0x1004: "RESOURCES", + 0x1005: "HARDWARE_ACCESS_ERROR", + 0x1006: "REQUESTOR_NOT_REGISTERED", + 0x1007: "NETWORK_ERROR", + 0x1008: "PARAM_BUFFER_TOO_SHORT", + 0x1009: "COM_NOT_INITIALIZED_IN_THREAD", + 0x100A: "URL_REQUIRED" + } + + // + // Methods used for getting the event log + // + + obj.GetMessageLog = function (func, tag) { + obj.AMT_MessageLog_PositionToFirstRecord(_GetMessageLog0, [func, tag, []]); + } + function _GetMessageLog0(stack, name, responses, status, tag) { + if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; } + obj.AMT_MessageLog_GetRecords(responses.Body["IterationIdentifier"], 390, _GetMessageLog1, tag); + } + function _GetMessageLog1(stack, name, responses, status, tag) { + if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; } + var i, j, x, e, AmtMessages = tag[2], t = new Date(), TimeStamp, ra = responses.Body["RecordArray"]; + if (typeof ra === 'string') { responses.Body["RecordArray"] = [responses.Body["RecordArray"]]; } + + for (i in ra) { + e = Buffer.from(ra[i], 'base64'); + if (e != null) { + TimeStamp = ReadIntX(e, 0); + if ((TimeStamp > 0) && (TimeStamp < 0xFFFFFFFF)) { + x = { 'DeviceAddress': e[4], 'EventSensorType': e[5], 'EventType': e[6], 'EventOffset': e[7], 'EventSourceType': e[8], 'EventSeverity': e[9], 'SensorNumber': e[10], 'Entity': e[11], 'EntityInstance': e[12], 'EventData': [], 'Time': new Date((TimeStamp + (t.getTimezoneOffset() * 60)) * 1000) }; + for (j = 13; j < 21; j++) { x['EventData'].push(e[j]); } + x['EntityStr'] = _SystemEntityTypes[x['Entity']]; + x['Desc'] = _GetEventDetailStr(x['EventSensorType'], x['EventOffset'], x['EventData'], x['Entity']); + if (!x['EntityStr']) x['EntityStr'] = "Unknown"; + AmtMessages.push(x); + } + } + } + + if (responses.Body["NoMoreRecords"] != true) { obj.AMT_MessageLog_GetRecords(responses.Body["IterationIdentifier"], 390, _GetMessageLog1, [tag[0], AmtMessages, tag[2]]); } else { tag[0](obj, AmtMessages, tag[2]); } + } + + var _EventTrapSourceTypes = "Platform firmware (e.g. BIOS)|SMI handler|ISV system management software|Alert ASIC|IPMI|BIOS vendor|System board set vendor|System integrator|Third party add-in|OSV|NIC|System management card".split('|'); + var _SystemFirmwareError = "Unspecified.|No system memory is physically installed in the system.|No usable system memory, all installed memory has experienced an unrecoverable failure.|Unrecoverable hard-disk/ATAPI/IDE device failure.|Unrecoverable system-board failure.|Unrecoverable diskette subsystem failure.|Unrecoverable hard-disk controller failure.|Unrecoverable PS/2 or USB keyboard failure.|Removable boot media not found.|Unrecoverable video controller failure.|No video device detected.|Firmware (BIOS) ROM corruption detected.|CPU voltage mismatch (processors that share same supply have mismatched voltage requirements)|CPU speed matching failure".split('|'); + var _SystemFirmwareProgress = "Unspecified.|Memory initialization.|Starting hard-disk initialization and test|Secondary processor(s) initialization|User authentication|User-initiated system setup|USB resource configuration|PCI resource configuration|Option ROM initialization|Video initialization|Cache initialization|SM Bus initialization|Keyboard controller initialization|Embedded controller/management controller initialization|Docking station attachment|Enabling docking station|Docking station ejection|Disabling docking station|Calling operating system wake-up vector|Starting operating system boot process|Baseboard or motherboard initialization|reserved|Floppy initialization|Keyboard test|Pointing device test|Primary processor initialization".split('|'); + var _SystemEntityTypes = "Unspecified|Other|Unknown|Processor|Disk|Peripheral|System management module|System board|Memory module|Processor module|Power supply|Add in card|Front panel board|Back panel board|Power system board|Drive backplane|System internal expansion board|Other system board|Processor board|Power unit|Power module|Power management board|Chassis back panel board|System chassis|Sub chassis|Other chassis board|Disk drive bay|Peripheral bay|Device bay|Fan cooling|Cooling unit|Cable interconnect|Memory device|System management software|BIOS|Intel(r) ME|System bus|Group|Intel(r) ME|External environment|Battery|Processing blade|Connectivity switch|Processor/memory module|I/O module|Processor I/O module|Management controller firmware|IPMI channel|PCI bus|PCI express bus|SCSI bus|SATA/SAS bus|Processor front side bus".split('|'); + obj.RealmNames = "||Redirection|PT Administration|Hardware Asset|Remote Control|Storage|Event Manager|Storage Admin|Agent Presence Local|Agent Presence Remote|Circuit Breaker|Network Time|General Information|Firmware Update|EIT|LocalUN|Endpoint Access Control|Endpoint Access Control Admin|Event Log Reader|Audit Log|ACL Realm|||Local System".split('|'); + obj.WatchdogCurrentStates = { 1: 'Not Started', 2: 'Stopped', 4: 'Running', 8: 'Expired', 16: 'Suspended' }; + + function _GetEventDetailStr(eventSensorType, eventOffset, eventDataField, entity) { + + if (eventSensorType == 15) + { + if (eventDataField[0] == 235) return "Invalid Data"; + if (eventOffset == 0) return _SystemFirmwareError[eventDataField[1]]; + return _SystemFirmwareProgress[eventDataField[1]]; + } + + if (eventSensorType == 18 && eventDataField[0] == 170) // System watchdog event + { + return "Agent watchdog " + char2hex(eventDataField[4]) + char2hex(eventDataField[3]) + char2hex(eventDataField[2]) + char2hex(eventDataField[1]) + "-" + char2hex(eventDataField[6]) + char2hex(eventDataField[5]) + "-... changed to " + obj.WatchdogCurrentStates[eventDataField[7]]; + } + + //if (eventSensorType == 5 && eventOffset == 0) // System chassis + //{ + // return "Case intrusion"; + //} + + //if (eventSensorType == 192 && eventOffset == 0 && eventDataField[0] == 170 && eventDataField[1] == 48) + //{ + // if (eventDataField[2] == 0) return "A remote Serial Over LAN session was established."; + // if (eventDataField[2] == 1) return "Remote Serial Over LAN session finished. User control was restored."; + // if (eventDataField[2] == 2) return "A remote IDE-Redirection session was established."; + // if (eventDataField[2] == 3) return "Remote IDE-Redirection session finished. User control was restored."; + //} + + //if (eventSensorType == 36) + //{ + // long handle = ((long)(eventDataField[1]) << 24) + ((long)(eventDataField[2]) << 16) + ((long)(eventDataField[3]) << 8) + (long)(eventDataField[4]); + // string nic = string.Format("#{0}", eventDataField[0]); + // if (eventDataField[0] == 0xAA) nic = "wired"; // TODO: Add wireless ***** + // //if (eventDataField[0] == 0xAA) nic = "wireless"; + + // if (handle == 4294967293) { return string.Format("All received packet filter was matched on {0} interface.", nic); } + // if (handle == 4294967292) { return string.Format("All outbound packet filter was matched on {0} interface.", nic); } + // if (handle == 4294967290) { return string.Format("Spoofed packet filter was matched on {0} interface.", nic); } + // return string.Format("Filter {0} was matched on {1} interface.", handle, nic); + //} + + //if (eventSensorType == 192) + //{ + // if (eventDataField[2] == 0) return "Security policy invoked. Some or all network traffic (TX) was stopped."; + // if (eventDataField[2] == 2) return "Security policy invoked. Some or all network traffic (RX) was stopped."; + // return "Security policy invoked."; + //} + + //if (eventSensorType == 193) + //{ + // if (eventDataField[0] == 0xAA && eventDataField[1] == 0x30 && eventDataField[2] == 0x00 && eventDataField[3] == 0x00) { return "User request for remote connection."; } + // if (eventDataField[0] == 0xAA && eventDataField[1] == 0x20 && eventDataField[2] == 0x03 && eventDataField[3] == 0x01) { return "EAC error: attempt to get posture while NAC in Intel(r) AMT is disabled."; // eventDataField = 0xAA20030100000000 } + // if (eventDataField[0] == 0xAA && eventDataField[1] == 0x20 && eventDataField[2] == 0x04 && eventDataField[3] == 0x00) { return "Certificate revoked. "; } + //} + + if (eventSensorType == 6) return "Authentication failed " + (eventDataField[1] + (eventDataField[2] << 8)) + " times. The system may be under attack."; + if (eventSensorType == 30) return "No bootable media"; + if (eventSensorType == 32) return "Operating system lockup or power interrupt"; + if (eventSensorType == 35) return "System boot failure"; + if (eventSensorType == 37) return "System firmware started (at least one CPU is properly executing)."; + return "Unknown Sensor Type #" + eventSensorType; + } + +// ###BEGIN###{AuditLog} + + // Useful link: https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Fsecurityadminevents.htm + + var _AmtAuditStringTable = + { + 16: 'Security Admin', + 17: 'RCO', + 18: 'Redirection Manager', + 19: 'Firmware Update Manager', + 20: 'Security Audit Log', + 21: 'Network Time', + 22: 'Network Administration', + 23: 'Storage Administration', + 24: 'Event Manager', + 25: 'Circuit Breaker Manager', + 26: 'Agent Presence Manager', + 27: 'Wireless Configuration', + 28: 'EAC', + 29: 'KVM', + 30: 'User Opt-In Events', + 32: 'Screen Blanking', + 33: 'Watchdog Events', + 1600: 'Provisioning Started', + 1601: 'Provisioning Completed', + 1602: 'ACL Entry Added', + 1603: 'ACL Entry Modified', + 1604: 'ACL Entry Removed', + 1605: 'ACL Access with Invalid Credentials', + 1606: 'ACL Entry State', + 1607: 'TLS State Changed', + 1608: 'TLS Server Certificate Set', + 1609: 'TLS Server Certificate Remove', + 1610: 'TLS Trusted Root Certificate Added', + 1611: 'TLS Trusted Root Certificate Removed', + 1612: 'TLS Preshared Key Set', + 1613: 'Kerberos Settings Modified', + 1614: 'Kerberos Master Key Modified', + 1615: 'Flash Wear out Counters Reset', + 1616: 'Power Package Modified', + 1617: 'Set Realm Authentication Mode', + 1618: 'Upgrade Client to Admin Control Mode', + 1619: 'Unprovisioning Started', + 1700: 'Performed Power Up', + 1701: 'Performed Power Down', + 1702: 'Performed Power Cycle', + 1703: 'Performed Reset', + 1704: 'Set Boot Options', + 1800: 'IDER Session Opened', + 1801: 'IDER Session Closed', + 1802: 'IDER Enabled', + 1803: 'IDER Disabled', + 1804: 'SoL Session Opened', + 1805: 'SoL Session Closed', + 1806: 'SoL Enabled', + 1807: 'SoL Disabled', + 1808: 'KVM Session Started', + 1809: 'KVM Session Ended', + 1810: 'KVM Enabled', + 1811: 'KVM Disabled', + 1812: 'VNC Password Failed 3 Times', + 1900: 'Firmware Updated', + 1901: 'Firmware Update Failed', + 2000: 'Security Audit Log Cleared', + 2001: 'Security Audit Policy Modified', + 2002: 'Security Audit Log Disabled', + 2003: 'Security Audit Log Enabled', + 2004: 'Security Audit Log Exported', + 2005: 'Security Audit Log Recovered', + 2100: 'Intel(R) ME Time Set', + 2200: 'TCPIP Parameters Set', + 2201: 'Host Name Set', + 2202: 'Domain Name Set', + 2203: 'VLAN Parameters Set', + 2204: 'Link Policy Set', + 2205: 'IPv6 Parameters Set', + 2300: 'Global Storage Attributes Set', + 2301: 'Storage EACL Modified', + 2302: 'Storage FPACL Modified', + 2303: 'Storage Write Operation', + 2400: 'Alert Subscribed', + 2401: 'Alert Unsubscribed', + 2402: 'Event Log Cleared', + 2403: 'Event Log Frozen', + 2500: 'CB Filter Added', + 2501: 'CB Filter Removed', + 2502: 'CB Policy Added', + 2503: 'CB Policy Removed', + 2504: 'CB Default Policy Set', + 2505: 'CB Heuristics Option Set', + 2506: 'CB Heuristics State Cleared', + 2600: 'Agent Watchdog Added', + 2601: 'Agent Watchdog Removed', + 2602: 'Agent Watchdog Action Set', + 2700: 'Wireless Profile Added', + 2701: 'Wireless Profile Removed', + 2702: 'Wireless Profile Updated', + 2800: 'EAC Posture Signer SET', + 2801: 'EAC Enabled', + 2802: 'EAC Disabled', + 2803: 'EAC Posture State', + 2804: 'EAC Set Options', + 2900: 'KVM Opt-in Enabled', + 2901: 'KVM Opt-in Disabled', + 2902: 'KVM Password Changed', + 2903: 'KVM Consent Succeeded', + 2904: 'KVM Consent Failed', + 3000: 'Opt-In Policy Change', + 3001: 'Send Consent Code Event', + 3002: 'Start Opt-In Blocked Event' + } + + // Return human readable extended audit log data + // TODO: Just put some of them here, but many more still need to be added, helpful link here: + // https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Fsecurityadminevents.htm + obj.GetAuditLogExtendedDataStr = function (id, data) { + if ((id == 1602 || id == 1604) && data[0] == 0) { return bufToArray(data).splice(2, 2 + data[1]).toString(); } // ACL Entry Added/Removed (Digest) + if (id == 1603) { if (data[1] == 0) { return bufToArray(data).splice(3).toString(); } return null; } // ACL Entry Modified + if (id == 1605) { return ["Invalid ME access", "Invalid MEBx access"][data[0]]; } // ACL Access with Invalid Credentials + if (id == 1606) { var r = ["Disabled", "Enabled"][data[0]]; if (data[1] == 0) { r += ", " + data[3]; } return r; } // ACL Entry State + if (id == 1607) { return "Remote " + ["NoAuth", "ServerAuth", "MutualAuth"][data[0]] + ", Local " + ["NoAuth", "ServerAuth", "MutualAuth"][data[1]]; } // TLS State Changed + if (id == 1617) { return obj.RealmNames[ReadInt(data, 0)] + ", " + ["NoAuth", "Auth", "Disabled"][data[4]]; } // Set Realm Authentication Mode + if (id == 1619) { return ["BIOS", "MEBx", "Local MEI", "Local WSMAN", "Remote WSAMN"][data[0]]; } // Intel AMT Unprovisioning Started + if (id == 1900) { return "From " + ReadShort(data, 0) + "." + ReadShort(data, 2) + "." + ReadShort(data, 4) + "." + ReadShort(data, 6) + " to " + ReadShort(data, 8) + "." + ReadShort(data, 10) + "." + ReadShort(data, 12) + "." + ReadShort(data, 14); } // Firmware Updated + if (id == 2100) { var t4 = new Date(); t4.setTime(ReadInt(data, 0) * 1000 + (new Date().getTimezoneOffset() * 60000)); return t4.toLocaleString(); } // Intel AMT Time Set + if (id == 3000) { return "From " + ["None", "KVM", "All"][data[0]] + " to " + ["None", "KVM", "All"][data[1]]; } // Opt-In Policy Change + if (id == 3001) { return ["Success", "Failed 3 times"][data[0]]; } // Send Consent Code Event + return null; + } + + obj.GetAuditLog = function (func) { + obj.AMT_AuditLog_ReadRecords(1, _GetAuditLog0, [func, []]); + } + + function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; } + function ReadShort(v, p) { return (v[p] << 8) + v[p + 1]; } + function ReadInt(v, p) { return (v[p] * 0x1000000) + (v[p + 1] << 16) + (v[p + 2] << 8) + v[p + 3]; } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32. + function ReadIntX(v, p) { return (v[p + 3] * 0x1000000) + (v[p + 2] << 16) + (v[p + 1] << 8) + v[p]; } + function btoa(x) { return Buffer.from(x).toString('base64'); } + function atob(x) { var z = null; try { z = Buffer.from(x, 'base64').toString(); } catch (e) { console.log(e); } return z; } + function bufToArray(buf) { var r = []; for (var i in buf) { r.push(buf[i]); } return r; } + + function _GetAuditLog0(stack, name, responses, status, tag) { + if (status != 200) { tag[0](obj, [], status); return; } + var ptr, i, e, es, x, r = tag[1], t = new Date(), TimeStamp; + + if (responses.Body['RecordsReturned'] > 0) { + responses.Body['EventRecords'] = MakeToArray(responses.Body['EventRecords']); + + for (i in responses.Body['EventRecords']) { + e = null; + try { + es = atob(responses.Body['EventRecords'][i]); + e = new Buffer(es); + } catch (ex) { + console.log(ex + " " + responses.Body['EventRecords'][i]) + } + + x = { 'AuditAppID': ReadShort(e, 0), 'EventID': ReadShort(e, 2), 'InitiatorType': e[4] }; + x['AuditApp'] = _AmtAuditStringTable[x['AuditAppID']]; + x['Event'] = _AmtAuditStringTable[(x['AuditAppID'] * 100) + x['EventID']]; + if (!x['Event']) x['Event'] = '#' + x['EventID']; + + // Read and process the initiator + if (x['InitiatorType'] == 0) { + // HTTP digest + var userlen = e[5]; + x['Initiator'] = e.slice(6, 6 + userlen).toString(); + ptr = 6 + userlen; + } + if (x['InitiatorType'] == 1) { + // Kerberos + x['KerberosUserInDomain'] = ReadInt(e, 5); + var userlen = e[9]; + x['Initiator'] = GetSidString(e.slice(10, 10 + userlen)); + ptr = 10 + userlen; + } + if (x['InitiatorType'] == 2) { + // Local + x['Initiator'] = 'Local'; + ptr = 5; + } + if (x['InitiatorType'] == 3) { + // KVM Default Port + x['Initiator'] = 'KVM Default Port'; + ptr = 5; + } + + // Read timestamp + TimeStamp = ReadInt(e, ptr); + x['Time'] = new Date((TimeStamp + (t.getTimezoneOffset() * 60)) * 1000); + ptr += 4; + + // Read network access + x['MCLocationType'] = e[ptr++]; + var netlen = e[ptr++]; + + x['NetAddress'] = e.slice(ptr, ptr + netlen).toString(); + + // Read extended data + ptr += netlen; + var exlen = e[ptr++]; + x['Ex'] = e.slice(ptr, ptr + exlen); + x['ExStr'] = obj.GetAuditLogExtendedDataStr((x['AuditAppID'] * 100) + x['EventID'], x['Ex']); + r.push(x); + } + } + if (responses.Body['TotalRecordCount'] > r.length) { + obj.AMT_AuditLog_ReadRecords(r.length + 1, _GetAuditLog0, [tag[0], r]); + } else { + tag[0](obj, r, status); + } + } + + // ###END###{AuditLog} + + /* + // ###BEGIN###{Certificates} + + // Forge MD5 + function hex_md5(str) { return forge.md.md5.create().update(str).digest().toHex(); } + + // ###END###{Certificates} + + // ###BEGIN###{!Certificates} + + // TinyMD5 from https://github.com/jbt/js-crypto + + // Perform MD5 setup + var md5_k = []; + for (var i = 0; i < 64;) { md5_k[i] = 0 | (Math.abs(Math.sin(++i)) * 4294967296); } + + // Perform MD5 on raw string and return hex + function hex_md5(str) { + var b, c, d, j, + x = [], + str2 = unescape(encodeURI(str)), + a = str2.length, + h = [b = 1732584193, c = -271733879, ~b, ~c], + i = 0; + + for (; i <= a;) x[i >> 2] |= (str2.charCodeAt(i) || 128) << 8 * (i++ % 4); + + x[str = (a + 8 >> 6) * 16 + 14] = a * 8; + i = 0; + + for (; i < str; i += 16) { + a = h; j = 0; + for (; j < 64;) { + a = [ + d = a[3], + ((b = a[1] | 0) + + ((d = ( + (a[0] + + [ + b & (c = a[2]) | ~b & d, + d & b | ~d & c, + b ^ c ^ d, + c ^ (b | ~d) + ][a = j >> 4] + ) + + (md5_k[j] + + (x[[ + j, + 5 * j + 1, + 3 * j + 5, + 7 * j + ][a] % 16 + i] | 0) + ) + )) << (a = [ + 7, 12, 17, 22, + 5, 9, 14, 20, + 4, 11, 16, 23, + 6, 10, 15, 21 + ][4 * a + j++ % 4]) | d >>> 32 - a) + ), + b, + c + ]; + } + for (j = 4; j;) h[--j] = h[j] + a[j]; + } + + str = ''; + for (; j < 32;) str += ((h[j >> 3] >> ((1 ^ j++ & 7) * 4)) & 15).toString(16); + return str; + } + + // ###END###{!Certificates} + + // Perform MD5 on raw string and return raw string result + function rstr_md5(str) { return hex2rstr(hex_md5(str)); } + */ + /* + Convert arguments into selector set and body XML. Used by AMT_WiFiPortConfigurationService_UpdateWiFiSettings. + args = { + "WiFiEndpoint": { + __parameterType: 'reference', + __resourceUri: 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpoint', + Name: 'WiFi Endpoint 0' + }, + "WiFiEndpointSettingsInput": + { + __parameterType: 'instance', + __namespace: 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpointSettings', + ElementName: document.querySelector('#editProfile-profileName').value, + InstanceID: 'Intel(r) AMT:WiFi Endpoint Settings ' + document.querySelector('#editProfile-profileName').value, + AuthenticationMethod: document.querySelector('#editProfile-networkAuthentication').value, + //BSSType: 3, // Intel(r) AMT supports only infrastructure networks + EncryptionMethod: document.querySelector('#editProfile-encryption').value, + SSID: document.querySelector('#editProfile-networkName').value, + Priority: 100, + PSKPassPhrase: document.querySelector('#editProfile-passPhrase').value + }, + "IEEE8021xSettingsInput": null, + "ClientCredential": null, + "CACredential": null + }, + */ + function execArgumentsToXml(args) { + if (args === undefined || args === null) return null; + + var result = ''; + for (var argName in args) { + var arg = args[argName]; + if (!arg) continue; + if (arg['__parameterType'] === 'reference') result += referenceToXml(argName, arg); + else result += instanceToXml(argName, arg); + //if(arg['__isInstance']) result += instanceToXml(argName, arg); + } + return result; + } + + /** + * Convert JavaScript object into XML + + + Wireless-Profile-Admin + Intel(r) AMT:WiFi Endpoint Settings Wireless-Profile-Admin + 6 + 4 + 100 + P@ssw0rd + + */ + function instanceToXml(instanceName, inInstance) { + if (inInstance === undefined || inInstance === null) return null; + + var hasNamespace = !!inInstance['__namespace']; + var startTag = hasNamespace ? ''; + for (var prop in inInstance) { + if (!inInstance.hasOwnProperty(prop) || prop.indexOf('__') === 0) continue; + + if (typeof inInstance[prop] === 'function' || Array.isArray(inInstance[prop])) continue; + + if (typeof inInstance[prop] === 'object') { + //result += startTag + prop +'>' + instanceToXml('prop', inInstance[prop]) + endTag + prop +'>'; + console.error('only convert one level down...'); + } + else { + result += startTag + prop + '>' + inInstance[prop].toString() + endTag + prop + '>'; + } + } + result += ''; + return result; + } + + + /** + * Convert a selector set into XML. Expect no nesting. + * { + * selectorName : selectorValue, + * selectorName : selectorValue, + * ... ... + * } + + + http://192.168.1.103:16992/wsman + + http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpoint + + WiFi Endpoint 0 + + + + + */ + function referenceToXml(referenceName, inReference) { + if (inReference === undefined || inReference === null) return null; + + var result = '/wsman' + inReference['__resourceUri'] + ''; + for (var selectorName in inReference) { + if (!inReference.hasOwnProperty(selectorName) || selectorName.indexOf('__') === 0) continue; + + if (typeof inReference[selectorName] === 'function' || + typeof inReference[selectorName] === 'object' || + Array.isArray(inReference[selectorName])) + continue; + + result += '' + inReference[selectorName].toString() + ''; + } + + result += ''; + return result; + } + + // Convert a byte array of SID into string + function GetSidString(sid) { + var r = "S-" + sid.charCodeAt(0) + "-" + sid.charCodeAt(7); + for (var i = 2; i < (sid.length / 4) ; i++) r += "-" + ReadIntX(sid, i * 4); + return r; + } + + // Convert a SID readable string into bytes + function GetSidByteArray(sidString) { + if (!sidString || sidString == null) return null; + var sidParts = sidString.split('-'); + + // Make sure the SID has at least 4 parts and starts with 'S' + if (sidParts.length < 4 || (sidParts[0] != 's' && sidParts[0] != 'S')) return null; + + // Check that each part of the SID is really an integer + for (var i = 1; i < sidParts.length; i++) { var y = parseInt(sidParts[i]); if (y != sidParts[i]) return null; sidParts[i] = y; } + + // Version (8 bit) + Id count (8 bit) + 48 bit in big endian -- DO NOT use bitwise right shift operator. JavaScript converts the number into a 32 bit integer before shifting. In real world, it's highly likely this part is always 0. + var r = String.fromCharCode(sidParts[1]) + String.fromCharCode(sidParts.length - 3) + ShortToStr(Math.floor(sidParts[2] / Math.pow(2, 32))) + IntToStr((sidParts[2]) & 0xFFFF); + + // the rest are in 32 bit in little endian + for (var i = 3; i < sidParts.length; i++) r += IntToStrX(sidParts[i]); + return r; + } + + return obj; +} + +module.exports = AmtStackCreateService; diff --git a/agents/modules_meshcore_backup/meshcore.js b/agents/modules_meshcore_backup/meshcore.js new file mode 100644 index 00000000..364c8305 --- /dev/null +++ b/agents/modules_meshcore_backup/meshcore.js @@ -0,0 +1,1658 @@ +/* +Copyright 2018 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. +*/ + +function createMeshCore(agent) { + var obj = {}; + + // MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent. + obj.meshCoreInfo = "MeshCore v5"; + obj.meshCoreCapabilities = 14; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript + var meshServerConnectionState = 0; + var tunnels = {}; + var lastSelfInfo = null; + var lastNetworkInfo = null; + var lastPublicLocationInfo = null; + var selfInfoUpdateTimer = null; + var http = require('http'); + var net = require('net'); + var fs = require('fs'); + var rtc = require('ILibWebRTC'); + var processManager = require('process-manager'); + var SMBiosTables = require('smbios'); + var amtMei = null, amtLms = null, amtLmsState = 0; + var amtMeiConnected = 0, amtMeiTmpState = null; + var wifiScannerLib = null; + var wifiScanner = null; + var networkMonitor = null; + var amtscanner = null; + var nextTunnelIndex = 1; + + /* + var AMTScanner = require("AMTScanner"); + var scan = new AMTScanner(); + + scan.on("found", function (data) { + if (typeof data === 'string') { + console.log(data); + } else { + console.log(JSON.stringify(data, null, " ")); + } + }); + scan.scan("10.2.55.140", 1000); + scan.scan("10.2.55.139-10.2.55.145", 1000); + scan.scan("10.2.55.128/25", 2000); + */ + + /* + // Try to load up the network monitor + try { + networkMonitor = require('NetworkMonitor'); + networkMonitor.on('change', function () { sendNetworkUpdateNagle(); }); + networkMonitor.on('add', function (addr) { sendNetworkUpdateNagle(); }); + networkMonitor.on('remove', function (addr) { sendNetworkUpdateNagle(); }); + } catch (e) { networkMonitor = null; } + */ + + // Try to load up the Intel AMT scanner + try { + var AMTScannerModule = require('amt-scanner'); + amtscanner = new AMTScannerModule(); + //amtscanner.on('found', function (data) { if (typeof data != 'string') { data = JSON.stringify(data, null, " "); } sendConsoleText(data); }); + } catch (e) { amtscanner = null; } + + // Try to load up the MEI module + try { + var amtMeiLib = require('amt-mei'); + amtMei = new amtMeiLib(); + amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; 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 + try { + var wifiScannerLib = require('wifi-scanner'); + wifiScanner = new wifiScannerLib(); + wifiScanner.on('accessPoint', function (data) { sendConsoleText(JSON.stringify(data)); }); + } catch (e) { wifiScannerLib = null; wifiScanner = null; } + + // If we are running in Duktape, agent will be null + if (agent == null) { + // Running in native agent, Import libraries + db = require('SimpleDataStore').Shared(); + sha = require('SHA256Stream'); + mesh = require('MeshAgent'); + childProcess = require('child_process'); + if (mesh.hasKVM == 1) { obj.meshCoreCapabilities |= 1; } + } else { + // Running in nodejs + obj.meshCoreInfo += '-NodeJS'; + obj.meshCoreCapabilities = 8; + mesh = agent.getMeshApi(); + } + + // Get our location (lat/long) using our public IP address + var getIpLocationDataExInProgress = false; + var getIpLocationDataExCounts = [0, 0]; + function getIpLocationDataEx(func) { + if (getIpLocationDataExInProgress == true) { return false; } + try { + getIpLocationDataExInProgress = true; + getIpLocationDataExCounts[0]++; + var options = http.parseUri("http://ipinfo.io/json"); + options.method = 'GET'; + http.request(options, function (resp) { + if (resp.statusCode == 200) { + var geoData = ''; + resp.data = function (geoipdata) { geoData += geoipdata; }; + resp.end = function () { + var location = null; + try { + if (typeof geoData == 'string') { + var result = JSON.parse(geoData); + if (result.ip && result.loc) { location = result; } + } + } catch (e) { } + if (func) { getIpLocationDataExCounts[1]++; func(location); } + } + } else { func(null); } + getIpLocationDataExInProgress = false; + }).end(); + return true; + } + catch (e) { return false; } + } + + // Remove all Gateway MAC addresses for interface list. This is useful because the gateway MAC is not always populated reliably. + function clearGatewayMac(str) { + if (str == null) return null; + var x = JSON.parse(str); + for (var i in x.netif) { if (x.netif[i].gatewaymac) { delete x.netif[i].gatewaymac } } + return JSON.stringify(x); + } + + function getIpLocationData(func) { + // Get the location information for the cache if possible + var publicLocationInfo = db.Get('publicLocationInfo'); + if (publicLocationInfo != null) { publicLocationInfo = JSON.parse(publicLocationInfo); } + if (publicLocationInfo == null) { + // Nothing in the cache, fetch the data + getIpLocationDataEx(function (locationData) { + if (locationData != null) { + publicLocationInfo = {}; + publicLocationInfo.netInfoStr = lastNetworkInfo; + publicLocationInfo.locationData = locationData; + var x = db.Put('publicLocationInfo', JSON.stringify(publicLocationInfo)); // Save to database + if (func) func(locationData); // Report the new location + } else { + if (func) func(null); // Report no location + } + }); + } else { + // Check the cache + if (clearGatewayMac(publicLocationInfo.netInfoStr) == clearGatewayMac(lastNetworkInfo)) { + // Cache match + if (func) func(publicLocationInfo.locationData); + } else { + // Cache mismatch + getIpLocationDataEx(function (locationData) { + if (locationData != null) { + publicLocationInfo = {}; + publicLocationInfo.netInfoStr = lastNetworkInfo; + publicLocationInfo.locationData = locationData; + var x = db.Put('publicLocationInfo', JSON.stringify(publicLocationInfo)); // Save to database + if (func) func(locationData); // Report the new location + } else { + if (func) func(publicLocationInfo.locationData); // Can't get new location, report the old location + } + }); + } + } + } + + // Polyfill String.endsWith + if (!String.prototype.endsWith) { + String.prototype.endsWith = function (searchString, position) { + var subjectString = this.toString(); + if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { position = subjectString.length; } + position -= searchString.length; + var lastIndex = subjectString.lastIndexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; + }; + } + + // Polyfill path.join + obj.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('/'); + } + }; + + // Replace a string with a number if the string is an exact number + function toNumberIfNumber(x) { if ((typeof x == 'string') && (+parseInt(x) === x)) { x = parseInt(x); } return x; } + + // Convert decimal to hex + function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); } + + // Convert a raw string to a hex string + function rstr2hex(input) { var r = '', i; for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); } return r; } + + // Convert a buffer into a string + function buf2rstr(buf) { var r = ''; for (var i = 0; i < buf.length; i++) { r += String.fromCharCode(buf[i]); } return r; } + + // Convert a hex string to a raw string // TODO: Do this using Buffer(), will be MUCH faster + function hex2rstr(d) { + if (typeof d != "string" || d.length == 0) return ''; + var r = '', m = ('' + d).match(/../g), t; + while (t = m.shift()) r += String.fromCharCode('0x' + t); + return r + } + + // Convert an object to string with all functions + function objToString(x, p, pad, 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 + '"'; } + 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, pad) + i + ': ' + objToString(x[i], p + 2, pad, ret) + (ret ? '\r\n' : ' ')); } } + return r + addPad(p, pad) + '}'; + } + + // Return p number of spaces + function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ret; } return r; } + + // Split a string taking into account the quoats. Used for command line parsing + function splitArgs(str) { + var myArray = [], myRegexp = /[^\s"]+|"([^"]*)"/gi; + do { var match = myRegexp.exec(str); if (match != null) { myArray.push(match[1] ? match[1] : match[0]); } } while (match != null); + return myArray; + } + + // Parse arguments string array into an object + function parseArgs(argv) { + var results = { '_': [] }, current = null; + for (var i = 1, len = argv.length; i < len; i++) { + var x = argv[i]; + if (x.length > 2 && x[0] == '-' && x[1] == '-') { + if (current != null) { results[current] = true; } + current = x.substring(2); + } else { + if (current != null) { results[current] = toNumberIfNumber(x); current = null; } else { results['_'].push(toNumberIfNumber(x)); } + } + } + if (current != null) { results[current] = true; } + return results; + } + + // Get server target url with a custom path + function getServerTargetUrl(path) { + var x = mesh.ServerUrl; + //sendConsoleText("mesh.ServerUrl: " + mesh.ServerUrl); + if (x == null) { return null; } + if (path == null) { path = ''; } + x = http.parseUri(x); + if (x == null) return null; + return x.protocol + '//' + x.host + ':' + x.port + '/' + path; + } + + // Get server url. If the url starts with "*/..." change it, it not use the url as is. + function getServerTargetUrlEx(url) { + if (url.substring(0, 2) == '*/') { return getServerTargetUrl(url.substring(2)); } + return url; + } + + // Send a wake-on-lan packet + function sendWakeOnLan(hexMac) { + var count = 0; + try { + var interfaces = require('os').networkInterfaces(); + var magic = 'FFFFFFFFFFFF'; + for (var x = 1; x <= 16; ++x) { magic += hexMac; } + var magicbin = Buffer.from(magic, 'hex'); + + for (var adapter in interfaces) { + if (interfaces.hasOwnProperty(adapter)) { + for (var i = 0; i < interfaces[adapter].length; ++i) { + var addr = interfaces[adapter][i]; + if ((addr.family == 'IPv4') && (addr.mac != '00:00:00:00:00:00')) { + var socket = require('dgram').createSocket({ type: "udp4" }); + socket.bind({ address: addr.address }); + socket.setBroadcast(true); + socket.send(magicbin, 7, "255.255.255.255"); + count++; + } + } + } + } + } catch (e) { } + return count; + } + + // Handle a mesh agent command + function handleServerCommand(data) { + if (typeof data == 'object') { + // If this is a console command, parse it and call the console handler + switch (data.action) { + case 'msg': { + switch (data.type) { + case 'console': { // Process a console command + if (data.value && data.sessionid) { + var args = splitArgs(data.value); + processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid); + } + break; + } + case 'tunnel': { + if (data.value != null) { // Process a new tunnel connection request + // Create a new tunnel object + var xurl = getServerTargetUrlEx(data.value); + if (xurl != null) { + var woptions = http.parseUri(xurl); + woptions.rejectUnauthorized = 0; + //sendConsoleText(JSON.stringify(woptions)); + var tunnel = http.request(woptions); + tunnel.upgrade = onTunnelUpgrade; + tunnel.onerror = function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); } + tunnel.sessionid = data.sessionid; + tunnel.rights = data.rights; + tunnel.state = 0; + tunnel.url = xurl; + tunnel.protocol = 0; + tunnel.tcpaddr = data.tcpaddr; + tunnel.tcpport = data.tcpport; + tunnel.end(); + // Put the tunnel in the tunnels list + var index = nextTunnelIndex++;; + tunnel.index = index; + tunnels[index] = tunnel; + + sendConsoleText('New tunnel connection #' + index + ': ' + tunnel.url + ', rights: ' + tunnel.rights, data.sessionid); + } + } + break; + } + case 'ps': { + if (data.sessionid) { + processManager.getProcesses(function (plist) { mesh.SendCommand({ "action": "msg", "type": "ps", "value": JSON.stringify(plist), "sessionid": data.sessionid }); }); + } + break; + } + case 'pskill': { + //sendConsoleText(JSON.stringify(data)); + try { process.kill(data.value); } catch (e) { sendConsoleText(JSON.stringify(e)); } + break; + } + } + break; + } + case 'wakeonlan': { + // Send wake-on-lan on all interfaces for all MAC addresses in data.macs array. The array is a list of HEX MAC addresses. + sendConsoleText('Server requesting wake-on-lan for: ' + data.macs.join(', ')); + for (var i in data.macs) { sendWakeOnLan(data.macs[i]); } + break; + } + case 'poweraction': { + // Server telling us to execute a power action + if ((mesh.ExecPowerState != undefined) && (data.actiontype)) { + var forced = 0; + if (data.forced == 1) { forced = 1; } + data.actiontype = parseInt(data.actiontype); + sendConsoleText('Performing power action=' + data.actiontype + ', forced=' + forced + '.'); + var r = mesh.ExecPowerState(data.actiontype, forced); + sendConsoleText('ExecPowerState returned code: ' + r); + } + break; + } + case 'iplocation': { + // Update the IP location information of this node. Only do this when requested by the server since we have a limited amount of time we can call this per day + getIpLocationData(function (location) { mesh.SendCommand({ "action": "iplocation", "type": "publicip", "value": location }); }); + break; + } + case 'toast': { + // Display a toast message + if (data.title && data.msg) { require('toaster').Toast(data.title, data.msg); } + break; + } + } + } + } + + // Called when a file changed in the file system + /* + function onFileWatcher(a, b) { + console.log('onFileWatcher', a, b, this.path); + var response = getDirectoryInfo(this.path); + if ((response != undefined) && (response != null)) { this.tunnel.s.write(JSON.stringify(response)); } + } + */ + + // 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. + 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 results = null, xpath = obj.path.join(reqpath, '*'); + //if (process.platform == "win32") { xpath = xpath.split('/').join('\\'); } + 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 = obj.path.join(reqpath, results[i]); + //if (process.platform == "win32") { p = p.split('/').join('\\'); } + 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; + } + + // Tunnel callback operations + function onTunnelUpgrade(response, s, head) { + this.s = s; + s.httprequest = this; + s.end = onTunnelClosed; + s.tunnel = this; + + if (this.tcpport != null) { + // This is a TCP relay connection, pause now and try to connect to the target. + s.pause(); + s.data = onTcpRelayServerTunnelData; + var connectionOptions = { port: parseInt(this.tcpport) }; + if (this.tcpaddr != null) { connectionOptions.host = this.tcpaddr; } else { connectionOptions.host = '127.0.0.1'; } + s.tcprelay = net.createConnection(connectionOptions, onTcpRelayTargetTunnelConnect); + s.tcprelay.peerindex = this.index; + } else { + // This is a normal connect for KVM/Terminal/Files + s.data = onTunnelData; + } + } + + // Called when the TCP relay target is connected + function onTcpRelayTargetTunnelConnect() { + var peerTunnel = tunnels[this.peerindex]; + this.pipe(peerTunnel.s); // Pipe Target --> Server + peerTunnel.s.first = true; + peerTunnel.s.resume(); + } + + // Called when we get data from the server for a TCP relay (We have to skip the first received 'c' and pipe the rest) + function onTcpRelayServerTunnelData(data) { + if (this.first == true) { this.first = false; this.pipe(this.tcprelay); } // Pipe Server --> Target + } + + function onTunnelClosed() { + if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls. + sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid); + delete tunnels[this.httprequest.index]; + + /* + // Close the watcher if required + if (this.httprequest.watcher != undefined) { + //console.log('Closing watcher: ' + this.httprequest.watcher.path); + //this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!! + delete this.httprequest.watcher; + } + */ + + // If there is a upload or download active on this connection, close the file + if (this.httprequest.uploadFile) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; } + if (this.httprequest.downloadFile) { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; } + + // Clean up WebRTC + if (this.webrtc != null) { + if (this.webrtc.rtcchannel) { try { this.webrtc.rtcchannel.close(); } catch (e) { } this.webrtc.rtcchannel.removeAllListeners('data'); this.webrtc.rtcchannel.removeAllListeners('end'); delete this.webrtc.rtcchannel; } + if (this.webrtc.websocket) { delete this.webrtc.websocket; } + try { this.webrtc.close(); } catch (e) { } + this.webrtc.removeAllListeners('connected'); + this.webrtc.removeAllListeners('disconnected'); + this.webrtc.removeAllListeners('dataChannel'); + delete this.webrtc; + } + + // Clean up WebSocket + this.removeAllListeners('data'); + } + function onTunnelSendOk() { sendConsoleText("Tunnel #" + this.index + " SendOK.", this.sessionid); } + function onTunnelData(data) { + //console.log("OnTunnelData"); + //sendConsoleText('OnTunnelData, ' + data.length + ', ' + typeof data + ', ' + data); + + // If this is upload data, save it to file + if (this.httprequest.uploadFile) { + try { fs.writeSync(this.httprequest.uploadFile, data); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror' }))); return; } // Write to the file, if there is a problem, error out. + this.write(new Buffer(JSON.stringify({ action: 'uploadack', reqid: this.httprequest.uploadFileid }))); // Ask for more data + return; + } + /* + // If this is a download, send more of the file + if (this.httprequest.downloadFile) { + var buf = new Buffer(4096); + var len = fs.readSync(this.httprequest.downloadFile, buf, 0, 4096, null); + this.httprequest.downloadFilePtr += len; + if (len > 0) { this.write(buf.slice(0, len)); } else { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; this.end(); } + return; + } + */ + + if (this.httprequest.state == 0) { + // Check if this is a relay connection + if (data == 'c') { this.httprequest.state = 1; sendConsoleText("Tunnel #" + this.httprequest.index + " now active", this.httprequest.sessionid); } + } else { + // Handle tunnel data + if (this.httprequest.protocol == 0) { // 1 = SOL, 2 = KVM, 3 = IDER, 4 = Files, 5 = FileTransfer + // Take a look at the protocol + this.httprequest.protocol = parseInt(data); + if (typeof this.httprequest.protocol != 'number') { this.httprequest.protocol = 0; } + if (this.httprequest.protocol == 1) { + // Remote terminal using native pipes + if (process.platform == "win32") { + this.httprequest.process = childProcess.execFile("%windir%\\system32\\cmd.exe"); + } else { + this.httprequest.process = childProcess.execFile("/bin/sh", ["sh"], { type: childProcess.SpawnTypes.TERM }); + } + this.httprequest.process.tunnel = this; + this.httprequest.process.on('exit', function (ecode, sig) { this.tunnel.end(); }); + this.httprequest.process.stderr.on('data', function (chunk) { this.parent.tunnel.write(chunk); }); + this.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. + this.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. + this.prependListener('end', function () { this.httprequest.process.kill(); }); + this.removeAllListeners('data'); + this.on('data', onTunnelControlData); + //this.write('MeshCore Terminal Hello'); + if (process.platform != 'win32') { this.httprequest.process.stdin.write("stty erase ^H\nalias ls='ls --color=auto'\nclear\n"); } + } else if (this.httprequest.protocol == 2) + { + // Remote desktop using native pipes + this.httprequest.desktop = { state: 0, kvm: mesh.getRemoteDesktopStream(), tunnel: this }; + this.httprequest.desktop.kvm.parent = this.httprequest.desktop; + this.desktop = this.httprequest.desktop; + + // Display a toast message + //require('toaster').Toast('MeshCentral', 'Remote Desktop Control Started.'); + + this.end = function () { + --this.desktop.kvm.connectionCount; + this.unpipe(this.httprequest.desktop.kvm); + this.httprequest.desktop.kvm.unpipe(this); + if (this.desktop.kvm.connectionCount == 0) { + // Display a toast message + //require('toaster').Toast('MeshCentral', 'Remote Desktop Control Ended.'); + this.httprequest.desktop.kvm.end(); + } + }; + if (this.httprequest.desktop.kvm.hasOwnProperty("connectionCount")) { this.httprequest.desktop.kvm.connectionCount++; } else { this.httprequest.desktop.kvm.connectionCount = 1; } + this.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. + this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. + this.removeAllListeners('data'); + this.on('data', onTunnelControlData); + //this.write('MeshCore KVM Hello!1'); + } else if (this.httprequest.protocol == 5) { + // Setup files + // NOP + } + } else if (this.httprequest.protocol == 1) { + // Send data into terminal stdin + //this.write(data); // Echo back the keys (Does not seem to be a good idea) + this.httprequest.process.write(data); + } else if (this.httprequest.protocol == 2) { + // Send data into remote desktop + if (this.httprequest.desktop.state == 0) { + this.write(new Buffer(String.fromCharCode(0x11, 0xFE, 0x00, 0x00, 0x4D, 0x45, 0x53, 0x48, 0x00, 0x00, 0x00, 0x00, 0x02))); + this.httprequest.desktop.state = 1; + } else { + this.httprequest.desktop.write(data); + } + } else if (this.httprequest.protocol == 5) { + // Process files commands + var cmd = null; + try { cmd = JSON.parse(data); } catch (e) { }; + if (cmd == null) { return; } + if ((cmd.ctrlChannel == '102938') || ((cmd.type == 'offer') && (cmd.sdp != null))) { onTunnelControlData(cmd, this); return; } // If this is control data, handle it now. + if (cmd.action == undefined) { return; } + //sendConsoleText('CMD: ' + JSON.stringify(cmd)); + + if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows + //console.log(objToString(cmd, 0, ' ')); + switch (cmd.action) { + 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; } + this.write(new Buffer(JSON.stringify(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 = obj.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 = obj.path.join(cmd.path, cmd.oldname); + var newfullpath = obj.path.join(cmd.path, cmd.newname); + try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); } + break; + } + case 'download': { + // Download a file + var sendNextBlock = 0; + if (cmd.sub == 'start') { // Setup the download + if (this.filedownload != null) { this.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) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; } + if (this.filedownload) { this.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 = new Buffer(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); } + this.write(buf.slice(0, len + 4)); // Write as binary + } + break; + } + /* + case 'download': { + // Packet download of a file, agent to browser + if (cmd.path == undefined) break; + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path; + //console.log('Download: ' + filepath); + try { this.httprequest.downloadFile = fs.openSync(filepath, 'rbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'downloaderror', reqid: cmd.reqid }))); break; } + this.httprequest.downloadFileId = cmd.reqid; + this.httprequest.downloadFilePtr = 0; + if (this.httprequest.downloadFile) { this.write(new Buffer(JSON.stringify({ action: 'downloadstart', reqid: this.httprequest.downloadFileId }))); } + break; + } + case 'download2': { + // Stream download of a file, agent to browser + if (cmd.path == undefined) break; + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path; + try { this.httprequest.downloadFile = fs.createReadStream(filepath, { flags: 'rbN' }); } catch (e) { console.log(e); } + this.httprequest.downloadFile.pipe(this); + this.httprequest.downloadFile.end = function () { } + break; + } + */ + case 'upload': { + // Upload a file, browser to agent + if (this.httprequest.uploadFile != undefined) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; } + if (cmd.path == undefined) break; + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path; + try { this.httprequest.uploadFile = fs.openSync(filepath, 'wbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror', reqid: cmd.reqid }))); break; } + this.httprequest.uploadFileid = cmd.reqid; + if (this.httprequest.uploadFile) { this.write(new Buffer(JSON.stringify({ action: 'uploadstart', reqid: this.httprequest.uploadFileid }))); } + break; + } + case 'copy': { + // Copy a bunch of files from scpath to dspath + for (var i in cmd.names) { + var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.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 = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]); + if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } } + } + break; + } + } + } + //sendConsoleText("Got tunnel #" + this.httprequest.index + " data: " + data, this.httprequest.sessionid); + } + } + + // Called when receiving control data on WebRTC + function onTunnelWebRTCControlData(data) { + if (typeof data != 'string') return; + var obj; + try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON on WebRTC: ' + data); return; } + if (obj.type == 'close') { + //sendConsoleText('Tunnel #' + this.xrtc.websocket.tunnel.index + ' WebRTC control close'); + try { this.close(); } catch (e) { } + try { this.xrtc.close(); } catch (e) { } + } + } + + // Called when receiving control data on websocket + function onTunnelControlData(data, ws) { + var obj; + if (ws == null) { ws = this; } + if (typeof data == 'string') { try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON: ' + data); return; } } + else if (typeof data == 'object') { obj = data; } else { return; } + //sendConsoleText('onTunnelControlData(' + ws.httprequest.protocol + '): ' + JSON.stringify(data)); + //console.log('onTunnelControlData: ' + JSON.stringify(data)); + + if (obj.action) { + switch (obj.action) { + case 'lock': { + // Lock the current user out of the desktop + try { + if (process.platform == 'win32') { + var child = require('child_process'); + child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 }); + } + } catch (e) { } + break; + } + } + return; + } + + if (obj.type == 'close') { + // We received the close on the websocket + //sendConsoleText('Tunnel #' + ws.tunnel.index + ' WebSocket control close'); + try { ws.close(); } catch (e) { } + } else if (obj.type == 'webrtc0') { // Browser indicates we can start WebRTC switch-over. + if (ws.httprequest.protocol == 1) { // Terminal + // This is a terminal data stream, unpipe the terminal now and indicate to the other side that terminal data will no longer be received over WebSocket + ws.httprequest.process.stdout.unpipe(ws); + ws.httprequest.process.stderr.unpipe(ws); + } else if (ws.httprequest.protocol == 2) { // Desktop + // This is a KVM data stream, unpipe the KVM now and indicate to the other side that KVM data will no longer be received over WebSocket + ws.httprequest.desktop.kvm.unpipe(ws); + } else { + // Switch things around so all WebRTC data goes to onTunnelData(). + ws.rtcchannel.httprequest = ws.httprequest; + ws.rtcchannel.removeAllListeners('data'); + ws.rtcchannel.on('data', onTunnelData); + } + ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc1\"}"); // End of data marker + } else if (obj.type == 'webrtc1') { + if (ws.httprequest.protocol == 1) { // Terminal + // Switch the user input from websocket to webrtc at this point. + ws.unpipe(ws.httprequest.process.stdin); + ws.rtcchannel.pipe(ws.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. + ws.resume(); // Resume the websocket to keep receiving control data + } else if (ws.httprequest.protocol == 2) { // Desktop + // Switch the user input from websocket to webrtc at this point. + ws.unpipe(ws.httprequest.desktop.kvm); + try { ws.webrtc.rtcchannel.pipe(ws.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); } catch (e) { sendConsoleText('EX2'); } // 0 = Binary, 1 = Text. + ws.resume(); // Resume the websocket to keep receiving control data + } + ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point. + } else if (obj.type == 'webrtc2') { + // Other side received websocket end of data marker, start sending data on WebRTC channel + if (ws.httprequest.protocol == 1) { // Terminal + ws.httprequest.process.stdout.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. + ws.httprequest.process.stderr.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. + } else if (ws.httprequest.protocol == 2) { // Desktop + ws.httprequest.desktop.kvm.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. + } + } else if (obj.type == 'offer') { + // This is a WebRTC offer. + ws.webrtc = rtc.createConnection(); + ws.webrtc.websocket = ws; + ws.webrtc.on('connected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC connected');*/ }); + ws.webrtc.on('disconnected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC disconnected');*/ }); + ws.webrtc.on('dataChannel', function (rtcchannel) { + //sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol); + rtcchannel.xrtc = this; + rtcchannel.websocket = this.websocket; + this.rtcchannel = rtcchannel; + this.websocket.rtcchannel = rtcchannel; + this.websocket.rtcchannel.on('data', onTunnelWebRTCControlData); + this.websocket.rtcchannel.on('end', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed');*/ }); + this.websocket.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc0\"}"); // Indicate we are ready for WebRTC switch-over. + }); + var sdp = null; + try { sdp = ws.webrtc.setOffer(obj.sdp); } catch (ex) { } + if (sdp != null) { ws.write({ type: 'answer', ctrlChannel: '102938', sdp: sdp }); } + } + } + + // Console state + var consoleWebSockets = {}; + var consoleHttpRequest = null; + + // Console HTTP response + function consoleHttpResponse(response) { + response.data = function (data) { sendConsoleText(rstr2hex(buf2rstr(data)), this.sessionid); consoleHttpRequest = null; } + response.close = function () { sendConsoleText('httprequest.response.close', this.sessionid); consoleHttpRequest = null; } + }; + + // Process a mesh agent console command + function processConsoleCommand(cmd, args, rights, sessionid) { + try { + var response = null; + switch (cmd) { + case 'help': { // Displays available commands + response = 'Available commands: help, info, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock.'; + break; + } + case 'toast': { + if (process.platform == 'win32') { + if (args['_'].length < 1) { response = 'Proper usage: toast "message"'; } else { + require('toaster').Toast('MeshCentral', args['_'][0]); + response = 'ok'; + } + } else { + response = 'Only supported on Windows.'; + } + break; + } + case 'setdebug': { + if (args['_'].length < 1) { response = 'Proper usage: setdebug (target), 0 = StdOut, 1 = This Console, * = All Consoles, 2 = WebLog, 3 = Disabled'; } // Display usage + else { if (args['_'][0] == '*') { console.setDestination(1); } else { console.setDestination(parseInt(args['_'][0]), sessionid); } } + break; + } + case 'ps': { + processManager.getProcesses(function (plist) { + var x = ''; + for (var i in plist) { x += i + ', ' + plist[i].cmd + ((plist[i].user) ? (', ' + plist[i].user):'') + '\r\n'; } + sendConsoleText(x, sessionid); + }); + break; + } + case 'kill': { + if ((args['_'].length < 1)) { + response = 'Proper usage: kill [pid]'; // Display correct command usage + } else { + process.kill(parseInt(args['_'][0])); + response = 'Killed process ' + args['_'][0] + '.'; + } + break; + } + case 'smbios': { + if (SMBiosTables != null) { + SMBiosTables.get(function (data) { + if (data == null) { sendConsoleText('Unable to get SM BIOS data.', sessionid); return; } + sendConsoleText(objToString(SMBiosTables.parse(data), 0, ' ', true), sessionid); + }); + } else { response = 'SM BIOS module not available.'; } + break; + } + case 'rawsmbios': { + if (SMBiosTables != null) { + SMBiosTables.get(function (data) { + if (data == null) { sendConsoleText('Unable to get SM BIOS data.', sessionid); return; } + 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'; + } + } + } + sendConsoleText(out, sessionid); + }); + } else { response = 'SM BIOS module not available.'; } + break; + } + case 'eval': { // Eval JavaScript + if (args['_'].length < 1) { + response = 'Proper usage: eval "JavaScript code"'; // Display correct command usage + } else { + response = JSON.stringify(mesh.eval(args['_'][0])); + } + break; + } + case 'notify': { // Send a notification message to the mesh + if (args['_'].length != 1) { + response = 'Proper usage: notify "message" [--session]'; // Display correct command usage + } else { + var notification = { "action": "msg", "type": "notify", "value": args['_'][0], "tag": "console" }; + if (args.session) { notification.sessionid = sessionid; } // If "--session" is specified, notify only this session, if not, the server will notify the mesh + mesh.SendCommand(notification); // no sessionid or userid specified, notification will go to the entire mesh + response = 'ok'; + } + break; + } + case 'info': { // Return information about the agent and agent core module + response = 'Current Core: ' + obj.meshCoreInfo + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform Info: ' + process.platform + '.\r\nCapabilities: ' + obj.meshCoreCapabilities + '.\r\nServer URL: ' + mesh.ServerUrl + '.'; + if (amtLmsState >= 0) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amtLmsState] + '.'; } + response += '\r\nModules: ' + addedModules.join(', '); + response += '\r\nServerConnected: ' + mesh.isControlChannelConnected; + var oldNodeId = db.Get('OldNodeId'); + if (oldNodeId != null) { response += '\r\nOldNodeID: ' + oldNodeId + '.'; } + response += '\r\ServerState: ' + meshServerConnectionState + '.'; + break; + } + case 'selfinfo': { // Return self information block + buildSelfInfo(function (info) { sendConsoleText(objToString(info, 0, ' ', true), sessionid); }); + break; + } + case 'args': { // Displays parsed command arguments + response = 'args ' + objToString(args, 0, ' ', true); + break; + } + case 'print': { // Print a message on the mesh agent console, does nothing when running in the background + var r = []; + for (var i in args['_']) { r.push(args['_'][i]); } + console.log(r.join(' ')); + response = 'Message printed on agent console.'; + break; + } + case 'type': { // Returns the content of a file + if (args['_'].length == 0) { + response = 'Proper usage: type (filepath) [maxlength]'; // Display correct command usage + } else { + var max = 4096; + if ((args['_'].length > 1) && (typeof args['_'][1] == 'number')) { max = args['_'][1]; } + if (max > 4096) max = 4096; + var buf = new Buffer(max), fd = fs.openSync(args['_'][0], "r"), r = fs.readSync(fd, buf, 0, max); // Read the file content + response = buf.toString(); + var i = response.indexOf('\n'); + if ((i > 0) && (response[i - 1] != '\r')) { response = response.split('\n').join('\r\n'); } + if (r == max) response += '...'; + fs.closeSync(fd); + } + break; + } + case 'dbkeys': { // Return all data store keys + response = JSON.stringify(db.Keys); + break; + } + case 'dbget': { // Return the data store value for a given key + if (db == null) { response = 'Database not accessible.'; break; } + if (args['_'].length != 1) { + response = 'Proper usage: dbget (key)'; // Display the value for a given database key + } else { + response = db.Get(args['_'][0]); + } + break; + } + case 'dbset': { // Set a data store key and value pair + if (db == null) { response = 'Database not accessible.'; break; } + if (args['_'].length != 2) { + response = 'Proper usage: dbset (key) (value)'; // Set a database key + } else { + var r = db.Put(args['_'][0], args['_'][1]); + response = 'Key set: ' + r; + } + break; + } + case 'dbcompact': { // Compact the data store + if (db == null) { response = 'Database not accessible.'; break; } + var r = db.Compact(); + response = 'Database compacted: ' + r; + break; + } + case 'httpget': { + if (consoleHttpRequest != null) { + response = 'HTTP operation already in progress.'; + } else { + if (args['_'].length != 1) { + response = 'Proper usage: httpget (url)'; + } else { + var options = http.parseUri(args['_'][0]); + options.method = 'GET'; + if (options == null) { + response = 'Invalid url.'; + } else { + try { consoleHttpRequest = http.request(options, consoleHttpResponse); } catch (e) { response = 'Invalid HTTP GET request'; } + consoleHttpRequest.sessionid = sessionid; + if (consoleHttpRequest != null) { + consoleHttpRequest.end(); + response = 'HTTPGET ' + options.protocol + '//' + options.host + ':' + options.port + options.path; + } + } + } + } + break; + } + case 'wslist': { // List all web sockets + response = ''; + for (var i in consoleWebSockets) { + var httprequest = consoleWebSockets[i]; + response += 'Websocket #' + i + ', ' + httprequest.url + '\r\n'; + } + if (response == '') { response = 'no websocket sessions.'; } + break; + } + case 'wsconnect': { // Setup a web socket + if (args['_'].length == 0) { + response = 'Proper usage: wsconnect (url)\r\nFor example: wsconnect wss://localhost:443/meshrelay.ashx?id=abc'; // Display correct command usage + } else { + var httprequest = null; + try { + var options = http.parseUri(args['_'][0]); + options.rejectUnauthorized = 0; + httprequest = http.request(options); + } catch (e) { response = 'Invalid HTTP websocket request'; } + if (httprequest != null) { + httprequest.upgrade = onWebSocketUpgrade; + httprequest.onerror = function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); } + + var index = 1; + while (consoleWebSockets[index]) { index++; } + httprequest.sessionid = sessionid; + httprequest.index = index; + httprequest.url = args['_'][0]; + consoleWebSockets[index] = httprequest; + response = 'New websocket session #' + index; + } + } + break; + } + case 'wssend': { // Send data on a web socket + if (args['_'].length == 0) { + response = 'Proper usage: wssend (socketnumber)\r\n'; // Display correct command usage + for (var i in consoleWebSockets) { + var httprequest = consoleWebSockets[i]; + response += 'Websocket #' + i + ', ' + httprequest.url + '\r\n'; + } + } else { + var i = parseInt(args['_'][0]); + var httprequest = consoleWebSockets[i]; + if (httprequest != undefined) { + httprequest.s.write(args['_'][1]); + response = 'ok'; + } else { + response = 'Invalid web socket number'; + } + } + break; + } + case 'wsclose': { // Close a websocket + if (args['_'].length == 0) { + response = 'Proper usage: wsclose (socketnumber)'; // Display correct command usage + } else { + var i = parseInt(args['_'][0]); + var httprequest = consoleWebSockets[i]; + if (httprequest != undefined) { + if (httprequest.s != null) { httprequest.s.end(); } else { httprequest.end(); } + response = 'ok'; + } else { + response = 'Invalid web socket number'; + } + } + break; + } + case 'tunnels': { // Show the list of current tunnels + response = ''; + for (var i in tunnels) { response += 'Tunnel #' + i + ', ' + tunnels[i].url + '\r\n'; } + if (response == '') { response = 'No websocket sessions.'; } + break; + } + case 'ls': { // Show list of files and folders + response = ''; + var xpath = '*'; + if (args['_'].length > 0) { xpath = obj.path.join(args['_'][0], '*'); } + response = 'List of ' + xpath + '\r\n'; + var results = fs.readdirSync(xpath); + for (var i = 0; i < results.length; ++i) { + var stat = null, p = obj.path.join(args['_'][0], results[i]); + try { stat = fs.statSync(p); } catch (e) { } + if ((stat == null) || (stat == undefined)) { + response += (results[i] + "\r\n"); + } else { + response += (results[i] + " " + ((stat.isDirectory()) ? "(Folder)" : "(File)") + "\r\n"); + } + } + break; + } + case 'lsx': { // Show list of files and folders + response = objToString(getDirectoryInfo(args['_'][0]), 0, ' ', true); + break; + } + case 'lock': { // Lock the current user out of the desktop + if (process.platform == 'win32') { var child = require('child_process'); child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 }); response = 'Ok'; } + else { response = 'Not supported on the platform'; } + break; + } + case 'amt': { // Show Intel AMT status + getAmtInfo(function (state) { + var resp = 'Intel AMT not detected.'; + if (state != null) { resp = objToString(state, 0, ' ', true); } + sendConsoleText(resp, sessionid); + }); + break; + } + case 'netinfo': { // Show network interface information + //response = objToString(mesh.NetInfo, 0, ' '); + var interfaces = require('os').networkInterfaces(); + 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 + if ((args['_'].length != 1) || (args['_'][0].length != 12)) { + response = 'Proper usage: wakeonlan [mac], for example "wakeonlan 010203040506".'; + } else { + var count = sendWakeOnLan(args['_'][0]); + response = 'Sent wake-on-lan on ' + count + ' interface(s).'; + } + break; + } + case 'sendall': { // Send a message to all consoles on this mesh + sendConsoleText(args['_'].join(' ')); + break; + } + case 'power': { // Execute a power action on this computer + if (mesh.ExecPowerState == undefined) { + response = 'Power command not supported on this agent.'; + } else { + if ((args['_'].length == 0) || (typeof args['_'][0] != 'number')) { + response = 'Proper usage: power (actionNumber), where actionNumber is:\r\n LOGOFF = 1\r\n SHUTDOWN = 2\r\n REBOOT = 3\r\n SLEEP = 4\r\n HIBERNATE = 5\r\n DISPLAYON = 6\r\n KEEPAWAKE = 7\r\n BEEP = 8\r\n CTRLALTDEL = 9\r\n VIBRATE = 13\r\n FLASH = 14'; // Display correct command usage + } else { + var r = mesh.ExecPowerState(args['_'][0], args['_'][1]); + response = 'Power action executed with return code: ' + r + '.'; + } + } + break; + } + case 'location': { + getIpLocationData(function (location) { + sendConsoleText(objToString({ "action": "iplocation", "type": "publicip", "value": location }, 0, ' ')); + }); + break; + } + case 'parseuri': { + response = JSON.stringify(http.parseUri(args['_'][0])); + break; + } + case 'scanwifi': { + if (wifiScanner != null) { + var wifiPresent = wifiScanner.hasWireless; + if (wifiPresent) { response = "Perfoming Wifi scan..."; wifiScanner.Scan(); } else { response = "Wifi absent."; } + } else { response = "Wifi module not present."; } + break; + } + case 'scanamt': { + if (amtscanner != null) { + if (args['_'].length != 1) { + response = 'Usage examples:\r\n scanamt 1.2.3.4\r\n scanamt 1.2.3.0-1.2.3.255\r\n scanamt 1.2.3.0/24\r\n'; // Display correct command usage + } else { + response = 'Scanning: ' + args['_'][0] + '...'; + amtscanner.scan(args['_'][0], 2000, function (data) { + if (data.length > 0) { + var r = '', pstates = ['NotActivated', 'InActivation', 'Activated']; + for (var i in data) { + var x = data[i]; + if (r != '') { r += '\r\n'; } + r += x.address + ' - Intel AMT v' + x.majorVersion + '.' + x.minorVersion; + if (x.provisioningState < 3) { r += (', ' + pstates[x.provisioningState]); } + if (x.provisioningState == 2) { r += (', ' + x.openPorts.join(', ')); } + r += '.'; + } + } else { + r = 'No Intel AMT found.'; + } + sendConsoleText(r); + }); + } + } else { response = "Intel AMT scanner module not present."; } + break; + } + case 'modules': { + response = JSON.stringify(addedModules); + break; + } + default: { // This is an unknown command, return an error message + response = 'Unknown command \"' + cmd + '\", type \"help\" for list of avaialble commands.'; + break; + } + } + } catch (e) { response = 'Command returned an exception error: ' + e; console.log(e); } + if (response != null) { sendConsoleText(response, sessionid); } + } + + // Send a mesh agent console command + function sendConsoleText(text, sessionid) { + if (typeof text == 'object') { text = JSON.stringify(text); } + mesh.SendCommand({ "action": "msg", "type": "console", "value": text, "sessionid": sessionid }); + } + + // Called before the process exits + //process.exit = function (code) { console.log("Exit with code: " + code.toString()); } + + // Called when the server connection state changes + function handleServerConnection(state) { + meshServerConnectionState = state; + if (meshServerConnectionState == 0) { + // Server disconnected + if (selfInfoUpdateTimer != null) { clearInterval(selfInfoUpdateTimer); selfInfoUpdateTimer = null; } + lastSelfInfo = null; + } else { + // Server connected, send mesh core information + var oldNodeId = db.Get('OldNodeId'); + if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); } + sendPeriodicServerUpdate(true); + //if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 60000); } // Should be a long time, like 20 minutes. For now, 1 minute. + } + } + + // Build a bunch a self information data that will be sent to the server + // We need to do this periodically and if anything changes, send the update to the server. + function buildSelfInfo(func) { + getAmtInfo(function (meinfo) { + var r = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": obj.meshCoreCapabilities }; + if (meinfo != null) { + var intelamt = {}, p = false; + if (meinfo.Versions && meinfo.Versions.AMT) { intelamt.ver = meinfo.Versions.AMT; p = true; } + if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; } + if (meinfo.Flags) { intelamt.flags = meinfo.Flags; p = true; } + if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; p = true; } + if (meinfo.UUID) { intelamt.uuid = meinfo.UUID; p = true; } + if (p == true) { r.intelamt = intelamt } + } + func(r); + }); + } + + // Update the server with the latest network interface information + var sendNetworkUpdateNagleTimer = null; + function sendNetworkUpdateNagle() { if (sendNetworkUpdateNagleTimer != null) { clearTimeout(sendNetworkUpdateNagleTimer); sendNetworkUpdateNagleTimer = null; } sendNetworkUpdateNagleTimer = setTimeout(sendNetworkUpdate, 5000); } + function sendNetworkUpdate(force) { + sendNetworkUpdateNagleTimer = null; + + // Update the network interfaces information data + var netInfo = mesh.NetInfo; + netInfo.action = 'netinfo'; + var netInfoStr = JSON.stringify(netInfo); + if ((force == true) || (clearGatewayMac(netInfoStr) != clearGatewayMac(lastNetworkInfo))) { mesh.SendCommand(netInfo); lastNetworkInfo = netInfoStr; } + } + + // Called periodically to check if we need to send updates to the server + function sendPeriodicServerUpdate(force) { + if ((amtMeiConnected != 1) || (force == true)) { // If we are pending MEI connection, hold off on updating the server on self-info + // Update the self information data + buildSelfInfo(function (selfInfo) { + selfInfoStr = JSON.stringify(selfInfo); + if ((force == true) || (selfInfoStr != lastSelfInfo)) { mesh.SendCommand(selfInfo); lastSelfInfo = selfInfoStr; } + }); + } + + // Update network information + sendNetworkUpdateNagle(force); + } + + // Get Intel AMT information using MEI + function getAmtInfo(func) { + if (amtMei == null || amtMeiConnected != 2) { if (func != null) { func(null); } return; } + try { + amtMeiTmpState = { Flags: 0 }; // Flags: 1=EHBC, 2=CCM, 4=ACM + amtMei.getProtocolVersion(function (result) { if (result != null) { amtMeiTmpState.MeiVersion = result; } }); + 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 != 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.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { amtMeiTmpState.UUID = result.uuid; } }); + //amtMei.getMACAddresses(function (result) { amtMeiTmpState.mac = result; }); + amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } if (func != null) { func(amtMeiTmpState); } }); + } catch (e) { if (func != null) { func(null); } return; } + } + + // Called on MicroLMS Intel AMT user notification + function handleAmtNotification(notifyMsg) { + if ((notifyMsg == null) || (notifyMsg.Body == null) || (notifyMsg.Body.MessageID == null) || (notifyMsg.Body.MessageArguments == null)) return null; + var amtMessage = notifyMsg.Body.MessageID, amtMessageArg = notifyMsg.Body.MessageArguments[0], notify = null; + + switch (amtMessage) { + case 'iAMT0050': { if (amtMessageArg == '48') { notify = 'Intel® AMT Serial-over-LAN connected'; } else if (amtMessageArg == '49') { notify = 'Intel® AMT Serial-over-LAN disconnected'; } break; } // SOL + case 'iAMT0052': { if (amtMessageArg == '1') { notify = 'Intel® AMT KVM connected'; } else if (amtMessageArg == '2') { notify = 'Intel® AMT KVM disconnected'; } break; } // KVM + } + + // Send to the entire mesh, no sessionid or userid specified. + if (notify != null) { mesh.SendCommand({ "action": "msg", "type": "notify", "value": notify, "tag": "general" }); } + } + + // Starting function + obj.start = function () { + // Setup the mesh agent event handlers + mesh.AddCommandHandler(handleServerCommand); + mesh.AddConnectHandler(handleServerConnection); + + // Parse input arguments + //var args = parseArgs(process.argv); + //console.log(args); + + // Launch LMS + try { + var lme_heci = require('amt-lme'); + amtLmsState = 1; + amtLms = new lme_heci(); + amtLms.on('error', function (e) { amtLmsState = 0; amtLms = null; obj.setupMeiOsAdmin(null, 1); }); + amtLms.on('connect', function () { amtLmsState = 2; obj.setupMeiOsAdmin(null, 2); }); + //amtLms.on('bind', function (map) { }); + amtLms.on('notify', function (data, options, str, code) { + if (code == 'iAMT0052-3') { + kvmGetData(); + } else { + //if (str != null) { sendConsoleText('Intel AMT LMS: ' + str); } + handleAmtNotification(data); + } + }); + } catch (e) { amtLmsState = -1; amtLms = null; } + + // Check if the control channel is connected + if (mesh.isControlChannelConnected) { + sendPeriodicServerUpdate(true); // Send the server update + } + + //console.log('Stopping.'); + //process.exit(); + } + + obj.stop = function () { + mesh.AddCommandHandler(null); + mesh.AddConnectHandler(null); + } + + function onWebSocketClosed() { sendConsoleText("WebSocket #" + this.httprequest.index + " closed.", this.httprequest.sessionid); delete consoleWebSockets[this.httprequest.index]; } + function onWebSocketData(data) { sendConsoleText("Got WebSocket #" + this.httprequest.index + " data: " + data, this.httprequest.sessionid); } + function onWebSocketSendOk() { sendConsoleText("WebSocket #" + this.index + " SendOK.", this.sessionid); } + + function onWebSocketUpgrade(response, s, head) { + sendConsoleText("WebSocket #" + this.index + " connected.", this.sessionid); + this.s = s; + s.httprequest = this; + s.end = onWebSocketClosed; + s.data = onWebSocketData; + } + + + // + // KVM Data Channel + // + + obj.setupMeiOsAdmin = function(func, state) { + 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); + obj.osamtstack = new amt(oswsstack); + if (func) { func(state); } + //var AllWsman = "CIM_SoftwareIdentity,IPS_SecIOService,IPS_ScreenSettingData,IPS_ProvisioningRecordLog,IPS_HostBasedSetupService,IPS_HostIPSettings,IPS_IPv6PortSettings".split(','); + //obj.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)) { + obj.kvmGetData('skip'); // Clear any previous data, this is a dummy read to about handling old data. + obj.kvmTempTimer = setInterval(function () { obj.kvmGetData(); }, 2000); // Start polling for KVM data. + obj.kvmSetData(JSON.stringify({ action: 'restart', ver: 1 })); // Send a restart command to advise the console if present that MicroLMS just started. + } + }); + }); + } + + obj.kvmGetData = function(tag) { + obj.osamtstack.IPS_KVMRedirectionSettingData_DataChannelRead(obj.kvmDataGetResponse, tag); + } + + obj.kvmDataGetResponse = function (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) { obj.kvmProcessData(response.Body.RealmsBitmap, response.Body.MessageId, val); } + } + } + + var webRtcDesktop = null; + obj.kvmProcessData = function (realms, messageId, val) { + var data = null; + try { data = JSON.parse(val) } catch (e) { } + if ((data != null) && (data.action)) { + if (data.action == 'present') { obj.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; + webRtcDesktop.kvm = mesh.getRemoteDesktopStream(); + webRtcDesktop.kvm.pipe(webRtcDesktop.rtcchannel, { dataTypeSkip: 1, end: false }); + webRtcDesktop.rtcchannel.on('end', function () { obj.webRtcCleanUp(); }); + webRtcDesktop.rtcchannel.on('data', function (x) { obj.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); }); + }); + obj.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('/'); + } + }; + + // Process KVM control channel data + obj.kvmCtrlData = function(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); + //sendConsoleText('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 'lock': { + // Lock the current user out of the desktop + if (process.platform == 'win32') { var child = require('child_process'); child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 }); } + 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 + try { fs.renameSync(path.join(cmd.path, cmd.oldname), path.join(cmd.path, cmd.newname)); } 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 = new Buffer(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; + } + } + } + + obj.webRtcCleanUp = function() { + 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; + } + + obj.kvmSetData = function(x) { + obj.osamtstack.IPS_KVMRedirectionSettingData_DataChannelWrite(Buffer.from(x).toString('base64'), function () { }); + } + + return obj; +} + +// +// Module startup +// + +var xexports = null, mainMeshCore = null; +try { xexports = module.exports; } catch (e) { } + +if (xexports != null) { + // If we are running within NodeJS, export the core + module.exports.createMeshCore = createMeshCore; +} else { + // If we are not running in NodeJS, launch the core + mainMeshCore = createMeshCore(); + mainMeshCore.start(null); +} diff --git a/agents/modules_meshcore_backup/process-manager.js b/agents/modules_meshcore_backup/process-manager.js new file mode 100644 index 00000000..47a7d58a --- /dev/null +++ b/agents/modules_meshcore_backup/process-manager.js @@ -0,0 +1,100 @@ +/* +Copyright 2018 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. +*/ + +// JavaScript source code +var GM = require('_GenericMarshal'); + +function processManager() { + this._ObjectID = 'processManager'; + switch (process.platform) { + case 'win32': + this._kernel32 = GM.CreateNativeProxy('kernel32.dll'); + this._kernel32.CreateMethod('GetLastError'); + this._kernel32.CreateMethod('CreateToolhelp32Snapshot'); + this._kernel32.CreateMethod('Process32First'); + this._kernel32.CreateMethod('Process32Next'); + break; + case 'linux': + this._childProcess = require('child_process'); + break; + default: + throw (process.platform + ' not supported'); + } + this.getProcesses = function getProcesses(callback) { + switch (process.platform) { + default: + throw ('Enumerating processes on ' + process.platform + ' not supported'); + case 'win32': + var retVal = {}; + var h = this._kernel32.CreateToolhelp32Snapshot(2, 0); + var info = GM.CreateVariable(304); + info.toBuffer().writeUInt32LE(304, 0); + var nextProcess = this._kernel32.Process32First(h, info); + while (nextProcess.Val) { + retVal[info.Deref(8, 4).toBuffer().readUInt32LE(0)] = { cmd: info.Deref(GM.PointerSize == 4 ? 36 : 44, 260).String }; + nextProcess = this._kernel32.Process32Next(h, info); + } + if (callback) { callback.apply(this, [retVal]); } + break; + case 'linux': + if (!this._psp) { this._psp = {}; } + var p = this._childProcess.execFile("/bin/ps", ["ps", "-uxa"], { type: this._childProcess.SpawnTypes.TERM }); + this._psp[p.pid] = p; + p.Parent = this; + p.ps = ''; + p.callback = callback; + p.args = []; + for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); } + p.on('exit', function onGetProcesses() { + delete this.Parent._psp[this.pid]; + var retVal = {}, lines = this.ps.split('\x0D\x0A'), key = {}, keyi = 0; + for (var i in lines) { + var tokens = lines[i].split(' '); + var tokenList = []; + for (var x in tokens) { + if (i == 0 && tokens[x]) { key[tokens[x]] = keyi++; } + if (i > 0 && tokens[x]) { tokenList.push(tokens[x]); } + } + if ((i > 0) && (tokenList[key.PID])) { + retVal[tokenList[key.PID]] = { user: tokenList[key.USER], cmd: tokenList[key.COMMAND] }; + } + } + if (this.callback) { + this.args.unshift(retVal); + this.callback.apply(this.parent, this.args); + } + }); + p.stdout.on('data', function (chunk) { this.parent.ps += chunk.toString(); }); + break; + } + }; + this.getProcessInfo = function getProcessInfo(pid) { + switch (process.platform) { + default: + throw ('getProcessInfo() not supported for ' + process.platform); + case 'linux': + var status = require('fs').readFileSync('/proc/' + pid + '/status'), info = {}, lines = status.toString().split('\n'); + for (var i in lines) { + var tokens = lines[i].split(':'); + if (tokens.length > 1) { tokens[1] = tokens[1].trim(); } + info[tokens[0]] = tokens[1]; + } + return (info); + } + }; +} + +module.exports = new processManager(); \ No newline at end of file diff --git a/agents/modules_meshcore_backup/smbios.js b/agents/modules_meshcore_backup/smbios.js new file mode 100644 index 00000000..f770dcad --- /dev/null +++ b/agents/modules_meshcore_backup/smbios.js @@ -0,0 +1,284 @@ +/* +Copyright 2018 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. +*/ + +try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { } +try { Object.defineProperty(String.prototype, "replaceAll", { value: function replaceAll(oldVal, newVal) { return (this.split(oldVal).join(newVal)); } }); } catch (e) { } + +var RSMB = 1381190978; +var memoryLocation = { 0x1: 'Other', 0x2: 'Unknown', 0x3: 'System Board', 0x4: 'ISA', 0x5: 'EISA', 0x6: 'PCI', 0x7: 'MCA', 0x8: 'PCMCIA', 0x9: 'Proprietary', 0xA: 'NuBus', 0xA0: 'PC-98/C20', 0xA1: 'PC-98/C24', 0xA2: 'PC-98/E', 0xA3: 'PC-98/LB' }; +var wakeReason = ['Reserved', 'Other', 'Unknown', 'APM Timer', 'Modem Ring', 'LAN', 'Power Switch', 'PCI', 'AC Power']; + +function SMBiosTables() { + this._ObjectID = 'SMBiosTable'; + if (process.platform == 'win32') { + this._marshal = require('_GenericMarshal'); + this._native = this._marshal.CreateNativeProxy("Kernel32.dll"); + + this._native.CreateMethod('EnumSystemFirmwareTables'); + this._native.CreateMethod('GetSystemFirmwareTable'); + } + if (process.platform == 'linux') { + this._canonicalizeData = function _canonicalizeData(data) { + var lines = data.toString().split('Header and Data:\x0A'); + var MemoryStream = require('MemoryStream'); + var ms = new MemoryStream(); + + for (var i = 1; i < lines.length; ++i) { + var tokens = lines[i].split('Strings:\x0A'); + var header = tokens[0].split('\x0A\x0A')[0].replaceAll('\x0A', '').trim().replaceAll(' ', '').replaceAll('\x09', ''); + ms.write(Buffer.from(header, 'hex')); + if (tokens.length > 1) { + var strings = tokens[1].split('\x0A\x0A')[0].split('\x0A'); + var stringsFinal = []; + for (var strx in strings) { + var tmp = strings[strx].trim().replaceAll(' ', '').replaceAll('\x09', ''); + if (!(tmp[0] == '"')) { stringsFinal.push(tmp); } + } + ms.write(Buffer.from(stringsFinal.join(''), 'hex')); + ms.write(Buffer.from('00', 'hex')); + } + else { + ms.write(Buffer.from('0000', 'hex')); + } + } + var retVal = ms.buffer; + retVal.ms = ms; + return (retVal); + }; + } + this._parse = function _parse(SMData) { + var ret = {}; + var pbyte; + var i = 0 + var SMData; + var structcount = 0; + + while (SMData && i < SMData.length) { + var SMtype = SMData[i]; + var SMlength = SMData[i + 1]; + + if (!ret[SMtype]) { ret[SMtype] = []; } + ret[SMtype].push(SMData.slice(i + 4, i + SMlength)); + if (process.platform == 'win32') { ret[SMtype].peek()._ext = pbyte; } + i += SMlength; + + ret[SMtype].peek()._strings = []; + + while (SMData[i] != 0) { + var strstart = i; + + // Start of String, find end of string + while (SMData[i++] != 0); + ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim()); + } + i += (ret[SMtype].peek()._strings.length == 0) ? 2 : 1; + ++structcount; + //console.log('End of Table[' + SMtype + ']: ' + i); + } + //console.log('Struct Count = ' + structcount); + return (ret); + }; + this.get = function get(callback) { + if (process.platform == 'win32') { + var size = this._native.GetSystemFirmwareTable(RSMB, 0, 0, 0).Val; + //console.log('Table Size: ' + size); + + var PtrSize = this._marshal.CreatePointer()._size; + var buffer = this._marshal.CreateVariable(size); + var written = this._native.GetSystemFirmwareTable(RSMB, 0, buffer, size).Val; + //console.log('Written Size: ' + written); + + var rawBuffer = buffer.toBuffer(); + var length = buffer.Deref(4, 4).toBuffer().readUInt32LE(0); + + pbyte = buffer.Deref(8, length); + SMData = pbyte.toBuffer(); + + if (callback) { callback.apply(this, [this._parse(SMData)]); return; } else { return (this._parse(SMData)); } + } + if (process.platform == 'linux') { + var MemoryStream = require('MemoryStream'); + this.child = require('child_process').execFile('/usr/sbin/dmidecode', ['dmidecode', '-u']); + this.child.SMBiosTable = this; + this.child.ms = new MemoryStream(); + this.child.ms.callback = callback + this.child.ms.child = this.child; + this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); }); + this.child.on('exit', function () { this.ms.end(); }); + this.child.ms.on('end', function () { + //console.log('read ' + this.buffer.length + ' bytes'); + if (this.buffer.length < 300) { // TODO: Trap error message better that this. + console.log('Not enough permission to read SMBiosTable'); + if (this.callback) { this.callback.apply(this.child.SMBiosTable, []); } + } + else { + var SMData = this.child.SMBiosTable._canonicalizeData(this.buffer); + var j = this.child.SMBiosTable._parse(SMData); + if (this.callback) { this.callback.apply(this.child.SMBiosTable, [j]); } + } + }); + return; + } + throw (process.platform + ' not supported'); + }; + this.parse = function parse(data) { + var r = {}; + r.processorInfo = this.processorInfo(data); + r.memoryInfo = this.memoryInfo(data); + r.systemInfo = this.systemInfo(data); + r.systemSlots = this.systemInfo(data); + r.amtInfo = this.amtInfo(data); + return r; + } + this.processorInfo = function processorInfo(data) { + if (!data) { throw ('no data'); } + var ret = []; + var ptype = ['ERROR', 'Other', 'Unknown', 'CPU', 'ALU', 'DSP', 'GPU']; + var statusString = ['Unknown', 'Enabled', 'Disabled by user', 'Disabled by BIOS', 'Idle', 'Reserved', 'Reserved', 'Other']; + var cpuid = 0; + while (data[4] && data[4].length > 0) { + var p = data[4].pop(); + var populated = p[20] & 0x40; + var status = p[20] & 0x07 + if (populated) { + var j = { _ObjectID: 'SMBiosTables.processorInfo' }; + j.Processor = ptype[p[1]]; + j.MaxSpeed = p.readUInt16LE(16) + ' Mhz'; + if (p[31]) { j.Cores = p[31]; } + if (p[33]) { j.Threads = p[33]; } + j.Populated = 1; + j.Status = statusString[status]; + j.Socket = p._strings[p[0] - 1]; + j.Manufacturer = p._strings[p[3] - 1]; + j.Version = p._strings[p[12] - 1]; + ret.push(j); + } + } + return (ret); + }; + this.memoryInfo = function memoryInfo(data) { + if (!data) { throw ('no data'); } + var retVal = { _ObjectID: 'SMBiosTables.memoryInfo' }; + if (data[16]) { + var m = data[16].peek(); + retVal.location = memoryLocation[m[0]]; + if ((retVal.maxCapacityKb = m.readUInt32LE(3)) == 0x80000000) { + retVal.maxCapacityKb = 'A really big number'; + } + } + return (retVal); + }; + this.systemInfo = function systemInfo(data) { + if (!data) { throw ('no data'); } + var retVal = { _ObjectID: 'SMBiosTables.systemInfo' }; + if (data[1]) { + var si = data[1].peek(); + retVal.uuid = si.slice(4, 20).toString('hex'); + retVal.wakeReason = wakeReason[si[20]]; + } + return (retVal); + }; + this.systemSlots = function systemSlots(data) { + if (!data) { throw ('no data'); } + var retVal = []; + if (data[9]) { + while (data[9].length > 0) { + var ss = data[9].pop(); + retVal.push({ name: ss._strings[ss[0] - 1] }); + } + } + return (retVal); + }; + this.amtInfo = function amtInfo(data) { + if (!data) { throw ('no data'); } + var retVal = { AMT: false }; + if (data[130] && data[130].peek().slice(0, 4).toString() == '$AMT') { + var amt = data[130].peek(); + retVal.AMT = amt[4] ? true : false; + if (retVal.AMT) { + retVal.enabled = amt[5] ? true : false; + retVal.storageRedirection = amt[6] ? true : false; + retVal.serialOverLan = amt[7] ? true : false; + retVal.kvm = amt[14] ? true : false; + if (data[131].peek() && data[131].peek().slice(52, 56).toString() == 'vPro') { + var settings = data[131].peek(); + if (settings[0] & 0x04) { retVal.TXT = (settings[0] & 0x08) ? true : false; } + if (settings[0] & 0x10) { retVal.VMX = (settings[0] & 0x20) ? true : false; } + retVal.MEBX = settings.readUInt16LE(10).toString() + '.' + settings.readUInt16LE(8).toString() + '.' + settings.readUInt16LE(6).toString() + '.' + settings.readUInt16LE(4).toString(); + + var mecap = settings.slice(20, 32); + retVal.ManagementEngine = mecap.readUInt16LE(6).toString() + '.' + mecap.readUInt16LE(4).toString() + '.' + mecap.readUInt16LE(2).toString() + '.' + mecap.readUInt16LE(0).toString(); + + //var lan = settings.slice(36, 48); + //console.log(lan.toString('hex')); + //retVal.LAN = (lan.readUInt16LE(10) & 0x03).toString() + '/' + ((lan.readUInt16LE(10) & 0xF8) >> 3).toString(); + + //console.log(lan.readUInt16LE(3)); + //retVal.WLAN = (lan.readUInt16LE(3) & 0x07).toString() + '/' + ((lan.readUInt16LE(3) & 0xF8) >> 3).toString() + '/' + (lan.readUInt16LE(3) >> 8).toString(); + } + } + } + return (retVal); + }; + this.smTableTypes = { + 0: 'BIOS information', + 1: 'System information', + 2: 'Baseboard (or Module) information', + 4: 'Processor information', + 5: 'memory controller information', + 6: 'Memory module information', + 7: 'Cache information', + 8: 'Port connector information', + 9: 'System slots', + 10: 'On board devices information', + 11: 'OEM strings', + 12: 'System configuration options', + 13: 'BIOS language information', + 14: 'Group associations', + 15: 'System event log', + 16: 'Physical memory array', + 17: 'Memory device', + 18: '32bit memory error information', + 19: 'Memory array mapped address', + 20: 'Memory device mapped address', + 21: 'Built-in pointing device', + 22: 'Portable battery', + 23: 'System reset', + 24: 'Hardware security', + 25: 'System power controls', + 26: 'Voltage probe', + 27: 'Cooling device', + 28: 'Temperature probe', + 29: 'Electrical current probe', + 30: 'Out-of-band remote access', + 31: 'Boot integrity services (BIS) entry point', + 32: 'System boot information', + 33: '64bit memory error information', + 34: 'Management device', + 35: 'Management device component', + 36: 'Management device threshold data', + 37: 'Memory channel', + 38: 'IPMI device information', + 39: 'System power supply', + 40: 'Additional information', + 41: 'Onboard devices extended information', + 42: 'Management controller host interface', + 126: 'Inactive', + 127: 'End-of-table' + } +} + +module.exports = new SMBiosTables(); \ No newline at end of file diff --git a/agents/modules_meshcore_backup/toaster.js b/agents/modules_meshcore_backup/toaster.js new file mode 100644 index 00000000..316fdb9e --- /dev/null +++ b/agents/modules_meshcore_backup/toaster.js @@ -0,0 +1,72 @@ +/* +Copyright 2018 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. +*/ + +var toasters = {}; + +function Toaster() +{ + this._ObjectID = 'Toaster'; + this.Toast = function Toast(title, caption) + { + if (process.platform != 'win32') return; + + var retVal = {}; + var emitter = require('events').inherits(retVal); + emitter.createEvent('Clicked'); + emitter.createEvent('Dismissed'); + + var session = require('user-sessions').Current(); + for (var i in session) + { + console.log(session[i]); + } + try + { + console.log('Attempting Toast Mechanism 1'); + retVal._child = require('ScriptContainer').Create({ processIsolation: true, sessionId: session.connected[0].SessionId }); + } + catch (e) { + console.log(e); + console.log('Attempting Toast Mechanism 2'); + retVal._child = require('ScriptContainer').Create({ processIsolation: true }); + } + retVal._child.parent = retVal; + + retVal._child.on('exit', function (code) { this.parent.emit('Dismissed'); delete this.parent._child; }); + retVal._child.addModule('win-console', getJSModule('win-console')); + retVal._child.addModule('win-messagepump', getJSModule('win-messagepump')); + + var str = "\ + try{\ + var toast = require('win-console');\ + var balloon = toast.SetTrayIcon({ szInfo: '" + caption + "', szInfoTitle: '" + title + "', balloonOnly: true });\ + balloon.on('ToastDismissed', function(){process.exit();});\ + }\ + catch(e)\ + {\ + require('ScriptContainer').send(e);\ + }\ + require('ScriptContainer').send('done');\ + "; + retVal._child.ExecuteString(str); + toasters[retVal._hashCode()] = retVal; + retVal.on('Dismissed', function () { delete toasters[this._hashCode()]; }); + console.log('Returning'); + return (retVal); + }; +} + +module.exports = new Toaster(); \ No newline at end of file diff --git a/agents/modules_meshcore_backup/user-sessions.js b/agents/modules_meshcore_backup/user-sessions.js new file mode 100644 index 00000000..d8fe2d96 --- /dev/null +++ b/agents/modules_meshcore_backup/user-sessions.js @@ -0,0 +1,167 @@ +/* +Copyright 2018 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. +*/ + +function UserSessions() +{ + this._ObjectID = 'UserSessions'; + + if (process.platform == 'win32') { + this._marshal = require('_GenericMarshal'); + this._kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll'); + this._kernel32.CreateMethod('GetLastError'); + this._wts = this._marshal.CreateNativeProxy('Wtsapi32.dll'); + this._wts.CreateMethod('WTSEnumerateSessionsA'); + this._wts.CreateMethod('WTSQuerySessionInformationA'); + this._wts.CreateMethod('WTSFreeMemory'); + this.SessionStates = ['Active', 'Connected', 'ConnectQuery', 'Shadow', 'Disconnected', 'Idle', 'Listening', 'Reset', 'Down', 'Init']; + this.InfoClass = + { + 'WTSInitialProgram': 0, + 'WTSApplicationName': 1, + 'WTSWorkingDirectory': 2, + 'WTSOEMId': 3, + 'WTSSessionId': 4, + 'WTSUserName': 5, + 'WTSWinStationName': 6, + 'WTSDomainName': 7, + 'WTSConnectState': 8, + 'WTSClientBuildNumber': 9, + 'WTSClientName': 10, + 'WTSClientDirectory': 11, + 'WTSClientProductId': 12, + 'WTSClientHardwareId': 13, + 'WTSClientAddress': 14, + 'WTSClientDisplay': 15, + 'WTSClientProtocolType': 16, + 'WTSIdleTime': 17, + 'WTSLogonTime': 18, + 'WTSIncomingBytes': 19, + 'WTSOutgoingBytes': 20, + 'WTSIncomingFrames': 21, + 'WTSOutgoingFrames': 22, + 'WTSClientInfo': 23, + 'WTSSessionInfo': 24, + 'WTSSessionInfoEx': 25, + 'WTSConfigInfo': 26, + 'WTSValidationInfo': 27, + 'WTSSessionAddressV4': 28, + 'WTSIsRemoteSession': 29 + }; + + this.getSessionAttribute = function getSessionAttribute(sessionId, attr) + { + var buffer = this._marshal.CreatePointer(); + var bytesReturned = this._marshal.CreateVariable(4); + + if (this._wts.WTSQuerySessionInformationA(0, sessionId, attr, buffer, bytesReturned).Val == 0) + { + throw ('Error calling WTSQuerySessionInformation: ' + this._kernel32.GetLastError.Val); + } + + var retVal = buffer.Deref().String; + + this._wts.WTSFreeMemory(buffer.Deref()); + return (retVal); + }; + + this.Current = function Current() + { + var retVal = {}; + var pinfo = this._marshal.CreatePointer(); + var count = this._marshal.CreateVariable(4); + if (this._wts.WTSEnumerateSessionsA(0, 0, 1, pinfo, count).Val == 0) + { + throw ('Error calling WTSEnumerateSessionsA: ' + this._kernel32.GetLastError().Val); + } + + for (var i = 0; i < count.toBuffer().readUInt32LE() ; ++i) + { + var info = pinfo.Deref().Deref(i * (this._marshal.PointerSize == 4 ? 12 : 24), this._marshal.PointerSize == 4 ? 12 : 24); + var j = { SessionId: info.toBuffer().readUInt32LE() }; + j.StationName = info.Deref(this._marshal.PointerSize == 4 ? 4 : 8, this._marshal.PointerSize).Deref().String; + j.State = this.SessionStates[info.Deref(this._marshal.PointerSize == 4 ? 8 : 16, 4).toBuffer().readUInt32LE()]; + if (j.State == 'Active') { + j.Username = this.getSessionAttribute(j.SessionId, this.InfoClass.WTSUserName); + j.Domain = this.getSessionAttribute(j.SessionId, this.InfoClass.WTSDomainName); + } + retVal[j.SessionId] = j; + } + + this._wts.WTSFreeMemory(pinfo.Deref()); + + Object.defineProperty(retVal, 'connected', { value: showActiveOnly(retVal) }); + return (retVal); + }; + } + else + { + this.Current = function Current() + { + var retVal = {}; + var emitterUtils = require('events').inherits(retVal); + emitterUtils.createEvent('logon'); + + retVal._child = require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']); + retVal._child.Parent = retVal; + retVal._child._txt = ''; + retVal._child.on('exit', function (code) + { + var lines = this._txt.split('\n'); + var sessions = []; + for(var i in lines) + { + if (lines[i]) + { + console.log(getTokens(lines[i])); + var user = lines[i].substring(0, lines[i].indexOf(' ')); + sessions.push(user); + } + } + sessions.pop(); + console.log(sessions); + }); + retVal._child.stdout.Parent = retVal._child; + retVal._child.stdout.on('data', function (chunk) { this.Parent._txt += chunk.toString(); }); + + return (retVal); + } + } +} +function showActiveOnly(source) +{ + var retVal = []; + for (var i in source) + { + if (source[i].State == 'Active' || source[i].State == 'Connected') + { + retVal.push(source[i]); + } + } + return (retVal); +} +function getTokens(str) +{ + var columns = []; + var i; + + columns.push(str.substring(0, (i=str.indexOf(' ')))); + while (str[++i] == ' '); + columns.push(str.substring(i, str.substring(i).indexOf(' ') + i)); + + return (columns); +} + +module.exports = new UserSessions(); \ No newline at end of file diff --git a/agents/modules_meshcore_backup/wifi-scanner-windows.js b/agents/modules_meshcore_backup/wifi-scanner-windows.js new file mode 100644 index 00000000..56a6daaa --- /dev/null +++ b/agents/modules_meshcore_backup/wifi-scanner-windows.js @@ -0,0 +1,171 @@ +/* +Copyright 2018 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. +*/ + + +function _Scan() +{ + var wlanInterfaces = this.Marshal.CreatePointer(); + this.Native.WlanEnumInterfaces(this.Handle, 0, wlanInterfaces); + + var count = wlanInterfaces.Deref().Deref(0, 4).toBuffer().readUInt32LE(0); + + var info = wlanInterfaces.Deref().Deref(8, 532); + var iname = info.Deref(16, 512).AnsiString; + + var istate; + switch (info.Deref(528, 4).toBuffer().readUInt32LE(0)) + { + case 0: + istate = "NOT READY"; + break; + case 1: + istate = "CONNECTED"; + break; + case 2: + istate = "AD-HOC"; + break; + case 3: + istate = "DISCONNECTING"; + break; + case 4: + istate = "DISCONNECTED"; + break; + case 5: + istate = "ASSOCIATING"; + break; + case 6: + istate = "DISCOVERING"; + break; + case 7: + istate = "AUTHENTICATING"; + break; + default: + istate = "UNKNOWN"; + break; + } + + var iguid = info.Deref(0, 16); + if (this.Native.WlanScan(this.Handle, iguid, 0, 0, 0).Val == 0) + { + return (true); + } + else + { + return (false); + } +} + +function AccessPoint(_ssid, _bssid, _rssi, _lq) +{ + this.ssid = _ssid; + this.bssid = _bssid; + this.rssi = _rssi; + this.lq = _lq; +} +AccessPoint.prototype.toString = function() +{ + return (this.ssid + " [" + this.bssid + "]: " + this.lq); +} + +function OnNotify(NotificationData) +{ + var NotificationSource = NotificationData.Deref(0, 4).toBuffer().readUInt32LE(0); + var NotificationCode = NotificationData.Deref(4, 4).toBuffer().readUInt32LE(0); + var dataGuid = NotificationData.Deref(8, 16); + + if ((NotificationSource & 0X00000008) && (NotificationCode == 7)) + { + var bss = this.Parent.Marshal.CreatePointer(); + var result = this.Parent.Native.GetBSSList(this.Parent.Handle, dataGuid, 0, 3, 0, 0, bss).Val; + if (result == 0) + { + var totalSize = bss.Deref().Deref(0, 4).toBuffer().readUInt32LE(0); + var numItems = bss.Deref().Deref(4, 4).toBuffer().readUInt32LE(0); + for (i = 0; i < numItems; ++i) + { + var item = bss.Deref().Deref(8 + (360 * i), 360); + var ssid = item.Deref(4, 32).String.trim(); + var bssid = item.Deref(40, 6).HexString2; + var rssi = item.Deref(56, 4).toBuffer().readUInt32LE(0); + var lq = item.Deref(60, 4).toBuffer().readUInt32LE(0); + + this.Parent.emit('Scan', new AccessPoint(ssid, bssid, rssi, lq)); + } + } + + } +} + +function Wireless() +{ + var emitterUtils = require('events').inherits(this); + + this.Marshal = require('_GenericMarshal'); + this.Native = this.Marshal.CreateNativeProxy("wlanapi.dll"); + this.Native.CreateMethod("WlanOpenHandle"); + this.Native.CreateMethod("WlanGetNetworkBssList", "GetBSSList"); + this.Native.CreateMethod("WlanRegisterNotification"); + this.Native.CreateMethod("WlanEnumInterfaces"); + this.Native.CreateMethod("WlanScan"); + this.Native.CreateMethod("WlanQueryInterface"); + + var negotiated = this.Marshal.CreatePointer(); + var h = this.Marshal.CreatePointer(); + + this.Native.WlanOpenHandle(2, 0, negotiated, h); + this.Handle = h.Deref(); + + this._NOTIFY_PROXY_OBJECT = this.Marshal.CreateCallbackProxy(OnNotify, 2); + this._NOTIFY_PROXY_OBJECT.Parent = this; + var PrevSource = this.Marshal.CreatePointer(); + var result = this.Native.WlanRegisterNotification(this.Handle, 0X0000FFFF, 0, this._NOTIFY_PROXY_OBJECT.Callback, this._NOTIFY_PROXY_OBJECT.State, 0, PrevSource); + + emitterUtils.createEvent('Scan'); + emitterUtils.addMethod('Scan', _Scan); + + this.GetConnectedNetwork = function () + { + var interfaces = this.Marshal.CreatePointer(); + + console.log('Success = ' + this.Native.WlanEnumInterfaces(this.Handle, 0, interfaces).Val); + var count = interfaces.Deref().Deref(0, 4).toBuffer().readUInt32LE(0); + var info = interfaces.Deref().Deref(8, 532); + var iname = info.Deref(16, 512).AnsiString; + var istate = info.Deref(528, 4).toBuffer().readUInt32LE(0); + if(info.Deref(528, 4).toBuffer().readUInt32LE(0) == 1) // CONNECTED + { + var dataSize = this.Marshal.CreatePointer(); + var pData = this.Marshal.CreatePointer(); + var valueType = this.Marshal.CreatePointer(); + var iguid = info.Deref(0, 16); + var retVal = this.Native.WlanQueryInterface(this.Handle, iguid, 7, 0, dataSize, pData, valueType).Val; + if (retVal == 0) + { + var associatedSSID = pData.Deref().Deref(524, 32).String; + var bssid = pData.Deref().Deref(560, 6).HexString; + var lq = pData.Deref().Deref(576, 4).toBuffer().readUInt32LE(0); + + return (new AccessPoint(associatedSSID, bssid, 0, lq)); + } + } + throw ("GetConnectedNetworks: FAILED (not associated to a network)"); + }; + + + return (this); +} + +module.exports = new Wireless(); diff --git a/agents/modules_meshcore_backup/wifi-scanner.js b/agents/modules_meshcore_backup/wifi-scanner.js new file mode 100644 index 00000000..23c548cd --- /dev/null +++ b/agents/modules_meshcore_backup/wifi-scanner.js @@ -0,0 +1,126 @@ +/* +Copyright 2018 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. +*/ + +var MemoryStream = require('MemoryStream'); +var WindowsChildScript = 'var parent = require("ScriptContainer");var Wireless = require("wifi-scanner-windows");Wireless.on("Scan", function (ap) { parent.send(ap); });Wireless.Scan();'; + +function AccessPoint(_ssid, _bssid, _lq) +{ + this.ssid = _ssid; + this.bssid = _bssid; + this.lq = _lq; +} +AccessPoint.prototype.toString = function () +{ + return ("[" + this.bssid + "]: " + this.ssid + " (" + this.lq + ")"); + //return (this.ssid + " [" + this.bssid + "]: " + this.lq); +} + +function WiFiScanner() +{ + var emitterUtils = require('events').inherits(this); + emitterUtils.createEvent('accessPoint'); + + this.hasWireless = function () + { + var retVal = false; + var interfaces = require('os').networkInterfaces(); + for (var name in interfaces) + { + if (interfaces[name][0].type == 'wireless') { retVal = true; break; } + } + return (retVal); + }; + + this.Scan = function () + { + if (process.platform == 'win32') + { + this.master = require('ScriptContainer').Create(15, ContainerPermissions.DEFAULT); + this.master.parent = this; + this.master.on('data', function (j) { this.parent.emit('accessPoint', new AccessPoint(j.ssid, j.bssid, j.lq)); }); + + this.master.addModule('wifi-scanner-windows', getJSModule('wifi-scanner-windows')); + this.master.ExecuteString(WindowsChildScript); + } + else if (process.platform == 'linux') + { + // Need to get the wireless interface name + var interfaces = require('os').networkInterfaces(); + var wlan = null; + for (var i in interfaces) + { + if (interfaces[i][0].type == 'wireless') + { + wlan = i; + break; + } + } + if (wlan != null) + { + this.child = require('child_process').execFile('/sbin/iwlist', ['iwlist', wlan, 'scan']); + this.child.parent = this; + this.child.ms = new MemoryStream(); + this.child.ms.parent = this.child; + this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); }); + this.child.on('exit', function () { this.ms.end(); }); + this.child.ms.on('end', function () + { + var str = this.buffer.toString(); + tokens = str.split(' - Address: '); + for (var block in tokens) + { + if (block == 0) continue; + var ln = tokens[block].split('\n'); + var _bssid = ln[0]; + var _lq; + var _ssid; + + for (var lnblock in ln) + { + lnblock = ln[lnblock].trim(); + lnblock = lnblock.trim(); + if (lnblock.startsWith('ESSID:')) + { + _ssid = lnblock.slice(7, lnblock.length - 1); + if (_ssid == '') { _ssid = ''; } + } + if (lnblock.startsWith('Signal level=')) + { + _lq = lnblock.slice(13,lnblock.length-4); + } + else if (lnblock.startsWith('Quality=')) + { + _lq = lnblock.slice(8, 10); + var scale = lnblock.slice(11, 13); + } + } + this.parent.parent.emit('accessPoint', new AccessPoint(_ssid, _bssid, _lq)); + } + }); + } + } + } +} + +module.exports = WiFiScanner; + + + + + + + diff --git a/agents/modules_meshcore_backup/win-console.js b/agents/modules_meshcore_backup/win-console.js new file mode 100644 index 00000000..d2c78f97 --- /dev/null +++ b/agents/modules_meshcore_backup/win-console.js @@ -0,0 +1,164 @@ +/* +Copyright 2018 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. +*/ + +var TrayIconFlags = + { + NIF_MESSAGE: 0x00000001, + NIF_ICON: 0x00000002, + NIF_TIP: 0x00000004, + NIF_STATE: 0x00000008, + NIF_INFO: 0x00000010, + NIF_GUID: 0x00000020, + NIF_REALTIME: 0x00000040, + NIF_SHOWTIP: 0x00000080, + + NIM_ADD: 0x00000000, + NIM_MODIFY: 0x00000001, + NIM_DELETE: 0x00000002, + NIM_SETFOCUS: 0x00000003, + NIM_SETVERSION: 0x00000004 + }; +var NOTIFYICON_VERSION_4 = 4; +var MessageTypes = { WM_APP: 0x8000, WM_USER: 0x0400 }; +function WindowsConsole() +{ + if (process.platform == 'win32') + { + this._ObjectID = 'WindowsConsole'; + this._Marshal = require('_GenericMarshal'); + this._kernel32 = this._Marshal.CreateNativeProxy("kernel32.dll"); + this._user32 = this._Marshal.CreateNativeProxy("user32.dll"); + this._kernel32.CreateMethod("GetConsoleWindow"); + this._kernel32.CreateMethod('GetCurrentThread'); + this._user32.CreateMethod("ShowWindow"); + this._user32.CreateMethod("LoadImageA"); + this._user32.CreateMethod({ method: 'GetMessageA', threadDispatch: 1 }); + this._shell32 = this._Marshal.CreateNativeProxy('Shell32.dll'); + this._shell32.CreateMethod('Shell_NotifyIconA'); + + this._handle = this._kernel32.GetConsoleWindow(); + this.minimize = function () { + this._user32.ShowWindow(this._handle, 6); + }; + this.restore = function () { + this._user32.ShowWindow(this._handle, 9); + }; + this.hide = function () { + this._user32.ShowWindow(this._handle, 0); + }; + this.show = function () { + this._user32.ShowWindow(this._handle, 5); + }; + + + this._loadicon = function (imagePath) { + var h = this._user32.LoadImageA(0, this._Marshal.CreateVariable(imagePath), 1, 0, 0, 0x00000010 | 0x00008000 | 0x00000040); // LR_LOADFROMFILE | LR_SHARED | LR_DEFAULTSIZE + return (h); + }; + + this.SetTrayIcon = function SetTrayIcon(options) + { + var data = this._Marshal.CreateVariable(this._Marshal.PointerSize == 4 ? 508 : 528); + //console.log('struct size = ' + data._size); + //console.log('TryIcon, WM_MESSAGE filter = ' + options.filter); + data.toBuffer().writeUInt32LE(data._size, 0); + + var trayType = TrayIconFlags.NIF_TIP | TrayIconFlags.NIF_MESSAGE + options.filter = MessageTypes.WM_APP + 1; + data.Deref(this._Marshal.PointerSize == 4 ? 16 : 24, 4).toBuffer().writeUInt32LE(options.filter); + + if (!options.noBalloon) { trayType |= TrayIconFlags.NIF_INFO; } + + if (options.icon) + { + trayType |= TrayIconFlags.NIF_ICON; + var hIcon = data.Deref(this._Marshal.PointerSize == 4 ? 20 : 32, this._Marshal.PointerSize); + options.icon.pointerBuffer().copy(hIcon.toBuffer()); + } + + data.Deref(this._Marshal.PointerSize * 2, 4).toBuffer().writeUInt32LE(1); + data.Deref(this._Marshal.PointerSize == 4 ? 12 : 20, 4).toBuffer().writeUInt32LE(trayType); + data.Deref(this._Marshal.PointerSize == 4 ? 416 : 432, 4).toBuffer().writeUInt32LE(NOTIFYICON_VERSION_4); + + var szTip = data.Deref(this._Marshal.PointerSize == 4 ? 24 : 40, 128); + var szInfo = data.Deref(this._Marshal.PointerSize == 4 ? 160 : 176, 256); + var szInfoTitle = data.Deref(this._Marshal.PointerSize == 4 ? 420 : 436, 64); + + if (options.szTip) { Buffer.from(options.szTip).copy(szTip.toBuffer()); } + if (options.szInfo) { Buffer.from(options.szInfo).copy(szInfo.toBuffer()); } + if (options.szInfoTitle) { Buffer.from(options.szInfoTitle).copy(szInfoTitle.toBuffer()); } + + + var MessagePump = require('win-messagepump'); + retVal = { _ObjectID: 'WindowsConsole.TrayIcon', MessagePump: new MessagePump(options) }; + var retValEvents = require('events').inherits(retVal); + retValEvents.createEvent('ToastClicked'); + retValEvents.createEvent('IconHover'); + retValEvents.createEvent('ToastDismissed'); + retVal.Options = options; + retVal.MessagePump.TrayIcon = retVal; + retVal.MessagePump.NotifyData = data; + retVal.MessagePump.WindowsConsole = this; + retVal.MessagePump.on('exit', function onExit(code) { console.log('Pump Exited'); if (this.TrayIcon) { this.TrayIcon.remove(); } }); + retVal.MessagePump.on('hwnd', function onHwnd(h) + { + //console.log('Got HWND'); + options.hwnd = h; + h.pointerBuffer().copy(this.NotifyData.Deref(this.WindowsConsole._Marshal.PointerSize, this.WindowsConsole._Marshal.PointerSize).toBuffer()); + + if(this.WindowsConsole._shell32.Shell_NotifyIconA(TrayIconFlags.NIM_ADD, this.NotifyData).Val == 0) + { + // Something went wrong + } + }); + retVal.MessagePump.on('message', function onWindowsMessage(msg) + { + if(msg.message == this.TrayIcon.Options.filter) + { + var handled = false; + if (msg.wparam == 1 && msg.lparam == 1029) + { + this.TrayIcon.emit('ToastClicked'); + handled = true; + } + if (msg.wparam == 1 && msg.lparam == 512) + { + this.TrayIcon.emit('IconHover'); + handled = true; + } + if (this.TrayIcon.Options.balloonOnly && msg.wparam == 1 && (msg.lparam == 1028 || msg.lparam == 1029)) + { + this.TrayIcon.emit('ToastDismissed'); + this.TrayIcon.remove(); + handled = true; + } + if (!handled) { console.log(msg); } + } + }); + retVal.remove = function remove() + { + this.MessagePump.WindowsConsole._shell32.Shell_NotifyIconA(TrayIconFlags.NIM_DELETE, this.MessagePump.NotifyData); + this.MessagePump.stop(); + delete this.MessagePump.TrayIcon; + delete this.MessagePump; + }; + return (retVal); + + }; + } +} + +module.exports = new WindowsConsole(); \ No newline at end of file diff --git a/agents/modules_meshcore_backup/win-messagepump.js b/agents/modules_meshcore_backup/win-messagepump.js new file mode 100644 index 00000000..8c2ce09c --- /dev/null +++ b/agents/modules_meshcore_backup/win-messagepump.js @@ -0,0 +1,122 @@ +/* +Copyright 2018 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. +*/ + +var WH_CALLWNDPROC = 4; +var WM_QUIT = 0x0012; + +function WindowsMessagePump(options) +{ + this._ObjectID = 'WindowsMessagePump'; + this._options = options; + var emitterUtils = require('events').inherits(this); + emitterUtils.createEvent('hwnd'); + emitterUtils.createEvent('error'); + emitterUtils.createEvent('message'); + emitterUtils.createEvent('exit'); + + this._child = require('ScriptContainer').Create({ processIsolation: 0 }); + this._child.MessagePump = this; + this._child.prependListener('~', function _childFinalizer() { this.MessagePump.emit('exit', 0); console.log('calling stop'); this.MessagePump.stop(); }); + this._child.once('exit', function onExit(code) { this.MessagePump.emit('exit', code); }); + this._child.once('ready', function onReady() + { + console.log('child ready'); + var execString = + "var m = require('_GenericMarshal');\ + var h = null;\ + var k = m.CreateNativeProxy('Kernel32.dll');\ + k.CreateMethod('GetLastError');\ + k.CreateMethod('GetModuleHandleA');\ + var u = m.CreateNativeProxy('User32.dll');\ + u.CreateMethod('GetMessageA');\ + u.CreateMethod('CreateWindowExA');\ + u.CreateMethod('TranslateMessage');\ + u.CreateMethod('DispatchMessageA');\ + u.CreateMethod('RegisterClassExA');\ + u.CreateMethod('DefWindowProcA');\ + var wndclass = m.CreateVariable(m.PointerSize == 4 ? 48 : 80);\ + wndclass.hinstance = k.GetModuleHandleA(0);\ + wndclass.cname = m.CreateVariable('MainWWWClass');\ + wndclass.wndproc = m.GetGenericGlobalCallback(4);\ + wndclass.toBuffer().writeUInt32LE(wndclass._size);\ + wndclass.cname.pointerBuffer().copy(wndclass.Deref(m.PointerSize == 4 ? 40 : 64, m.PointerSize).toBuffer());\ + wndclass.wndproc.pointerBuffer().copy(wndclass.Deref(8, m.PointerSize).toBuffer());\ + wndclass.hinstance.pointerBuffer().copy(wndclass.Deref(m.PointerSize == 4 ? 20 : 24, m.PointerSize).toBuffer());\ + wndclass.wndproc.on('GlobalCallback', function onWndProc(xhwnd, xmsg, wparam, lparam)\ + {\ + if(h==null || h.Val == xhwnd.Val)\ + {\ + require('ScriptContainer').send({message: xmsg.Val, wparam: wparam.Val, lparam: lparam.Val});\ + var retVal = u.DefWindowProcA(xhwnd, xmsg, wparam, lparam);\ + return(retVal);\ + }\ + });\ + u.RegisterClassExA(wndclass);\ + h = u.CreateWindowExA(0x00000088, wndclass.cname, 0, 0x00800000, 0, 0, 100, 100, 0, 0, 0, 0);\ + if(h.Val == 0)\ + {\ + require('ScriptContainer').send({error: 'Error Creating Hidden Window'});\ + process.exit();\ + }\ + require('ScriptContainer').send({hwnd: h.pointerBuffer().toString('hex')});\ + require('ScriptContainer').on('data', function onData(jmsg)\ + {\ + if(jmsg.listen)\ + {\ + var msg = m.CreateVariable(m.PointerSize == 4 ? 28 : 48);\ + while(u.GetMessageA(msg, h, 0, 0).Val>0)\ + {\ + u.TranslateMessage(msg);\ + u.DispatchMessageA(msg);\ + }\ + process.exit();\ + }\ + });"; + + this.ExecuteString(execString); + }); + this._child.on('data', function onChildData(msg) + { + if (msg.hwnd) + { + var m = require('_GenericMarshal'); + this._hwnd = m.CreatePointer(Buffer.from(msg.hwnd, 'hex')); + this.MessagePump.emit('hwnd', this._hwnd); + this.send({ listen: this.MessagePump._options.filter }); + } + else if(msg.message) + { + this.MessagePump.emit('message', msg); + } + else + { + console.log('Received: ', msg); + } + }); + this.stop = function stop() + { + if(this._child && this._child._hwnd) + { + console.log('posting WM_QUIT'); + var marshal = require('_GenericMarshal'); + var User32 = marshal.CreateNativeProxy('User32.dll'); + User32.CreateMethod('PostMessageA'); + User32.PostMessageA(this._child._hwnd, WM_QUIT, 0, 0); + } + }; +} + +module.exports = WindowsMessagePump; diff --git a/agents/modules_meshcore_backup/win-registry.js b/agents/modules_meshcore_backup/win-registry.js new file mode 100644 index 00000000..2fee12a5 --- /dev/null +++ b/agents/modules_meshcore_backup/win-registry.js @@ -0,0 +1,167 @@ +/* +Copyright 2018 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. +*/ + +var KEY_QUERY_VALUE = 0x0001; +var KEY_WRITE = 0x20006; + +var KEY_DATA_TYPES = + { + REG_NONE: 0, + REG_SZ: 1, + REG_EXPAND_SZ: 2, + REG_BINARY: 3, + REG_DWORD: 4, + REG_DWORD_BIG_ENDIAN: 5, + REG_LINK: 6, + REG_MULTI_SZ: 7, + REG_RESOURCE_LIST: 8, + REG_FULL_RESOURCE_DESCRIPTOR: 9, + REG_RESOURCE_REQUIREMENTS_LIST: 10, + REG_QWORD: 11 + }; + +function windows_registry() +{ + this._ObjectId = 'windows_registry'; + this._marshal = require('_GenericMarshal'); + this._AdvApi = this._marshal.CreateNativeProxy('Advapi32.dll'); + this._AdvApi.CreateMethod('RegCreateKeyExA'); + this._AdvApi.CreateMethod('RegOpenKeyExA'); + this._AdvApi.CreateMethod('RegQueryValueExA'); + this._AdvApi.CreateMethod('RegCloseKey'); + this._AdvApi.CreateMethod('RegDeleteKeyA'); + this._AdvApi.CreateMethod('RegDeleteValueA'); + this._AdvApi.CreateMethod('RegSetValueExA'); + this.HKEY = { Root: Buffer.from('80000000', 'hex').swap32(), CurrentUser: Buffer.from('80000001', 'hex').swap32(), LocalMachine: Buffer.from('80000002', 'hex').swap32(), Users: Buffer.from('80000003', 'hex').swap32() }; + + this.QueryKey = function QueryKey(hkey, path, key) + { + var h = this._marshal.CreatePointer(); + var len = this._marshal.CreateVariable(4); + var valType = this._marshal.CreateVariable(4); + key = this._marshal.CreateVariable(key); + var HK = this._marshal.CreatePointer(hkey); + var retVal = null; + + if (this._AdvApi.RegOpenKeyExA(HK, this._marshal.CreateVariable(path), 0, KEY_QUERY_VALUE, h).Val != 0) + { + throw ('Error Opening Registry Key: ' + path); + } + + if(this._AdvApi.RegQueryValueExA(h.Deref(), key, 0, 0, 0, len).Val == 0) + { + var data = this._marshal.CreateVariable(len.toBuffer().readUInt32LE()); + if (this._AdvApi.RegQueryValueExA(h.Deref(), key, 0, valType, data, len).Val == 0) + { + switch(valType.toBuffer().readUInt32LE()) + { + case KEY_DATA_TYPES.REG_DWORD: + retVal = data.toBuffer().readUInt32LE(); + break; + case KEY_DATA_TYPES.REG_DWORD_BIG_ENDIAN: + retVal = data.toBuffer().readUInt32BE(); + break; + case KEY_DATA_TYPES.REG_SZ: + retVal = data.String; + break; + case KEY_DATA_TYPES.REG_BINARY: + default: + retVal = data.toBuffer(); + retVal._data = data; + break; + } + } + } + else + { + this._AdvApi.RegCloseKey(h.Deref()); + throw ('Not Found'); + } + this._AdvApi.RegCloseKey(h.Deref()); + return (retVal); + }; + this.WriteKey = function WriteKey(hkey, path, key, value) + { + var result; + var h = this._marshal.CreatePointer(); + + if (this._AdvApi.RegCreateKeyExA(this._marshal.CreatePointer(hkey), this._marshal.CreateVariable(path), 0, 0, 0, KEY_WRITE, 0, h, 0).Val != 0) + { + throw ('Error Opening Registry Key: ' + path); + } + + var data; + var dataType; + + switch(typeof(value)) + { + case 'boolean': + dataType = KEY_DATA_TYPES.REG_DWORD; + data = this._marshal.CreateVariable(4); + data.toBuffer().writeUInt32LE(value ? 1 : 0); + break; + case 'number': + dataType = KEY_DATA_TYPES.REG_DWORD; + data = this._marshal.CreateVariable(4); + data.toBuffer().writeUInt32LE(value); + break; + case 'string': + dataType = KEY_DATA_TYPES.REG_SZ; + data = this._marshal.CreateVariable(value); + break; + default: + dataType = KEY_DATA_TYPES.REG_BINARY; + data = this._marshal.CreateVariable(value.length); + value.copy(data.toBuffer()); + break; + } + + if(this._AdvApi.RegSetValueExA(h.Deref(), this._marshal.CreateVariable(key), 0, dataType, data, data._size).Val != 0) + { + this._AdvApi.RegCloseKey(h.Deref()); + throw ('Error writing reg key: ' + key); + } + this._AdvApi.RegCloseKey(h.Deref()); + }; + this.DeleteKey = function DeleteKey(hkey, path, key) + { + if(!key) + { + if(this._AdvApi.RegDeleteKeyA(this._marshal.CreatePointer(hkey), this._marshal.CreateVariable(path)).Val != 0) + { + throw ('Error Deleting Key: ' + path); + } + } + else + { + var h = this._marshal.CreatePointer(); + var result; + if (this._AdvApi.RegOpenKeyExA(this._marshal.CreatePointer(hkey), this._marshal.CreateVariable(path), 0, KEY_QUERY_VALUE | KEY_WRITE, h).Val != 0) + { + throw ('Error Opening Registry Key: ' + path); + } + if ((result = this._AdvApi.RegDeleteValueA(h.Deref(), this._marshal.CreateVariable(key)).Val) != 0) + { + this._AdvApi.RegCloseKey(h.Deref()); + throw ('Error[' + result + '] Deleting Key: ' + path + '.' + key); + } + this._AdvApi.RegCloseKey(h.Deref()); + } + }; +} + +module.exports = new windows_registry(); + diff --git a/redirserver.js b/redirserver.js index ef8aa699..d68becf7 100644 --- a/redirserver.js +++ b/redirserver.js @@ -71,7 +71,7 @@ module.exports.CreateRedirServer = function (parent, db, args, func) { // Once the main web server is started, call this to hookup additional handlers obj.hookMainWebServer = function (certs) { obj.certificates = certs; - for (var i = 0; i < parent.config.domains.length; i++) { + for (var i in parent.config.domains) { if (parent.config.domains[i].dns != null) { continue; } var url = parent.config.domains[i].url; obj.app.post(url + "amtevents.ashx", obj.parent.webserver.handleAmtEventRequest); @@ -82,7 +82,7 @@ module.exports.CreateRedirServer = function (parent, db, args, func) { // Setup all HTTP redirection handlers //obj.app.set("etag", false); - for (var i = 0; i < parent.config.domains; i++) { + for (var i in parent.config.domains) { if (parent.config.domains[i].dns != null) { continue; } var url = parent.config.domains[i].url; obj.app.get(url, performRedirection); diff --git a/views/default.handlebars b/views/default.handlebars index b187cbd3..6c55dd95 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -927,7 +927,7 @@ // Poll the server, if it responds, refresh the page. function serverPoll() { - xdr = null; + var xdr = null; try { xdr = new XDomainRequest(); } catch (e) { } if (!xdr) xdr = new XMLHttpRequest(); xdr.open("HEAD", window.location.href); @@ -2253,7 +2253,7 @@ try { var loc = map_parseNodeLoc(nodes[i]); var feature = xxmap.markersSource.getFeatureById(nodes[i]._id); - if ((loc != null) && ((nodes[i].meshid == selectedMesh) || (selectedMesh == null))) { // Draw markers for devices with locations + if ((typeof loc == 'object') && ((nodes[i].meshid == selectedMesh) || (selectedMesh == null))) { // Draw markers for devices with locations var lat = loc[0], lon = loc[1], type = loc[2]; if (boundingBox == null) { boundingBox = [ lat, lon, lat, lon, 0 ]; } else { if (lat < boundingBox[0]) { boundingBox[0] = lat; } if (lon < boundingBox[1]) { boundingBox[1] = lon; } if (lat > boundingBox[2]) { boundingBox[2] = lat; } if (lon > boundingBox[3]) { boundingBox[3] = lon; } } if (feature == null) { addFeature(nodes[i]); boundingBox[4] = 1; } else { updateFeature(nodes[i], feature); feature.setStyle(markerStyle(nodes[i], loc[2])); } // Update Feature