diff --git a/agents-new/MeshAgentOSXPackager.zip b/agents-new/MeshAgentOSXPackager.zip new file mode 100644 index 00000000..5b713d6a Binary files /dev/null and b/agents-new/MeshAgentOSXPackager.zip differ diff --git a/agents-new/MeshCmd-signed.exe b/agents-new/MeshCmd-signed.exe new file mode 100644 index 00000000..4625a563 Binary files /dev/null and b/agents-new/MeshCmd-signed.exe differ diff --git a/agents-new/MeshCmd64-signed.exe b/agents-new/MeshCmd64-signed.exe new file mode 100644 index 00000000..bfca8595 Binary files /dev/null and b/agents-new/MeshCmd64-signed.exe differ diff --git a/agents-new/MeshCommander-Small.gz b/agents-new/MeshCommander-Small.gz new file mode 100644 index 00000000..a2000b85 Binary files /dev/null and b/agents-new/MeshCommander-Small.gz differ diff --git a/agents-new/MeshService-signed.exe b/agents-new/MeshService-signed.exe new file mode 100644 index 00000000..fbbb3af7 Binary files /dev/null and b/agents-new/MeshService-signed.exe differ diff --git a/agents-new/MeshService.exe b/agents-new/MeshService.exe new file mode 100644 index 00000000..cf8d3f40 Binary files /dev/null and b/agents-new/MeshService.exe differ diff --git a/agents-new/MeshService64-signed.exe b/agents-new/MeshService64-signed.exe new file mode 100644 index 00000000..67d976a6 Binary files /dev/null and b/agents-new/MeshService64-signed.exe differ diff --git a/agents-new/MeshService64.exe b/agents-new/MeshService64.exe new file mode 100644 index 00000000..b2a5c18a Binary files /dev/null and b/agents-new/MeshService64.exe differ diff --git a/agents-new/agentrecoverycore.js b/agents-new/agentrecoverycore.js new file mode 100644 index 00000000..762fa91f --- /dev/null +++ b/agents-new/agentrecoverycore.js @@ -0,0 +1,466 @@ + +var http = require('http'); +var childProcess = require('child_process'); +var meshCoreObj = { "action": "coreinfo", "value": "MeshCore Recovery", "caps": 14 }; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript +var nextTunnelIndex = 1; +var tunnels = {}; +var fs = require('fs'); + +//attachDebugger({ webport: 9994, wait: 1 }).then(function (p) { console.log('Debug on port: ' + p); }); + +function sendConsoleText(msg) +{ + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": msg }); +} +// Return p number of spaces +function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ret; } return r; } + +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('/'); + } + }; +// 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) + '}'; +} + +// 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 = require('MeshAgent').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; +} + +require('MeshAgent').on('Connected', function () +{ + require('os').name().then(function (v) + { + sendConsoleText("Mesh Agent Receovery Console, OS: " + v); + require('MeshAgent').SendCommand(meshCoreObj); + }); +}); + +// Tunnel callback operations +function onTunnelUpgrade(response, s, head) { + this.s = s; + s.httprequest = this; + s.end = onTunnelClosed; + s.tunnel = this; + + //sendConsoleText('onTunnelUpgrade'); + + 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; + } +} + +require('MeshAgent').AddCommandHandler(function (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.on('upgrade', function (response, s, head) + { + this.s = s; + s.httprequest = this; + s.tunnel = this; + s.on('end', function () + { + if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls. + + // 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; } + + + //sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid); + delete tunnels[this.httprequest.index]; + + // Clean up WebSocket + this.removeAllListeners('data'); + }); + s.on('data', function (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.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) + { + // 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._term = require('win-terminal').Start(80, 25); + this.httprequest._term.pipe(this, { dataTypeSkip: 1 }); + this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false }); + this.prependListener('end', function () { this.httprequest._term.end(function () { sendConsoleText('Terminal was closed'); }); }); + } + 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.on('end', function () { + if (process.platform == "win32") + { + // Unpipe the web socket + this.unpipe(this.httprequest._term); + this.httprequest._term.unpipe(this); + + // Clean up + this.httprequest._term.end(); + this.httprequest._term = null; + } + }); + } + } + 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))) { return; } // If this is control data, handle it now. + if (cmd.action == undefined) { return; } + console.log('action: ', cmd.action); + + //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': + // 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))); + break; + case 'mkdir': { + // Create a new empty folder + fs.mkdirSync(cmd.path); + break; + } + case 'rm': { + // Delete, possibly recursive delete + for (var i in cmd.delfiles) + { + try { deleteFolderRecursive(path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (e) { } + } + break; + } + case 'rename': { + // Rename a file or folder + var oldfullpath = path.join(cmd.path, cmd.oldname); + var newfullpath = path.join(cmd.path, cmd.newname); + try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); } + break; + } + case '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 ? 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 = 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; + } + } + } + } + }); + }); + 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; + } + + default: + // Unknown action, ignore it. + break; + } + break; + } + default: + // Unknown action, ignore it. + break; + } + } +}); + +function processConsoleCommand(cmd, args, rights, sessionid) +{ + try + { + var response = null; + switch (cmd) + { + case 'help': + response = 'Available commands are: osinfo, dbkeys, dbget, dbset, dbcompact, netinfo.'; + break; + + case 'osinfo': { // Return the operating system information + var i = 1; + if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; } + for (var j = 0; j < i; j++) { + var pr = require('os').name(); + pr.sessionid = sessionid; + pr.then(function (v) { sendConsoleText("OS: " + v, this.sessionid); }); + } + 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 '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 'netinfo': { // Show network interface information + //response = objToString(mesh.NetInfo, 0, ' '); + var interfaces = require('os').networkInterfaces(); + response = objToString(interfaces, 0, ' ', true); + 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); } +} + +// 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 = 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 = 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; +} +// Delete a directory with a files and directories within it +function deleteFolderRecursive(path, rec) { + if (fs.existsSync(path)) { + if (rec == true) { + fs.readdirSync(path.join(path, '*')).forEach(function (file, index) { + var curPath = path.join(path, file); + if (fs.statSync(curPath).isDirectory()) { // recurse + deleteFolderRecursive(curPath, true); + } else { // delete file + fs.unlinkSync(curPath); + } + }); + } + fs.unlinkSync(path); + } +}; diff --git a/agents-new/compressModules.bat b/agents-new/compressModules.bat new file mode 100644 index 00000000..1977b9f1 --- /dev/null +++ b/agents-new/compressModules.bat @@ -0,0 +1,7 @@ +@ECHO OFF +MD modules_meshcmd_min +MD modules_meshcore_min +"..\..\WebSiteCompiler\bin\Debug\WebSiteCompiler.exe" compressalljs "modules_meshcore" "modules_meshcore_min" +"..\..\WebSiteCompiler\bin\Debug\WebSiteCompiler.exe" compressalljs "modules_meshcmd" "modules_meshcmd_min" +"..\..\WebSiteCompiler\bin\Debug\WebSiteCompiler.exe" meshcore.js +"..\..\WebSiteCompiler\bin\Debug\WebSiteCompiler.exe" meshcmd.js diff --git a/agents-new/compressRemove.bat b/agents-new/compressRemove.bat new file mode 100644 index 00000000..c5fe66b0 --- /dev/null +++ b/agents-new/compressRemove.bat @@ -0,0 +1,7 @@ +@ECHO OFF +DEL meshcmd.min.js +DEL meshcore.min.js +DEL modules_meshcmd_min\*.min.js +DEL modules_meshcore_min\*.min.js +RD modules_meshcmd_min +RD modules_meshcore_min \ No newline at end of file diff --git a/agents-new/meshagent_arm b/agents-new/meshagent_arm new file mode 100644 index 00000000..91c56b1f Binary files /dev/null and b/agents-new/meshagent_arm differ diff --git a/agents-new/meshagent_arm-linaro b/agents-new/meshagent_arm-linaro new file mode 100644 index 00000000..6f8e8305 Binary files /dev/null and b/agents-new/meshagent_arm-linaro differ diff --git a/agents-new/meshagent_armhf b/agents-new/meshagent_armhf new file mode 100644 index 00000000..8d6aa42c Binary files /dev/null and b/agents-new/meshagent_armhf differ diff --git a/agents-new/meshagent_mips b/agents-new/meshagent_mips new file mode 100644 index 00000000..dbfae549 Binary files /dev/null and b/agents-new/meshagent_mips differ diff --git a/agents-new/meshagent_osx-x86-64 b/agents-new/meshagent_osx-x86-64 new file mode 100644 index 00000000..066b5a04 Binary files /dev/null and b/agents-new/meshagent_osx-x86-64 differ diff --git a/agents-new/meshagent_pogo b/agents-new/meshagent_pogo new file mode 100644 index 00000000..e89794d3 Binary files /dev/null and b/agents-new/meshagent_pogo differ diff --git a/agents-new/meshagent_poky b/agents-new/meshagent_poky new file mode 100644 index 00000000..6c025f64 Binary files /dev/null and b/agents-new/meshagent_poky differ diff --git a/agents-new/meshagent_poky64 b/agents-new/meshagent_poky64 new file mode 100644 index 00000000..6ddb3677 Binary files /dev/null and b/agents-new/meshagent_poky64 differ diff --git a/agents-new/meshagent_x86 b/agents-new/meshagent_x86 new file mode 100644 index 00000000..082f8260 Binary files /dev/null and b/agents-new/meshagent_x86 differ diff --git a/agents-new/meshagent_x86-64 b/agents-new/meshagent_x86-64 new file mode 100644 index 00000000..760f1b01 Binary files /dev/null and b/agents-new/meshagent_x86-64 differ diff --git a/agents-new/meshagent_x86-64_nokvm b/agents-new/meshagent_x86-64_nokvm new file mode 100644 index 00000000..028f97c1 Binary files /dev/null and b/agents-new/meshagent_x86-64_nokvm differ diff --git a/agents-new/meshagent_x86_nokvm b/agents-new/meshagent_x86_nokvm new file mode 100644 index 00000000..5862f8d2 Binary files /dev/null and b/agents-new/meshagent_x86_nokvm differ diff --git a/agents-new/meshcmd.js b/agents-new/meshcmd.js new file mode 100644 index 00000000..125e27cf --- /dev/null +++ b/agents-new/meshcmd.js @@ -0,0 +1,1604 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @description MeshCmd, command line tool for Intel AMT and MeshCentral. +* @author Ylian Saint-Hilaire +* @version v0.2.0 +*/ + +// Debug Stuff +//console.displayFinalizerMessages = 1; // Display objects that have event listeners that are disposed. +//console.displayStreamPipeMessages = 1; // Display stream pipe and un-pipes +//var __gc = setInterval(function () { console.log('GC'); _debugGC() }, 2000); // + + +var fs = require('fs'); +var os = require('os'); +var net = require('net'); +var http = require('http'); +var dgram = require('dgram'); +var httpHeaders = require('http-headers'); +var tcpserver = null; +var broadcastSockets = {}; +var multicastSockets = {}; +var discoveryInterval = null; +var membershipIPv4 = '239.255.255.235'; +var membershipIPv6 = 'FF02:0:0:0:0:0:0:FE'; +var settings = null; +var meshCmdVersion = '***Mesh*Cmd*Version***'; // Dynamically replaced with MeshCentral version +var amtLms = null, amtMei = null, amtMeiState = null; +var wsstack = null, amtstack = null; +var oswsstack = null, osamtstack = null; +var amtMeiTmpState = null; +var SMBiosTables = null; + +// MeshCommander for Firmware (GZIP'ed, Base64) v0.7.4 +var Large_IntelAmtWebApp = "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"; +var Medium_IntelAmtWebApp = "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"; +var Small_IntelAmtWebApp = "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"; + +// Check the server certificate fingerprint +function onVerifyServer(clientName, certs) { + if (certs == null) { certs = clientName; } // Temporary thing until we fix duktape + try { for (var i in certs) { if (certs[i].fingerprint.replace(/:/g, '') == settings.serverHttpsHash) { return; } } } catch (e) { } + if (serverhash != null) { console.log('Error: Failed to verify server certificate.'); throw 'Invalid server certificate'; } +} + +// Various utility functions +function debug(level, message) { if ((settings.debugLevel != null) && (settings.debugLevel >= level)) { console.log(message); } } +function exit(status) { if (status == null) { status = 0; } try { process.exit(status); } catch (e) { } } +function getInstance(x, y) { for (var i in x) { if (x[i]["InstanceID"] == y) return x[i]; } return null; } +function md5hex(str) { return require('MD5Stream').create().syncHash(str).toString('hex'); } +function guidToStr(g) { return g.substring(6, 8) + g.substring(4, 6) + g.substring(2, 4) + g.substring(0, 2) + "-" + g.substring(10, 12) + g.substring(8, 10) + "-" + g.substring(14, 16) + g.substring(12, 14) + "-" + g.substring(16, 20) + "-" + g.substring(20); } +function parceArguments(argv) { var r = {}; for (var i in argv) { i = parseInt(i); if (argv[i].startsWith('--') == true) { var key = argv[i].substring(2).toLowerCase(), val = true; if (((i + 1) < argv.length) && (argv[i + 1].startsWith('--') == false)) { val = argv[i + 1]; } r[key] = val; } } return r; } + +// Convert an object to string with all functions +function objToString(x, p, ret) { + if (ret == undefined) ret = ''; + if (p == undefined) p = 0; + if (x == null) { return '[null]'; } + if (p > 8) { return '[...]'; } + if (x == undefined) { return '[undefined]'; } + if (typeof x == 'string') { if (p == 0) return x; return '"' + (x.split('\0')[0]) + '"'; } + if (typeof x == 'buffer') { return '[buffer]'; } + if (typeof x != 'object') { return x; } + var r = '{' + (ret ? '\r\n' : ' '); + for (var i in x) { + if (i != '_ObjectID') { r += (addPad(p + 2, ret) + i + ': ' + objToString(x[i], p + 2, ret) + (ret ? '\r\n' : ' ')); } + } + return r + addPad(p, ret) + '}'; +} + +// Return p number of spaces +function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ' '; } return r; } + +// Parse the incoming arguments +function run(argv) { + if (meshCmdVersion[0] == '*') { meshCmdVersion = ''; } else { meshCmdVersion = ' v' + meshCmdVersion; } + var args = parceArguments(argv); + //console.log(JSON.stringify(argv)); + //console.log('addedModules = ' + JSON.stringify(addedModules)); + var actionpath = 'meshaction.txt'; + if (args.actionfile != null) { actionpath = args.actionfile; } + var actions = ['HELP', 'ROUTE', 'MICROLMS', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTINFODEBUG', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG', 'AMTPRESENCE']; + + // Load the action file + var actionfile = null; + try { actionfile = fs.readFileSync(actionpath); } catch (e) { } + if ((actionpath != 'meshaction.txt') && (actionfile == null)) { console.log('Unable to load \"' + actionpath + '\". Create this file or specify the location using --actionfile [filename].'); exit(1); return; } + if (actionfile != null) { try { settings = JSON.parse(actionfile); } catch (e) { console.log(actionpath, e); exit(1); return; } } else { if (argv.length >= 2) { settings = { action: argv[1] } } } + if (settings == null) { settings = {}; } + + // Set the arguments + if ((typeof args.action) == 'string') { settings.action = args.action; } + if ((typeof args.localport) == 'string') { settings.localport = parseInt(args.localport); } + if ((typeof args.remotenodeid) == 'string') { settings.remoteNodeId = args.remotenodeid; } + if ((typeof args.username) == 'string') { settings.username = args.username; } + if ((typeof args.password) == 'string') { settings.password = args.password; } + if ((typeof args.user) == 'string') { settings.username = args.user; } + if ((typeof args.pass) == 'string') { settings.password = args.pass; } + if ((typeof args.host) == 'string') { settings.hostname = args.host; } + if ((typeof args.hostname) == 'string') { settings.hostname = args.hostname; } + if ((typeof args.serverid) == 'string') { settings.serverId = args.serverid; } + if ((typeof args.serverhttpshash) == 'string') { settings.serverHttpsHash = args.serverhttpshash; } + if ((typeof args.remoteport) == 'string') { settings.remotePort = parseInt(args.remoteport); } + if ((typeof args.out) == 'string') { settings.output = args.out; } + if ((typeof args.output) == 'string') { settings.output = args.output; } + if ((typeof args.debug) == 'string') { settings.debugLevel = parseInt(args.debug); } + if ((typeof args.script) == 'string') { settings.script = args.script; } + if ((typeof args.agent) == 'string') { settings.agent = args.agent; } + if (args.debug) { try { waitForDebugger(); } catch (e) { } } + if (args.noconsole) { settings.noconsole = true; } + if (args.nocommander) { settings.noconsole = true; } + if (args.lmsdebug) { settings.lmsdebug = true; } + if (args.tls) { settings.tls = true; } + if ((argv.length > 1) && (actions.indexOf(argv[1].toUpperCase()) >= 0)) { settings.action = argv[1]; } + + // Validate meshaction.txt + if (settings.action == null) { + console.log('MeshCentral Command (MeshCmd) ' + meshCmdVersion); + console.log('No action specified, use MeshCmd like this:\r\n'); + console.log(' meshcmd [action] [arguments...]\r\n'); + console.log('Valid MeshCentral actions:'); + console.log(' Route - Map a local TCP port to a remote computer.'); + console.log('\r\nValid local actions:'); + console.log(' SMBios - Display System Management BIOS tables for this computer.'); + console.log(' RawSMBios - Display RAW System Management BIOS tables for this computer.'); + console.log(' MicroLMS - Run MicroLMS, allowing local access to Intel AMT.'); + console.log(' AmtInfo - Show Intel AMT version and activation state.'); + console.log(' AmtVersions - Show all Intel ME version information.'); + console.log(' AmtHashes - Show all Intel AMT trusted activation hashes.'); + console.log(' AmtCCM - Activate Intel AMT into Client Control Mode.'); + console.log(' AmtDeactivate - Deactivate Intel AMT if activated in Client Control mode.'); + console.log('\r\nValid local or remote actions:'); + console.log(' MeshCommander - Launch a local MeshCommander web server.'); + console.log(' AmtUUID - Show Intel AMT unique identifier.'); + console.log(' AmtAuditLog - Show the Intel AMT audit log.'); + console.log(' AmtLoadWebApp - Load MeshCommander in Intel AMT 11.6+ firmware.'); + console.log(' AmtClearWebApp - Clear everything from Intel AMT web storage.'); + console.log(' AmtStorageState - Show contents of the Intel AMT web storage.'); + console.log(' AmtSaveState - Save all Intel AMT WSMAN object to file.'); + console.log(' AmtPresence - Heartbeat a local Intel AMT watchdog agent.'); + console.log(' AmtScript - Run .mescript on Intel AMT.'); + console.log('\r\nHelp on a specific action using:\r\n'); + console.log(' meshcmd help [action]'); + exit(1); return; + } + if (settings.action == 'help') { + if (argv.length <= 2) { + actions.shift(); + console.log('Help usage:\r\n\r\n MeshCmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.'); + exit(1); return; + } + var action = argv[2].toLowerCase(); + if (action == 'route') { + console.log("The route action is used along with a MeshCentral account to map a local TCP port to a remote port on any computer on your MeshCentral account. This action requires many arguments, to avoid specifying them all it's best to download the meshaction.txt file from the web site and place it in the current folder. Example usage:\r\n\r\n (Place meshaction.txt file in current folder)\r\n meshcmd route --pass myAccountPassword"); + } else if (action == 'smbios') { + console.log("SMBios action will display this computer's system management BIOS information. Example usage:\r\n\r\n meshcmd smbios --out smbios.txt\r\n"); + console.log('\r\Optional arguments:\r\n'); + console.log(' --output [filename] Optional filename to write the results to.'); + } else if (action == 'rawsmbios') { + console.log("RawSMBios action will display this computer's system management BIOS information in raw hexdecimal form. Example usage:\r\n\r\n meshcmd rawsmbios --out smbios.txt\r\n"); + console.log('\r\Optional arguments:\r\n'); + console.log(' --output [filename] Optional filename to write the results to.'); + } else if (action == 'amtinfo') { + console.log('AmtInfo action will get the version and activation state of Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtinfo'); + } else if ((action == 'amtversion') || (action == 'amtversions')) { + console.log('AmtVersions will display all version information about Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtversions'); + } else if (action == 'amthashes') { + console.log('Amthashes will display all trusted activations hashes for Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd amthashes'); + } else if ((action == 'microlms') || (action == 'lms') || (action == 'amtlms')) { + console.log('Starts MicroLMS on this computer, allowing local access to Intel AMT on TCP ports 16992 and 16993 when applicable. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd microlms'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --noconsole MeshCommander for LMS will no be available on port 16994.'); + console.log('\r\nRun as a background service:\r\n'); + console.log(' microlms install/uninstall/start/stop.'); + } else if (action == 'amtccm') { + console.log('AmtCCM will attempt to activate Intel AMT on this computer into client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be in "pre-provisioning" state for this command to work and a administrator password must be provided. Example usage:\r\n\r\n meshcmd amtccm --pass mypassword'); + } else if (action == 'amtdeactivate') { + console.log('AmtDeactivate will attempt to deactivate Intel AMT on this computer when in client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be activated in client control mode for this command to work. Example usage:\r\n\r\n meshcmd amtdeactivate'); + } else if (action == 'amtuuid') { + console.log('AmtUUID action will get the unique identifier of the local or remote Intel AMT computer. By default, the local UUID is obtained unless a host is specified. Intel AMT must be activated for this command to work. Example usage:\r\n\r\n meshcmd amtuuid --host 1.2.3.4 --user admin --pass mypassword --tls'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if ((action == 'amtloadwebapp') || (action == 'amtloadsmallwebapp') || (action == 'amtloadlargewebapp') || (action == 'amtclearwebapp') || (action == 'amtstoragestate')) { + console.log('AmtLoadWebApp action will load MeshCommander into Intel AMT 11.6 or higher. If the computer is in ACM mode, MeshCommander will replace the default index.htm on HTTP/16992 or HTTPS/16993. If Intel AMT is in CCM mode, MeshCommander will be installed alongside the default web page and will be accessible in the "Web Applications" section. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtloadwebapp --host 1.2.3.4 --user admin --pass mypassword --tls'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if (action == 'amtclearwebstorage') { + console.log('AmtClearWebStorage will clear the web storage of Intel AMT, removing any loaded firmware version of MeshCommander. This command can clear the local or a remote Intel AMT computer. By default, the local computer storage is cleared unless a host is specified. Intel AMT must be activated for this command to work. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtclearwebstorage --host 1.2.3.4 --user admin --pass mypassword --tls'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if (action == 'amtstoragestate') { + console.log('AmtStorageState will display the content of the web storage of Intel AMT including any loaded firmware version of MeshCommander. This command can read the storage state of a local or remote Intel AMT computer. By default, the local computer storage state is displayed unless a host is specified. Intel AMT must be activated for this command to work. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtstoragestate --host 1.2.3.4 --user admin --pass mypassword --tls'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if (action == 'amtsavestate') { + console.log('AmtSaveState action will fetch all the entire state of Intel AMT and save it as a JSON file. This action will take multiple minutes to perform. The command will fetch the local computer state unless host is specified. Intel AMT must be ativated for this command to work. Example usage:\r\n\r\n meshcmd amtsavestate --host 1.2.3.4 --user admin --pass mypassword --tls --output state.json'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --output [filename] The output file for the Intel AMT state in JSON format.'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if (action == 'amtpresence') { + console.log('AmtPresence will heartbeat a local Intel AMT watchdog agent. Example usage:\r\n\r\n meshcmd amtpresence --agent B4B6A24C-255E-A75C-F5E8-B00B4D946AA7'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --agent [uuid] The unique identifier of the watchdog agent.'); + } else if (action == 'amtscript') { + console.log('AmtScript will run a .mescript file on the local or remote Intel AMT. Script files can be built using the MeshCommander script editor and be used to setup or perform actions on Intel AMT. Example usage:\r\n\r\n meshcmd amtscript --script myscript.mescript --host 1.2.3.4 --user admin --pass mypassword --tls'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --script [filename] The script file to run on Intel AMT.'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if (action == 'meshcommander') { + console.log('This action launched a local web server that hosts MeshCommander, a Intel AMT management console.'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --localport [port] Local port used for the web server, 3000 is default.'); + console.log('\r\nRun as a background service:\r\n'); + console.log(' meshcommander install/uninstall/start/stop.'); + } else if (action == 'amtauditlog') { + console.log('AmtAuditLog action will fetch the local or remote audit log. If used localy, no username/password is required. Example usage:\r\n\r\n meshcmd amtauditlog --host 1.2.3.4 --user admin --pass mypassword --tls --output audit.json'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --output [filename] The output file for the Intel AMT state in JSON format.'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else { + actions.shift(); + console.log('Invalid action, usage:\r\n\r\n meshcmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.'); + } + exit(1); return; + } + settings.action = settings.action.toLowerCase(); + debug(1, "Settings: " + JSON.stringify(settings)); + if (settings.action == 'smbios') { + // Display SM BIOS tables in raw form + SMBiosTables = require('smbios'); + SMBiosTables.get(function (data) { + var r = SMBiosTables.parse(data); + var out = objToString(r, 0, '\r\n'); + if (settings.output == null) { console.log(out); } else { var file = fs.openSync(settings.output, 'w'); fs.writeSync(file, Buffer.from(out, 'utf8')); fs.closeSync(file); } + exit(1); + }); + } else if (settings.action == 'rawsmbios') { + // Display SM BIOS tables in raw form + SMBiosTables = require('smbios'); + SMBiosTables.get(function (data) { + var out = ''; + for (var i in data) { var header = false; for (var j in data[i]) { if (data[i][j].length > 0) { if (header == false) { out += ('Table type #' + i + ((SMBiosTables.smTableTypes[i] == null) ? '' : (', ' + SMBiosTables.smTableTypes[i]))) + '\r\n'; header = true; } out += (' ' + data[i][j].toString('hex')) + '\r\n'; } } } + if (settings.output == null) { console.log(out); } else { var file = fs.openSync(settings.output, 'w'); fs.writeSync(file, Buffer.from(out, 'utf8')); fs.closeSync(file); } + exit(1); + }); + } else if (settings.action == 'route') { + // MeshCentral Router, port map local TCP port to a remote computer + if ((settings.localPort == null) || (typeof settings.localPort != 'number') || (settings.localPort < 0) || (settings.localPort > 65535)) { console.log('No or invalid \"localPort\" specified, use --localport [localport].'); exit(1); return; } + if ((settings.remoteNodeId == null) || (typeof settings.remoteNodeId != 'string')) { console.log('No or invalid \"remoteNodeId\" specified.'); exit(1); return; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { console.log('No or invalid \"username\" specified, use --username [username].'); exit(1); return; } + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.serverId == null) || (typeof settings.serverId != 'string') || (settings.serverId.length != 96)) { console.log('No or invalid \"serverId\" specified.'); exit(1); return; } + if ((settings.serverHttpsHash == null) || (typeof settings.serverHttpsHash != 'string') || (settings.serverHttpsHash.length != 96)) { console.log('No or invalid \"serverHttpsHash\" specified.'); exit(1); return; } + if ((settings.remotePort == null) || (typeof settings.remotePort != 'number') || (settings.remotePort < 0) || (settings.remotePort > 65535)) { console.log('No or invalid \"remotePort\" specified, use --remoteport [remoteport].'); exit(1); return; } + if (settings.serverUrl != null) { startRouter(); } else { discoverMeshServer(); } // Start MeshCentral Router + } else if ((settings.action == 'amtloadwebapp') || (settings.action == 'amtloadsmallwebapp') || (settings.action == 'amtloadlargewebapp') || (settings.action == 'amtclearwebapp') || (settings.action == 'amtstoragestate')) { // Intel AMT Web Application Actions + // Intel AMT 11.6+ Load MeshCommander into firmware + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + settings.protocol = 'http:'; + settings.localport = 16992; + debug(1, "Settings: " + JSON.stringify(settings)); + digest = require('http-digest').create(settings.username, settings.password); + digest.http = require('http'); + if (settings.action == 'amtstoragestate') { + getAmtStorage(function (statusCode, data) { if (statusCode == 200) { console.log("Storage State: " + JSON.stringify(data, null, 2)); exit(); return; } else { console.log("Unable to read storage state."); exit(); return; } }); + } else { + if (settings.action == 'amtloadwebapp') { settings.webapp = Medium_IntelAmtWebApp; } + else if (settings.action == 'amtloadsmallwebapp') { settings.webapp = Small_IntelAmtWebApp; } + else if (settings.action == 'amtloadlargewebapp') { settings.webapp = Large_IntelAmtWebApp; } + else if (settings.action == 'amtclearwebapp') { settings.webapp = null; } + nextStepStorageUpload(); + } + } else if ((settings.action == 'amtversion') || (settings.action == 'amtversions') || (settings.action == 'amtver')) { + // Display Intel AMT versions + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.getVersion(function (val) { + console.log("MEI Version = " + val.BiosVersion.toString()); + for (var version in val.Versions) { console.log(val.Versions[version].Description + " = " + val.Versions[version].Version); } + exit(1); return; + }); + } else if (settings.action == 'amthashes') { + // Display Intel AMT list of trusted hashes + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.getHashHandles(function (handles) { + exitOnCount = handles.length; + for (var i = 0; i < handles.length; ++i) { + this.getCertHashEntry(handles[i], function (result) { + console.log(result.name + ', (' + (result.isDefault ? 'Default' : '') + (result.isActive ? ', Active' : ', Disabled') + ')\r\n ' + result.hashAlgorithmStr + ': ' + result.certificateHash); + if (--exitOnCount == 0) { exit(1); } + }); + } + }); + } else if (settings.action == 'amtinfo') { + // Display Intel AMT version and activation state + mestate = {}; + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.getVersion(function (result) { if (result) { for (var version in result.Versions) { if (result.Versions[version].Description == 'AMT') { mestate.ver = result.Versions[version].Version; } } } }); + amtMei.getProvisioningState(function (result) { if (result) { mestate.ProvisioningState = result; } }); + amtMei.getProvisioningMode(function (result) { if (result) { mestate.ProvisioningMode = result; } }); + amtMei.getEHBCState(function (result) { if (result) { mestate.ehbc = result; } }); + amtMei.getControlMode(function (result) { if (result) { mestate.controlmode = result; } }); + amtMei.getMACAddresses(function (result) { if (result) { mestate.mac = result; } }); + amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } }); + amtMei.getLanInterfaceSettings(1, function (result) { if (result) { mestate.net1 = result; } }); + amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } }); + amtMei.getDnsSuffix(function (result) { + if (result) { mestate.dns = result; } + if (mestate.ver && mestate.ProvisioningState && mestate.ProvisioningMode) { + var str = 'Intel AMT v' + mestate.ver; + if (mestate.ProvisioningState.stateStr == 'PRE') { str += ', pre-provisioning state'; } + else if (mestate.ProvisioningState.stateStr == 'IN') { str += ', in-provisioning state'; } + else if (mestate.ProvisioningState.stateStr == 'POST') { + if (mestate.ProvisioningMode) { + if (mestate.controlmode) { + if (mestate.ProvisioningMode.modeStr == 'ENTERPRISE') { str += ', activated in ' + ["none", "client control mode", "admin control mode", "remote assistance mode"][mestate.controlmode.controlMode]; } else { str += ', activated in ' + mestate.ProvisioningMode.modeStr; } + } else { + str += ', activated in ' + mestate.ProvisioningMode.modeStr; + } + } + } + if ((mestate.ehbc) && (mestate.ehbc.EHBC == true)) { str += ', EHBC enabled'; } + str += '.'; + if (mestate.net0 != null) { str += '\r\nWired ' + ((mestate.net0.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net0.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net0.mac + (mestate.net0.address == '0.0.0.0' ? '' : (', ' + mestate.net0.address)); } + if (mestate.net1 != null) { str += '\r\nWireless ' + ((mestate.net1.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net1.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net1.mac + (mestate.net1.address == '0.0.0.0' ? '' : (', ' + mestate.net1.address)); } + console.log(str + '.'); + } else { + console.log('Intel(R) AMT not supported.'); + } + exit(1); + }); + } else if (settings.action == 'amtinfodebug') { + // Display Intel AMT version and activation state + mestate = {}; + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.getVersion(function (result) { console.log('getVersion: ' + JSON.stringify(result)); }); + amtMei.getProvisioningState(function (result) { console.log('getProvisioningState: ' + JSON.stringify(result)); }); + amtMei.getProvisioningMode(function (result) { console.log('getProvisioningMode: ' + JSON.stringify(result)); }); + amtMei.getEHBCState(function (result) { if (result) { console.log('getEHBCState: ' + JSON.stringify(result)); } }); + amtMei.getControlMode(function (result) { if (result) { console.log('getControlMode: ' + JSON.stringify(result)); } }); + amtMei.getMACAddresses(function (result) { if (result) { console.log('getMACAddresses: ' + JSON.stringify(result)); } }); + amtMei.getLanInterfaceSettings(0, function (result) { console.log('getLanInterfaceSettings0: ' + JSON.stringify(result)); }); + amtMei.getLanInterfaceSettings(1, function (result) { console.log('getLanInterfaceSettings1: ' + JSON.stringify(result)); }); + amtMei.getUuid(function (result) { console.log('getUuid: ' + JSON.stringify(result)); }); + amtMei.getDnsSuffix(function (result) { console.log('getDnsSuffix: ' + JSON.stringify(result)); }); + } else if (settings.action == 'amtsavestate') { + // Save the entire state of Intel AMT info a JSON file + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + if ((settings.output == null) || (typeof settings.output != 'string') || (settings.output == '')) { console.log('No or invalid \"output\" file specified, use --output [filename].'); exit(1); return; } + settings.protocol = 'http:'; + settings.localport = 16992; + debug(1, "Settings: " + JSON.stringify(settings)); + saveEntireAmtState(); + } else if ((settings.action == 'microlms') || (settings.action == 'amtlms') || (settings.action == 'lms')) { + // Start Intel AMT MicroLMS + startLms(function (state) { + console.log(['MicroLMS did not start. Must run as administrator or LMS already active.', 'MicroLMS started.', 'MicroLMS started, MeshCommander on HTTP/16994.', 'MEI error'][state]); console.log('Press ctrl-c to exit.'); if (state == 0) { exit(0); } + }); + } else if (settings.action == 'amtpresence') { + // Heartbeat a Intel AMT watchdog + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + if ((settings.agent == null) || (typeof settings.agent != 'string') || (settings.agent == '')) { console.log('No or invalid \"agent\" specified, use --agent [agent].'); exit(1); return; } + performAmtAgentPresence(); + } else if (settings.action == 'amtscript') { + // Start running a MEScript + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + if ((settings.script == null) || (typeof settings.script != 'string') || (settings.script == '')) { if (mescriptJSON != '') { settings.scriptJSON = mescriptJSON; } else { console.log('No or invalid \"script\" file specified, use --script [filename].'); exit(1); return; } } + startMeScript(); + } else if (settings.action == 'amtuuid') { + // Start running + if (settings.hostname != null) { + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + } + settings.protocol = 'http:'; + settings.localport = 16992; + debug(1, "Settings: " + JSON.stringify(settings)); + getAmtUuid(); + } else if (settings.action == 'amtccm') { + // Start activation to CCM + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + settings.protocol = 'http:'; + settings.localport = 16992; + debug(1, "Settings: " + JSON.stringify(settings)); + activeToCCM(); + } else if (settings.action == 'amtdeactivate') { + // Deactivate CCM + debug(1, "Settings: " + JSON.stringify(settings)); + deactivateCCM(); + } else if (settings.action == 'meshcommander') { // Start MeshCommander + startMeshCommander(); + } else if (settings.action == 'amtauditlog') { // Read the Intel AMT audit log + if (settings.hostname != null) { + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + } else { settings.hostname = '127.0.0.1'; } + readAmtAuditLog(); + } else { + console.log('Invalid \"action\" specified.'); exit(1); return; + } +} + +// +// Intel AMT Agent Presence +// + +function performAmtAgentPresence() { startLms(function () { tempWatchdogTimer = setTimeout(performAmtAgentPresenceRegister, 3000); }); } + +function performAmtAgentPresenceRegister() { + // Setup the Intel AMT WSMAN stack + tempWatchdogTimer = null; + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, '127.0.0.1', settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); + amtstack = new amt(wsstack); + + // Register the watchdog + watchdog = { DeviceID: Buffer.from(guidToStr(settings.agent.split('-').join('')).split('-').join(''), 'hex').toString('base64'), Retry: 0 }; + amtstack.AMT_AgentPresenceWatchdog_RegisterAgent(performAmtAgentPresenceRegisterRetry, watchdog, watchdog.Seq, { 'DeviceID': watchdog.DeviceID }); +} + +// Called after the agent is registered +function performAmtAgentPresenceRegisterRetry(stack, name, response, status, watchdog) { + if ((status == 200) && (response.Body.SessionSequenceNumber) && (response.Body.TimeoutInterval)) { + console.log('Asserting presence of the watchdog...'); + watchdog.Seq = response.Body.SessionSequenceNumber; + watchdog.Interval = response.Body.TimeoutInterval * 800; + watchdog.Retry = 0; + tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval); + } else { + debug(1, 'Failed to register, status = ' + status); + watchdog.Retry++; + if (watchdog.Retry < 5) { + tempWatchdogTimer = setTimeout(function () { amtstack.AMT_AgentPresenceWatchdog_RegisterAgent(performAmtAgentPresenceRegisterRetry, watchdog, watchdog.Seq, { 'DeviceID': watchdog.DeviceID }); }, 1000); + } else { + console.log('Failed to register this watchdog.'); + process.exit(0); + } + } +} + +// Start a new agent assert +function performAmtAgentPresenceAssert() { + watchdog.Seq++; + amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceAssertRetry, watchdog, 0, { 'DeviceID': watchdog.DeviceID }); +} + +// Called after the agent is asserted +function performAmtAgentPresenceAssertRetry(stack, name, response, status, watchdog) { + if (status == 200) { + debug(1, 'Succesful assert, sequence = ' + watchdog.Seq); + watchdog.Retry = 0; + tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval); + } else { + debug(1, 'Failed to assert, status = ' + status); + watchdog.Retry++; + if (watchdog.Retry < 5) { + amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceAssertRetry, watchdog, 0, { 'DeviceID': watchdog.DeviceID }); + } else { + console.log('Failed to assert presence on this watchdog.'); + process.exit(0); + } + } +} + +function performAmtAgentPresenceEx5(stack, name, response, status, watchdog) { + console.log('b', status, watchdog); + if (status == 200) { + watchdog.Retry = 0; + } else { + watchdog.Retry++; + if (watchdog.Retry < 5) { + amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceEx4, watchdog, 0, { 'DeviceID': watchdog.DeviceID }); + } else { + console.log('Failed to assert presence on this watchdog.'); + process.exit(0); + } + } +} + +// +// Intel AMT Audit Log +// + +function readAmtAuditLog() { + // See if MicroLMS needs to be started + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { + settings.noconsole = true; startLms(readAmtAuditLogEx); + } else { + readAmtAuditLogEx(9999); + } +} + +function readAmtAuditLogEx(x) { + if (x == 9999) { + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); + amtstack = new amt(wsstack); + amtstack.GetAuditLog(readAmtAuditLogEx2); + } else { + osamtstack.GetAuditLog(readAmtAuditLogEx2); + } +} + +function readAmtAuditLogEx2(stack, response, status) { + if (status != 200) { + console.log('Unable to get audit log, status = ' + status + '.'); + } else { + var out = ''; + for (var i in response) { + var name = ((response[i].Initiator != '') ? (response[i].Initiator + ': ') : '') + out += (response[i].Time + ' - ' + name + response[i].Event + '\r\n'); + } + if (settings.output == null) { console.log(out); } else { var file = fs.openSync(settings.output, 'w'); fs.writeSync(file, Buffer.from(out, 'utf8')); fs.closeSync(file); } + } + exit(1); +} + + +// +// MeshCommander local web server +// + +function startMeshCommander() { + // MeshCommander Local v0.7.4 + var _IntelAmtLocalWebApp_etag = "LlnBXeX//SEsHV5KjuEC"; + var _IntelAmtLocalWebApp = "H4sIAAAAAAAEAMQ5h3ajOtOvwu/ckpwNG8DGNd5zcEn3Jk7PPVWADEoEIiCMHZ+82P+1R/pe4ZMMxBDI7vr6Flc00vTRSCP99x//2f+/wXn/+uFiKNjUwV/2+a8Q0DmGXRsiy6ZtWZJ+ZnAIzC/7DqSADaSeCJ9DNO3eizea2CeOByjSMRQM4lLo0m7leNiFpgUrMcoKTuGM7nEeHcMGfgBpN6QTsVnJEu3Hg8XruQcTfBc4sDshvgOoaEIKDYqIm6WKoWcTF3Zdwlhi5D4JPsTdCmJDKgJlhLrIARbc81xLsH046VZMQEH7DdjRQQDrtV102zu/jKTTQ4t0GaWlIb7oxJwvMtboOGAmZttkCv0JJlHbRqYJ3c6EMPEnwEF43gY+AnhXsCGeQooMsCsEwA3EAPpoEg8M0AtstzzaMQgmflvHwHjq6OzH8knomu3IRhQynr6FXJESry2lDQwndNXymUC8KUZQf0KUDQ0NWzQAxiSkbZeZ560rZOyZCBgaaccTd0oJ3CEvZdCgCCwAXjFaxKIxoTxgmsi12hIDAx3ihYkCD4M5U5cYT4nqEXJNEvEYyegvZvs6JQQjZFI7dkRMu21zhywKJGxmIMyN1HnXXnJ8Be0pChCF5oK1eZwZxAc80GJ1YpwtqTbhQ3mM/cC4RJQEpqpq59WWFyu3y7JH4yiI4njSCTZzgZB1terNsnEgS6u2TiglTrvOIK+2kuHQWodBPc+gXqDP3OctvoFRK2Lkw1PhAlIzLyCD2EVIarvQD5iwHkEuhX52YmwBADqvn3lqYuM8EqClFyZoBs1OPFGSGZJOjWTS1hveLEdIqtY7wutnzyeWD4NAB2XkYrRyikqRIJMMuTlb1Zi/GBQTa5Edq+s60NW4Q/6wR6A8DQnUb7uUzWobYXObmOZODgE2IZxAhjAJMTYgxqVqtJgYqfyplxK9WM+7ZMaIOQC5v4OYrNaL5NJ5yy0Sm43187yIRYCR5bYZUcbSBdOPnNCKnZDjl6QAzpABfRP6q3ATAoKRKWz1pH79oF/CruC4TBsjFwJftHxgIujSbUqEmOmusKVPTHliCNLPu4ndBZ6DdmLp5UWaoGQmgsS+/L/5Nj24qb89L5dpXww8YECWWCIfeJ38VIgZKbkQqyr5+SjlSBbw/fepiIGkRWHtYVB5kdg1sbn8Zlhmm3mHZ8LEolwOjqEsSoDVtclUP8rmW81qU2noRaUCz4fAzC3YmSWiQCdVkSIH+ol4Gbm2gG4AKBfxkg6O6WTM2Fhakdk+m+YV6eMsvNVv8nch72a8yhN9TFRZ5JDKRkXAdxcf8TIk/mKj+M5IXiR24Vk7NZeay2SiDz0I+IKePGX7lrundujj7exuykKTdDd1KeHD8wG2h5o21s5GF9pZX5nPWgNfwnPlLrxsHphhaI/nmJzfvbyY1typH85/C5/lvWnj03Pf9ozHE+kE3jsNqE6ne3t78yO1pzFqWlM709iL0+3xv8t5c4RPnmXlfKTDQB9q88fhqP+1d0sej8m8P7JPtIcHa3AuR9GoL52cAas21JqHA3LRm58+gN6wf3N8Mohs63wYRQfE0r6OTh8H46jvj476dnV+2b8YqSFpXRxFVMPDZuOoDzXVdI9PLi5H1vXLQaM3Hp+c9sbPE218OLJrD4d2BPHlw6U2CLqVncTiyl9q8ZPhQLsY3I6AMxpEzEgXWQuO3lnweO4ef/J6vgbuXES+3j0jVx+fGNdVcPIi3R1ePQBLOzEokM6PcaBPjs+UGx3iwXh2qgVXKLh+HBxrRDuPuittq3+ptqfHR9rZ0DiC97QBSmJnL6u98U77rwCe+caZczc69iLk/db7enyIH3q1F817PAAPPe3xYXz9ULPvD6+e7f7dZRVcnX3qucPm7FgbDi3Qm40HY6TV7jCxoHU1Pjuo3RxpAakd2s6JO7y6fbpsaM9jZfxk3BzdyMFT/+lWC+DQ6K/ig0KnB/y3daPBkwBy00JDkYo7rdzOqskAsb1BSMnbMghMFAbLzpIMajT1plzMoAZxvJA9cpEM5KduVDJu5M95FrX8Fojn87yAfECe9iLPOSu+kKqdWTI5gdQ6SoHYd9YJNjoMFuW1EXIRRQCXlkdcmrLyiC9VSXlUhAZFYAHwKvCE3uf7qtKY/3X5GDAtHAe4zNB7LLYIH/rZc61fd745i1g45baSnGCBHp+jgSpxcjvLLYq0crAqpeEUP+Y9lbg+LngYL2U9XqK6EbfqmtxkaSN2tXXZbaaduiY7ZTPt6uuy20i7xx+MSqVeGpVKPeXFHr/LS1mPl6jUN+FWXZObqmzCrbYmt0ZzE27qmtxkqbYJu/q67KqbxAlfqRaCMEGY9cXrlpCuBBlgYAAMt5clnkA8YCA6366zBj84yNXt4lvVKv0s8OKjuAmSGHiCCaBxmSMIQmEJKKk8fY7MCs/J8sVIs2ejxd9J5VlY+5LukqWiuNsClALDdhivdmD4BGNuGuX36sVlXVuxRBmuWKLkn6aYHPxdHgMSf3+kWNK9gceCv9RliTY5l/05mmFdDyklbrIbra2UYM+F3ajKIeWlfu5IrripfjOZDzGgaArfZ49k8relz2pGrGT7mXbKma4A4sUKqZXvSUvCplKmQ7oAClyfPO3vr6RcQ535raokefJdlqwqaZZkj9/LklhX1mbIHjbiWF2fY722AUdfX3zcn5slmWOzqvRzWZ3DgjfM1zhFimkxo+YwPixk6nrLNBrLssflJcSIIeSOfw9a/M1YzMTABiaJ2mxmCjJ3gm/pYFuQdpPP56qw0ymedRmG0RHeJgDQGTikMH+WjlFAxeXFWKxE4UZGTQrXt0M33gaztK3y9ouImP9mbVWSuD4OVyc92qrVap30dgi5PPeI8SVR7ui4uSoGY7vnIFxiNdNOjhs5qPTSJpmD6s9pgJhwAkJMi8fXheyQip+/6pm0+Dt3tNxqsam/vxffKe5TRNnfCAZ2P43m/b0YuL886Sdu6GICzG7FwBC4obe9U2HAxPc8WLo2Q8Owv4qGbTiFLt35sm+iqYDMriQYGARBN74iYUyBjmECS4rP5LI3c0Ka7uuZsRgGxzKF6fJQtlthSBUhPo3uVuJ/dk3qrUjKeZWyXQqXSH5PjqEjxxKW/LtyvZ4U/t16TUgG+bxdSeRMYlYSAt/4gUvc5dnO1f+ILItEWYElDS+IAW5D3N2Z4VC4y+r73LYXVUB6/l9qBK0QNH8hLfl7sSLH/PvyTKTCOfMvRSpZPxAYRpes2j7c/v5L5NifJ6rmX0Dm/+I/hmIYG/b+ZTh/2XXcM4w16n9BCncYRiqez1ZC9F8vVjTwDsw6mURDOWrOOco0XmDyisy+OZIuuRQwjPCTpzRFQ9GPxbm2r7gk5gK6mUGT0O36U62SPYyLSdqkCdfw/M+Adk/qmFYUXXXuPJEXGlN0VDEVdpcJQp2RVaaZDbcVQ+653CPTt/WlaFB/AcDacwD5aHIiSR21o7Zg+rW4BryQvFty3ta+m+8tCFdyg9jfGYVh5ZFjNIc1wj4jYpIlOZZXXwoRp058mYESmJolIv3mCtN2DIy1WBCoF3FaakWeR4ZxR9LAJe92RazB1OB09C23u6XJhvcZJS4cr65lheJUrUhyef9Plq79RnNcbD1THn+cdthOkxMLqTw1lKAWOg1QuM/CJ+520Ud73Hm+B+/qTEBPQgb7mJsJvOiOC7FTlV/iGklfC6fTYWfAYEKjxqhchO/XpMwlDKiqehTYFo/hsbFTDh1ZwuaaOXXdp1p4s4zOM1yyjcUwQTDqBYeVXuzNiCdIRb7eIYcqunkCHXkGmbzzGReyBjYNUwitoeYhVu2EnVHhbDWgkxlIQe3MJMarZpv9dS9ycjNv6Q6voPXRQV/DNJo35w8aX+Rs+/59dY7KnjPyFGEaDa0U35/iiaBjgwEgX4R0XWPR2ydhUwdbWrVoJMnK6CuWay80+EU3pYTzRe5LYCkgAywlg1NQsb1UVAxR348ptso4/oxDF/Qof4BEO6WespYanfAN4ykbWIwIF+fJA1jRSbCXgeVgdWTyYN9GEzzeBaiwBAnzuq7mVmQcx7zV71AbJL+aTilpwLqIH0EG/7pgbg3Mo35GTFO+LawMywQNpy2M/PZMSTAsnzDZ3nDwzUokI4EdL7CMGjZG5DHe0jDA67BkwjILa5SNSs/sGjBF5vjmzBYlq36N+M2mjrErxkQEDyBM4CvslLAZxTa7w0pCa/Qei3NC6LG211J3w46OfQYSEPwp4YqQ41zGFnoVh6RslriVX1eRWNmJkH+zOiXV6Si2E0eNMc4p0NIkywkvt+aMtzFBft9fwtUZ6wBsWDAaxe6EyAFMWXBxwbCAaAH8R/ExZv5uzcbsSVAYR3DXrmubjjcckQqqrpc74Uc8crcw2sKIi5uvrn06ozFvhiLRrsQ6ohsU6Tw+7rS2jsicMLsFVZhoq9vCUpmxROCXbkK0KSwUfxiIAvd1PuuoI1SNULIZIYgIm/caOr9AlxPGBGnUIzG3OWPIc09tp/xEddSjRNhvwGevUZYSx8CI9Ea0hxpaemPRSKYugds4EeG2PaielGRZhLl2yaW8BTOem9yaWWaA+EdcjFxI5e2grToJesWNlHpgEonRE4ba91K3Us3XgDVh3AVxjjo2Psk0bcv5nNorw5yGd19zDKWqiqrN7paMrMvhj0JKXqU82Oj/1RdOT6lGNxZ+rsqJCwv0DuF+i372wxh8kfI7vZlqOKrBXwPsOcCV8Z/jinf/4zxMOfZA6txV5ZP+152eWwWD7XmxBqca3reVo77V6RmwimketIjvOMLyukjr6Aed6RW0EmShudTAEBCuvii0Gi9a2e+8mhkj9uZqz42J8YqIL2lOK06VyiWhgATPvIhv74fME47AIvqZEgUk8OMHdkqjsB+oUXqjXIf3rhpaZFB85xjb4mjDVLMgLF82OJ83X8icYXrrZNiCUxr2T9fT8BssWxGLEX5LJKre0h7QyvfxvFZLagFhhl0ybhK0zllytsYynftEfQ2Oc9i0UPQw6rqyQtGAeWG78Qz9d0Y0ClsIb8c1KdgGbygFcXGXcSS1rviDOGshxaM56pIV5EJviK3segcO10tCmyDuWq7aTcMgDH04arMNXRtr5cYtzVZxBaLlyhw04qzeoOMNLq6gpMPeFG+I+vmEKWI4NsaL1Y5Zh4ekaRcwrkfvUWTEES10FhzLiwxodpbzhTAP8v5m25IWSJrCk5BERMo3/bQPKK82rmpDootntCpjOEFhrV5J2q5phskj9rh5czbY5lHZnpCiJDvazpJKyagV9P35qzm1xyYJRUp++mmA+JyMkpcc6lwcdPAcfm6aAISALmp80DcMo4l48LdvIwk4+adfRvyCXlyk+RGjudyMepuScjjvddcQUaiWwAvHeubtxgqvW5TNLps6zu21XbyVcvQdSb4JdHqR0XOwciLrNf6VuWMeE9JZaFCc6DBZkflS9QFbb1JeITKDKQTAP5IBsx+/zpavFFJLVRYx4/vz5rLnleXyetMMkfYUIAVQkMd3GafZkVtsELiyYtXWRyeDYG++iiccETZqxoVAPzkqFbTOf1G1fJ8rX0Rlka9six41qrgZX2Y1HPgG2iftyThrHwHwfQhc2wOA5uQdk1W9XbS8fk5siDlU9Taoo1QJ7iBvMlbE2nfyMqPBcbd6sWovDU48sLXBBZh6tQpl7Q6O815vn621yhykYveb8/NuZTcQ8zGl6zfk/H6dHLjwq4TKNrpxKCerzs3L2uFDhG008Radnin6fFfxGtHadIVDGWgrbEYTRrg/SZYmpRUfLJfleaA/0J3MHz9h29dlpzlGHrFf2TPlQolY8ZklVLFg0CchVBQ/ATUgXLz7S2uVQrd76teeE7edHuDZqr32Z+aDqWGrMa1xAb14VDQ8a1bhxnT300hnxbIg0cgT9ba01fjLkC8ixf57wbo1kZCRsv09GzeACjq4YFY+hQAbxrGOUhtXu30nIA8p+eQ6P1rWkZL8Ru+sAALNYHGLooOkBv8zz8jcYjMLSaqKWgC9xooH5ozjXSO3/aRCez8Z9G9Z0NcHdZ0K8Ys30SLW2HDX2V+NbdKwhFzXixS2HyGS0RAC8/l5zPKBH+d2TNSetGWp+8mydS0QU8p61qtJ+FWIol8m5PRvNr23tGnrE8jqO8WS33ZrgMYYTzOTBPMcDUVLf6m1JoMp3YGwG4OwjHe1wkLSfQ9aI8/V1BYk3JDLX18grswCgrMt0k+6nLC6okGn3mt6i0OtLEKYvPGbp9+FJn5XZrLryneKlbY4JQy/SLLrA3uuEd+DcV5zu/062Z1pWfawgx7/tI8KtsieuLUiwqu0aW/zr6KLCzhWM3qPnLBg0aX4B/PlacJqAETvIgV/tlckKryAkP22x4J68eGwZeVCn5yM5YwjbpyY0+UASGkeCI0CMy3ZLUQs0zrjenwSNPO1viGlPlJ+H0WU3kehxUe2oNzavgHS3CPE+RVIdIMXtD5gQKqTi3PQ/gRPOn2U9hSL+L6pK/ZuU1nsGxpDEeihIOI/AXgyeMDLZXZtsV/tOerYektRBuDcpU2MBAXrB/mccX7S2JU3hfW7p1Se+1IgSf7wS9g+r62LqwhswT2RCaYUeSKowt/j1aZ/7wBp55kVzUQtx0ZNyHcBXj/QkiYQ8ajkIt9CmxauDoV39fnUHgOkHKesvi4RwktLTYHJFsdEq/EYOOoM/y6jrieb2mIKSaa8Y2tQXGhaj/cVtG13RbKzOhMOdwnaj1/QEEnErVEb0yvzQMnrLnFDjyrgId8dJGRyBs/fRxXSBAtADTYBP9o2de7+DN3Mnw23Jw7fX0AXGobhHoWFDhgAmT9jW8gNWyhA6LGUy7YYA6aQxCWfnDMfQ0jhndPgMDznTcD/q6syj+oKYlCJ5IEmVSwGccZOnNgEQs/vjaHJvcq0Sq9lBKcZQsg8LfuxzeM9bK/vNqT+KpwA8h1fnu/7jbhVVRRIuQBJAPZGVGUeOkESZQARW1UBlFEJl3H5ofClSSv5fA8KgsBx0zQhZ7NePbx8Y2jWXCSk1Pyv3Dj78ttCs5CdoWnLfP+7DEl5HOucmf9DYVgd4liWRcs/EFJvqQ/H6AEhq+vfrZGb04+YSXDiumNj7Ms12U+W/srrqlXXVQVQB03TIEhgsjy1zQOQ5UlQBEG8nzhjtU3iIOqPMkdGYl21dKS3N5ZrJLlt29T8aRZs8YeS0Azokw3SOFWjV02CGGoVQEh+JFpRpzmiWSnhukedzDkZNovMOkCzZCG5u4HUVsyO4wn+GvajE9BS4uv9AfRWgWIMUtgD6O2DE6v9M9IP9y+7oskXqmqbZ7H9/j74flKjcxTgWq3S+9+xkV33oWiNetCHOip60zsOBjHnknIUfEfAgq8avijAKEB9I98howLR9s0cxT8q3eJLSxQBpe0MubZOXwj+F64ceDnWw+ezOH7pAd8EgaDiSmOPd2o/FN2TN0gv8Bv0p6qBw5u8NaQg/KpC/aNwj7ri68eJT25XBf510/ThO3KtwOHMZHbzJMSD9YVOz+BWipR8KAhQ2F8VkISf8KqBI/Fy9PtJ2BFflxY+wVFRi/qiJE4DbzsKiewQ2/ofnTRfoPIXEVlVx8ODonEs2nVdBO/WcTB5N4NSkuT1ZwrpbBl6PAVZAthObr8fv7tFCNfxHKRHEoHs3Ec6MJcgnD8nmq9sWR+kdSemtPnLIJqWEAuxScNQ8IhuFUxOnB/IkILKKaH5ceqWBVB7vk3DcOoEQVAXtoxlPPxv+wEtA2L4Cwk4O+pPkhCwQKQG2mbEOm3tfV+MJMHv+3CKTIs1cOJ4ooVM0HK6I48Xf/xpmkRzR7cXR3R18KDJ2cITHXofIvyDiyfbNItQFGE4OHQP+rRuI2Dud2zcNK/IkVesquIw5I7lhEOki/8qECjQrqJBMr76JQbrprlppN1GAkvu71vaokTxy0HuWJbroijiFy9OvaAo+rh/WxA+AFDF4hCWFeB052lpmtKkxxmBC7RG6PONPAHMBKw1B6n0iT19WJAJxoDKsw2C+PdUIGgF14t+ZQyS7/CpInXCV01e2L+1Gm/fFldgFwKI5k+tFPuIqtg/N6OrU3aDsurv+c1ZB4sw2ABVQTAvb8YwYv39AMAy9WLOwUh9UHSaxLaB8q7Zz1PjKZ47PG3daAWqrFhM4w8QmTwS7eZ1X0FCeQon0ctSaBIdbCoxalDjMQgHgdD+aBKlLvuNwguUzPxxaqBo5bf33wwGyWjM96/jv16aaSiZzBWurqktACSJ25JGoBIAqxM7O4QlMNXT88+vi8KwtYKVpXAHl29uD1fiyY4Vft6kS8Y7q6esD2+nnw6k0QL7iQr3cchwVz9Szk9+hFsfMhMqM8bCjKtz0GN4oTDGqDUzftQPxL1a9ieQgFRriC9wC7HWqgHBf76pAvbXHzoYpLBGU2fCjNIW/XAKqOs6DkMapOa2olfWwvF66gGA+yYQ3kfHpBD6qvDjK+dM3dSeKAAeKCVtJlJzfNPYuq46z8pKruO2wQz6lTDM3l00oOmBaY9hZG3HkPnutew6T/qV//Ad2sTuSQKbARcIycPdYS4vs6QwRcFT5P7NjTN/L+OKatxFxMCk+AtfVdDNv2RC3x6ndvva3B+eqakVXdURbe/2lEvfn5fNc9GdGJLMQ9ge6SFZoQdaZUwgNyRKoicRbDcT30Bh1ODG9Ku8mRp0aDFal38muTcYtucvAXt5f8oTzUmqBArklpi3Bi9veinBKUsASo3Re1Cn5JtU+j1kqdPzg8+O7y8dneyRhmeSkRJ4ugOZkX7kN4aX/GvhnLUHzdXdimd3ZGMbqrJ5hFP5yDWHVvp+pIP8m2LFyeA3WUz4LYxWMkMQPY8q5CJH6AdX8qzwrfTcQLBYRVtrJKNVTYv6cQI0/KMC/+0lb6iZiVfjhpl/1i8MD+QQbp15Ppt2nXz9nHHQ0yDu/3tfUvH1V43sD14BahK9cNBDf8eH799S1vUd8uICrQ7rFC2O+WZV1XVZItTnCNAjzc9f3Sv3vu++GXOYFwi0otqaVNj0A2R6MvZcs/OyCA7ZuaJ1L7q4Bh2rkdDSr48LWtlMO677gAKgydEWRMXSv/Xy1UhxDbsQr7quUVo9JZom4GuwbfVP6hb3i6O4v8ilo6MG4HVZZm0yya/lqyBA/1lZ4lQRxCi29X9ENQBtqFMwIrEIriPlgmNlZLLsd1Ko7IgdZxZNi43Y0k/ucxMhqL0U55LZqN6U6FdYb3G4Ha+h/lA5+YUEb1iF3zjpIW6MfgRcK+kQ/+5mNZPwM27fce1fnuKNoSOQ3glYjWDNZ+DknszrOj4eiqLgAZ1xAhDwsmSXLtjL/+ZSYxLZcSC0u8UrGhhaZxyks6OOUyUlYlN66lF5NVpMuX7FX0Y1szwZuIeChJpC1opLMAxPR7+gqTjzCWix+JrHLFEqhApqaXWrwU1lWx69G05n8v332ch+XrNtIv/k65yLb3YXAmA9wap/mBfHrewn+2V5HMfv9fw1s+kQhuEwHYzfyvUqh3fKAkE90Jbpq0X8koOwJlOhbBtNV2xlyu9IQQPlOnmyC5VpxAqz1/bCzj9En3ehhd4ZQikTgddoDlFB4AW2N2X1eiL7vWWp0OfMoB4NtnQBem361gcxCBIwdZBzekvdLUhOtSGKVVHnuRf+4UR05wvmDyuAD/XkSX2TMtWaTq1doxhWyRRQKXiR2imCPoNiK4d7ZnNLVnmJvIHqb86VVLKALAuI7PC8iOCzHFOqfnsVTx6c1h3DtMez8CSEtKyqc7IKYa+HLCEE5i6tydeQLdxKmAVTuTiyEbrBaomvdyt5AlMoNXIFeDpE3B0M6eecXKGg6IP+88VOfdtkjwzEK+kfPrmPDvnSHVoLVJ0mFEbWlGh9LbClwJltXHSdozc69q0GZaA5w+gjcBNxZTNwf6G5BXP4onf6fQzSTRN9uPB+nvrxpcs7qSCCKqSr7Ct7CmHesW33nMi/4w9wWPF8UWma4jzjz/WKG0N7vWYQIa95Nio8OWkkqXZ1fFbvlU3F2VOR3CYrePHeMHJC1Fq21U7JcxJ6gD/54HAv7iqtrW9XR/Z5q07QIuKohrAPT+Vm0RStLuIprt0Ffl/yg6oXCxYYzaCq9XjWwrG+EdJ8xy3hlq1T47hxr+NAkzyuQ7VHsrgderWQP6ziHpHlyQyBtrC4EcYLbPF3eTpbi6ZiwHBA3TQICKbqXdh51J83kHhwttN7WTT2fJfmBOXBxvIZxqi/9EgeoPVxY3J2L4SE2LOoN/egdak5Dt6KVbrYYafvfwSucmtC+7/nYS29EzydYz8NcahxuuYGssjyhC6vjFNkaLy+4vN6jHcNT5t+sp0AhYNSZIdWV1LGYWYNXJIDE/BbeTVOR3JrkocH9SFKHBWyuPwZqnYhA7ZiR0rbShjBCF2nF4xnjBAgddITPSEX4oSBma+A9ZFl6G42aFdHUNMRI2VZPvZjGfCNQ/cuafcAMfkAFr2kaXc0Hx71Xgd/wbNa/FmGzI9vJ/HLuWXIMV3xJg4+sJoBbwizBMZGGgkq+o5B7TqukvU/bBAL+zyJsjo0k5JrTmxLRRJDHq9ZcOB17Ox+vw9vwmqLNxoUWmePy7XVRQljCh9JUnnw0mVZjWNSCAswniaEqM2mcG9expjD/TBjZeruXBNF/aW55/DqzXHXq0/txgfBbImNZhRlGkY+qLz/XSOlfgxl5NGwnOGpvYkiTQEKu9YX9PQUAk6jgEMm/dgpxT/lcdKM0cAXgHqYCUzAFeyO2HYpxGxQwngehuEvJi+oPSbSRWfo5RgFIxsjdKGHHQtW1vafEeoYQhXBVW/C3n9r11+Pc4YuUNzpOPB6Oai3atw/+fdQoJp9Vh/b0/eDxs0g1AGGEaRYb7Y7bKuKAqCS6oOKm6qf09arNOQPtTFbiSUS4MdLLDXLEvwDuE6DPZ+fySEhOSMfgt4exFvxr1dqamdMoRwLrPrLjeITQfD6uHm4hZDJCzZzy3101ODEFNw/kezbax4Qc7/Z6g1GHfxYlS5wDcsFfO5ScgOfzgBjfmDwB5RanOXNSwYxw1QcEP4uiGtVayFaHehWkhn2dX05J0609dGrJZaAJxfWXT8xyzP4OaA8k21ZsyXREatG0wMxlIE1lA3gZGVHCQOFRxLRcmlnUqDkHovE3upuIE8P7+VptREK8Eu9YPKOv5K1uBHdrdC7SrYXQvmpKTuKNVEjxdgXmuXwYLwWnAZpYJRuGGPiZotVWrGKfHKUKs1TvGZwHOPMgk3r8nuf90CYpvBnyGMkNnLewB//wrhDKk1MThZNLQEEF0znmQUAKI5scXSPFJYsWrzaHUUCWWCHg0Ovy0ZeywW6eR3233vun88RXgMxEeqneS713Pgw9sP6z4FxAncUXaFzr8nYxfsEyxgNSkRvhou9LMKuilkWbmzvV82nfWCeIkndfjN/VkfJ+sqmbhH75qFnM53imZE33iWoGac+ukBK2tOjtprn1WZopKDURk7FyjkduCqAB4oUcklZfMjsPPyIThPPcQWl0UTGW698F+vbdO/FtslvI2d8snlBIh0JRAY1R8zdHSF+AQbp5y7BorbQZUhyBiSm8k4OZ7qBqRGW81vEN1mwX3MgFfeKnfSs9yM9IqZ8zL2zfrTtaQQfEDGQWt6zTt4LMdUxQdFPn8L9XqMU1HfujLFaun2EAqMZ08wDetG+W3vRMj1Vkb61YEmIta4CtMZ+sjOEtM92fhcy5Fq21WCFo3jozAOmaQFwJzBbHNHmz41URVlzgfbLBbmwQLVkQ4Qpiz+2/97B8ZiLUVcU74B5VQg4TJ6P94VyujhYqwKxRu9A3R+yQo4lX/TZFrSHpeJsVX0zCMQnFK7Zv8ZaW/tBWt+4V0Zrl0+m4CwwznMsCgbVtAUf96gBGRZUYTlA22C0dmsg1TQvQJvlYL/MPvNKkOS40zaNuE2EZ5sm5mECL6036F4ibLellGH2i0o6yhQz8wzj8p13yJvlnRSgdubA0jnXGG1dU8pT5tooqAZu5S48Eglv46CoAhDAop44ju20U/JqTIzI1NyqAAoOFvBJS19lCELmcgVlvTimSyZqXmbEmmfA+Og0VmvCFSoN0/qfnb9qjvuUEC6VdwX92i+Gvi5Fa1i00qUaZs6WI7lXdwBkuiOxyqM1RIvjrFfvyoWMFesDRJhYh2rphyGQMkh9hrLI0neITstZesVQKT9koqi/XLTKk5utgENOmW+fIoKFzeMQb/RxutouJrqNjjcuiGdvErqP/CnLAkSU9hiiwyteTMAGBnZcFgyYVUc6IaVgoiwdvRagQQpy+BNErWkAV3kDtNk7xoddu4+s1y2AhYLPmWCidfGPuj2JxB7B3eBmo0W2GWUPLzqvg9RNJ6J/vjHxwxew/LvIHRZ9UDDT+Wwmi9ipui5vqZ257kC301JE9/QEPKNYDcAy6MuFd39Tl90p34E8ObnZKRCsVNMqis1PdTOK/LVnEidg9m68Vje55OlUZ2ZGp8ReE4DjdZQMx7LP7B9v4LgPMxYUU7tcA6iY0kq7wqrFCwqveroGTuUGro0Ry3iNUIV5pmKrlJHUo0yrOooWkEk+62Kw26NkzJqFIZ6eSVFXWJIA+vyPA8uVFfwVIB9UkhxAZx9ZNacsfJerB/thEeUmU0rqMLOAGr/MOdhZ4Z20X3MU4tEkFlfdiswzxquyq57fPkQZJqBRX7qj6NNph78Thyut+wws84c9vYWZ2HFnrr5TzIp8zXR/ytqsnrvySTKisj0xe1OPABJYKbM6PTzIOuOKvXprbv6egUIYv8miKPy+eC8R1bPxE3UA3IIR2NrdIagamr2TK2tz+SkMN5xaN5u4PfaSfu6B3rpZHklAs6X8qFTII0VcG/kiNp0qGy//5t8A8uqDQ1mynMCiSUCiGemAee1ugxV520Qloc/4fKkg2xJVEAd0wTLr9VbXEZpXWotvu4ko7K8aksGdSKpDIg97PgeGkVTqQEHUDmstNtyv5KysyDrV6Rczdd9bmDVGSVqF0bLFYYebeb6x8s4U0gJdM7XmQx1BYI1ZeZf23BpmcHkyHshYOTpmAcSTxmICaj8KsLzPYgoYcSK4LaFyd6GsKX7r9xju/crRDfuWd2equiJXj3k3+4K1vviWY5ZA4RtFZdRdDXKNwMMWlIAkBaT2um0QeOgeRDPg+ykNkz2WPNH6/aZMKeWR7UzG72Stk/jMKcybiGme3g31qY2GPTJw2XTCsemYlDldgZOSkkmV4GWSkU0Z+/xTYRm40FxWsT2kv7p+as9rvDUCpx7KdLhgChcTNNIz7HlSuXRkygBxhpRbdq75GfmQC7MpUkJuT1plTf+Ep+aYUouraIPSpAW6copBmoBB8QJBmoTqSH2Tp4AiVH7hAVoErsra7JsJ4Z5+F8iMx4g9zepFHY2dcJdQ44Z0d8FdxsNxLa77W+EBmPCqVf2e2zcOG/eoG383q2Bqmsb2PKvqXD+YYrPcwSxuSju5DO8KUS1VJ1mVunXgeC2m7JDd/BM7OzPYUWgSxW8OIBBYovZ5b9ZXXnFQM2jsAb+gpeqlNMYfmiX4AnFKpx9LgfUqu1qDcv5n+3NlD8j6nnv16lanjE6XLJrXfvkvQlWd/63A7mte2inTIk0/ef2IZXOeuOUpQuU3Qh9d2/UmdxNQ1XW1A1xl6wQXaWc7XASn1zx+nRUTN03UxyqgSq7L2lZksPwVg6+dqzAb74N4kltReKXGT5z/6HBGCNwewkrc5WB5SFn55DcoW0Hr4E5BI+h2tNTCz2zctyXSTlxhWty/PVujFNM6GXiB43+sMc/O0MohQbJW8w/eXjRtADmY2T7BwC7xxofi69dYKeV2/e+uYGBOwLEb3VgbT393hf3H1mRm/nN+ahhPWgdLDM4KK+FBkB9IDw60AMqouk4hRsC2ZY4usyiRU8WO9LjuIEFAAzoQG49bZ0uAH/uaB7JO1RrBdWpjzSod/WamkQeWV6HNJ7bl1gMRuv+Ci2H1DxBuo4lHmDdp9as1QOm3KG393Bcy3PYOIpbCTI7VYpYhtZri/l2uFmECIIgxeAGke9oTvRp4Rmc4V0Jli3CAboQtymqZNDG9wuGBIedIfz/ZuwDfT6NVEDoDCBPcOiX/xgzJjs45RPFz9BeY4LuQ9faiU12lVeuQN3chEs5cKzbspAsS/boRowfVZ6i9MANtytoFEkU7dwzfgD8nvbX7ijZvNlXojyq8PXVtVou9gIex1/TjQU4bYLVR2bN/0/iRnq+XO9cCtK9okGPLzKZgJzqry/U+SAVTaoSyCipgxRceVQVPQiEL/ExwlIEu6WK6YGugrG5TYcC2g2Dt/da2VMg7fVbTlx3eWXtA3L0oewBS4OCPA+9JzTVwO8Ya7GJsNvQzh4sWBVJfFSTxDwUiTFJmjy66P3mRVrFfOI8pvjybwsZj3QT10vWTvzzJODIC7v1zTJRWXNVoTj58wXklpUPftTfybl3/JCO2X550QYxZ463LnyKyneD2WGN/uny9FKjgSOKSz2V4/HAaOGJKZoXu7pjRGCbKu0ZHeHvHZAyDmz3jXYeVbdtFXQalj7sT10gr239pEKUCp4QZIDPkr3n8qs0/9VfMv1Q/HE7rnR+j+V6/KLCi3QvzgiVcUCp/4WwrsEuEZEgZP4FrwAA7Noy40q5WQ4+ziHlM/S5q2RI36VTXX4MbZObrXitf6T0jB+sNjsDttv1A1psuIMZx7PKrsbhZ82UU+11nNuJnSkD2a2D/ffGYVMCN7u7HStWyPpdETex5/mGxQUdwfOX/rFdbL9Qa1ac2wx36sdVM7Iisjw7sV0yTyPnDWpAa4j916/eJihkX0WeN/O2SQ9JAH/30OuR109KtatG86JO7dXGknqyGTpL9dTkbvBJ8ChSBNX2X8FCI5lWsfhmEAefgij5HkgjjEcW0MLC/vBleO+qKNILtBjf46Dbxe6RmeJlF2ilTEvutsXtNPngcelg6UfmrBeZDcuiFQyUFJNO+CXXwZMUdX8VFP57fIvWNfr/+6cqf9nUqQ0QtgmMCV3rGEPZSg3Cc592Pe/K6HUvjApl0FNlfgAnq6J0OMWAk9b7PtIeKcWveAywVb9T9mi6WO6aiZ2HizdG4Ol7WzsyH7lm2lgs1EqmSpl2lJaxsCjCcpo060ou3/1X7SNwyHg97gRg88+xcd5s88xViC7AZgez83srXw5DUqogGnClKHPCiqZuuqFtNnBJtbjgdkbmRsq6YleaJG7CQitSu7fFMCYYXdnZ6DyMTFxJiZv1wpdv5pWjpwUwG3eANHuv56XM5we2XyQ4rkYrfLTfDSCBkLWm64fA/+4wX0avAiXnx5NipZckJtmgFlW0qhQb1kjbv3KDqKkHBSEB2/WzNn9RyU/ZrvS7hsRoaWHMK7EUQ3ikoeOjGmXDghE7AWmX129DplJQNnWkJXVAfOKdQM08IGKXiujnB3zj9verrvjrI9a0buI4jpIsSrVovOl5XT8wnF2uaam+2a66x2ADSAwN019UhTX4ewKZf4ku/Zm3bf2ebSB8DfR9icL4/KbV/OFHZ1YL5m6jFIdSUN3xRedaggwWoF5XkMBdPqWa7tTXBl80jIU3X6TmtDp03vMMZxYRFIZVObSnvw867WTVYMpiAjwCNph1pXtJl9l4mU7+J6rQfoxTAHeD9tSujT/M9iF/jSUNWtvYlRyG5XznJyRcSkZERiEAvJXJ5JbVu7xnDCpUiLf9+QqSLO1xe04fDSnO/j2sCQue7SeNdRB6MstVjNdWqkPJcUCsBKQdpqNMvvBqJFDlGe1gseNebXCjrXhT5eajq+9lae4Z7AmGezqykBZZD2Zo2jjuEau7/4JDD2xsfiluZBDANvdGFfqGvO9DYvF7lu0NJf3kgtpjmqzuyxYBTWLMowu+tpP76/bhHzgRncmh5ts9OoFdeFwsh8YDKlod3AbxTcn4siykN/6iuxfhm6AsErzJTH8WIg+tuFYZct3NpDgY/NQ8gxXKYJemcI1gMshG8wJ9YcVXaSbkZ6CbfZe7mTyfO7ksc6BqDg1g9KW3h0ocMg7F1O/rpqD58MlpnB1d1x8Uvz/mlO1VVNUjiEmF+NCzkU5CGn0n2n/IEPE7rLSwcgN8Cyx5onmJQnuiWqnL0L5MpA/Inkb6f13ow/A1aIUXyW343lHzvzO8/NeAOMquDThhxTR3mMZq74b6ZnvhK4eoUojXcoRzln0Xg68IoXcWkkxaAHxeropiFA5OlFS0Dkt4O2nqic57fROFDRGlP7DMghHNbNknrB7eWygp1n6fejqgC400M0pi0gLwo3j46LPb3BJLLQb3rJ0UbGDraSjZDOcqCEzMPZdGPFVvFS1F8iFLGt8oUFpgHDkr4dMLgpw2iZjhvx7KBy8HiEPBcKKTsr7IcK4CQ4ijcvttyqIXVoF125BQq5aeBi4XhNOoH4g8vR759sF3FZgZaBGnuDJXdze56JxCkFvxuDW/vYE8l8Ixqlx0XZdH8NR3XzxGrtMKjQpyz0IFFaIvHgmVYwxN3Wi1TAilbgW5Cjwb2JZRWqJ/kjrc2ZT/t45Qw8ZR0H/NUkxTPybJ9ldJp32ZXqMQd9oxzZ0LVqxVbvxznMTGosuvVAaVPnwP3wEqLhY88ekvpIf2VqZpGWkT1JTMvFZJ5od8KTrbAlDEUT0AVGudAexUF+qQHxnNPsYJRe4RfIBbb8cFx8fWigr9mr58DV3fL0jXUEyeAZrVUezLWMvb3bgwyrHJNE7cx9RyPnKaWQQTW6AzZxx5hw3sTPkQTx/s5KuweVVtfsgf00oUD6kpo20Q61zIDf99jfY262I3RFhJ0JaUwUVydEFCGMVzAmFAcwyQWF4o7nbEoT1Wl/55H2gRGW/skBAnWEPTronAx+BPH3vmtcXYJcO+k+McOuY03eqodG6dKJ9f40FjvJfG8givzrO+RW7BRIk/2CrwFRUOzQdeOw7h3HuGt/3wlnjNHx79Yz3V11wgmKTRqWVld1uF6s+P9VjQp2q135Oc2z9xTz4q0W/bsUX10ayW3qLLwc/AtAq4MhhDxhcjMqIlppei6GgsrlpOoPwNgWO4cyG0l2kG+X9pnUWsJM1yYM9wY4QZ2rN1rqr5TcmiIWt565dgYzMqVCu1SltVXQXh7vxKBHFgODEbwmktp2kpQIs0reqfL0RZhEFeICFcmbT0ZE3C1PwhxJuXfJnLZ4K9YaAS/IiTdLw/Rmpb/7QfMbXUKs1zS0oNmbHh5GJo98PVR3YTo52Q/y1Djw9062f8GYV5Vv+4SLzyM+V2kIn+zObGTuYNw6DooY+/nMUTFXIV+g2vdAQ+NWwc/H+sX805Rz2s1RTZ3TseRhDutW5kkhlQqrrrpfgmepYeEvpmdizavksd0IRC6vUPO68AFao+16tM/mxIZa8oqr3G3ClEuhmWGqE7LUg9cxEJUv+PiH8EgkVZuFQvnPKiTfiWyC4aixaAkDC5rscoSyMQu+ryzKJwrBoM5w8EYIUDEGvIau6O/WAsoLGP40y+VlajhtAREcDlTmmWY97eBPyVumYUMVlD6lDuJbPVQseSPpPDO+jOtMyJbKrmFj3pvDLQxI+cK9IrIYXFpPUP/8D12V/bTa4VBwCHFMwYzI6aitLtocIXlmO3NBWfcnaGk7Fu6tkxv1uN7N/kC5THcQual6KSK+CVAst3XLeBimA8KpDsaLFUQ0QtKI9FKK0OxkShcRu3CvCioFrBWuerWzJ6hKI95BHXgxuNWwylZ3wmuKpCjJgEP747bJit+LzftO1p0e2Np2vrGGdiY1k6q1h18MCDL6+FaQfYn2Rs/OgjZw8+UIcrOmvMcAcf4T3CVFA4HE9iuS9UC1tnl37XVosIvM0hzq0VISCGDM0yANca00HT2rdJl3/vWxgHi75ydjVs5h5mos8jRvsWvZvJjh86oY2+itikG+8UjA9eoF11F+gLnOBQoYmPh/bO3wJATlcDF3awZe4ES+OQaDOVY7c/AWVvwUIvPV9dYF/IXIcYL/RyUnALJWl+/CJ/olDUWXlC2DJ03651BPdzNlx04SO8YWblXoI13WQSZafvFL4TGHIjDW1jw+YU+JB5JTDrvT9mYxth+dra6W0c5hStyTb8Td1EEUfUK9WOL9w/t7VjK+jXkXFNaPY/gnXJZTagWsnYebdYLTT8gpw65Fn673SQrUNTlne1YJEtyMo0QzXQ7c2ScWfFgcyfajIQO+yq8sEQrXGRfAGUvmwjz+sO4+I0VpXTuVQvXek/UnTxwraUZYFf1tNmBkTSDAzC4lKXHXSrBjAOW1fOIaUJAZp3G6vnhbZ6VcF7isuiifpTSCfeb6RMvJkWDdNZHS9bEEtS3/6zdB9wpjbTeSwwhbT2c6V5AErYcmPCk9F8TS1/VrzxjH/Fu2TNgdouvgpINX7xHZk1QJNwDvCvaxfWcKwyJZxsZUDqDiobxegLc4n9GdZ0cKjieePqLOjku6fRxWCcsRmz9T5CL7A9lGMoQ4yY5Eoby8i8UpJcarMdC+7cGAYX/QehnCSeP82vgX/37/oIUyhJOmGDB5Pm0UWiYuZtzSvt5nYNPCrxoLZRo+bWCZ0qbqVWI/VnnAO55XnkW1EbbkUqWdqJX7oW7puUf0JaSdwLOK6OPPAAj0r4weFCnRT5BVJB3Z6AQRYOus6FQGhUwa7kCt116KqORjRoA9ARv+kN9LxArAvdVL4pVixxm+7Hfk9CQXaeV4KvWuZOO56Tl1XV9IFrtwVqnCSLuxJR0hg4gS26VdXx9OZ2E9vGU2FMImFVxrOvWMBVw/eQMBSQa7+q5qXW9n182mRfAwnZqq0qFwAtaJxPXD/ipCNtR+MZ+IZ72TNSM02PiqldBXTraFS1WNKwPmavCNtTSr9kNyV9JHSTLB9ZIt//TrHQoG/DEO9GAjKMugrZgy5UWeu2ILscPY64P154uU0BOC2VGPddO8gF7d1fln0p47qwM8/E88WoYa5SzFUoE66w8cBoo+Sl7K9hXKwIJ2hcAS66Q8rMywZ8GqjqjLVqFzJ1bbjj/iuAoGMl7PeJE0LMXhSPZyMK3AnxVj/4hH0fj1ZQ9ubtGaYUJaJVESBnuI0K0xAeUYY2H2DRwRTYqGM7qCoJeUSQnJt1rZ1jB34JS7ASshdZHlR91fdEmTn6ki53r2RQuZDO4DjBZQTRgUS54lyuf2CtvCq14M3/G/hd7T8Letq3kX8Gq+1L71XJ46Wpq7To+Wr/YiWulyd79IBKyuKZIPYCM4/frF4NDIHhZip3uO/qO1gIwBwaDAWYADP9088vgjN796fb29giSjL8Ur/LFm331WL6Uh3jzlN+zs7KbtBZNOU0piTheDmn9U6PyFRmdJFhhLiVfDQnkqrCyKcg8DlZKU54egK1xCiiD6WWGoe3h4eEPL6GUZzGg8v9xui5yaDSQmdhl6hPIAVCQo5MkYwTSGiRxeHcUxSzM0pSE+d5+helhM9M6UQRkcVD5DVRNQyJAB/5bSgar0xsA/jzLEpGBgzMAJCWS1hxSmuUNnPi15+wrmUhwIy6Xo5i+SOds/erFN5PRaPhKiymPjBhHWlp1Qb0l91y2G7IpuT9RyQ8vYwbiaoV8tyZpGTTjvxthgQOGPxFdyV5LNHWUM96qjBKgtmWndxxFSDfmSHobLDiKdDkgkPIxrIVOE7abIkWzkMbr3MK1YqLsV1qksvY0uQWkeVTXdgozqkxIMXEukn8hrl8hWWZJROiRKsrSO/JQrCstz4s03NtHkDESKhKSc/6yxQK4WmRhwfivVDWFn3s5Lcg+1M6TglYrFzhhZN+2D8DdWHWgITf2ZFhNUO7DrDV5snU2k/6DyquEwpUYEKmZpVH5xhqM3ob6pM1YlNMo+cCHmHQic5o9JWwL8jZDd2l2nyItSqbH3UxCk/5z+iPJeSGmOYnQ/OEH3Kw7Cs6esdMfiqm0Zz+8LLhU8XRDEmUURRTfohcootl6DW245cIbphAkvYEMcQTFKcqXMUPyewSHTfbVdZr72tjW7RxObeRhHOt51g0Wr8HgWIlTO5YD11fAvbrJPBP/eVW2sq9q+YG0ygmegw3PnuBZZwXyTdYfsL1OOUsRJLrS//9mLP5TT04EmtQrr5I6X1KLKXYdVxtj6GQwfTEvkkSbXa0s6Aqn+JZwsFxIZScCXpnAoGlFsmj+MnuNZiQv1ofzOEVnUZxntHFAvuZa99subFuuZgWb/5qSeyGc13G6y2oGoLCi1WFBkqP2xcvCAAuYwVCzuW6L0a3ZU2N97Zm6mc8G5aSeealuVI0RrdrXLqN6wWGTH1ixro8WVL+g5BZGqVhPj6/eI0st1XygO1nh1nFst8QhJTgv2WKMOJywsAc2Pntw2xFCszK+FJHPMQMSHBsBc1438ggjpju+tXX3HFsgrtNpXT23/jkly56alp6a9vLjF2XZayM6BlK1mQHAZuf8uqzrp5tiuWdZU8IJ9CjvNU2R2GL0ZA3vblqvqG/Lba31x6bza+DjNnNNL1yNgRfvgTXG09kDA4s6y3FeMD5QBixogwsE4A1ZZTlBp4Td8SlgQfptkL4kSeATTH2Yq/3L47dlUK8F0hOAP2Ea3WNK0EUqvj0FE78MPWyBHgroM0jFhi6zW4vXQRuvAwF0XERxDchz29hUMs0zrtekDDJugRgLgLckv8/oHcx6mCD2OIzaOBwJWLAtNCV5M/CwDXiohiIsaJw/NANP2oAnUja3INBrShhJQ2JBjtsgx2WlOyULkjIbslVbpWh/YYSi4zDMijS3mPVaVceTJIu58EBAZ2xAvw1QautHfEfQcYLpygZz2sAcSU8QU5sKq4dtjLqepDe7On6LXtPsnhEJaJsvza7+CJCpCSoRCbfyDaTxAofjyEoLaX8aCgBqllAhLSXb7HAlueav0cXpWf8GzQhjXNbGaMURoVBvRRIaty9WnMPbbGd+mE8NajH152a75w20g9po9IfPLZtqIsovlJVUEyMk5SV/mZyqPBm5caccFmNFzghOYrXBpDhHneIcf1VVsztZkmZla2znGwUqdkrSQYOISsh59UbuvZ8/7HnjA6Sd/BfffPZG7vBV1wgEXZr6HnYt2l39lqFFTFdi7WLLrEgiNCeoWEc4J9GBgsGNWyn1dUT4HCP7/uVLpgx2X+5HD6FNcsjpvMTRp5jDPRxitv78L6Kcj9TF2/dnl/3Zcd9xnNHgRYLT2wLfEl5D0v6C9uRnGdOMEyGUcnJpBhs3wmtyPmAkP+r9OudQdz3Y060TghlB4ZKEd2hJKNG7u0NQqUZNadhVW9+xjBcUrwg09Z3OptoBdTgFCVSNorr1zZlxCD7rOaGbrzmipWuFSflPG+XabfD0AMzeNgGksUS+Z6aOhcxrQaaK7QkCqt+y4bGI+S3Ehm2cm22QjSjQiEzRoAX3uAV3fR9jkxjWSYxaSLitkrd3ADaBcRu2NtHbqy1gE0B2Yl74DCCCpVYp1pEjfnFCIfyqq239Wz/a2W/yIQKolh+iEZ2YoFWR5PEaAkD6r1771FCRLIlAd1xRM4530BSr/bkg9KHqTRqbeM9WOBVtuvz/k4Rg2oYEDOtPe4F7gL79dr9XDum69TBuHYuO60pWZCMTDdCdndNykKhgor9qKtc0wW/QhFJ27NFYiHPpVr0U9J5Q3gwnoCSGJpDSymVyatd8yurCZc/18kLEltn9OcF5QQlTIXLTNzgL0dTMxw8UNvhAVX3H0PkFqrKlrIWsEtAvhpNVlsoAhghTIIhQ3JAopuqjv+uM5hCvrcprITuBYoa4JGC8InM65U8PkOivWEVQniGSihkX54cd+44geG5RX2f3hB6LnvzVSFu71nr3ACJMsxytgVcScf6rwosZKwjCsgVS2fjtYImYMbtZMc1vOWpsf/QMflbimNaGqJbwvfZd1pOTk5ad86u2AyFtExhJI5iUF1D6hjwwlWxdnfdQUNCjbLGQv/E6zjmyvxAoUtQ234DQJ7faqDrlbSJojDoQ4oQFtddJIQ5hjELrpVJvAOvWcvdwj1LDEEe24yB0FkmlZXDI1qnR9u5CnUK1hq1CT1GRnhbkvxeuCqY5okItYTbfoRUsvyhbE5m0v7d792zHUFB4lFlg0P8qUtV9PMFrsFo93XP+QPoWovpQ+ZKBx5YtUK6WAhTK1gfofknAmVJRzHy5+fI6NIefqiWaF4sFoeg+ThJwASDMHcEMxiLcWRpKTUMxJPloF5CxRO0aCNIL9KqtgpCaXCh/60VOTyVtuY96+q+ewm9Ufzg1QU0S2ebbtg3Wd30dpx5e50ESSgAp8MFR8F+/uXmBLo1217F4gaTQDnnRSRYRdHSEeMATyW9CcPsEgTJto141qaTsg725uvnu8ryii/dLnAudUjg4PalPYBBtBZIQJ9Q6gwnGfy2964ltBdo7dx10hM5mJ9/957ur/ercO3dhgkAbTpshsioSYXNEL5r6e/7Z7u/kr6a/Z59zkkYkQscsjONqR/WU36KL73k576Saii1z/2v3Gm2rxHnSP7E6MeNS4Nj2IML618frvzXy6gV/dczyGdPM6uivjtXX3CiLT6c3Mjwuz9eB83VW+GvMctK0ohlflZH8NMbc37/iHd/zD74VMN8e+AfArfix39NLm3FCLQcz2MbB1M0HLviatbM07WFaqAfgi/zuZ775cNXpWw6+0Lcc/AP7lr/7lkZ9qp6cGTM61wv2TZbjnKBLPmSlQ3kqSvf6Ll+YswRTqlfmDhQ3QL2OQ6CgJRTG/7Ev7do7CLifhFhICUnRKovIl7hlylqec1SGLcLuJAko3spNG3axCfcpgUHtOeEQvtzGySUPamd7C1Mei4GEEvA3Gcx3fWjyhJ71zgX54yTpNXUQKrfq4aiph3CXCWE1BtwIbBxA7TxLE/8E9qu3pQAjlF3AV9d2cfc1PhWrB5yqE3BoXWEYMdXsSzi3rKJa5DTZnQMU47/iAEWTRpwscXpLQAeUCWVi4ttqscLhMk6fMl+fKyqkLZZZGMNJpx2wFzB7gayctlprqbKv1kFrd+zCdbqDF0qzdOxid1FuE+4YbBPugHajetBjnvC/61GP+jcsN7KHLgmLpJD15IKeU5xyspSDq70ADB6KspyzJD8t6g0GBw7/76G3X78gXP+ubfVLljWJCQMsZBZt/jSSFkXFGurEH5WaVfaJQJ36U9VqoYU4/YSZ7q768uQwcPSXJwNHbyD6K9bPsyJc9nGovxVqfT8YNg2/eU9MLV/M4Dg9Mj9Ugx5aZX/pZ2v8Z5iq4ELITj/TBgf0bVzf5pRns63GYiZDOAV+69NHhaAsTvgAv2nN2c3EBSo1D53pxzi1i1wo+u40u6+Ue6L8l7Vd6ovSS7swEIVXduFgOlvGi/y7hqrh9Ny1S0bTc88uGU/PfbtkMj0PKqw70/NBpcidng8rRd70fFQp8qfn40pRMD2fVIoGnE+nUga8u5WyES/zzIGusIV6cnw8bVzB0+gpyxuMrvLEmQkqVV/7DCZNh785TfrHSd4/JcmTNgac/MnxKVC39XTolFgYupIFcf9knn2evoabKWgmNlsW2wbeK8P7FfgPMbkXu04LuNO/b35WYOiZaxRL19wete8pDNsuVrittzbqFzVtjMM2jKM2jPa90TrGURvGcSuP9q1OG924Dd2kBV3teqmFbtKCznPa0NkXMvVND3PFo3p7aND0+fcNIUAjMcorQAq49knye3mgOM8S6zbcdAZnRSQy3HdcFAQtVXz3Nhve+zgPl+CfM9kv+Cw3IqIR+sQBesAl/CEB1SV0+5ohIJYV4jlJNwOviziJSBMH4mPgjbQVzGPE3f3HHqZoouKyidg4SySKau3+ZErurVeGbdjh9lcJPfxEWONe0GwljuVq6GmRdqO3fbW6cwjo86wZOeOtJHa9T2rFf0PEwaTGD2+oOMayfHAaoVsCrhGOHoAkZx3Fqm/QTiAwPMBsU4qtBqeDPHzoPE4LounD009D29AIC0phLpPPJCxUMC9Oy1SLdFuarynBd5rgNS6Y7K5BnS0MDyUSc4DblsgsJ+uNMywwE46II4XyFgJQZ+NvDDNKsLmcGM22ylO2Sk05MFZe08UxZ/Op/3qY0IOv+uvrDIEDP0peWh2DLmoMdYgJvihf0epJKnG6JDTONR0PbsTWcTc/HaxfCO5ZV8J66k6YIC4cWn3zQ08UbmAlU6FwsSMdYdUcs05m/RHvZAtr9Wdk9V71uobXJm8Ct9aA1HFuyw6IAt5MHfWMKCKqXd8D8WRqv2ZYFuq37X6190La1pJCSkUEzwpTgk1D+NV+QXEEl7gpEVEA3pE8DnFS0zt95WaBV3Hy8P0x3CU7+Ikknwi0P2A4ZX1GaLxAbE2SROzgjnpyF8mZ1zyJHjTOqrnsiDKREWrrUagadPdpuy5182qOeARnHzCNYcPJzHSHVVSXWspkMeM5TgM33Zqk1bphGApGaF86H98Dq6/692R+F+f9esXdMl8lDeXg6zaUslqhNYfU+KScXdI0LqKidUjGdSH8v3dPrLrgXhz1rIGv7lnb7jrrh2T23nfktO19ve473/YTKBun24bTb8FpvYuycXk2rnYzE4mzVq3Z1mP0xpfv5SfqEOiB/7vijfpwOGywH8gYEGQsSH1X/6rhrb87dPTDeWWuyxJQ797rc7LOt+P4PudO/To/P6/TR/B/BzkKK8jQb3AotBK75pzMPHzpDLyalcA64N63n7kY6kHNF2o9j4Re63k21M3qjS1+wXxaUbsxAFpK4VpwcvFsS3EBuxXD+8Dmvf4c2Cbk1QlZaPVFb/u909DaH0UezPwUr0jDqJncC+Y6uzzEko8Y1ICozcv0F4WpxnE3A2vM2H1GIxUh0T+bcp88mcVrhfyPX8ij9/V5hHUEXlwhzWuTAoyGrVwLI67ZhmtZ4sFhN1u14OhlFuLELtw8kalGR4/TBxPyE0LeUK2yPv2R4hTi/KYJU7VFIvo10oYJsqT0xd99ELkwXaU3VeUXg0LxzZSu7x++aTTL98s4J/VXVg0rL6yARdL5pNFRE+6PV3Ear4oVGqNwiSkORU6Y+zhfomK9JvQAcVqEhpiRA+T0JwcIiwioOFX7p3/95p//8D8v8Gr96o97+9/126e+v6ONsTckkb+G+0CbohX+nJD0lh9d9AJnMtQ63L1fEyNS3xrYfAbPYaKCnc2TzshiT6xzGpM0Sh7Q252NVJDjW9bNguUBXj38SLNiLemKP7+E6DJj+TP1/SdA1cZBuwUJ9KPNR1mQjmwLDzX7chrfEpajl+htlhK70jWV7y9nVWPzhtA5oRlrBPVNtQC2zdJxkS95uQ5HN06uIBK0txkcvW4q2jhaxekTBuppi2igV6TnXZ80i12L6F+JWQzuCJ1vI6k7rSJPEYQ12UNVeRhlkNngMBRvYCcTT8fhLhYyE8wiJkmExB9JQqIDUSr1Z/OsomDyVQUl/LyVydvyWqt5+R28cU9ZTnAEogEL8T1cLzzsybF5J+YDTtB70fRGYtllpI6THDQwJ2hjfhYZrfCg2XvMQRp8qf23rNBAHpnPZEn3Tsae8+WbJVUurTwCJtflR0xTWPWVIzjLVvr2i+SCoRV+QJSwIuHcpSjCOUZJxhiorKgzKW5g9PQ1pANzST6j8qIPLd0RZURuhw7bhTl8jsV0CGEKkubvyedHRFneFgxNBDOU8Cc6cNl0dpoWqzmh7F2aPKiInVJPRRydZNGuS9HwVDqxZq2R/1IoVS3nZ7ed7jWNuQzFoAG8XS0OL7M0qjeQLL1fxjRSlBVIYyBDtNMYtIbaElFYHptQo+eYUKHr7iQld3pzeTY+QOewa2S5XelBpTs8QDcEbtiKRyLVZfnm+CMHn3Ebb9cEUAOwHwh9EPW2cMTFQHSWhhlsxLsVBqJoVmij3Le6SwBhl1KPrVhcLWjd4jzoV+H20bwYrBHcXBOXRacz/heSN6HeZ1kCQ9QNJuMhEk44YuhKXCE9EeVbwONIApevOHSDJfEqzs8hM8UNzsn0En4i8RtBQTdwmgn+5LXg6WmWfpsj+UMybr8HmL7Ll4Sao/smVR+xbJHffVox1ag5kBfoka75fuZkxs74OONoISkF3MTnkb/A0hczjZCDxD97lgEazeN8hdd/LnDy6IbYOEwcTxRTbhnzpFeZVgNnOnD+UJkRzjQwZZI6XOrTf/X0nHKmfhXWc6Zetcx1pm61bDAdVFtN3T+YmVe3HzC1fpb9tsdrZ+mxkGNJb58kvXapuI4X8P5WOzyeDKfj0WG116PheDqqFg75CAy9WtuB69UHyx8HU7+O1xsMp15NxN546gLex+Q8kxLaLgBdvdAi7v1YC0LnEFk5gOAqpZXmwtvOtQGu2zrT5s20s2Sz4D/Bn+niy46ttct30rncttrE0A2m5QdA1xnN9dIs6wcdsMMpPBSyH1YZG9oON5I5xgxdAGpvPq5lMzQ07IC2s70U4GQgQzDkR5HrSEKTzWbrbZYLl4QzGAlq3ZCes7FPGkr4IiAeOJvaBoWrDas3CSbDkTcZTI+Te/zADCNt3Xbbu22F7ccdCuQ+R5A+9Lztt+q+16s4rx/jRawdV+2SXuHPwh/3vZJDrg5xuptc0wzu/uwezwo9/6+nF7PZxeluDkjoBZ3sm5OqOr9Vr5TGGYSgdmVg8AQGKveOP14fe+h69sYuD6AciuuRM5LCYSS03ZXr4dO5hlk22fB4cnJ13T8+m5Vqx87G13j/5uK6f3MSlGtdc5X77Lpc4W22RBBNtHvN3Q76IJruqOYje9Hawcv2t1H6S9EazUl+T0iKxiLuMPTrM2D79l94LhZ647+9rrYcr7VbcP/L9gCR63PdiqPpB/in8I4prDVdACykeAU3t2fqDwuuibnuA5at5udkx1jAB0IZ/HbtCm9T4VXdf13hV62NrgjsmWcyiH+CBjubHN/ZsUtSyEwEYcWb4rnIgsOKVTWW4VhtrXZWF2QrVSkQPKpng630TCjKgIGEuIDESiw0Cf6qndshHIZknR/1QJi9ZrLDp2pQ5A6Bg3aRD+0TIsjDniogWba3rxeB1loZhznqNdaXX2k0NKitv/q+GoJcJI0j4g5vSUpoHIpRf0zd3O6+b6hbuaC8biD7waHN9gdgqoXvsGB5thJsdylbdxzRYtTfSsH+l8H7+8OQfWrRs/H2FIM6HdGhzUkLXA4QFJtJdXttEI1V05fhT+oOdprHlJj3rXYyB+F05AClHruiOFVX4A/1OmJbD4E5OkBz3iUGJwiMpCyG95HivEAcE8wBTZgUEYkO6x+4Cv1BmxTwKheMtkvA+0KPzXMEDs/B5qRWJ6mY08fB5huLesH3aHBIsobw9lawoYknX53sCBvppUbSfYHqKFoWUM/9Qkm5krSbOZUN7MW1WL7U8wo4Q1ItE3P5cU63QOxujdi1EKv+jf0taHhb0/AsGppO/dllW9RlWJnjQ2v7Z1Nut4y+xj69uEY4iuDU6fHNgRBHYJEfPZH8rJjDAzTe87vdtsz++ImUf+QwPH6xI9XJE6nqY7LTt7PdKAfOEymb82hDe6vYqOc/y1lZ4G5794UtM/Fk7TRlvHcnotB2vS2Lape7m/IDdPoTt15SWtU99lkq2tj7mdMHPq/jEAQEGXBImu84Rl53F9XNFMGQWBopZwftreK0yAnb35GYvw2x9+8v0R4Th682ge7bC6dkwYfZ8Bgz5AZcBRWrB0g0SHIE+HnlxHGQonLYoUnB82hSsIsmHUefxO2FdlXy1PWGYm2XD1R5+BAmxK4aq6qo9srdBc+GkdwunUwm4I2heZblSNYwW/dUmPpEJlfa9ohWiGPwpJPakbfbSa0eUS+IXscZE+/v2n1xL9g0enxYXl+8myHR1tpmWPTEtTPymsuxk6jV8nHKZ5BcPyRIwiAA6mAB7G4ndd1oyy6Lts30zoGta/XtWfGGg3VRbmj+OA8CCK0VFCICrJmdyyy8A3j1nreLlUrTx9kAAHVDaC5A2lkQM2w7FkTTnVigAPEoC7OEkPV2LIimO7HAAOJRFt6Qh3mGadRN37Tbkvidat5MGE4itav2+gECll3k6623nBKbSOhcQDXzckMWCWZLmG5dTJhmW1BXjRFw0Ux1hhcE3s50kdRtHqcHLUUetFZx88PImy5aqsnjpHhDBC2bKclDzHefCL3EnSptNXycauvhqE0c7O4Zxd1rSanZ44RN7EGdAWvrLuCBj9pNRrD7LTdqHt+VDJ93V+JMG+50K1t9cvry9MOpWKbsBp5qcP1vZw21vqqFb8rARbm7hjaBbMOr8W2asTwORSNrs6LklBW84a5SGv0WUrqAV4T1wLooroXVVbHfXBw09PyKRDFGon47pzmOol+5+sLkAwSn5FMcElsu4+eWi+A0zxBHuF7X7mPq2pPTm3dXdheFMRH1wOfuIzx57p6YpDLgcuhaoDUwFxt+LmJi17nlA5V5xohV6+lxtjII2ZIQcPB5iJ1G+WZ2BkueaNgtCsvU6RVPmTrKCJRUzvJb8UFYs2zJOBNbn8x5gy2PLqxPjEOUqlEYdgrXoPICcIDhvfCvnc9x3HHHLQacEKpe+glPGjSmnhljQ/sYyKGOu1PtfLeMYFN3GDCimrb0wXU6+7DV9e+DYKCTT3f1WbzLFhztPRBM+6sszZf9CD/sf1UZ5PHqt5DBYLy1DARHe8usoN+vuDIzEn5VCcQ6XPLXoggmxsQHn/VBEKzPJfF0KdQnrF4FbJFEWVg7ftl9BXgD7pBAWAv2cZIiMw+S1xmh0v4SWqdxWOTwJRauKlsEROtvyiv5a2xTFw78pnxJGL7Y2irIsWM/i7cSiktrHSYZIzpZlyYVNJB696aDTAtad79JHQaVjg0aqImBsKf/uHr82kjS68pCo7J4XpG00Cn9SyX12+waXCa54MkzKHzYcU2zPAOWD0WqK/aRv5f7P/a+vKuNXFn8f38Kp+850JoWdtsmhHRb8COEZHgzWV4g9805Hk6OesH2w0tjmxBC/N1/VaVWW73YwCxvv0twS1WlUqlUVdp//LA35IrLmwlt/bQDdp92QlcIgYuXDeBjQcHfh0s74C5bMr9EKp5EupjqvOpCdlrP0kKGWQH0qYzHTpD+wDI1dv1fDSahv92M8emGfrw4GcX489XdaQQQyxX8GSIsZncaCQk0SJjLUC7CgR2y+6UBfwJchAqDQLM7cp+FKYLMI/zTQDhTGNRGIjy0LM/ClrKqMY8IUxUznEzi2c/n7351RGiA/FwFAhC1DIRU9dX0m7rIO0hhL+mL+V/lrB4KSiLV9Vc/hWWZX0apn2IZwVmQ2QIL19K2gwbuiMJDWEcLEFq3u8+cfJrTYhVEfqukojGq6BSonE5yjNRbey9evGi39n4qYDlVxFt75fR2JfOdIvNY7kYBtHf/gjJrxbr+9nBlEbO6CCz6qTKmVjqfQtc1+lbakfFOu+MUzQ4ODva38KLlAP+tpPDbQyQInwjlSUDFH8lCe1fTaO3lqPGgTPOpTJUoU2km0XfgQM+nR7OZvDPIBltbk5vR6JmAH9Y0+HfwyNYzgRYQNoYEh73gwguMpj5LRsNFiUZjjsm2xS2jvOMRGBAD6l/OPrxvJHIG3oR+zqlCw0ukZKCdzEOZxD8vxiPEHV7algK0RMYVy8qdxXQ02W5uNfvcokPTFlulHlBqf5FL7FLiKJ9oUeL1zTSfvK3IJtM5JPvITDCdjmI5Mbj58cNSkV8Vh6t6kdBSY/8O5tmws3Cwq0p4UJjkLs8+Qt5iPffC7GUfsHFQL0gcJ99Ub0M7KYVlIXMutaL9DFjCNhUiYCkjlv0eEhhBBXSkGiIc5JS4YrCsYiOhCLKAeekIC2be6s0Dy+nLBC2UdYqD+39YTuRYXt1yysz0oguOXdaPR/O4XixHwVNBawtB2nXxCOKAmtMSP5W23CCt9t8rrt9nv0+oHu3HSKv9dHGVC1knrfbjxZVJC2hib9MVC0FCXArXl93dnwJfOg4LoXx1+bKl8cMcfvsRBOpVuHn+M4NRqfDu+g7R3oDZVqgZ5iD+1p6BWSlYmGdGn3aF0GGcVgrL11XzA2FblhOwxpjCo2aj0ewzX9de+hKQ53gPus18rHmV8bbcb5YjWYVE0N21gcdVjezAgXN2rLHQUmrBx/wmwDrstDH9M14scSzBuBr1xDpqQqtmIT5V4+gq6hbSJec9sWRVXMaTELK/3Cwu9w3R30xi0jVbZX/+dIq3SYAnwJiEmc0XxWV8TC2hKYJ5L4H7CtvBaBrktU55pqzheFUte/JCFKqnazfB65ORaA9/fYaZgn1FMWQXpljlJJqODabfycWgAQM44IN+pgDsJzOgX8xkFOMWKgp2yy7sd/vT74z8Da6GWMzMOX+XZhERyFzWsMLHsxjPEuCb27glQeiylG/hEY/ZfVb+xGb348YcFg9jugs7Fm1ff39Et6wS3SzxKAxv6IHD6Qx1Xif/HAMLM4EmM0t7Dc2BMNgSQzRY40YST3AIfvTv8tuxBGMKoJCSXtFhl/J7wwvwd7wyvbMmfddslCtbUmfWQUzmjGUDlYVBVkuIa3bbSG7mAztNzcxvH8Qto6P5q+FEzu5UL2PX4pnLq3LslaYoQhesTIpU5xW9I6splTJyfFAfDVCOUhQUUIPVVrouG8HdIlaHQHgC7ZZ0Qz8BDQ+q7Y3sJRfMR5u3JE512aZil2SYCZFtYo75f5YtKQLFlWmOjdJVd6FiKtTTEdL3iXNXiLJOs3spKrCy0Ts5Vvy/ivHcA8noFuqiylfRICNMKuFyyXQgvCJGkQVgyvEiPf9BXj3BTpInz4h3MwUks+IRVmhhcdZTm7XtT6x+pN7ieicnsk9RZf08DgeTKczZ3NUttrVVs81iy7QN3nf3GKvs95urLJ1dVmVDWiXDoL9/S0V5/3o4i6kCXoEv90ILESqx9NcK65lIIHiTm0TmWYwXCu6VwQstuJj+Or3VrvRio9Sk02ZsiYalWusCsdNCHfg6HUY4MVXgpUH35lDPgzEEzbNZzzYA5Vn78UORLWH0LHp1CIzLDvlg7EoXoA1WOLiBSevIEo/CyJeG5nNteekT2jvKy1oXWHMa6OFExMPQKKIqPVMA3SDtjPLB/hf8ER0OWF5ZpR8Id0nmOHzYamiLEaZMliu+ltuQ8dYeoQ/n7+V7YAT9820cKLStLeOjoWZhmU+lLDcLLHTaDsSLKUe1h+QG4BxR/pD0dFk5GTpCKmMOkvRdQaOssKg2XAoThxuSCxuZdei1LhjX8gEygdhz24zvui0i2zlwHDBycGKXrhaNZ4djjOxGKIkYuqIcz6EUIqzu2bPDnnV7e7sjV4d8Y1BBD/grhRg6gue5EoQL38r2EiCm7uxAWn+6eE9z3vO5hKJsya35TRjCp8Xv5/T4iBcseYj0PsYzMGxjhEciNmO8KhTjFTEXWxozsQk6bLIswwlKkbgBMY0bi9H8a4uutK61dozPVUvpcA+JZp1aIeeVLuNClU8K3y1JS8fc93K9JH0VQ8je8ws/EwICnXx7D7HAv5y1bYlRoOy18J82/tPBf3Yv+M5OAFVHAmNx/3FF3+td8EJzeC6Hg/DFxBZ/I4ejo9HoZDabzgCmoCge1o7DrHcYp00NKEbDA4YSgwI0hOi5S6gOXiAnAviBN9SJEH7gpYlCYgquiUQ+NYOIfbN1MNwOqVBhDh2MoV5HD/Xo6wXzc42NBEwvj7zlZSuyIReoJA4MEt7nEbsvaTG0aVlsW1ukXobA04Y+LDSgIk6kPeicyWEe6WaidKCXgUGvy4NQXG7mL/1STxFZXSjce2aXanEgqqqBA/rKajA9J5TP1ApbquQa9WRlVm1Q1yK+KDcF1YO8qqmerGRPKNnWhiQPveRWjH8tTqpJMqwR9Yt0WKKnfGClC+MxVrZhjsMru6TB6dIv9WzRW9OTK2ta3ecNtexgGZVAolqJ3QMRQdsWxXdoV9lo2N9fBNzaKhtukqEWqBa4K4pF7Lr7pWboZcxdVJt5rzzyzek9VQtwsTjTTkNv+gb1oFDw58UiOaMsm3ntAiAEevmRtiTRo1zN5II4MWILDgPPat7iZILlhyI8DD3r44ezczXtlYjQgYjcCeDfn8/PPzZbjRYFQNp/FP0u+XyYSvoyjp7b+q+yiY7lWU4JAQfHozHlKYvJ1sCRtUzzTHOtwXV+Fe71NKEczVBIXwFjPHGEhVd/TGfD7xIl49WRwAxkFs/S4OFeX4PrqYpwYtlbUxXlS7w1FeA3s6EXcGDIq2ST6wOdXsgnoVeoqsNDTV39WDKnpiNSKbAyeAky1YE8E9VT+SaH4I7TMFyN1BFQpiZR5RMtR6K3L+tYMWbQv2iC446AhPi3ODhTqR8+nrxHFStNaqgC1fSBmivQab7jJCyA8ZaQ5lxdwnxcr9blkUrbQSNQsyzpanUfV6uXvhn4mQqPIYrMuVRj/Wo1hSWZhEkmgf80AHBsrybOoZrRTRjbZifSM6yBJiawJXohOIwLEYLHKCw2WcY8PL9fYgfVylZmWMVNvQuTu0AZjiHza4qQpRCxk5YYNFdmAwcq6oTOtrC2HeDwwtm2tpfIkSGUFjJUZXNMD1yORLSW5GcBqOEzdbBvhxDj3DZGU3XFjtp0EU5HmYSsARQHTN7OLeZYzablFFFIpUt0IIDC3pkbZq0FMjeIWE2LYUkw4MKnfe8acj74dpiI1hZFdatOtEXB3aonbWFEh5/wV31RWKeTVJDn2NZPlhDy0Nqa0ywORpWiZXkgcsi7ASYuh5M4MubbogLsFsWS0B8RZxXDN6aTKbgTUZuYSWPlycSVmUjBvEiWZM371CLwcFf8SQ3GYH6yxW9Rw6qmOw/7QGA0lVFOKXECcSFnfSCvLghmONi71fEhkvQemDy91YHWBWNLr2J+FLyILjuePL34Cop2ViZuzyl5/1KcQfFZReTAKsO2BDq6CiDyGTyBcHE1Rdx2ATVsqNjCQNJJJjjlSg4oKnXpV8eGovb3s04wY05Q92pQ6t2jbSBIT6bsL5dc/1zxTJvqkOq/3sSzYU7SagnHd7tVEbqvzV91hB5kbEOtqSztnIypFLtiLoUbaYIIFEbGbKkt9HjJ1VLL0XihbxxcsZ+Z/vulHzbGIvCDhnrzW4SQkFKDX0ZZ8IUGRf8mq4Ig2M11IsZA+jdaAQgYhNU0bjzEKeFhGFt+LcyNKEM9aTjXRWcmVgT6J1EdL2R+kYfS5hgj4oi0pb6v4jiRoyG+0DResQflI/n0amydCmmzQnQZ8QQXotIaS13dQFc30nVNKjj/7+5B2tqDyJXzCDK/EaeuIXqCa0jWuIZahEh5JxSaEz9hwWmE4N4/TJREUzcfY1uU/IgCTI2NCUA9KU8HUyIfkwztoGiisjgzmriZjaAfwcAh/dGgG+MXMxlCxJk+K9fAG9OsTyevTz/tHH94//7k+NxipeLazG8JsdJ6QEcIjBXDhu5ApKln0xHz24+D/eXrmPmdx8Ge4hqF8rWy6Gsj9LUx+lpZ5WtlydeCgTGFhxGXHRR9X80VItbOD4vw5GbfG+d8r6z0vTLzvU9lp8xNhSuOTVec07J8aWaY6Th+1SpvYK7yRixWwXFQWOWtEgmLcG32AWEFpVXey3J9NKVyRYPiKu8VGtvSgEiD6dXUmQjKq6kzWk29ql5NDWg1tVZqn6t00beYoYtc+sWcnHtG0W1t4b7nvIV+eLWYR+XVYqhIZNTL2I+S+HL9SnHUk49fKYZcO9evf/zIdV1YTGiJYm30JpcGhBqzKU7dk4wkK/lKR0hi+6k269PJ8T9tyymSy0beDAfi2badIhgDu9YVa5B9HNfWXH9O732XcM1RtMugU0mQYeuFB4LaPVhDUgvzESRbmqSLFFudh0gGYiO1Ni0zrKHRbXWcQBPKLHCVyrRecjf/X4YahPhqKc2P1HlFDyOXaWKzpUqmqrSpLi8fqgqqeiyyTdBFaP58Y11eOrFJKNksF8Y3C26X8VofXIvRp2LqU31lEDfhvnRwo1dUom8EQy85sgsShD++2m4RMLcr+npVFBg4fFyL7DJntc1ZRYK6F2Thrk7YZ04FrTwWc9RnJSQUWE2iWBRbFV5NSGuRl6t157G17jyh1i+eUuva313tcqVbj610a1OlMfLXX+0/2845ciylzrLOnTnvDm393YV/f/wAp5YwF1es7Oqgsbp2nbaqXb5uxugJOp1jni9onewWElw3n+D+AYQalq6/GG8/oQZ7u0XTyAvRrV0Yj7V4MdLuMFYQL3l+XLvui8i0LjG5fcOWxE6Lw/+dPuOxiB2777QYvy4h9SuRrlOka4Xkwv9pCH9Lo5FPtIj6HgYo2E6Mv8Joa1dtRCiXcF1dAqG56j9tDwaQNIV+jf+ClSwtbYSrpY2E/g2NRYw+/fvK0cC0sIIwutdhYCnyXSPRP/prLUTtNrOQTpSZDV3T2BHXOrGFLG/spIGpyPGf7YhJBpRU5vez/P5fYqBuM7jbynzwIFlbWpUQUUYh0gKMquPQ6wzymq3CjygXOnQ6GDq014dBek9Tu+NvNjMvHzYza40/b79IsUsDYrtqZmceL/RhZFtzBVNeeLD3CKF4+6QDpIpWwS9bBd+QxW6LQkL3QVm03Bxa+1FoAaA59ubAhtFRKDpMthFwHwErw7XSbrTiGGFD0NTCzkUDl1z1SEP2HxTKvom09/wxSLWKBhqrmTkw0vvdNdhbW0+o1D7VaA2lYmxtjoM+T64m09uJ2sdK9w2H6jY9HPlsHrQ4Vh3yoAixdgTF/MwZqaB6qaJUvaO3iLYp2JW41Ur3zvzaw1OHfWcn71/bliPXjPMky/YK4whbz1qHj1lV1XMFgaitW17lkXD9yFxajVjQiwpLqxHKrnpZFaVQkkGe2/JwGiSRD6g2R4u77hPjqax6jmReRlriVocq27Xivcz6ZsY6DzOGZebjjt+EJYMQeoDband2n++92H9pFWFKKyB60kQ3mB+p2ZAibWo2aLK1505qJQy928nPTib65XnbPzUb++uHs5PX1qoDLotuoTijlC6NPBMwtaQ/hORohHJ4Oo9x3W75pQfGiil2yDXOMuXHrFrRXbkll7bTqlwdKeqNHRa3SuYWeZhGKLtaxB3Fcma42xIM4+tWX7BWpXns6vBuj9dUx9rv8Bcv+Ys9DgGxX57ZXofdIuQXz/n+Hn/xgu8jcnmqex22q7A7fG+f770kbD3HZi6p0cVvRMec9l2dh4M2u2q8joMb0Dalr/VsBQE07qpRmPyf2NaxeRRZPupsUMLG1WeDZlWzxgnO9c6eejZoVp4c1pT+3Nmg9WdwariOFndDP950CCe+YH6UnQ2KymeDIiXD/+InhPRUpcyt4GWTk9aR5eEWTmG9skBLZC5OBZ3xrtKV2zRauqJlQg6p0xn+oU1fCDOfwx9YW8sTOEECZP3y6W8MwtpP5fbaoA6jUObnU+gPjtC+baeVo/OzheHfFVg7dRvRRxBTsmCFBGCbG4ftCyWBNzcOYcbYtbTBzlK1hVbm6yqzd1dPC0jWxiMhruya8UgI8UhYiEdCFMqaeEQtodzryMLrcLLb+S3aS8SnhVJwYSLIiVi4+vMNiEwnkInJuSnT0UmGFNe7NFegJ8sUoEOf0Fr5kREH4wRukmitowR8K2eIQEZAngMCOm/oALFZEVN5ELmwHJ/wWsTH/BUfYSG0Mp34SrtF5Cv9FmNfabh45ZOOi9HDoqtepg+QucKiM6SUFpglJuYXleOCVW+hwEqevKigNgjlrcX4VdEvX+X9MtE2/X/WPXXsQstvxZXbBFduxzi9XmX4D2dVu6Siym1KY702iiS9B9zIOLdSO6tcqdVlx5MHi69VlV9yPlmhbIniiQz7UlTDny2ncKOHZKvNM1dLTieUQeLhlfL56caVivPKfGL4/atcXMxxg03qL9BQDEcR7g3Xs73kQcgFRcLMBufhB9TsQkQqPb2FQx8MqEw/jBp4g1W6S9a7wuGRtZjdxJaaGwrAaUPKpRzNjaQW87NTTAFzLEvoLCOZkXINRLAa80UNuQDhBXhtP5y46Jrf2mqiIAbinp5DwoNEeLgqqIL0A5DEoGf9P8sxc3vBRQO3rVyIWjFZ3bAU9iLa5DJ6j1DFWy8O89kqUhowL5+cCjqfeDjwevkUPrhY6kCwfPz4mcxfuUBDopAiiDDdmdsYyPmH2wnoYxLPFnhAnw6qiDBbnYDqM5Q8XTvhhDknmN/6yvzybS1JBStVd9Ho7LrEbNk4TaV2+jrN2O7eemd00d10dhYvDozPOopCWCsU6wCYMkg4Vre5Aj/QH5pUJpxCEQVZIV9lcbF7kExtu8zONu4MBk6wPighCPbBHOA4l/amx/iuoA71AuBQeieTKJmCm88AgQPMszHzSD1bc2A5RCz9xJqt8gCsohAQFSTP8f5ivA9CU6iAbBhgSDmPV5QOrkOspWRAZr9REtQFGkNlIe2EMW2W1EhdT3frAbvZJJYzsxOYbWGOBXXAXw3qw4XWtdQYoQo5xVyDhhhF1UDpVoq0WdlcS110DQVToggAq63jJS3UZ/KMDamnkdfiaetmZ0pwDyhO9YnCrRU5458//VM+9BOx+9SU4/w8nmRSVHNo9nb38Nt4pN9TFFar4Vp1fbRZWHDlyM6+dXjQPZl8jUfQJeoAPZl73+ZDQRsHvWYTDok2bjuN6azfbLtuq/nbu1/PwkE8ljvaMFoZVvQwlgaWGeic0ucNSJ9PZUI4t3NE2226+02ppAf8atTbEmo0XlwqvCAeKyk3W+pvA7hKEdcw12m6z5tY8k6cSsGqbzu1CHStq3b2HmD3JfFj3+NGW9DeYrWH+TDYsB84XC4J1qNz+nSylZod4wN9iEQSBdlQ2GZX5rTpGdEfKmPPbQEYlfXwVmPSlzKMLQn1bbxAO4ih7efZqOIQhixt+/T1rZBCBIfSM8dbgdMiqiff4vAMUkNwunFRqyM+4gPQ/q/8iL9RxdyhxzsR6P9W805HWmRvQPfvxHZ34Z3O5zdxdD69iifzVE0WD2sYNLzbbkIwM19o5ZrHGVo0DeeNqZwP5zsYsadoWjNbTZWFX25rBzLw/3F4g08878APvHsa+hsp4AGwmB44O0tBiNdP6dEmzKcEfJry4I+Wrw9l7SyQ1E6inuxGJv6hX+SnQrpNozSDtTjKMYc35HoasZwCPrp25Gx3m2YaAuiLvOtI/m+Q5j90AeeQiKHCGzTGRsFg3cucN9dXs/lQ4zTzCnaAKokRAx6Tq6cvoz/FKAF7Ydo6TcRqRnRgyWoebOup0q+g2qDy6yKCsQdDGbBGX7Hq9LHW1VnMtz5CjIp3uB6FVxZ2zkBYm9gzwT1CziJ7a42Zpnueoac3X8c4RTu7e4djDqIEDNQeNPclOpmVgHpp69uVoLdQ67EZPlFaOUQqxT+Ird3yayKSc9SOU0cUE4aEn4zugL4RwD3VbTVnU2hmOZlO7sbTm3ku3mtmJWBcg7sN7rBHabfzahrdHXRjL5MFfmgB11HCJbFuOwFErQj3froYXhZ4x5jWjDi1BhnQlnOiUnQ5wKXJgeXnQwwStGK0qcOIA4tseW3At5VVjZ/a/NocjzPEb+itrO3Mi3yebPIj7P7pGvd5Mv9fqHMj5lhljTNk0Xxsk5Po/3iLY9PWVNt+vFlUxgbsfvA4si+b+iKfJtD639GaWIMPSTyTWNFzWCKb3iwOPp7vuQ3Xdc+wKqVcbP9Buf1phC+z+3BZupOtGBPiqoEEFzXz8PzOdtpjZzSjoEbOemz4VV3dCVSD4gD8K97PBfGz+LqasPjyxYJUSszPYmiOel/hHidLa4ix+oE5rHJVRuHgv9XjeOlQTcgeHuSG64jz54brSOHPD9dpkuMIK/9nRuxHqxH7G+H6b7pHesT+xnGYLA+6j3pv0hE7/to0Yq9CTjHXoNXkk4bsunnSYXqpbigaVT1VNfwu1U4TUc2CVcoumAFms0J0pco46xECIR07TYkxhenbn6yiCR04QbURVd5LOzk1Q1BtCzf1yidbSSroP9Lt1f4LWsqnWcluP2f3+uvtHulQP6dDSE2nVLpXIg6ZD+sIPWXx9BioWg+Q2P/pwXo9CEp6UG+ajVNqy0JjQV+tOFifx3lqmwHN/+URTnV7bWwnXlOy1w3zLl4MplHFPCvOSClbizNQ/Ig69xF27JCttir2ji5YyR9hquFuEYeSvmqfckT2ANLQD2lfcrRyPmXAPFSO99/GI+L6a8b1sphf6UiweiUD1KTD2f+nVpVmoJbYcdkfYEPh4PvL6fuPn8/L0bAaeisgSwFVWndqlKztTiY347/KYsRAK60MFIi//2N9/vZ/U9Nx0M2kpVcSnixwq96saO3tohn6COakwgj9BQ2OlB/R1v/X1iioP97MWlfo61i9/gV9n4xpRU6X2qXSDtRUyy99c8HI0A16sIqW5s1dHtnqDB38pm07GsMC+Lq++wqf6RJC9EfTQI789L6wmOls2s7hLy3GbMakIEL2DCbJh7PYxjngaDq2WOP1h3fE24wx2mRHgxD9fgW3sIpNALayfZ/6wpIMURPPEh5DKL1mBvHU5Ya/qYcubOvdMJxN59PLRQNWHIEmbcOW87tJCHtS4CfuDIIcO6BDG8ulEla2mrbEfTXSeI1s/uruXPZxeGVbCshiePNl5Cdwg+R6WOkZ0MzHVkr0DgkMGSiKULv/kootPKHewjMQNTOfFqUbinRvYG43GZi7dKha8VrmUNeIMT+GSsQbKoGQRhXiXBXcblxmnVajzXRAXvHJI2OW58Pnc/CBFhMi0rs8XxB6lNuzuspkjOvKN9J4LYIUZFJc2YVCzR3+Sru/ZtpdOIeDr8Ph68KkeHVQD7oEUO2yXxp3H/mr7aKw26+8jau0V1vdenKNI3R9YxNl4rtut10Jlb0VMl3xAbDpJN3imO7e39p6pc4EvBKSl7NtyW8ZbaJTlNz8Ru/sGs0B/54uUvcP7dC+5pJqhjmM44ZC5q1evso8nV79soTICx3YUjJvlO3Z4XVDrbprX2YnfC0wN3a9IZ8j2qQHP5Dt3gUfEedL5plM77kdzXZ+TzYPVGUB7Tt/S3uWqM4jlmTYmKdwM3uEyQJPP1vIblbpZ8VKE5VaxsRujlC2N+8XjPHTCuPTR3MGRZjfvV9K+8lYfrYgD8zMWU49lZkHoYnNgdqGVs5SDD5IZS0J5j+hsfuPa2y81fitbuwEPgf8LTRai9oahcpVkw1Ue4W49XLV1jG6vuv0VlssaK6utRXSL6ceiGt9CbJO1psdISftlJSu94FCaZ4ti5n6BvTaNdWtcP0xqoJr6uMk1cdId7+M3Cs0RVkMMt8RbZrXfSuCrIyRUIX4dCPWWygJuvdImRH+VrwtbJgf2W9XwgXBgtBi/gu7/wUY6729EPfZ/alK10eH+NcbUUtxnTn3Rjy94Tdeok35BSqXyuTHD7pmPqYrAsDCU7+K4doA+ntob6jcT0FKA1pRNysyBixGDASNqZmwVM53xtL7g/v44Yd28XEbSds3dYt1cZfrzQw3LR/CLzkaBWCYsSQCgz9ZHWkbDW4D7kPRpvaCZOH7WL3JG5P3SwvpZcShlWuZnAubsCAYIKFElRyQzYiygg2GekneylyIhGMV2RKgk9mQ8ax4xymIYpYN4vsraxeBIXOhk4eqH34i10WT76wPigQ8KdO/uskQ+sy78y9ppP7rtP8FZPEpDqezaG6HmS1QLXoa4Vrd5TCe8c5LF+2twU/yl/Cjoh404X4gMNmPBMWH4JKop4w0LcUkmVB/tR1Vmzc82V0GFL1yGhRMO4rR+tKcKQU3GFtL8dcE0Ie1LHKWi2lgMXvUG1wwL42FMU2lrKgsU9ek/P/31aU6kruMu93v0PvaL3df7r1ov3x+AF3m/q24fx1jFKK3G8rCdTgnuNB6FkPkM8ONOfn852l+OWcvzflweTmPF/m8F5oqDQzLuPtZqV9j3FaTz33JuGLnPb0amc9suYA7WZSQWi2drrcHF/LbaZl4TASfRMBhnqc1yG6ddH6yvzt77k8RBr2Y+X06iVXlbMbUQzsg8FbHb7cOvvvfod+9bWQUlY/MlQjC9wGCeIIRizjt6a8Lv/YWjtLMQzG2IS0vf04pWq7cKINr/BxdiNTNUvTxcQsdNDH1li3pCZ6ss72fvpvO4rQvsz/Vz3vYWXlA/VQbDtV/00TTQY9z1662nguRbQ5vd+ArBMRD2O0Nm+2HETaLtDwXdyWNeng99IU3UH99xN6n6Lb1wlV4KSHrqA8c1m+xu0TTPoTr2YN9IT5CYH528p/t/GcLPq2dHP5eHuI5QTQajXqo4m4cKljOdePf0tKPlYGmgzRzYP0FsF4D3p8T61gzzfWxxKBzghsOMRajCr5sZ2BGPaF7Q82RPRIipbZXta/P6KRo/Qy6lRzVP0D3qv969L4OLgUpg2Dm9Ri6RzAazgdx1FBF5Yl82kwCbttUuHXcSIdDpgXMvhDlGZCezjTZ9hreTl+f7Bh3tG7mrVPmrUziabwtkeyeoXxSUHunrz5jceq1ZdIRuhMDdYcHwvoH6AMqvNEcNiTfAiORxXhmeTt0lzVsnYViwxgizKieSDqVC1v7oDMRR/QyJuQA35ZTCxwLNQDm8mQYNywvo9XOaMGkVABB6oO01pJyidRZMp1exk+mYr1RgDTv9xC4VmFDyqmqHlp6L2U9mY6G4R1gfZ1eYZudTcdxfTqrS6jrJF7Ajs0rfBPy8nIY1u3z3xgVCq2YJNiMXvvPEfxUIriOkK4Ntir1unJvhF+qfvpHJ1NZ0sSZ2kZaBx+iu4HxbJnl1/JUO21NtaOptvJUT46O6zFt767LBQzJkgVaH/BcwPscIOL6LUx6xPX3ADdM7xL5Hc6tXUZ0o8hwXtev31PtqgvfXVOl43iGXgCfhoLapMLOjkDsKYVdvR9FPVMCNxHoCXU13cv2GQO1WQwxaK+fD+L6/G4OlQHNuqsHcR0v951h/UBToX06Sn/fT+vBdLqgyZkxGAEJOaqTpCOMSV/TGU3Dq5sEVSDBl9qUgs5ukgWgPFedgQCJIPEIkoO8F2be5XA2vpUzYA6PikIlbLmoj2IJzQkRQv3442cUZ0Ibl0Z39fgbaBEywYDl7DIX5d9p5zM+e2y+LGxLXtPDhiw+Tlik3ChEKkkxAhYRDjBHWfzLY/XkVC6GnauYOo4YBS6oBSpfBRQpkDAfPa/IZ7wqMR8Mm+FqBXTvexbAjvPnhcf0YMo6lEDcH91Ew8VRkpy+9jDQpctNVKRL0IXkNuOnk+FiKBdVkewuW0JEpCmKrz380ORx9pRIQnrLdX8y85w0y4CCmEvDo0/IAGjSLWjkuAAXMRDFmNqAETXzPMQe33MGjA8E/vFbVdSCxi/xDOLi6RxNy+nk9XQshxM9EgA5AP1CiS/zJUKEdzaM0ll0mb+IqeVCwUiAfvjtKg5MWlZ3ePArTuN2m8MDC/CeM7/zGKRf/vmu/lrdf1T/CA1o4MdGZQYYx2I4LvKxeoyx+qg6VvcHjtgFtHfHyBn2MuQhL5IBjpur0gJYs1qkYyVhCmfAB05MtOM1iCffyggqHWSt5mlIrSDKPvm2wKdMIoxyIdNGpatVax1HAhjyq2k4fE9Td7NzMIMj1WfUrNZbfRZWRfW6tC8oTx3Uaxinxfu8h2aGv9Wxe2p03vIkvUPgGu/sT2dERAC/kstvoqfXv9CejnD/tT4sEA7HzVZTjhc7amkMPiy++QCERoJ/NVIbkTYXMUzmRhEXfn5aDg+gr5t8Em7FdCAmVs0HipZfnl9Xtg+lcytc/gpxyzP55iF8Pcj5qXJm0amV+XFSkWPFq558MPPLD5Wtqzq2ZHlzfH5KUs0TsntzFizDKc2FMUTNz9ff4RbE0GZ+hBNd+ImzQdw1iPuQjbx8nmziJs+Dhq3mIsNWtRgpDoJstjghDiBTl40NViozXyJA/PGSsnJwy3qVpPNlAVRFWbXAEK1ZXJIVF2FxmJUVSCtPD8tTgVUU+ugysxJpb+DDJSLYX1Qiklujv/ky1ezpI9QWUO9MtV1hIBm9/GODa75bqXOOHzwXBVupnsAWQFdyVsMQ8mjWv6F11/MpwiXsL2Q3v3coa6yyGepWGsVDu8JgOdysIGYU6xaUOs+dbmkJTAxw2piSlsQO8wrWUr0CmHJ7kVWGbBxCrO1m1cbQMRYhfMQ5Hk0nyCWh3i8RO19I2WQouV3Z9/TkneT4Z+4FXE/1ewlPZ+k911hRAeIL2fciDjP5Xn+ZllLLy8soSk/1yNUiOXp3i+mxNbllcN2O9EuQx6fvSpCtSsjTj2clyDZALv1K9cpzmB0LgR+SopOtLf0etixN8kM8WE5UQRKuoNN6E90kWAG2WsAnztITmh9xgFd9XRAPUAtQDgS0eg8+XZ7/soYEYG5300hQb/x58tn0g6didJvZ1qXyaYc/wUfX2KelqTzxuPzB0wM5lDrqzg0wr8bT3WZuw5hxwuOPctUtXNCBro1WmEdyPsck66CKDY1VwlcoSk2iMnQzfyilopFw+x4tX9E/AVkQAH41neJGnMth/9N0VK2gCKK1soRh/wXa+H/auJIpCBjnaf5+hTQvsKGZOHvGcBrOqyMzdcXNjfJLdffpuiaVjm2+1UG758prHdRwkRZPPkIbYRF6FQOsY384h6Iot0AS3YH9/4m72u60kWT9nV+h1Ycde804BjtOYiYzB4OwuTEvi7Az2Zw5HBkpNjdYsAKceCbz3+9TXWooCaE0JufcD4lRvT79UqVWq9Vtb9TFY1xC26b76vf8VWeY1tDkdJiYuEwagE833odWv0/E1lBGGNz7xdzH7N2zMWgDz8Pg+/wsmfXxwV2xQAPjwBCNNgUgnbHPZ7J7xXbwhX/exq9ywz59OzIiSRyqyyqufzaNfzre8MyngRG7zofPw330M/lALEthBj1thrsQW8hHwAr0OnOJfrveq6vMliZMuvBNdYeggbZ52EitdOAUZIWb+t05dmBmt+iBgd3jh3HkR5AxlB8bPN9FnRs4hqALWXEzeFCPnQN/8fDwJGtQTBTWaM9l/MjsslISFaNlRfeUEnpYnTUo53bYaHldEz5iYrBsgXihfhe3sYlPG/4NNYbMiU9T50IFXuEs4s2MVI1l+XCX07rDz/lZTrqRWvBDf7hA8ObCfejPUMbG2LtDD7v0Qn8cYCsnGFzz73yl7Un1pTu6Cz08HuUmAIFjgzYg0W+Mj1rBEE0wmj2oCsgsfiz5LnhqeXO1biAj4jYiyDSQ4Z/f6RRXsqgY3iS580m8kpwh+hKXU0woJGF31fvd3mIcEHpBMoIt1Bm9IAK2o9aNA6giBz6/v7rVr6yAjkWpONtgO1+MP2+Pr2CvW9kRJJJINPrTEwfsUqall1HV4dgJ8VLQ+WqQcbMMoT7XTAEtn9tO5HiihQl6Xyfglq/E3JGvEjBN2SM5PIzU4hAkYkT2+GHGWTi3OMvF7gLJKHX0tVFhsg1l5JV8PBiA5FavCZaCvWYFMDix6NSWC+J66qMgBs1cvDeqmyx7AlEx1ei36UYfrjX6dL3Rfd3od38DVm75aG3RYwLP9u29biNZx3kION79h1G4Uzvb61bQ+H/lBA/fOPO6X8qiQGWEKK0vBgzGPnlOcFfPbGUb/2383R0CG9oehctKKlnzuGct4sxif92QDDWmc1eAxe9WTC4ks1rJwZNKRno7Vo7tGq/p02i2GmPm29pt3GmAFWXu8uKsBMatEK5sAFn8C/dorrRtYVx6M3xHuDMWNvRsPHwfiHW5Qz0b0rotwGLi9rWEJ7bONP0IthUcaUTHu5F3Vyru0qPdFAJc3AShP4no4aIgmq86vkOYzu8f0h36cRRNQnpbUsfzpIIRz5vS0hUCyjPkdUxNhrOAR415DZhvEJCzTQI7/+A2NMXHGeZmGvYmCyLuhCxtTIyjE5iw8jEKKTiieWxgRhV1NQo/dyM9hZvTqtkmAGDNCBAkCCI9JdvxMlhEmFAaDbtq1S+v5aUAUcQZ8ugsmPNkMye6WV5iyLdGSNftAaq8ZslkxenxnGxAhFAtCtR3B9645g3v11KEhJZpA3A2WOGQzPXv5vvnyjFAsMFOdheSn2PwfP3yE4yNjqUS/KXU4CfjK45sp9lTN4Wc/ipUd76LSmsG81FaNntGKufjlryBVNruSmtTPRaxTkJMHOmRVB6CFAAT9xu9dyc88dif0IYbG2tTi1U1BPM6KNhp5c1VgUeg6i1W+S7U7ChL87wtz2DlIOtPGqNopuEZ9vVMZe4D2d27EQXBn/TL1MNSAVb5dzJ0uotb3JswJZVaXMBTI7XeVU5j52nDNevTMCYao3L5sxyuTe5mBiA4vcPMFdJuAoo5kIItjeRPJ+dXh5iceyYWO2kFYMQVHQm0DZx+tKC81KP3wrsjyzS4O0jQd0AEDtzj/63cXgShmrvqvqu5paM4gb8t5OeMXCiZFhlZ1xtR7qi32zzZc03Bx+niuVAxffKDscKkRKunosXYudjGkg8iB7KDxtpbFyf29PzkkTLE4JdwUQJc8hR6MpWIj+tynrRzRohpA+aP1+iceTD6NLcXQtLlb/7ebokhrQ8E8a/1B0T+2pCfrEQstqZ0EUTZk5/p1/LZdoBEWAII5jbDTxO0Cv1pTCJ8YIceRc8ANJ+NiRReN4p5TtG3MMW5nNu7Ky5n9e6LtfbZ+G9A+U5pJHn14iCzbAalKtgbTaKQ/Wh0d6fGCP1FGAbjq9GnoD9S8S4/iEBpdc2grOoE2NAbaxLP3+eVSp3VKxnxWajp7mLSSjm28u+BGPAvptXQT6zu0QjpWJ/RnGNgloMpzwiBk2Z2gHMd4vO1xxHH0zPBFGxhBVi6+jcSJJ1IsAWcrhfRU9KPQGWnbO3UbDyMwitZnIKBB43OYo5C8kzBDghzjO4AleNJNgI/aT0f5yaL9HahHkubAyRmyzn/qhPW83GlDKHO9M/t0PSv3K77LpX4tkXCRghDs07PZV2Xb6xGIPCcJ6uXXs2uPwlthSjTong8MsZ1vRg9F0TBZv1tXYqQPacPeYGflvBOQvoqYocKybXLGHdtrpvyD28w2Exhy5gkJUjxvEo2gGw15VcrGnhxs7wUbw38FGxXOop/cZzmeeQp/NW8Yf7wJKecaUMA0eadAZp68wKErUrJnZAmdBC+2n4KIX8uQGuCVfoQl/k5JK0MVEl1bgF4PSr+tVo6DCBLAFRv7lM4vMd89frruavJFwxV0LWGT0vBDQ2VbwzINpjTkysmiFC4y9Hd/TqkwnojboFsk1nqVt4RDTEfSme3+L+sHrvEChYaLsffIgf+ajj3zFeK+dZ+xHQojou+bj4THev+QCyjxogeSDITIob+xNcvLPKCVH8uxyjzrFLSSBkGZrrUr76AWF5qqWY4XdDzU9NxnNdH5dLXJGOID75GQShm5em5qiou+TnDpOCcVX582ZcJK6f0mvz/XwvLJafNPp99t/HRxqDcGcbQE3KGw4bYKFx3R5dlLucBjL47QaKiDyW3CWChtmvsClPr0038LXDMNkGTNdWUMAJkfJ8DopjUD/AFISQEpqyvcQZcNKJ3Ij85yVIQjZSpDBgpdQDhTeh0Yxh8Z5VbA0IT3tZ04W8NFeoALC447umlJYqaF/mD+JYxidQIIMc3y8NpUgMelwR4UrTA74TKXdJVc0YDXXTl21QhM91IaTiJ94HuT2r3wfBzsjpR6ZhCmxk7YHFTHwV20vBCait3GgR+jnGIwbAWhNF6MBuhRtRlEja2IJFzhNXudsGZYcA0TGXTtGDB47kl3qhxQGvBFTWnmGtacL3U4/XkXIE5fvSwM2cVV463hDY88oVIQ2e3ucXk2RThNteleAXFg88cw/xGnS+2rEKpunw373+vIjvheBQ+z6FUhUO+/J6/fy9GwWz4PIdaV3uMr7/bV7zHID6cD/LbtJqdVP1u6/V4pz7hrLCNN61u7NA06HOc7n5v7t4/zTCdP27Qd51GeTStZJ6xpSot4PHutvbIauY+n/H1ff7j4WZ7wJRtcS1HsaofQz675aQ1TDUTffyQuGuzjcUUZ4qYZ1CptX3uFMq5WTPlJjNdCgnTRClUDFOk0BDJ0dxJwSQvCg3jjCh0THOhUDHNgkIlL/+lrXPq2t4B6xn5ME122Y52T3O8kdYk2hw5hRQGofSMwNGquWEj5DKDRvCNQ0YrmAaMlhfhYurAKFa0uHmkaA3jONEKxlGiFTJipJBd/cYhInRMAkTLbhke0snuwcHz/N9d9ShEsxc9pq2Zlylte/cymS0kyQv/DBM/AhhvyGp+A2eFZ6Qg1svPPyyUnXyYaZ55IG2adljYPOdA2jjhQNY42wjTBZNcw+LmiYal8+/ELGWeYaRZVjGwbB6H0vzufV2/7vLGtLwmY7F/TsuklLdf288YlvuCvAuCaXU8esxewi9FqTcspWWVSnPmAaxVtg9hrckVZ4A7M4w12zSQtbxhKGtxDmZz82bhrKVNA1qYN4toLZ+O6YJBbeeGtZYzD2xpmpUMrJsHd8rF7uGt31WYxoJQ2T4WtGZeLAixrFgQ7I2xULjNtmcYDFrcNBi0vFkwaGnjYNAKpsGg5U1vcFo+NxaEnHksSNOsZGDdPBZSLgq7BQNtYHmJTxrPvRlkaaGNHnOqi+9uVrBRH4VXl8DSjj/npjVmTjiMnqZ6f3HgipeSaAG9OUVr2J6EaONhYt3udH35uE/f5o/m3ni5DQvvW5BfuKrv01c/ZLsZotJG4VpJzcq4bggFZgrD5tpvzq4C75Ok3YKW+txBr3XPB4564qYpZLWNKWq2snvzrDfIdK1B+H14frmup3eR5wf8Zr0/gb9nN0mWKRRTQ878BCEF2agp6nwaCPuJvyKmVbsJ2GaQN5nKej1euNW4Uu/SxMeTeUv+BaI8E9nr/pG7DLzTf5SJwmBM68Ge5Txl4zm+36N1c1rD0D2bgX8i8Rdu4tZDdjpTxL7uFWqTGkXJLHZaHq5WGlzIbLv8cSobLhhaFjp5pt0g9BWhlt9707ilGuzr39+tnfjCuH6ETm4xcCrRtqahYmDZ8Oac7WT3+7Nc3Zo7RVXIQ5Vp5YfDy5mPAyYzRFo1I/uJfuUOoyAIN61Mj1NW/rA+3wyQpAwBkLxEtUBvps4uegx6AZ2INMNnpsnqcYNhs/PMniR1jZuqkDfU6/e7qPavT2IgpK71l0ejcJ67YVqWESDLMGPwgZYeXdTDmYuDtkZf9bZp6S3NBaTl0SBCpqbOKff++C2DhvOk2u/anfftgdPrdXo2G5dCb/86OrPd61rNcV27WDqzm+2+02tXr2KNYvnMbnf6g55TrX+wi8ckcFO9atYHXXzy3Kk7dvFkRWvBSvXCGVw57Yv+pV18eWb3q+dXzqDRbF84vW4P1gdkrnpTbV6BA/VT9nnRa/Y/DGqXTu3doAGmU7eLrwi/e93tdnp9pz5oujfu4Mbpuc1O2y6+PrOr3e5Vs1bt43rAIC+aLuCTbuHNChbTeyxYr/arKOlRUr3ecVxlw/kdouCjKtRlu3N9cTlw+50eCgZ6eWW2XW0RBXVyftUB7DUbombOP/SdQafRcB1ivEwxap3rNtFP2WnX6bWafRQZpFdMQhs6PVy+1s7oP4fUB53+pWK90SySZzaa72jl6qLXue6ycZfq0AUbxWRyGny5LJu1de70NMoyCtyq/j64agIkdQw0GnkSpa1e9y8H/Q9dB2SUlS6ddl/XtW7e8ulKo35Z68b9qfxqRW52B9V6vac6Z/m1EO+0qs123ALlN8l+suwihWOUvuf8+9pxse667fzedWqqVo9LK1PcQRnssSh0t9e5aZIddF20f7VP/OOkp875/8Ai6CfCXrNFkqKJm+268ztIp8J4tQfo6Kogi+K2nX6r6r4DEWVtXFXdy8F7xIXDdY2mqTlOXRXgjTDfkiF3cpTmuM2LdrV/3XPARLlRrm7HdQbVtuo4q9o6kYXHv0an16r2QZdB33VXdBT6HH0F/aLVqrbRF3WnO0Hha512G3Uj2/vkNEHudzoD6H0AA1XQQy1fOG0njlI0LoBecMufvGa+SEQnb2DL6fWbDepVjmQVSkfUF+tNFy3LIdLtINDBKh+RKdTy+07v3aDZ4CQ3OK+6jmKmOlLHaQ3a19T3ifvyKMk971BcdgmuYos+FdeIIotaddH/mkitki0q9xK0K0dRT2RXcV3AZWnRq1Daq5Yiolo5P6FRa0jc7X7vA1XgtcvGULuU9AYU9ujMivYatGtOfyyEojs3UL3qXAwavc5/HFWoU5S5+66pVQfvnA+uopeYrltMskSBQVMkUUhqNEU74QYkGdV66FO1S8V5qfILGL1zHeg6yxD7VDYDk17JsG12EDLUD8B4zdmzgczFkm8EEtwnUGA0iML96ihZ593LXtwtXql74AC0DppPt/crldjqzb7q34pyGmdgqg60cbfThn3ivC4Bs6tSaNsFbUBJqQn/FK9vTtWtaJC+84LDyR+cJsFs/idWQKmumuc6cgeyNoj9JpVnKO6PVCZ0O9c93OkVAZAuq736+2qPug2o7tIxAmiZNzu9tVsr+MfLKBJKaFHlb3B+3Wg4PRXg7iVwKa7KCa1BqjzUT/uXaF62S23bu1pVT3zyVvzkmTWiNtkXZi8qFj5CHodj4pxIPv2dDr6eTYMhbULjH1bak+VZovh2O3pSR3TGi9fGuApnc/wIfPyy5suDR5XeQk1fJNWLFqSFVmz0no4s/jqlcxTCIcheaC3CCBjxmToZ0UeKHlauJRl6kf+zP5p9foE47jZfNOuO5asZ4WwNjebn2wk0N8mQQTz3Q3hxy/Lf9a+PSB4H0SbZrvuiTCeoXrvn1ufgKYVAbXiq5OiBgc9jtUL8+kQnFadtPY78YJLpsz1hpq4GX+3ARi3Z0Mev7p3j8WHf6nVasKBOcUW/EIJ0EOvjZDxHz7Gw/as6ndjam+oVGjO0sze3Zvdka+Y94D+1rAmV8bhSCPyljfhsfnUI176yjv4FvpLDU54Gbx/OpuPRfM+u2Ps4lSHVEVtx91NfiI3jr9gOK2oeAEZEUyRF0Jd8a45noQpvBu7ByLIse7P9lHhFHTPsyUN3mfYzy6GGdI+e0XRdhZozis89sYbyibHSrTU3sTpc6WiDtP8bar00Ue1zlia6Let8MUtT3+muJXpHSsTBnke+H0iRFw/L5Z85inX+yteazdU1nyh8T0oV9faIeL6UydAJ/jcYMmM0y1ZBaceKPkkfQ/wFZ+z+jHOIH9VHGtz2mYIUQ7qVKzS3ylWC6HuYoGUjvkyVDk1F+2L4lcYYJ1k/bapY7kzqaRYedZwxMRo9JPpXykayhzcTPbzSIWCV+JxjmIpNUD19rtBj+xR8b1xxuYiiwR4m/mIcaIYCqcOFWStrmqBeTsaBW6n6Kn0PSa8RTWBx6mGKM7Z0jiXKkqB1pbd6NELs30JyOoakhjKKdxxBbocBmiJheSpryoSAKL0sUH/8M4lclJ7F409hFAaJVkMZMr+Cwy/1b0ahr3RJKIP4cXGeRL2rS/W2kTkNDzU2mVBHrdT4L6OtUYbmosdHk+vG4K6S0YCzyac5peYKZebK8mSjlrNs08WschFNkG4k0/mqq3e14yaaaw7qk65PgnU79vygoj+pfaSD2WdfRki+y0pH/Cf6S/NFZ73rCGIrK1voA76h3m01rSFPlKssCPzqL/pBBGPq2q25zHBx737hVl26EO4+qZ44Qzokhgwd+pBJ7UZOW1zhWKlKRczYVyqXaEd1o6OzT+bgqWPia4yz4iJzAHvFeST0XJBIUy31XqhSvSOePg/EUscyp4lstlIbRcPFaG6dR4H3GYbiySuLptsqvGvU2KJZruiB08jyNswfpFacZr+iHFy3K/qbU4vnyDTmTXRGG5cEgzxg8nxgoM0OFKGCxx5L1VSlwk4s7lCyNjGS1IsoanzGopozxAwYTfUgj7p8XLua8nL5kH81udVbhDRJq2accPgFGsDnqRp3gawW+rjkMeUjTBEZc6IROh/D5imcXq3DkzeiBXWj8NRNqr40Uz3GSJu6zDx3I5sBlPKSws6xsIpvxDxro1t/jYdSJvoJT9uk2lwwUcpkNxE8lPY9ijjmBhSDAZ7BwYMcz9jgBRTmMVA2NRLBQOHnZmgpFDOeiOHJaescmZZumzz7optQS6IhjmBDzqbrhlS8UorH51JqLrxQ11GbrKNW/Jh8LMl4FUk3LuacSI4ay8aMl4qhOy6yzj2i4RF3RN9afRvNcE+lDdUHFRn11r9ymWDFJ0ej9cF5zRzezcoS78xBmivdNxslGCMJlY5YKN5t0KL371J0Vf5SKV9SFrxUZll0BBopQxrjB42Lpkb17raW/o48UaGlEyHR8uAuIgNJGdSt2u7Iov2OrMkCYPCwANEZkMxiV6hVvmXGnxolTaBy4Z9zhFVNjHpJkCsI9Ry/Prf4ZbQ1n3Cs6Ey0kqWZonCa3eteqR4ZRJQMUSEM63qqOKV1Th3jIMUrr/NqT0N1KAu4x4Kryw3yiSoZHwyot+1GpiEIeErsWfE7G/CQpH3FKqVYassyZpVjFi+SYtpxTOOBLBOV28lVlvWXzMkwfsocafsVkxKmX6vcoA3oelWsN0kW7hfMKB0xQ5gulZgkTVNnvWnXLL2Ww2p4I7CsY5U/Z5SIUW/pVOwremmNztrglp3jrAxtqVd5SuAI6mkJ3mJGdFNIlbPsiCIUIJPti0vOVk4yJfjcpljkZaZIjx+9lYyaMVKjsH9GwV0F4zBVSRza5TJx+7Vus2uJ0z01D4WlxR5W2xMKKFt98uCNwiQZxbm5qrazzKActFm5rilNBvZm9/F0XeOYQF1gx1K6/+tb3XyOI+AX82AlBHSa6yARixYAs7xiNrprXHEPVQsjqN+vbqLkvjpGnrSWR8/7il7SdDwHJTllvvHK/sKMY8nAw8qfQUjN/5J81M4t3kFdp2yQS5LM+ZkZZcXgKhTyx5Is5U8UA9sgeYvxXFY9MV8q5nI391mccZb80xSf72aiYLhZ66GDvpNrUOCV0jyBjG/WKc2h8I6sK0Ye8R4b2ji4pXWuMI/su8YXCaCsEiq6ixUfgWCpPVsjy3X6iltSXBGGKpeCJKIXtOOUEaoexThhhhuILF5GNuIkBhLmZVbWC2CVJEt4AavMLJ3m9GhC8Y6Zp97dh9RTMWIJ/Jh5kmTqBHdMCY5HaLpHsEmw4tQW+ksteq/MwzPFBhiVwvUQT+2hFvgsoSd49elucldPd57c3UKdar5HozacQv7tG43G8GP/n//EqeS3h0OMPshzdb53tDyT/PaQ4g0ZILzbKxfLBwmxEg4Gh0Ua78GOVmFjUuo3aeV4/4wOaY4VX64UP9p6vIdM6alhoF0UtPOvmvrHxxTaP2Jrp2TtL3qSGL79aK9a1NbtnqFZWMeLs9KHB2/tomUfJJEvz0Ef/h3/oGEnnP5m81MeND7iUYjGR/DKo8n4orWYL7wxXWSgOIAzfuwyNyAR/3GGEZUCIh94P+KnjzsQzvpnH0nr/GdZTWmrJ2z1DVn9aNOEA4SpGfCHsbac5vL3excv5HDF9YDLaqudUdAzGiCoCkNKfgAegujivCIGeWAfJknlddLJOukUJAw1U+ZerwuWMlwUSuUMwZP9s3KJoe4N34bBFwsRFRSHhzPeTm+v5Bz/S9bvwalz8q89Lbh/eMdyf07CoPPpE7T29vehPp+o+gpc1adAO0NukBVCDRQiL/DjHW5748z+guIaCHPfoBTDregudFwtB25zgMwKKRWlMrmkv47cfO7nXgmrvD968csiveDmb61s3QdfBw/+yz0kpJiJQfldcPjgH4J8OFT7Gu3tHy7UzQNih746QA2k+eQy+Lq3v7IVIThTxmC+TOS9lZ/9vwtLjQArkarR3UK9ZuhPaFswzoyPk5GP7IV08O0bFZ5+6aSmUhYnFtsuehUA3vNoLhSqRPbf3mK1UMVH6oDE6rQY2PAPB4OpHmnRuujfhgdLAfbvYdnS2fBAve2SRODWCUcUICmmVn1J9MMl+uEaeu/tP/4xBJ6Q0sPUGwZFn7reL/89s8/sX+xioK5e8OULFPSt/Ut0hjR4sOf99hOfzn7237f2TwcJKwc/2T+d2TbC6Fe7GKrKAUyg3h8eYtK08yWMP2F42gvpdvOPt2/DwxEdxdj5tGcPBjalXFsXkCptjnqafLKGH8M/vn2rRpH3dDiaqb97RNv/9m3PntzSG4KU9G9D3EQn4+AwiKJJBKEQL5xAe4R3C7FijYNHTPnSGceHh4f2/pl38NY/CAn5Aemjh+nQPAiYvkr73sEeqoUrBAzZq7hFn9squpZxkr13VuVT+3/lA+5/ebGigJl1IP0vX87kgfq2apxIU6LRAUAnRaAhz7m3i75qNH9Do/lxo/mGjeaj0bKax89oTF81JlrhJwFKPeFQN/PRtX5Fb4OYaBkukBZeb6Fk6VCD2dWW3ZLId+7IZ1eUGahi4sh3f4Z8Ik8CSpr2ah9hU654v9wejtVG/y9OKt7BwT6GFCQb3zN+pzvZvzwxokgjOH+aB1xJ/8fel3cnjiuL/8+n6PB7w7EaQTCQdBpH4XTPm9zXd983hsyRlzaZQOIsE25ewnf/ValsSbZFgEz3nX5z7izE1lKbSqXS4hKZp73CLFWsUijCfJEWwCuHbHhSoIZmuG3ugW3qTVut5p/yx1J1w54fRJrmIAKKH0k5wXjdJmqYm0RThUAinKgMBxOEXElBkut+hOHs61wqUNOfsrYrp0DYGUA+Dr7qxKYHlxLPuh/nV0BcOOlP99V7drX0+nzQZ4y1gR4qidmtw4ODwQFTvERiUOUDlKso/ndiQqvLquEVYqc+61LoOPkIX6S1WvS3KxfxmB69yRTqjMKuGr9E5LEV8+5m57dcAyUhAmguA4MqZo9mPCLXHIuVbjTgD3zBr0XYaun23W8yvhT33YXM+AexbLWWk+brJnSqx5VqFmjjLtItlT6SIw/pAP1aXHdvYd6ReD1+XYjcZ4EU0gIezITUmcF99xJa6ENM4YZarW+6uHfpyclsil0f/wr86d4k2VwC6G94E7uiBFxgcSMJZalNZqIXzI4L0MGsLXykK1LVOdEcMaIE4My4z3inMwuS+W3yCgo2u1QEK/lgh1CvIQmeJLZ+S7+AbveOZ0ichtXxeZ/xWUf0GcELcTE+aCDn38NeiWJ8pXJ6KDpj4rqQgaCEtCdBNOfxrp+ePkDukj1GZRESv1HBK5ATACvsMRORboEZM6gR2jXDWgtxbWotoNYC+Y3FcmLabmHVnFJ2PMmm7DEVcTAXs0Bxt4KMlBGje6C4H+A/KAXMJAIf+IOYsdVe2mpBppeKhM/FAwvg3YuQF8I15ymasshg1O6INA5YPrPMM7SG65RlV+LesRfzhy4eBfJk4XvxHiv0ZAIwpgDegL3wZB2owQOGg0u7/M2a8jNwy0RoFcywIMjnlKj5wBuS5Z1UfFA+nIo0+ko9v8Pae73gWjMRMhTuXl57xnH6XLy9gzd2B7GTl6++Ie/jt+ikGyOPxBhKFp7U1kHIsaV5e+CXQAfs+McRNElYUsAejxgv62TU9nnRufRQOAm5jSx1yUen3Lda9106eGKeJlJZltUKabzmS/4eVGImHlf8A/7c4887/DkVv1NjfReW8++u0GhWHAjQt8mUdJh/I/a/7X5/+1/7wXs9nbAtYCxQLhz0GXpzIOGPPw1SUlMvhXIgrAy0G9R1LAXIJwIzdbPAoxPJ2HoGmBfo+Y/Ivo48KeipwNAgFJxQcERBkLUIHz+O0nHahuZoy5Hkl/B/djNKeTaKVivobY/5gaWR4/sCfF7xRC0Z35YKkKqhKuRomj9c0nASN/f0mBOOw5HSXWgATpvpDjSP5zEQBYuF4H1rZFiNUxOOUiQDiL2ufpaREiE4ytzza76ABgoetKcWYN4ySEX69CTRQlk0CiEewP4W8NQ7ewzFXjHmYpPQE8w4SUQ4Rc3JgydipzkdhcpaXgvoYGbEvs5Hh3vxHgbr6ylaoQcY9D5yDUyhXECemHfzNOBTDxcalV0uT1Mtv8Q+rUsTOVQ4EXlxSrSh6i7/AA6rth7Wyzt4IWyZ92Dq3XczBv9351cyhpdLfglqvNdj/AZK8ccV46rObPIwpTq2BZEw01+c0+mMZhughiIaR7k1Ug29YCOaZAQS7TuY9IJVdNjLr1hhjD9Cp45CoYotwQknW8ny0RDAUUrEVohWLGs6xGfKlDbJDlkek14MnCNG/PGgC2bee9UDux/VqLdXDNKgikKCuxEn2S1Q4tETv1dixXM6VLxwe4Mwrzf2pAg5kMYjgT4oG0kRr0Kcv1smbhWUdLVR6Ljq7ylPxQxNybUXc8UVG93qCxM8C4wpsOJDbdGXq2CZm0vXV0ZL7H5A73d55xGzQNY+2SrYgRaIFD+TKQvMAGNrG754ODKJiaqM6ysSHVLx+P0ffoDTPKO93mrFPBZIr4ne23ekx7f7cr6AM435nya35cMsx9TyS0NPWm8RvqFr243lnRTNZqBewMWIofuuUQJTXuruEBdzv/fwzVZy4yFLlbS/nicoOPYo1cLbX+BAy5HKxu4Ie/6aDudkI+8cqBDoIkS412HP4zLR6AWZ8Ubb7YwIhejsOOfyJDpUq1VBsNQLLqg1jokt9hQH90gg5lyqmyNLOSg1SzhUlBuBUgmS8HegXQD8Bwr1g0jo+jjRU+MyFoYPCOf5HxywS80JDLjGl+LkYauVP3Qvk3+B2kNfi/WjqObxGJc/PyzUoeO7RLgmS3aBsf0yMoC1MmwCwCoI7Rdu4Lm6nl1U9cIGIn2sALQrWv1e8h7UWCe7JThqVzD7clFPeTBVvS3O3OfTaBxg1yBH7ZSgfreop4EPwKQeSuvwvCatltqgmhzmgUBxXlrGsdocwntD8WQZjHFUt8ltnGGXVoQAoWbJARuyw1yZPagCB7vQr5OpJBXj6J/S/IRpN1T0uJoVfyOh89lCljhHZiscAFfr5As7HQr278JbtQFS+Ey4sA4O3hLwRDCC80zEV5GaS+RrxnlgWa8Zn983GVcyb+CafA2kV52gGx4Cw0OwngfkontF0LyMP0q9TY4mmAUIdCbKDe5uf1oO8A+ODXudcOyV2J1BEXRhSUlixstKkiFcvVHvNWUTBRThhMrqJGXsNExoyytK63JPT/Ue1ZyQ4XulSkxRLapuv16io/EKe13FtDt6qlMFrCqtlm2B7ZxV4Bg4HBjQQDdq4043VA8wfyP/CZBDGgwAZF8ROA4HOd1R/kr8PZNoSeO7qwx2V2Au8nXVhJeIfNbMt4UM8Aun42dLQc/Uw0k+MfQwgjLfMISw1bMcFB2hPmE02KhIRw9eGyCe336zyO4eHCB7J0IBIYDeBtKK0drV3PZofuu5Vh0lwwHhWfhwfGGO18ZUkHC01cIN01pL1fKBpZwwYGHLp01lyXh4cnIifA7pkCQxKdClRUTP6zUHRwiLze2EVA42pbEB7o3oigbeESvlbG6cuAuL8iC9v9x9PMJW2QwZVnL9wxe2+snJUQuOAB2wtjO7hVnbkdAfvpgE/7DlJEFT+EkIHPRfTGB/SCT8pPT7h79+ad9+lrzG0U6t/HmIONos4O3b+Scksb1eg7bnwLUKiPPL+OpV2BFHHKzmGjShwhIsZ3CUwQN7ygIn89EmW49F6QbxOjm9E0lmun98HHb8GgqooQpuZpXSNreVxKMj9LhJgkXJ5wZoe2tSD9Lt9mbIVUtbzGOeh8yOj4/ONiAHKZoX0debcVuR1B++gKSGf7iRqG0o75coH+xG+aD/Asr7w20I38xefxv2BiX2hruxhxZ7Zwa3apUfpS1AVOOzULWNxP3DH6UvQPtPSPpmbUH1/BEaI+rbIj1l9oUXApWsvdGIcQkjhB4AzEZbuBm/MfiNOhkKBxGJfr1E6y87/SA8EWoVpCMkSGgHdGTQ6wwHEhex1emGBWyyliZAHCcLVnvT+oRmnxtBSGa9CMlGaid7HMIwOvJCgW86f6wBjtaCzsFFeOrcY1uzGdo8umf41iroeD360XZMbyBH2gq27cDY2AgWl1qqXoIGKhzTcJtk9xkY1q5Vsyq1/V0mX3N5e7eTP2DP4v1NzEdX2UPdJsX5+hsVN2BZQCvZRvu2NRARnjmJSoz0jjUUe7lDbNJi2qLYQYSk95ZZWL/xsQPQuxsAV11yLrq+/Bfpien8ndKywHr14JK9lCA8SmuoMRskyCQPrTYLjzV+s2miXXWnZuE69uFJRK5zs9dkAfyNzBE+/5CttlMFXceh1HE3TvTqgaIjtPxm/ASCoFV6q9ohfFxZcgvVHzqn/fTU6FFWCvuwf4JVERHqx6cnjI0VEOf1rSyeCfdeVgAbR9nY0tponB8Vl3mJkf2uVyc5LUkSZdxen8y1e6mi1DbVHyrVxFPJ47BrJWl7WgIwssgpIccXm68eKyHrcdxbw+VSs3SKz5VpDOM1qrDfGjglEk2T7bYISTDs5UcN5eULj401MGQEdgl2VO1urD+sKcEAP4FZVAah6eigeyXt4pKRPlU2O3XraF3QCbZOOJuWxy5gmjrovLQX4UUsWKMEcY61ZjixxFarsVjBFpnnW8gQuyLP0oh2m0s3uq0XZx1YQ3tdtodnQ8F6RcxBCSBv7MDsbV0H1m1ku9p3qz6eich670RWyaDGaVZsO21UJC1yFsyMHuh2EFmpFZy79oxKONhivEZZVGJqI4GM51TZlHKbQBugygiqO/V227k37e2t+UZpb965a0+oWy1nGyP1z8mk2kM5IeJS98mdpeYAaiSkJbhJbCWZ1cdhsNj6fEIomuH5JYQtarJADaHF67rjH4+YDh/hNO0vaWpcKsMYJedzvdew32eMb2kOHboRd4muLqDOHQRP8rouKbJDeZscDpUKrCdx8NpB5PDTEEkEPEtn8wfwb5QQVXNU9kzsdiGW6EUI1UY3cvms/DVDn4QbwFawEhkpIwP+4fNk9F+7CPEPd6bkDva7uwohyclQYh+s0x+WqjJ4ZzycrwMVCFbOUvoDrhEd6NVjw3YLvVXXKJDF5No93L18Q03yXNjan9puE63eHuXBmqpYgzWX5SGj7+Zkm92zen/bhBs3KOijj3rJI7ug3qsoEzuwidX+3uatNCe1wzINVOUZSQ13kJRZVH15O/G93o9pqk0EDLZtgu0btUbxYAeK9bLpyxusgTJ7eaNt9Ej3j5je3nLLTjvEm7a5NCk77Gm5Cdp+p0tj3H0zKtU86kVcDfAle1C6jIG4ZnNpAxYwSY3d0OA6upuxzXtFRMjuu0S6zBp2h1tiIbuyE7/YI14o2W1QHTn3MBx0tH2gBIX/Qum6iGm4BawZ313GO25vaBlstbexHq2zy798U4Pw/Iy3M/TA/9PvZBAhu+5hpHoVxQ1t+60Lex2Eu8eYnfcabPL0Up2v6duwu6Dh4WTArqGguaG49w5wImptH+huv3m6ozUorM2+7cl5EKrZtly7mgYCtURg1Ndeu19tIXJSYpu17ddwLVz2au42Le3evTBQNm5jEFptGHSSPY/bTMhLdy10U5V3LhoORd1148JFpC7tMMLrVM7oWlmAgB9jNdESQGV6L/X03qw2l2biNP9FnvRKjKsoZNhF9aqIuzTllSsQeaXieh5+RAsCdlH/0FkWM0zhTdN1PQ+39x4rxs3entA0NrxiXYS51lNYYJkd+ww4nWdXa8+15uXlQBHNLY79ajwRQv3X1U19TZlHBmqM+p3hzwx/UtHjc9EDPFHQ6US83U5ZJkp7cCk7C8vv3O8dizngj9tiRnAABuMz9xG7jAHYeUFm3J4Boagsf75aM/wjwEj09BcUxD5wHboR6MgS+OU+h67FaK0+iMznWSC9PttUX++LRrzPEFDJi6Hh/M/KcjQcw2ll+1rqMENY9xy9Qc1xvfJPc4iW4iUnYnLY5x0//+9wwA/6/AB+h/zggB8c8oM3/OCIH7zlhz1+6Fslh+a5x33e5wMOdfghf8OP+FvuQ6LP/T73B9wfcv8AZMr9N9w/4v5b3u/xPtTp8/6A94e8f2CA6f/6h7z/hvePeP8tH/T4wOcDQDLggyGH+f3gkA/e8MERH7zlwx4f+nzY50OgYciHB3x4yIdv+PCID9/ygx4/8KdB0UcPh890Ok59hM94qvrG3GgRy0Sj1Dnm6GHPRD0tdaRh6JZ377/+729Of/E/H375q1//5re/+/0f/vinP//lr3/7+z/+KcMInMJ0dv79xXxxeZVd30Bswvvlvx7+t+f3B8ODwzdHb9v7olkE5chAOz41TC9r4XGs4dPs5GTI+Pntb+VvvRkbIxYhwG3+xOigax8Avv5TenJyqJghlCkbNwHdJ0SVtg4HjPHQfFV+EpIFi8wRm5C1m9/efHuJ5kcnh4wZ29VQVjZOtBLZhzCkDmGyPzl71/mn7Pxvr/P22/a3+9+K6X7Km3lcD2PkeEx6BlqWWloWiWRStsGgPp3hYMrjtTnZ2pzZupx19jTCFomVBhwOYdTLQFBrinoxteDwidRRlZ89U54U7PBpxsrG1Ro8Xebxh8vkNpJZ4lExCD6F4WQgEJeahDLdKGsBUG6pHkEsqpNbIh5hQB89rjiMT/iHvBR4WgUNh0/kwrT5W+LAsc9RGbB1OLgghk+1a9vwVpgO8z1yhNHBerwSJafdnrF4krXb07JFmhnxj7NONIpXgcOTE/aoVy7wErrdm3QsINID4gNZiMqDfyZ8Hk9myERtsCcR2J9iZzjW6+LVsT2jsd1if0bsu11T0dhtpLDmCOhJTeZABZ8VD2nx8J+x4AsfCxqbB4OopjMv6RRrt4VZsM2QojuPNgSkjvxe9PhCRMG9NbDUBol7e5Bw56Rrc+Zrc+LJQnU+bE5UHxoXUhQy5RStPcTW7lP23MpO82Fizqx+usB+ii0hldyAPbClNOsTjzgtQ4utpn/KYNtzx+TS2S61WVvQIBsUBhk0VbaF3Z0VdrfiKsKUh2Vkg8qeYMXwZCVC6wrkPqW4cZDRktF72LsrZv+1c5ypbqrrI15cyyIVkVseqUMeOG/sO6xxaTb/wtG2SqssaM1dho/zyiG8BsVSEcbJ82RRzjPTBzQE3Zt7Ca0Zqdl/n1ejPw/6KuMQF/3s+M+S62CFQ0u7aZKIeFxqKinPTUNgBVBUS9z4MLI5yCd6yxpkFT+nHGzsb0lYxNbH+wDlvTyfY2TnLpiaHEM0JsuEQds/3CULoASGA2GR9ss//e63XWL4/OODF7E82FhyR+U5pKwNjCEhFppabSEJE3WhIPokhWTt5qEoGEjzPBZ5KjzCOwaU1Sn4wsNgxctxwnZmvUGDPm2yEM/IADbM+R2Dp0I2RDSCj4gE6mVZTn9UoT/IkP5I0x9kRH9k0R8QlVmwoghFFFQmynEF+TlaCkWkJK+8Hs/SgIjZUcf5vKIIPC6IfI8JuqEz5XthbJ8M43LGwVKVz9iKzxxaalXG5lP6H2EwWDmWUH+EGVbQTP7BbY8KOLlQKQCVggNk5nH1YoAXRGLPGvfyApDo5/ELUSKxIKxEecxWK35f0QTKUsVW/KJMU0MThfmBc+eGBD9pLpOwyZvQTW9nzSkL8sEYyOGpqs0pTOocCY1UKMfJfKoiEQGneT0UOh6Ju7qjZ/aoVYuCrpYUlq7jmavQ6bfrNBd7B5lEXBJGwc6EhW2FyJH0GmrEJxTwvFfwGihkr5cHR0owfGSC4GZMx4/cm+UUp0W7o20vDEFNDTkwfOHNuYnumDEsn64pr8eBC29mVYqxkjZQjnqI5UO1Au2KYPlb0SjXwPL3VvkIy1M3+8vN3LGEuX/mze7ustsxG4Gvtu9Nzkats2/3p6/ZaOx9G79mXvc1+6/9NAjV9tcHjNkoeioKL0YW9yRZF1E0Pdn0x4/4K/ltNEsWyQjj4fIZxPSBp/6UYyQ2eBrAEziU8DScrpjsYh28BgbaDsty2cWC4yMysfgMq9pILMV8JdhjU6+N3nebSo6Gw0G12q1dD/u8syYbuXBgjjjqjdyAKBtQMk5AdW67OdrfB9AalbYqNNKdKsGR4qiIZn+VN+fYIRzLzY6UxuPKjmnbalYPf8tagONYoIkzwTdFk/EM1tXjsZdRlh18M2Y8rqbiV5VslJfmhd1SZi0E9yycZFMxmeYp1Zg5Oi44eHJYkkL86GUTEwMePY01+8+FnTkF2Z+KZ2NW0d8uGgeUXC0BOri8iWbj0HNnWGwj0xi+UIpTjLwXetIMEbqTnYL5wZ7naCvJI9rTkEb44yYD0WeOqKcZ41EpKUOpB4DXjr7b6OkWBiVXaqliX0PF2fnHOw8aQajkaPy4Gjm0zIt09E/si+SljkJ+jaXyt4i6qaTEUaamLAt5kfwxgZRbF68VaXgSuXmk3t41iAgiJFnoOND4eyy49XEEhKgBY8hZXrBpwdCD9jqlikVOxsjTjwAM9sycCkZDdmxH144N4l+DqbSR62sTIt0ElvrE43gS628Sp6NwtdI+UCFrvNiq7v9LQXEQdYB5ycZWnOeRDMKihDrS66kvwfKpeLNphZHv6YikY9DKdoj3G2BqpFP/X7MdYaoaFqmNXG6689ODwtNiZnsP45kVKIP4OAtIRDMRTmKYfOGoEuPgruJuRyqEniqQipny1LDAHsRrhcl6gdK0DlZSWbmlwHeCRAYTnlYrGq/djLjpVF5EAF0txj77LKc5O2nBjjcTqaI7j7E9Safa0s3GcqQamnzGGkFVuTacgtVmn8dGsNFxnFOSASVRLthIiJjlDiqGfyTpokC9jIh8enIIFUpq840vechtiS8kz/pnZ9LIMiTQ6C5Ub1wIi29JwCXOH3oIjq6HdbktX3X3U+WI0TrsZEo3OuCgZ7kmjO7z9eKSKY255cx0+ozD6Ket6EwHnYuFVQwX18C0giOD6hFJmNc0b5sjerhqjrJj7XQVPSaHpNNxcftV25+yUZ7TPB6fgBEnKRKkr5o68yudFdPlaqYadMVG1G5i7VWeWOLPzKFmuTFoMiPO36pvfdbOrGg1M/+CT4a32Djj/igMQmGu9xg3OTAfxCYpHje7zVEM4u+dyHGz0wRbQd9nWWvbBmhbwvoL7jyfnv8rib2M0WVFuNM/OJ4ZEdLDV4NRT5vEtpdChl4ATVk7VtZKp6XMrEaCD/s4WDFvLL6NGS5E/pffbMdg2rJx2NbUyM7MpiU/vNZno5Lg8PNFZ7w94ffeDN4M/aP+8FjIcVnQntw32bzPQUwcyW2++sX5++bI7w2PDt4cuutRnlWp0Xz1G6q1FhUg6SH0X2G5aj5lqa2Spj4qgFcxffi9g7OOv1e+IqDJxqU690MoPKoWG9WKHWIxumGpUr+E1XJlu/ndHgoyKYHzHo+w+jU+4xXPt92OCtU2ioieq99TKEjfM1YCH+rwuJlxSK1IRVU+Dp2nXw0/KBM8SnMHFNole6XAlu12aMyf7co3+q+9o05RsB0yntX5xg21oxPaSQO+cJCje2zwKa9KtM2FfbBFlWRB/2SuCck0+yAjelEl53mw7Kz0SSoF6Y+E7qKZS1J/vnLq2KuhJYKxVZZ0yz90Zjt1imqVcGynQpOpS2lCsqylVeDIWgkl04qaWqbgsEqBf7gdCfiDw1n9/pBG3wyj89Jep2q8NvzgwBI0e+gfzNUcAJ5xsyJgczEvLKOvND4vRbqQiGgSGeeT3xvnAea291AwgeXSuO2PPfUg7rn620m6t3hN40mEszhMwAdKU6txBihjo4hk+aiyR/ccyo/uV2xFMka9Mq6mcpAQGMfZDUKWGmwRPNzLk3ipQNtHI8mxU+kqYfeHS5oMYdYbzMIqmIGoMbXepiNqU5jcnIPxhDiRN7XPn+1Q4Tzh93TqFsVFcl0I61IfXISOfwCyyzC0+x2ueI/taxUB1JFC2dAHTX2+YMFf/vhrAHR/dZHQtBre7X0a2krI67JV5t1b8Y95rKMuzyADfQRFeccH2lfMvjGkvH+MWhnjT66WaF8K5xa3Lf4Gt8cnN0hHulUk5ow9xkRHRp8RK1c/Zx2bh3BngC1T2DKmNAtMJ5ylVVflBQWrbIWTGYKWshXWs6mM0PDZsaRnFp8zJ5+9IFaVY0YZ5DjHuL0YwR8slG8YqZ0iJH3P6kshrpR6GSjfCfaPVgsfj5MuxtlIMDVTqQmmZpAKs4FUd4HCwXEoS8Noi1YJs0HDUH1WrvjckpYWuFSL41LI4vKkplKSJi5Fwy6GzC8fZE5VWr8Dcinvz1MJi664xCZv4qW8waCqcFE03j72gOCtIr1j/dJ1lC6QF8r/bGH+PIlGAqSeVdj+tvXx+tmwWrtfq02GGfsnDcqmf2IXQRjepOmVLiK4TeYfN3YY7Rg1THhsa9SQ7WFgMvAMboBgbZ1HmzuSPIEV1xX2c+teOd5kHmtO+SOyOmrignl+x/3+9/Je4r3T2V1zpSwF6D2eioQOZ8ext2eHzDn5pwsZWi31V1/DkXcXnE3LarQaL+JUuLiUYP3iD12kCSqu/qKK85CeqUUuy7skOHErKDDpUUHMJV405jluX5LwvNKXN4W0fIL9KOrmJAn9VPQvnaDuKWC6a+NbUM60N4cWYFsWx4lxQxYsmSymuEzXKMFYrfiNkLb0QuTvUtQjE4TjyExoQv2IVOoOXywG8Bt7V5qCpOu1W6pav9YKDcuNXkt6CYAVXuDx/e0+ctbk1jU6+vIcu+dcvAgF/Os9d/eH7Ebn2QwmxsWDasripSvn6dUNOLyw5+JIK5clG/A1gdMISwcZ6s0U44qiho0e9LsCPM7oIaY7ZMceo9th4vIGG14Un9F9/a80VfjRQFg636+hq0u1iUDv0VSI+UXyMIp4nEQ3D9ndaM9fsRpf/51En5izn4CxXomxmyRFA3yj6arwFooQ7OZfMlit+lrCjjVz6cUknIqIgGo+HfBc0IgTWiFzQB433Ojy6Q+5Ly4ROD4M1xRJ8xyorAUeXSkXUmmUGyJUtQKiC5s0KvId2LTzW9xIpne4WgRmjoLyzi/xGQnWQdiBhLw9xgZm0UImJblUKXm1PN/UDSok4zmH8/xONIY2WtsGmhJUm0J1XRLh48q+GTZkyuML4QegFHhLVLj41rzSFTWVWXpJMmH+8PTkLtvQQiDSvajCEHlttdVW8PosQkyQDsgP9grpk43UGLhVg1tEcptFvP3Pfg+YzXHxKaJXoZLKlqjcw4+5vvn6PToQmgR1hgQ8ya/ff11Ph51Fk5DJWDgH6rKq8pDv+WzFTcUfLneo2mP5zSYhbhuEa1QAGvE+uYF53tLWdP1F21dluMrGlQBQW2m+wM7vlRI8u2HshfKy7vXonTTCmBQnKi0Jak47xbObPoR9AJMvP4KFPFXosJ4rvVJ7vOejpd3RZfyPy0iG3DiN9B40qiW29BwrcH6eriPx5nQeebNLnuXn9yLNW4Ta4JAoTcgd5j4kB4iy9IZuiI7fUG/OGjfLDcRMDmkdJLY/rzCL2jGu+K5qqPD0hpiEJioE49u9TK3zoVoCsfKqJ9IsLorSW9tvDftvh28P3/TfHphqiVkbnsh9XeLwqcelVWG6cjrsdH5UJykLdVt5VeWW3SQKq7sPOk4qnW1UIxS9V1BVfSKpnzFm6qEeFcFqlEvuD3We8tMEyd6UZ3k+GFEq0KiVyIl3OTaamWoZ7Ua59uxNWL7jMrVg570IF25MCT0AkemhdXNDnA42qTlUF6VbumLLsyDKK9XgZQmwtYhIowmuVYeQOsQUJ1+gCOLEJYLG55JBJmPnFSSGPSEqOjsuv47Krx1TM5DlfaEIhKs3tOqkaGfMEEOhK4xLZbydKpUcX2BsjTq0qRGdlMmCTzpMZakjOngViqIw2mQE0B39txsBu/2dJXLinzUC+kgu7s7ew7v2PTPYRmDOiAMf/mqi/3Wb2r+/F6ZicT0705eGNs/vm+pwhy4deQolN7VEkaerB6r6VlRobr8Ic2aYgrezn8S4BY2qZHW2ltWXb/c+oXR0czhkZYvKxqY1UYvsyzCTmhS3mWz8FHbyY+hcOLHt5GnFWQrX2MnwpXaSlo82WEbd3PIG14G2KvQ7Wo9xetTlkhQYoxDJJuu7ZyzjTtZW288K/42qDd1I3QZrSbMJSzXzTexYd/WdLZqGUaes1YpPKk2st1lpv7fUybOKNcnK1sTu6ZTNa0bBVGX2EVKv0jfj2jJN7xi/Ak1FpWDqVBwd3RaZcTNiV9qWGxcmzZ8TIgsayjCkjAJudyr004irqdwobicSkI2raV3U6mNA9QqkJijlvUhvO5uTRs9CSzsOeIw7ukLKQYO3BRs7wbp7WL2LxcmX0cUan7KPPdejqhr75fex3XuUk8n/O12s8X++j11t9jt+96X5HS93Ka4+g0vR2OBTbO9SXP0ol8KkfBm+hWXZnh+HGXd3WrvMl2L4dCU3b43Pb83K8P/jLGhD5nQW1nQqdC7ubjZOuP78x+0MX+OLt3zI7uefTL3U8GniNhq+zGH4ss9k77K19g7D3CbHjVJnTbY1eIntxi1q1ixzWLMFWLNF1ZotNlszorNCpqvS1oQTLW5bxj6pLVq8xBYttrZFi11sUea2RQ2nPsdljWNawR3Gyan4UD6NFpuM0y++/s3n9srcdugzGqo88Y9i8ObN8OjN4LDXW5E0nj1kZNuucEvbRct4zn1iy5SRRCmMm+ipSrOgMRNNGcfniF7OMWKzQjx2AyuXZKPnpHEn0xxXUz8W9y/qhJHfPzLlaQABCejjM9A/Ta6bJshhRrsZ1+Vz27onRIWg/aOKXN/9cDeDTfv8PPMrKPgqvkpuVdSRBYYBUUkEzowVM3k7e1Z1NEem/J9+COFsoaOCy9hPelz9O+VVAEX5Iuzj+3PoAIXG58Y1xSPiIKj/gVp/xu/3vSoU3qhDYUEootKo5PfV3VRU+fuemET2JHn9i5/7uWi7dWXNEphXC42BTqQjjXVyi0J8WxKi8qmDHZEgmcWhnMQ7eh0yxlYOrwAKG6+gajDdpmHm1OVZUVpi78o7D2KeWSHPvUjM1p0XY63WrPqxXWWgxbPhpkVuSw0yqzXI7RaiuuWTmS307V6mzBjDL99Xeiw7S+t9pZqXcVZaU3KZ4nYF2erf4E81PodDpWW6eHrCo3BjwJBV6OUu/hPuwqo3lyqsJYyNNktxk8to0S1c2DWjTkE6XcbVZ/MY3S4q/5GOZOMzeZJOR3IXe1JuoZpNdViOONnecmTr9q6zl681OYisOgmTnmt728r3N+T3N+QPXPkbJN7QItc51la6xK/Sy91HPmPs5PTMBkNJTuez2gRjR3+uWg5Xny+XqKuFddjY+f0JNHRkPM1Ib5C3WuFa82NKWV6e2w+mFb7akG77FHWmGAt26SspC1IxmToVVrsyKSuf/K3M9hesYKTatreTxfQshR/DqxGMTtHeiOdwtG0J6xoh+eq2a64+7NnzTZyjenMuIK7JOZzCXXvNgXGYYxFqn4zjaiTMM04ytQwpJ9n+oP/Um7b84+OB38m+UkFNMWDLmYjhl0cTXz36+NhXj318HKjHQbHGm8FnlDGPNcVRjWIsspZYCZBaPlA6wIBqQacTM/x6REj4gftQ/CcPnjo+lGFIZxAqCwI/mKkCtIaK5Hya6bCKd+j1/6YuNENFKBpGZhGIadA/iUwQjDgHvphE04mcRPtHTwr98LX3phN9dcQg3vE0CLXkglBLLgi15IJQS05Hx6gRS3peM+AEOzKwIwM7MrCxbeyPGMqse6FDOLXp0dqGOtoPeSyGryOQkH8If7J8/hax/JIDFFlKIkssjzqZpPsxSEz4eGsk/HjQnp30q5i9DoNskk7LEzXo2eW5mlZ4L1EXxOmPvjMHOw4gzjNJSAtvxCJCNbJYCTKlfLrXaIuRihiL4j5EwLTiZ5P+63TKFReTKQgCb/BRdVLRB5HEge00+0ECtdttHe4A6/Fr+JNMURLtBKAssK2v4YcvJj4++fjUx6c+Pg3gCX6mq/S16K8yKGjJmjDHbV83R4JIzuKCRonQE4QuEXqC0CVCTxC6ROgJQg+0jH++X6I0PuunKL/BY/P6exQ7MXAW3f3DFF31Z/x1CjH4WT9Raez6jQqGBVn/GSzkO+8nRGEkt127XFwKIhJDcfVh+6WY0I1LQ36EtyoNMIg+h6Eb70s6GE61msjcbPUPVCRyGt5DdX+dxC9rQ7isk8NTG9LhDf9Ayln/aBB8sKoG9/bLaf4yZMGDeUSUiGGYwz9F+Bb2h/K7HVKV4vPwlCd8wa8VnVAkh/MIRvAsQ6rgp48/A/wZBguxgEuuzhZ4l9XZ27fBBzwYuwjuoRuIKLgWEh5wAQmSg1SFawoSFSIwuD4T1wBreLYAsIf4C2CgjDc7S88SprK86KyRMMzHR0zGUtHZ7CzRpC8Vu0sgcwnsLqdIwDV/gCekIeXXhObp+gQI5alI1VuKbwEFfItEJvwRLlWdyQn+C+CnUzDFZwLfsumUreyPeKqukfHdYg6QeKrXJPlczF57afuw7TO+EClYi7kyE7GIJguMSaRWIL5Kx14sPkzik+I+salin1KOKAGEgAn5y1Ge2R9Ozy6BRCzPs3abjQ5xL3lIYJWbqgtqmIRFAy1hOdJIGI9QgkhoOj2L0fZYfGfiAYenFP74ODg+4MB0D38GU74UkZHJ3EgD7CVY/nlnpuSwwKvrLjpixsxKzEIIzGdLxNyIJhdTDo9tH8m4aA/orU9vfXobqDcoYjb0KfxwLzg9RqN8ymJV4pTKe4NW55RNYbzVgsFZQ0kuOHYbseD7Pb7TcxCJpQ5oY/RiWY02aC4S6fh5x5rzRRCPvVlJdgnJbk6yW4h7NoISp1TilEqcUolTKvGBhtFrvuQX/JK/5++gpynnU8JPsITneDwY+fgOcrmA9z4+oweq8vzRAN8HxkbdiAGXUviBlMc485CSXYrZ5JoEBPJZaumg63GhRXM2n4T0ICft9s2Uv4dqS13tolQttKtdl6q9g2oXebVGiiWtetd2vWWpXgj1Qo3uulRtaVe7KFW7Fpegpu85bIcE6LCLRcEr2SSbX7JPFs/KVJXZBiAkckFVDaCLGqCwAui6Agj0m6oZIGENyHUFyLIChBpZUFUD6LoGaFkGVJaTUe+LekyB5rtv/tRptr1QfXv49KQ+J2Ll+A88DmKhN8jGa+JteBEPu7hTNGo4I43o/DzsZkxbkUH+17Fcku9l4ZUFUOQyQqeK1j2se0DVSaWIY3QEy3csQhik8Hh+L8JgRq5IDLBXZsKv/AShflU99UT0fENLGqWLRbVxkOLCewReRpITolJQEo6iHMVAjyRYXmjH4iYkJBrCgsBJSMIZga2KDMVSwxeuWIkBaJcXMtDbgQHCYjHQeAEHvRoH2nWrCGT+9BR7xfYzTg2DKL+nBB4QiIr5FnqPZhUPvDrSxtFjckkInSQuvaj73ZLLIipDnGxZuMdWFOftO4ztIfb8GhOWW2zCf9T24JEdglHMnFV/4WrUrk8vcD0Gw0/qofnpqT8svQ761itj7v36iNGYW/+2O2K7YniMRSPSw5EbH+OOT7+jyqffKI4aNQg+CnQwvFTE9io7UZrmJKY5bSlDatBRFP0ccaoxYhxle6vMjfbpCUN0muiPh6W3I+vNfXQCmrB8diIWKiLtRH2RxNX5YK4Oy3F1KsVcflCOMFKs0i5FgqbUrHHuxZRV6F9vVSjgdzAhl5fxr5IHVzfSXZq8YV2JYnTQdvMyiDw1ROCn5rz8nTp+LsuKfBw2eKNSIAojU+C0DiD6aAD8zpF/ZeUrAVXr393ofBRdJR8XrIrYd2AlZ2LIP/B7fslP+cN/gn7suNIirRUWfDG18E00dlxSkT/XpRS5fgklX2bJH82Ky78zAIjsZhfnQv2Sx0PP3avz+FZI+w9lT5p+9/+zd2bNietKHH/Px5hnD4U3tlt6MMYz1xUCXEzufhYHK4nqEJuSzaxf/qhlGdmOmmRezr4NtLr/v5bVkhBmCpzBxBsObNv1venAhn/ffEfe8DLVp5c3fxNrv9NCzEKE6AHxKfPhr5Fsk6ANTgf9dhTvYXgf8OVjahv5Rgcxc5AEY0gAerGRBdFGhmkTnEYRQpvI0Xi4t6F38EiMUZh8CvJjcqR7ds9oBhBtEbMCq/RQXViSBG83SSLjtCmcV4gMA9qqFI4/MhYDcREEhqVxVBp34iFpjC6CwLA0rkrj2w6WxuQiZphK4w5sT/zh1LMqoyW8uApY/Yx0I3oSZ9RM9WZmk54bBM7AHkF6WSpwe8LXqowuBEFiYcEjnNbQ65FGOA7endbQ6pFEMK6hQMLw1a6iNhFiijBWdlwPBnz/M2jhkRijELkaA/aQ02yhIMrCUA6GkuNA8w/0UBw1TTdgQBcDerpvQZ5FfbLZQ8wkmAUmjy+Hjz3QstJkbSM8tBpyUqt3b5qnGzDgyAwU/0vgU8oOQZZxWpbAa9vErEJwstynvKz4aV+dOM1W6RMFZL+NmNUIVpZenNcqmle7z0dJ1KYZ5mIwWXb19c0LWQnAdRqIWYcAocZXciKJw9qO1RfcMolZhNBG9bWexNXxREBSGDMg9trMWLTQY4l9TA9wGKWbtCw/FjyT3H4jMesR8KRf8tZEMjQTMwObnrJY9JOodMmKXP2SGaD7bQSRYxN1COB7zmieHT43s7RtE0SGAW05C+TPW17Tz7EcWm0RRIPR1KvQJ384DSmv2D3bp5XsY6+JIHIEbQuPMGu6eEc+Tx8AWj8jaPxLOAdwx5/25SR55MUpo9n1mW1oJhdIFxOpnUBcvoKrp+SS4iLQk0B+UDx4dhHnXcapvYDuOW26qIyLVP8ytT7LpPc0rDe9UqF7TXgCbF/w4bClSudv5lHiAFZbBJFgMKcFu168kzRtIji85GqeHu8onByTvwdBntnOZM6qbegB2+whKAxP5DxL5A2NebSDoCg4DSBO91ke961YFDvOjge6UDeQoJsvxAAGy4Bfpfcsu/OK7M43ZPcuZPfRYjo6MerGc/oXco5Uzo/98umUiBfPiCwnV77IXsEblbfRInKbBLrBzAQdcvpX8zKlpRiKhqdNoGEynHhGTvUYaBNHXmB6DdPxR5qpTYzpNUxfmOqU9/RU5M0LsrZIE6QF6m4G5Sw9NAJtkXOQFuizFf+sUyhTS0ZaIktav6qz6qzRthaN5apXxkT2rEoruuYbXnxg+Z42YkMzaWQ6sbrjUPCHNGdf0orpQem3Ea1oye2+PD3c5qwyQbSHaHW/1rY7ds8nh7wMKT8fxbVFEEnTL2da69NT9VhwMYLycERzOM1Q3g5z1AElqCrO7k4VLVteNVX0KWhTHNiedWM8RbiFc/2WloJT3+TWMWpHAvHnm/R4hJut2qtedk93Fae0DItcIFKWV60QteJFDNwnDw5qeLVfTgRWlifKDd4peJV4wbj4s+DmK1bT4S4t2V73pBtRV0akwAIcfbVYiPtiFq/V5371BqZ2oqUdkN+uD4ib51rgdwT1Vs7ZB1HwaxW7oZwVWScMSvK8IoNuC9HhHbGxXoNOA9HBesmDOUXGbtBvI1qikzfvSfbbZf0rkB2XrVxbmpadKay2c/rpyLhczAsxOh2/LClT78REQFhk3QCvDpCf0okl+Qzgq9wLVsqZCZBN0Z8YzqgZOrGKnoV2ItXtvEOVhttlnGewhIvu9U5eDZv2toIYatWBucMXFoZrv+oKXQfdda5aUe6zPaVL8V5cha7/uj3SHb2MGqs30NethdYyiQ5syzxJvue0fKRlJarUdvpqwjyyO1YF+eeN7MD5BuxInup9uPOmbqVS/oHyQFwOJNcWMYSbIPWwH5gYggaiLCPEMULU4SKjSX1jRlK0SQwCE8Y73y/b8KKi+/NnPr02YlCaeHKeV+yJJlX6dFT9atvEIPnGz2z/+sy2YJn+0FZaWgfm6/8ivEbAx7ZXf8DPbeHSfp3f9tLf3ZuWua0eVJHDQ1qW5OvtKv5ntE2C5WxoBZvNMg6DXbxezUaeFa5Xu+jfux+STRTG7+IQvt/C2mzjfwa7aGZPHaDII+rX1XoVCf18vV5GwWpmW7FQvo+2M8eax7tkt41X72eutQ53UWN51up2uZz51jpezEbW1XoRJeFsbImE0XYlujOxtpF4mFrR6vYm2oqci5k9tKKbebRYwHPbut29m4hOWVtg2K6VRP+4jVah6NxIPN/N7DF0d7UL5stIpbWnVhz4ynAcgQh38U00c1zrfbQSaZbxf6NF3eRZ85vNz+x9aVfcuPL3+/4UXM55mPZYZLRZkmk8cyaXzL7cJXflwjlAe+gcQxNIaCak83z2/68k27IbNwyz3TVL2yqVSqWqkqwqyXLDPKfWhu1GPetkU4ZvU9zd4jRL4mZoeqmRhfe3Z7ETlEn4hDhGmxleHWq/h0mJZDIrTutdxG/xQqFX1s4xI2PAfjp02jD5KKc7U+bPvHhFt8vlHS4YJiHX5c7sXdiWSZ2a3nkur/5M8PBq48AnnI+aN6ObczMc2DxuT/3ZAuCj5g3d8ZjSlt7sQ1ckOX2Hb0Pv9b+TVoJy88V0GtxomEwmox/xnRD54XE8QqL+qnO9Mer5xcXGd+VN+Mz3xusL2h2FsXbv2R9od9TZEw8vYvFJ2FZ1NnkXNo4ex1bT3vwtGDm7xFUJtiimYIDqj8V3w8nyZRLIrGcDrZhufPzHb56IDa8OcMPOMFy+xhMuskMfKN/d2EwX7Gyy6IA9cxWbF37f2RjsYJyrirn/olK1tXUGaN2fn7TdeWvrEuDQQZ+0nXBrSxDTRPANaiC+6oMOum2HBvqymG0VJIrZUEXLZRe8OmYkCSIBJKTKyw+Yi+1xqHh79CZJ0vQN295evDuhk2nGz/D5jpBZ+G1UVUI/1Hta21n4bXeTiZf8cdDoWBLh8HFPb3u/rb9bPeaMw0baphDm5Bj0q3dV6GytrXoTrc/1pxredM2E7y4myXAJttgu3mxHXNYrSOSI0ch+z2Jqe/nmYr4du3RjKWHWsYEu8SJMEl68LuO5PX0LAc2Outthy8uqKjY3wRWfvEEr3qSFTKp0UFjNd22EGSeB9Y2q6MhuET/UW3fM8Rm7ZJiPJNTpX1/0u3w8EHNoq+boFKSbkW2JWzDOZsPIodc1wxzpsyOtj06X6Bg7s+6H2/snnBw/CZ1uaOSt8/z4G0iEOuvmjGN+Ej/6ELhdJ++1lRL9Wr51bvcD62Uj87Ylrxq0ZDJtW3daj8f2w87ROUnMj0Aak2sLLCMu7B/2MJlebBwPW0FJG/wTVtLGVje5mb04g0h3ezw0hrcU0jXn2TWwbYHeUpR4BbxMuiX6LX3ns+JRQaP4oryfCj6/Y0vHRfgCOr5mfv8pYZjIttVq/r5/AkDo/gVzJniSdiDCQ6K94FnOSnbKzguJCetxd8L61p+wMKPjCcqiQ+LckyB5nhYliTxIzjI8jMcwTRIRmzUf6magIqJQQ83TYtYTXnh/PrZihpeZY9cLE/Sr5xffvpje6W0nk8c+UH2zYy8n8XW/3z79QENkEHk6/X+ad7+xBU47A13So8Fmu7skAj9NmKUF3Vi8QpcWRGk8S6d+r3bUO7UKDJ7Q4j50DxYH5iS0/56y2ElUwFHzgX/OZEKaQGYGGZ58JHLO05Md+UylmKQNlJB1iW3BXg5k64ZgOZBpmszTgUzXZJLfQ51VtJ8SCU25hDaoP6AvEFpVCD7ZTMntvMRHILfrm/H5AG3RtrOikfwdOkX5GpPYT+A1/I3OQ6IJ6ctk0sA/u7i+ejX2Ns0g7wpkO7VXCUO9BapbLlEv3STAGJJvlYqm5qPBbB2zzTMcqmD4+yfpUVvBR54j0u84Pd4e4by9LgCIrS9IM8j6CAB6mWH6U2xCB5aG1K/vV7+5T/3uPvVHFQ0qUDa5l/51R87mNCRs/h1SioqJH4sjfQCDh566V7Q5GbuN+Hv+qRBEfdvo8japBhjYi4rcG8qOiqxaRVbpXqPIW/BTvV+AMWIcdvukx7jQiTcx8UyFofeTs4ujSJ7y2ciPufOPxmuMlw0Z7yXAXYOpkmQnEBgs3S/aty3suYNB/SmMNj2bGnwb5qg9ucqrgB6f7ISeA/WLHuPNzRSuUL8lSdIOM6g9YBLiuMH8+mLup/yikx3pkEmPB3NCwwazvn4xpzWO4cw/lpgzTZHZPQ7pJD7hjhKcloIzjmoIPTMwWnM4KrhSRivCFLYaxfhp7KgPiHP0A+U5JM7/VBkiuFye4mE+OHU+WT8b3qZDAAo82XH9sHXL/ZSBwq/l1E9OmAvISloT0OnuvgLChBJOOWd4KBPu7ysldSglhbbaKaNDwZj8cLS+sJI05WjfbPLygM98sXGGSFc5wZml32+8eLWh5DZi468w94tiK45rB/5k0s6KAoW+MB8/JyLh45DM3ltgSu6e1H7bI7htVU42FNsdvmftF4hWIkpTBj+oeUv1N4Jqjo4SZgbTNrG1FcPHnZh1RFjWflUohZv1JXCTwGDXVzWre8M+ZoL+pbH0vYONZ9+/LL3HCryNE0Lc2HwvjcXS0XubbOP04jWBI+n0vc33ErbK20NVACdQp7u0T5ggRDS+cdjzEQtU0k0vl4OB9x5O8hbi9/O3qffCwOBKcK2GJ+3p4/UTfYKDFard6aoDWCWnRQ3EwQVPLl6GjQLL5W8Ea9zMywPoAG8dR9MYxywWS3sbST5K08udAZKgQbwnCfsNWJmtkezzYZ2RZO8Ke6Ns9EC1NXEIQum3s6uXUd8H9goi2VD4D6I+eomOQfflfps6aBzyhLWwjxGz7mMRBJiNRz57yHQ6Wg0cdwB9Q+pnvNf23tMQPS2LD/YP//GPa44/2/763XcHH9CTAniv3/zuCgNTvy/XJ2nNvM9dwPBgHf5VUjonjeJseED8Y74ZXVAfrVnQkda70/fphdJFUgFnY3MC1CrdhNZ2kHh184ICZrFPYRXoCLK4E57boRqwGWVR4h2qs53NEP6a9JC7cX9C/xgLEfX50cMFVqN8vhRtm8Q66Hb9PtAJio4GyjYLCFTkd2HrwY5ff4ttGQozJnWLUawOFoVL224ficFCRKC8MUZQrUwi9xGnWaUIaE8vLnCO7HwIM4ZNG9wXrzfCo2QQvVn0CMj1w2EQs7sQErC/hcndS5xWS5qWYVY0iINlkIZciB3GRe5hfFpz6ZfYK1+dYFvi64vhEu3qTCj0DFvGrzDgbFxcbXxen6SAgCWKju6WxXJOUw57LoZbENd6mhrm1+f+LLjpIH5YDYrY2OUxnaKX/27vz4P4tGJU49LtIA6tJrV8nqEXLMqNHybPdv0plP4j7aOHRNbgPm/RXg9irC5dBWw/xtCBeBt/vMcSP85Cbl2oTW+MP/7jbz//PBks1ayFhTJIbdCy+SBqd60sFun4AqHooB3ERbVQCum2LWFAb/s44m2zlMbHFAEGDDBx1Wtjc2W0JqyVQHFcgJsXnH0SB9Y7sdnF3YDwgp7E87QQ7JO06A3w44jCpqnAEM8WqVghisIoh6XeJKkHbhxmGJ6dr4j5efpJG04O+X49DllsNboMc/QHNcWwXxsXZig6Zf41262t+LYtvgiFNYONLmAcZL2ZRiCiiulmsgEO+1XGkcyv3aBgf2rd1l4v2rxJCGeTf0/EaYIUFmWeX3xWfh9xfWPbekZ3B0KcsP0ExVrx0jf5iS54riGBW/ZwZcnOrIhNij3/o1ldCO2hnSp/ev2dawvtxBKD/W+5jAgrvQx0ayo7K21AzvhBZjlI9q0HxTb3aSPAweZOS7uZi8z+nQ9zHP2TjhjAjDF6oJSa9DMfu12FyvyHnjKAlt1/UiPd0ADyax/ZiDoGV6z8KlSVNu48fTMioI2HsHnCjE7i8YyKaZYxwyxzLGcCQMGEZEIxoZnIgGMIxBluOQE0oWmUc4QkmSX0jFLCF2GaQJwyObAMoUsqKJG2hJIRQHkcKka1AxlFiZ/8YHJW7HuiwjIp2YO3WWBI8vvvQgXCMKkevjV1Y6V48JYOcAwOMck1nsbMJ6Y5Z3KGcyW7q0pa5jo3Vubm/ZEHHx2/GvubVy/Qiyigl0w+R5/snqsZTlGOJwz6lbpLdss+Zees6n7oxejdosIOgRImMYPDRRcxuaSLnNzSRXk+qaML8+G57+K0lFfEj6x8RctYL4vbw1OEsw9v6b5MX6YzYKWEyj4tzuhSFrcIxF8imn/KTtMCp15+unyJFUAltz/1lUyUrGt4WYAQXPPDyxVqc1weQVC7luDpIUj+JGJGd7jDguX/v/3RzJGwvcTTcskpJSgl0tOQkpSS6WVIqWJEv+ktktV2YfS7d+EJ4N+nD79+HKc7n2xTT46a069eFSvpiIPiq5keVk7KO9u4krefL5cYX+p4tB/ByrVHTAVbF4a2CL1tqe/40wCYPxys/hyU0Sy8l16nhWH1O9E1gLPvUNXXPRhV3kfzR4055k9L2+nwfPakhwZbxti3Sq9YwTIakfZ4jtZqdvjaGJuC2NQfPT1NBoiGYAtPJsNCoi0Gb2d8R1glM6dFrthM7GgulVRKC8tGM7kjMyOVU4JLNlM70gJZOevaE/TOsGHtrD4iLsFdODoq6gwzFAR2rzGDo8csfTemDZeX83Zyd1JHcy/b4WGy0uK0uJzE+N3+5QdxbIJdc3ZJvwcw+iE5dFftb7Fqfzskrf3bA1RCew3oB3f8IB0P461UnrBhNOQVnBEhortaalLGDSSYssBboF0NeMZKrh2mNVAV+pLfhxc3kCAq5/2moxOIO+oA0gom3O0s9+69iHWXzZcRetAqLs6OMB+O3WV7UCb3Sf0gHbDerT5RepJE/dKK/A9W5SVWANao8xyE7lgKNbJ9dnizSSaXviMcY0xEF6CrYDNJV7J6uqp3UNAlFARN3SfTSBi07oLEXZC8C1LdzztEHfuwYxj15uFyFi6zcMGDWPysLsfoP3+HvH8ARY8DiUkv67H+Bor8B7kbo46/gZb9ogfDP9LJoFnm9O4s89wfpbyHwWPan2ferptnnod5ZkUX7XW9F6abe9DwHqZb3QMi2fH+Hs6cRv87DxPOc5qFjcvd3WxJ+8mkTRAyqlKRCZdxLnWevoSRYxwKkzFsvebLU0Jk2IZGe1bC7E7ytjrUsI1jneniwkXo+moOUBkd3x7mcuKX4gYz4dFPYoemu+fDrLgstzZTufphrOi+YExbtb/KmiUla1ZkYIX/EqyYn8zK1uXyPPgVgwxJzXkOnrj7YQy5n182o4YXpfJMm9w6+SAvj3Qn6Cc9DylNKZ1WSN1G32JahGPL6stP8S6o/GpuAE4n0wH/okIws1wbvGDl44IXrMLjo+etrNtlfVp7Kw4F5z1vhZi9312R/Gd1V+Yr7sqIT+YD/sr8fn9lPuivhC3X5K+Uyfwef2X64/yV9e4Km+kdJV2m0OElbydVczgv89Z5md9xXkp2GZ0Xv9ezHHBeytp5qdqJOkitOC9VZ+F4v1qdklbBebkp5g/MeG8w470ZEh2+k4FKyHmhH9yR8zKMd8d5GUZDHnTPQAnkBryXaceDoCN4j9kpmzbey7TjvUy73sv0rvcyJx0Mey+LdR+5i3VPo/fSgZbRe5n3nZehxs7vdV4GTHlrftd5GeQ0ap3dsDdwVIaqh+afoWM8213PB3rMs6RaU/5ZKsh27lgV3iG5YYv4eb03Qd1vYIzVg/4OnH9NN/oddFtBt4tkslYdsY4KJFcBYhUgVwFqFaBb61jEzlrv7QgjafV4Z+d/bwPTwyQ6O5Sa9DMffYgzCv2Hrq9Qy/5NHJ49H1z/EkPMFbtmf1h1ff4A12c4jN51bSaj1TgzULb95HFME0dhlzTXz5LDkMx9UiWHPsVZ6fFFRsHncQmYXWJaKQmfUsJRUujkkFKK+fpfplTGHqQl3dDUlaLMwUvbC17abfDSPg1e2pfBS7uhSza5oouZXNPFtisFnRaMv0RdZvkl+DDgg1JC+KSokzKjpKUZ2NXhl1vjm8OrhBpQUd6youkuMCklFCVFXielzw3vB1Rbe0ssGFSHezSxv0ZM/jSdtwsQJaKK7Lq4Qie5wTD9Jfuy+DR9ueTsUx+k32N7RcUqyIKmz3EyXfUm03u9yfRtbzL9aW8y/WVIZV5E6U1IGUqZ9CqkrBdYeo3UH7aL0cq8W2amvfmJc29QWM2vwb/O/BuLh0IIozKpuWPC5bnWVmvBFNe5kkpb3OZSkN9lFcuNyJ0FPhMZd7nlea6Y1JkCBasdk85ya5SUKGWkVk5wx5kSPMud5oIZbqXMpEVVWhrniBoTucy4dcqhvDASt5IbJo3QDhhcMSW1kyhHpJzKVM6JluaASW2tBq4GpyiICrQDB9Ixa7nMUC1YlToHu0JKcJ2Bb2Fy3Oa54UbnzjDgaSm5cxINkMIpUMvZSOaZBJLjDhyAD6EMSUMpk1lICreZ0xmaLAQTAlIykAbyndTIzpgxRqG9PAMvikgJ1CpzbSFJi1sFaaJdIASGMlRrOQdbDuUgMAFhUBsgWU4iBorhyjJpFdqYQSfELFcctQkwmOXIcKCglM6sgVyIQYE2Zk5YqINzBWa5huByYIic5yCGlqMAgCAkwadmGTe5dkYYZrKcG55lhjmn8tw6a1kOaipHcfAvJalF0MIv8S452YXVwFPW5mhKhrKkJCaJS7BNy6y+Gq4zQBUEAMuTmuHHaQWuNfFkwIdwYFpC00poEFNKwh4hRXfweKeRLH2x6jTKzNzvNirJRj+n37i4s8y1GHAbF/e7jYsH3cbFT3Abbc4VVOndRshdC6Wl9W6j4IL6ndS122hV6GjkNwqFfpYrIXI2y3YkLI3MGlqdmR2YHFBhxGxmd0SmhYbpyuxdnL1i0to6mIufz8Fc/CgHc14s1rs6I+9hzuFhzoekvD8f8DCH8e54mMNoyCt+DQdzQToYdjCrNRZTDTqY1aCDueg7mENtXdzrYA4Y/dbisQ7mnGZ/cBAXww7mU3Shp7uL+xzMp8m8GA0TeBo8zPmqWV2Rh1lFz+0qqPsKVjR/2MOsHUzqVbiiCxm6GupKuFpyPOfQeZVM1qopVj1HTasAsQqQqwC1CtCrgGwVYFYBtjW0Kvb7O75qvWT3L+yyjv5lfVaZmei1hvRkFeGxC3Wh1H+s64q2/VjndfSrea8zeumXPFe/aHft/dfnbHrEnrJv2F/YyRE7OmLfsuMj9jX7jH3B/tb1bP2blX+rXdsvgmv7BXT9BVzbLw72ed+79cOVzxB3M9rllFD+vAAiPF9a9/BfhsdFeD84OIL58jx4vuNzJGVOjiBSlGdCRSWhEs7y3BcgVOAsCUUiRZnSIJNKhCKhUpGt1nra1EqVKlF7n45SUodKbaAwI0zCCZXWtWifcnUq8ylb11n5Oi3NC+hmJAxVW6b0NE5n6Zzqb4T5Mq1wIceWLuPz1Wd8T8BUiXfk9zkVnszpjnLIV8eFYDfhDrAr3EkPex7uAJse4VZ54NNwB+A3uNMe9pdwB9gJIWYeeBRuCfot7owHHhPQeODXuLMe+Fm4A6w2nqh80vI3JD+9/As0CMGFpPNJjeRfkMyX30CaqtUdyhDykvIIySd1SDoqQ9hLIpQnrYl8e/gNdkMdHX5bgy6L8fHR4V+2xkdHh8dHAdjqX7rlfHeXSM97oQlKWUrJLOnZgV56REc4hBuML6RkhlRjByOKRIyrrevlFcUwrmsyXxbj+dbN8jnerji8aRv6WXqeXqZnQc8p6Tt0ja9TxC8CnAf4PWZSwkACuVn6JVp4mn66DnVWo35dfMs+K44xHBQYFkipRwyq/4ZB6X8Boadpyb4ppkdgYw2lv9SUYFlXmA49x8B/zZ5j/nJdVDS38ZY/84GY03U05rVlnzf2nM4ntY03tp5WawpP6iIdEsKTuEGOCCTCNb1eT0KskJCexHPkyEAiXNOr9SSkJzGKNJSn8RRZKtAI1xTSXEtErfChPY2/IEcHGuGafrOehF4hkXkSR0fIygKNcE1P7uEjWyFigl0SEROIhGv67XoaZoWG9TQ+Q44NJMI1/Xo9Cdsh8bftQkjXC6llQrY3PzGkBgqr+Q14Ws85mw9utVWuSS+XmPINbrNtpjN11ngTXwjYRonNJDKC5BAjBC4nsaYwOVtJo0WB8s5DlaLMByiAikPN+xTbaIAHqwz0c1dr7XMldbGSfiRXUg9wJfUwVzF3tdaBOCimznMEQqv1gdDHvEXhC+BVhW4odKQMz62xOkPAab8TGDVculxYmQHcC5IarZ1WeU7wGDGVtBafZ5kmMjF8iiqEkU5bCXAnlqp4ppzS0hD5bmA1V2BGZJbI96KsRhvUZDjgnZCrpPiMUyrXgMf4K9qn89xkmqrtBGPRCCNAk7A7kVmV5Zza6Kl0wrSaGyecBKeAd2K2eS4UCAkPjvFbo5TjSgkLcDeWq21u0TjjCB4Du9Lgj1BB8p0oL2lAgDiJIEZ8IX4hjbSWKo3hX8mRCR0oAndiwTrP8pznXADcDQy7DBSFVJD7aL8TJgbXmRROKJJYN2YMAeVAUtSoTgAZBpBbkavAZYwmW2MsqcAQOAaWZWZMlmvn9dqNMksITNk8I/xOyBkIWmdojofH+LPUxoBM3a4YjLaZU9IERcXItDAoZHNFRGKUWgjnAM29FXRC1hksDHUqAnfj15mUjsOwM4LHYDapxlFdVGeMbJOiQNJCyQSPYW7BhSb9OoJ3Yt5CcmOzXHhb7QTAIQBuoWMv+BgMB2fcGaV9T+hGxgVJSQMT8G6YPOMZ9ADBEjzGzEeCGynAsAO8H0A3AKJ2gsdoutBKWpmBI8BjaB1wYzkqzwk/xtldJiATK4nLGHNXAqQltEVtjQF4oYySqD0nEcdoPPDQAWHQ1KQYmlfWoU1cekHGOL1SwkHD2gusE7RXToBxpTlR6UTwJZrGYbK+0k44XxnkK+P8CNeJ7YvMUpfignjvBPqFoD4nc0mC7Eb9LQTA0XZD8LgEoDVQDPfy7SwHoJUmr8XeXRqwaJdAbcRNZ51Aov9Ba5lXd1w0oNZmOdBkUHcuYE9GQPLgD+YK/qnjU0lpLFhkmTGQpBWC8HPNUanhkD1sCfrJfG/QQsDkOKFrDvFR55e+AxowSdwL2K9Q0JUOwqSwuBQ0PAuoUtpgrDmNj5nxvR7scy8abZBQ0uQENsgR3gpcpv2eLZY5q3PjFOFChAK0LfUmZyzalAmqkAsLlfn2G/BAZubZkwbs0hgsqdfSc84QXDrwQeMqmslzcC3C0y/jgnqLdkxLCABZxuMbyAe1Qdm5ozttPLpD8yEMMmCpDY04uTg4gKfytpkbbO7gYRtXGzR3uVRZ6BWddQcpJVlfFkwxrkAgUwgLfFJyZy1CANPSgO5NNK5KyBzYJhNhsI7rE1aiiUDISfdxpQIayhS41oQe1yygBzALZeRoTDvhQ0vIIjkJmlBgTFbw8LigBy09ejgjM0CnNZ5hraCvHC1nTlB+HiYNUJCRynCGCnUuoHlfv4VAOJggvnJubeYygsPYUC2JmQkL0lzxMCcxSHFUQMN8riEXWLdXLjBg0kKFZTUakVxoSJxEojHoOUZnwCBdc6tySM5LDXxA4NT1FPVSGkcBz2CCDrarmHAGzDXcgYJ04BdcAFVLY6TwcJFLCFw5hmyba4UmeaUDpEhKwIei0eCcyFuoArQ0dKWpw0KEXoKoFDVJv0YqHOxW9poivV5gUmGwM2iLzjMaCPzYpbUwGlpiI4hP5jBon5FBFRZsGwbTN0JCH0EB4MyQ9dMIkwkjRGiKI/WRmZJWBM27CMzp8UvNYhZkcx66EDcW9oWeBm05Urn2j1lUpskuFUMbDenWoKv8H3tv3tVGkuwN/69PYXPe4VVZKbtKG0JFwXEDvVyPu+d63L7PGOPn1GaJQQIhFm9wP/vzi4zMjKyioJvZZ063W1RWZERkROQWudaN4osSG+ek+cYvqytfFfG4ndE9CbOgfq2XvnzpkcF9JAugdOuEd1tsQudalZmMn96xmnrmbcFd8YzQCjNCq+DsYHVo4no8L77rL7bSPdjLeZpjaNDF9OpagBuJf3/6sVztpucl+PprsGiCqouwo8Ffvnc3Gt1ehN29vXl3t2EVtoYGsfxl2AzxTcuwOaySb9FJ4TzYvWcZ9g4Lx6Wxop3E5RxirhammZcHOSZp8cfMsodu3n4XA65dt566e2s9lSaZZT21oLLUsJ5q746bJZlNtqZxJ5l5d+gezOoLXzNeT53DUvdv2J1jOXXeZK2D+SESockz+oMQTZc14t1eTm1G4+VUYpS0Zg3rqVNZvaQ1GFp7VlO7njr11lOn/nrq9PZ66i7lQfN66l0r8IWkPZX11KLxuOFudT21Sdnde9dTG0rv+u5D11Nnaq5eYD11t3k9lS+oaYj0L6uZ3UF/1Ymo7NwqVS86yVwVsrj4gqABxJi5o/tlpe6wFKWfJrgj/0v8lcqTt2fI6+LuDRJzaXCR/9mO1WJi/YAquNubuODAE2SuJfAUIGFgrUBdgX7exfVwXifGTK+v6/jRoStpxY2Uuerxx8dR9fDjb1uBg7j10HVV5IOsq/J7XEd4+LoqUf3HrqtCt3/6puDq5HGrPnv8FSc1JwQcKggcIUgPxXOg/IZA7fqFIb96x65qmzg58Fs1e/DpYv9wcexHPPxocVOtav37V6tFsaZsjTJF5tFTQIf4SyWRHyh9HKAqaD8xgXvG/v71rY3d0os0T/hBeRw0rJl4GzZzfhT8QNGs+emlmutLtykadagMGu8z1+AyKWvjiZKGQrU6H2RJvRk4KA/tkoW5bNcfO/3/P58cn5x+xJgqPZ/JwIkuV+ULepkkS8pY5ITQjYLOg3mjXzE3XG59dAsx9rrVedxM61+0ip0E/ve4joO598mN48Pgho+KzWVvyNV25vt7NAywgwaVmUFDe+4cUbgSGTu0QLj7fofiDrgkbcRmka+0rDNEpvoLDrmTejh4PwtU4d43e3gnQ19tVeQOiNksqcC6V4rZsyl8poFq+Tx1S2V1hPCFDd84Y8TOGHlwozg48W+Gd/Ep4rFp5mWaT2plPvVs51JrSKHwwqlr1oQWI7vSvKDMc1oWq/ylq/R+63ha9Z6H2irpe+gtrkY+tP8hmv9Mv440u9OrWxT/rBNfeJMpmZSvy16jm0cL+tLasnJdoys2azT3dWO2zKd8I+W5/3WrgudpbBT6CTeB9ex9+90fO+9W706CZ2oJA2cdtBp/PsVdb7BB0FmjKLofm+oP5jf8r2hJCqrTKahWjoZ0c3Y3QmVN6bNDB+mhAhual9lpdzqodkkmo/7UsIf4DpoGwaQRCbeHe1idKIBJym7ajRTJpSCE63lgD6SYQU1cJv/uwntRNhykSenaI7dtY1ku+K+ucwXPH9WnmtCq6miuymtd+u+b/e9++JHU4DvZGailVtM4ozKSv0aEvvz9K2XqZO0PgHUJuKbM1bMHZk1f8J/SzeBIOFAC0ylgPrVVdpK8PaUco/biAqVt73SRHp34iexyRJdjJKUaCdh53Iry+IeTD6c+n739F12CCQeHJv4HuAh0ma5AeQH5aT6JqbgUNuEEkr6+JnhWpgWBqbRN6db+LQeTUjcNiEiwD6aHQdXYiOeyE8QIViYFRwMQZqfFZwW/PP00RxN5fT0auAJve6GOyeH9H/ca8xfFBPrUiolU4pyqbZE8e3f+xCso7YPn3bdhd7P76LATGF477/DVnYN3n3pR992njfLd+WFnp70z0RH6TxAgfgLCtPsFtJ13zxKNFDj53kU6+GyKwpE885ghlQkkqLB/PwH0mZpBNuL+DAU1pu8qFOi3SliVZ+GnAV8SzR3GV9J+MqUZTGtlnqmulCYGmUzmF5NDExiDbD6Rq345K6YHffh09rMuC0obsN6hGPI4oXczBoAndcLfcjjZOrYFgoQ/PjiRpg1G7/x/zzA9L47l5+SkE8WfhQjfuOROeQXaz4daZ9A946uCVzSRZSww7aDnOeFvX04xX7rQFyyXgYj4mWsL28fWE1SKlS86NapqF8Lvbq1EiN3gs19HkPCu30RDEdKDa8fClfCA3qo1GU5BvdKjLf5MHQmj28p3fS2VWjAWti6xGJ/lK5lhAqRq1xJURhd2ZeYP+y/JWYJ56JMOZlb26aPXs/KRpPiIk3m0uDy/wHjkCv7AxaN5meLt9KR8hFYeF7nPi6cYlDiJ/QUYyhglzQfeIzTvVNSMJ1czS0IEUHnN6SPtr6j/YIU+HK0gMRqUdHl+OU8p3lcsg8qSDCmDhHuP/3pDCtcGS158PHUGPKdEW1Jikq+mR2ELUnXWtru5uel0TrTDjUvyX/3pD7jlX9/d6LWmj11O/K0yHvZZrspz5BJ6bV8p+kyPJwgpcXNjCmHeZLS1+4VYE5f2t1HFg2eN4Q/JoAIvcSXqoUMKkPxnjiig2L/Q3RHsq6ZP86PlrFyhL5kenaOpfG6bUMS3bm95xScbYYQCLZOPWFDC9due1dKUO/70dWqvx+9PNuNl0geo3FnuYEOp6vbw/+HkIFT9nkIA0M2BGhGUIKOBwrOGBrAFIn5zBLqYP7uV8UGZjE5yZEmb7iUb4BK8deyp0BsPhvHifZLFU/zBgQiLEo0IBzuGqvHRCAh8pOf9NFjHDgxs5MDeGB1NiMDpWZQxoUTYyxhhP5aPMXapUCIRNiUhoY3R0KsXi/cZHXp4T2lSAI/rKd+gh0h6W/DbGarQ2VYZn3WSvrgWb5PlwRmtIF7qQO9QvaLAYfzqcfI2ftVJLjkzfkZC6cGrQ/WaRR7oM0PjgIAdbbBp3JomixgGxKmQg59J88E6NvFcz/RLNNIvV/plrMPfHvysn8cHrwV7jheH/QNeLPbq4DU9gxtKyqR0A4WBAI3pqBIgCznc1Gy6aib9cgb8yly8vyQ0l6Yc5Y0zboBwdEhZKZWhNN8/diPCPEFn98fuWgfDCzQAJZyO3W929Q6Rn5dLN6NbYESdkf+7+ry82HHVlGcZ90p+becYUB2Xn4NJDWG3Gm1qRsETcLF51lpXc70rtTdx/uiIvwhETazxxWkGkac39Yn0XOXoj/wJqNPLC0w0JiWCR1dkN26gCjC/kcVb3Xok+q+m0yEWaP9Ea4sGXkTjpoRaqqRsf4Uyk1RxQhOA2TwTLPySKSfom3R7qRem1/Z3v1mbsHEhZ8ppIDtcY24TZ5tx6pQoW8+XQbrKuhCU3C05spugothe+ZcqFv4NFEPqD1Gs1ahZWNdMOoAaPy7kF7Oj8zjXXnOSIkDUCfUeWfurnrk2V0ZwsZ18LU84oUbZCjgb/xfSnSuy2uMouIFgvx4/hKMFQwFG3+HHNoFbKnhdK6Ec0XeQquN1GveRTswDVbpx3t9UN+OJEj5ZgJgW5aef4D72UffXsIOmN4BjKZ+obPZVX+NjXvOyC5JHYPvoHDLRLrbxE48w9iYSQvoaBrYr41xF1HMhutQEYfo7CAm62adzGzY0BCawW9jkxyQRNg660FiN6IAB/QUik+BAgAsNMHnBH+OIgIaG2Tw3FFrhcIytfjYwVKNxhIMdkMEEIjoKgN+GpsGmffPsEwmpENpAxCRIzwawgbKkdOnUw4D+gBMa/g1snrQBaEEBHAuwgY2eejAFDtsiHaBjpzEsQLt0I6CO9Ub1COKCY7RJuzLDIW12J4QebbvWCLSdlIgievT0PnSN0idCjTJAN6T5UqpAAQTyEAp2a4MvodB2XBh6pgUZ9fAC8XQIOdEAwkZmCuNoDMJR1KMwTH0XHDuBFzoPQwincwG4tdc+bdUd4A0BhBwEMjNkPP41ONjhxEqMoR9h0D54kAJAl9xCi56LHOvIzdBFjtRfTInr+5EuVwTOf9p4Wq0tUi8A67lCPsZmLJuD0SbqAWV9P+rxvUUkCB0jQHigQ+CLKArR/vwew3CMA6ofe/nnAj0OjCTgmXEMZ2fjHsjAQsa3IZhhqpp6bMPIDx/e8iMo0/l1NBhDRajgXsf3x9KJcfbN6U+lPYDR6u9ca3R9kBAVNWze1k/Uj/o7rhtBClJr0W7xC+qj1NDxeAMCMQBHxRiA6iYtkvkoMkPolBlDhhBjhJo7CiNA6OxUr28g2FTNkA2qiN9CCq5MfnMwoCMmUMIUTJCg7BAcW8HBkUOjSMvM1Y+pwdJSD0Ki7ofEBC+hpYYYhppOlvygk+fGE6XUD0dqiPAGwpEfPqRbYLak18AYrBWp5zT1/A0xA6H8q78d0nHqkK5cwCPO0q0V/nQ63NG/TDL/JvTvK684cd9+qR3m732H+fv3yU/xS/yBx0wo3wOlC6/7pfW6KQ5YhAC45dIDF3HdfS69B3CJiIsMI3w2kWUzBhMZRnh8xr+Sy0ugXhOnXoieXqY/Xibf69sX8HfMCaBYa8QxhO6ZcG9ARLDlT4puIfivrW9kvuS/gq/f4Bz9TvslJdK71oYZAZcYM/UomHBsxLEbHBshlu/yjlmUl1iGG1Kcfv4pyQ8IHQXsuqAQiYHjN9clv4T6ZapfopF+mfFLT78s9MtYh+c6rMlVmeIzJ98bxscIOcZXeHGMT/DiGH/Ei2P8LV4s4x8ozIwpJ8qUh2t/sln+/CBFyTxM/vT+Jxcu0/eUK7jVhd03cguT57H4cvSlKrpWSA/LyLVWbjC1OCUvscyzwMaT012Pz7Nc4r+9TZ9/EPqfGuJPvfjd169u01+sdHz/lwTs3ythizHul7H/S0L275XSXDUWUZ+wgXbVdrkMGIc6QEfa1Ahd50ANOJ47Fkcl2KFxydCuDoTWdQADwhhbjFACxN3+NWQ9CTiO7BIb508CBh4yd5bUpllXaCBsRX7GlYDoB0TLgvhKmowi2nKyko4Vta6C0IusIgjBWrfNY9mxCJIrugvvkhdCZ5Dh8FAY58HRbVKfzl3xOOo7N38EqGKC/hAOjxAMxiY87tOxzjpTCqOfExzg+4k1s+fUobV1IvzkQp9ZVVrhgeSFVsRznEEHR6MmotBybHib70BE9mSS+JraLF09Vizt28slBrDQiZ51ea0cLV/BJoM1xVszhDWBOBFJ1le8LivotZ8PR5jHOptwl5UJgx07SxGXRITplKqACADfzDpH/ZGEnBvOTHuC60ZUlKY4ZWNJn51FfTJa0EWkuhhjwUWSPnwsyRNPSU3SEpgVEGLVhI98lZmTwRX2giAmGN5hyrHl35LEhZPox1oJP7GFcIK0AreU45qxxjwipXOC4zBScJbNnwgpE3RTP8d0lNp43Jvk6vchPhPJk9E3VYRfaIhGjijiEQK/jg2RTkdg4Euphy7FyH8dMQeRSpKrJ9Yskoha5SqJNZtBmIgWYom6mUSN+5UVXXg0QN5/q4/zrWM6bKkDG5SFUUjjWJQYN1gGIoAYxVBGe5ihPq5KoybG5OHkCAGJ8vlRcNwLMeIkAnoIWxmuGtooqgRDg9ujws6MEPKDkrqk4xM51Ugfp7ckK5EsHCtVUQCRQtBoEsEVE3iCCYnIKLIISS0lwRV1nQlFbokUicKKPQW3xeR12YjaKu6TipCCp+cKeC6EiiPmmzDkZQeGxrD0jkkFvPsxHngQbfKoFSxo7gSQHrgDIjGGOUOgjuDKJAwdooeiNRxqK1kQ4gqIBxeZYF0JhU4AIyTYMnPLQuCSvIjks62TiL7MUnRz8Lt1E1zhZviLcRuEDz15XL60blFwRIP9wkaFb+HRRMEBz6S4uZCxooEq8PW0UTjw3oEJHMYch6OBDYyU5eFmXQCywYFwRlUILbueY8fEA4lwPAzhSFI0uBJDEjJfXxgEQ18CC6oDrOCiowSM0BIQSQ0bEVn4iKAQiVOpQUU9BoueIjpIJbZVZSRqCyMRA2CWhSeuaLqOLq7h2WA3C0klItoY+fOCggk5fXAPYhBgtAmCUGh5atkCRjzXjOrAKYGJ0DA78jM4FQRRGIVFNRGQCk+Nhn8S2ciNkxb95M1nVpMMIYJYdOFWT0TUoFDdPpSGWE8sJHo18+LEmkjFMi1+shnwR3haCUS9w4dtZfrtZB6e57KTCS9xJeqhO5lA8vfaydT6525lgmZ3bmXiWSEv+PIU6P/QXU5uu/5xfj60T8ptVSZSNr0KgTTz8hw70U3A7qtvgDw9gTrqLKYNjynOJp2n2bz8Mb04uip3EYMCfpZgnkyvTp/Sjlwknx0XH3pJYQN+WVCFvvH42FOB9EGmv93et9l+zPb5gkm8PV7tZwD9CeI9Oa8lYXu4jmbiX5/yfQpvIc13yZtkT85mYbKe44L4MunF37a9fVzfshyXW0lhBbmdunIpvgnUi2bW6rvEiPPpdMUwut95Fag3yQvV6VwqE32OpYPFoiyOiN+3Qfylk7zd2t/5bvKddxNEgMr2Nj6BpNK0eW0YMoA/TcnGgQJ35tSZyRCQmM0VONdhm8XHwjIAwmDLYv/x84ndYnp9/RgU/DlGog6MnWzlflwRa5EwZqByvRPC7BnI1Vp2dJKuPiPieGcAPg0p7bQs0BWaalMMPVNXXBCMTZnJsK/IHBtxyaD6TG6xW/yVDO8S3IfZxIIGHpMmRLVoQqVMbexikBk2I4NF4g6vy5nXxqOqC97d0V40HaKt7sxoPiFLmzIWQcwpohNw6d3wwYHFU/9+HxJitu1u+Rg+WdFuEpPAXrlC8Sxovwftcb44PX00P8X9nVC6BbpjyRF0bSxaFutk9pOXKW4aycujeXv2bEVnCGbd9n43Cp6s1J45pyyWsDV5ocCI6L8ka2uKquWbmKxx7O8tjOK3W8k+1bvg69+vAbLpUUNEjQ7Suwz+Di3OHc3KjTHtlxtSmNqXfw33qfVv5D9xDRYXit/jOsJDHSmm+s/cFc66NXtTLfhMVG3/GWdO2Yf623hLfMta3NAJowdFMapTHawRWfdjmR0fXawd0vffqj5VO4WK2E3Jj+bbF7L6uVlkfr+3leBOstPT+Tl27VavhHLlAs1HCtPM4I6UxbdH8xJk3buo8JFsVS2PSCYLpDYRo/x0PkdbQWUa3JHxtf3y9tA8EplfTo9QOQtpqVupbe9EhqY2L4gl3p20l7PCEbyOiL7inuvr1LKkH+ndpLKoM6Fd0Cok6O9mOBBA6iNL27fSz5vTVxJv06fPbKWNjX3qRHTsM4TvwJ7RvkoxDx/geVF+JhrOp3rkHwEjr8UpkkiPCw0deCecuHAnAvq0PClXEKdIQsmiRdtubOWSjDxurBkfsdHz9KOtPPz2lIvt9bV5XZzvakCMg9AFKfkqBXzxhg58kblzrxl3zfItRMShDJk9281XUFDLrA/IxqXb+bOVxSzdlN0FnGxtR4qDRyjAXUHlZerg2QAZq/3Vn3Vfzpd1aIoP81NwpzO5F6vP2l3I6eQln8edVc7h+td5TbH5P9eHI+fseTXb8r8vTy/S/U85cqYstHu0vj6XfelNCNZbm/NpMF/tQIuXeHJr9Z5owEobFsW1Zik+XUybdDaetHPeZALv3UFo9wn07SSIpKXZjYB2mhCAooawRHu67irYRtCh8wP9iFhM16U8aov1t6faVDOi3W7TSQgY/r0vcW9Yl1e1Snu5R+NN7zNsuxoGrictpU5lXHhwQS1Xm0mmUMV40zdVBg5dHC1KDpkqMgmVqyCT8AbVO0Nj5d3LwsWj3wvoNjxqbq70/W/HdANdJo2aaSqSYxMCrlS92nl67ywFvFLfCy4QpGJ+5nJtO8kkUgt+5uscxLw6PtzyKjrqnG5fZMRoBhEaatmZOnZSfrp4fZQf+x1n3i5pIz5OIDMjxU1S4LcmncQdKT7zbji0Tdu8bWkXbUMduKbti4u0UXGracQMKag6udG6JM9jKnMORJpKnp9RC4EcnSCLyElQ84bmVn1pambV2R134IhVYxoMxVV5XC5L21oXrGwSbNok2KJJMF8AW0Lnd8g6rzaRv1xM/DKCqPs8i+trcQHEqyAb/IJngQoO58COz3JTCFqNxeuLLV5zKV5fbB5M25a4vF28Fi7SRLmh0LzSXsTljid+bSxTmkZJYwPkxebVyYQMwTjjypnL6F67pKpqnqaesJZQIBzAYHK3gNRFmVQXILNdEITL8OfmVtILz3ETVrXrV9jklUtwbXby81CGw2aomavIuUrsg3EYjggHOtGNpIw+s3qli6Sf04C9QMoFUkYBGAd5p/HjINglWVA/UPVEkYg79Pk/p6vjclXRMoVg5+X8w06zQW851+S5QdEU7pwZqJqA9tBRQYgZElycXpX7V6jHv6eUUXrba6bUr6mchrQ+2dNytVI+gO+SQuZpbmlR3M0qJhQY9PziJQPbXzWfyVdiNPl6ot2GSUpHg24m6X3MnN58lI/1zKyeWUVPb9SQ+YJzcrWhQnqPfFAdfbLWd5KTkPpf3LJt+2/n1B88OQG7ytQEvcXVyAdPS4DmX2dSovU3nZWAav8qt1+lpsVfX7ch1y1dXzcP993VizxBwJ09XzfnaGsF0vZOrk/V4BuPoLlHqpKAoHZpFC06Ga94EKi7PlpbiC/T4Bc10WTQxfGNW3TqPcn9wxd0AL4O6d2C9GsQKTwl9sejjsLgNNDmY5eQU9yrv0jQv7GcGYnE3mKtBhoNuPv9hk6cElyVpIf/sd4SAtUAUR3QqwEgjZPgWHwkso84qpWi0umkIHLWBaK9r9d+h4ydU5RcNXvwrFuredrt5NdPVlz90mTF1fr6VcNkxUlThbhqnqyAHM0zgDMs0J0EX+ee09Pu0IzDHrJOYSx5pwon6dXRNL04XbEWM3KJVroNX9FijkST9yctcp0aH3Mg776T+BDrIX4bfL2Zi/8exOZy8QwkWTvA8YfLc+3WtMUUVWWgdj4/QpH4PyoaBXFj1J8oSnebAbnidO3N+b0MjXenWmOQGeNy6xg4/eeBhUGfZI4/fAWehSbz2AZNnf3BTK8k+U2zxf/835fl6vOOfvB0QfBAR+Q3R4QtLq4Iv8d1hF/pjrRqfP4zl0lYt6Y7odHM65uh8Yf6+kfsmPxjb4Pm3o8+5aYi2tU12FQR7SMbqh5tBR9Hqoft3YMQjz6gfRUBvEHbNQGKRvRBMRCMAcaW0SHtr1cDIEVjpT/g11OI2wAanxlXozFt898EpwgseuAKDgM1BmRA1PhtbKoNEkJt4ig+AiF+g0iZvegQbAhWYwL29e42oukPACLZKGmwAgYUgcSI2NT7oJX+cmKoxqCIBoBEQNlQ+kOIEA+xPSBEQzXGG0j4UBVwyCZgSe+EQCQ9BS2HJCMi+QCvGkE3oNHW1DEoIRoRAJOIIqDiR0nDGvp0sNpQ9HUm0huJgRcZbwxkkI8QATheyLaEMgKcVEU6wEbqJOQQ7PpKK0EskRbEIQ2AQVgg6PV4/z29AgzcCFERiUBG2KCdw2oDUJhhgIghOIzABPFgTeohs8mmI7UB+aAzbdjbHCjwBr02P4mCJ95HQAEpiRABsY/fQFE8srYVbQCMSLKS3jKOtJEwlSiQDqEsZRcZAZGE2KO97vgplA9Yjw4ZkAiRQs6C4SYVR6ARSo/0IttRToIZIDAMlTBo1scPcWPoFVIORYoKM37hBvCIJWJRLiEUbE0WU8i+8RhBkCPZiEphX+lN+YqSog/OgRPlGBXtMQoXqFDUSXoCgjFymKTZRHAASSMUapBQRo8oSURFCJM9RubMORhCc+IP1aKNvr6fAjQKSR9Sb5f3Ev2XmmV+f+q83NrEc0ODSX3+HV5uEOuLX1FSzM2vdKGTnLnGLGmhjr1NGmfPxgSEATDdf7a+EagT3dyfJNMYTLZP4pNOJ5D5/fygpEvDT7qtKOiY4DRYBz2c0ZJmgp9ftEHYPVaMyi/B+hnimTHs0j2mLxCBd7cbWKITZXl3ouC9CR0H4uOWN6xSdedaaZ0uuvYm4cl2ftgvsqiV2le7ao8+JJUlNWMTDxZsH53baLC9H+9D4T17CSw7+9Ho96VemNmp+ZqW0NJ9TQ/2DzvJHi7G7LTTg/Z+px/8bnC4roM9Cgad9v/WIyIdEfNgkTioPCnwiClM1z6ZVZ/rdsaBgNZ8unm82+lQR3uvSFYiSZRuvsIsZaMqfcoYECJjvt4hT8uTIr+GdCQKQzRC9y9Uf7fbJWXuF8omUNeGZ6d5qGG30PhfNxAXBLXnoVWKCle8uGPQfEZOF40TGqKxGpPFX+ydVGeNF9mTipicX1AVYypA4/FWspCr+2lmE18IVCf0RTu1wt+RhDX8kEsPlfF6ATB+waJSlmPz5YRjKF7u5O+T40r0hAaa7jUPaGzPVcIuQN7sJiVmi0d971NpqfUMcyRrnUaeHE4PcvreUlwgRoejQ5j2lqwVqSoyZMj4YEJ/67Ki/bqFiIIEJ/bofFYxNZvocciupV4OQKa3x2qhHpd8iawx1jhJPPvvjCfjrrzGC/1t6//BrjtuE2mKhkrQDLzVFzvZDqM9LnW5CivcAsDSHU74jBKetNNEFg9Vjhc0fmk3QnibMB9H2Jd4sYImvL8t8GYebkz/cfflZeaGL9v0Nd8zBiw01PJ5BCKRROIW0z7sjjJ77ZUv4F75KwUE4kMErJI+QL7o4TvsfvuCA2wtA0e8xJWoh85gg+Q/dLiY9/6V7lpNlXYo6dIRvXpEnQU3uCkK3NrJ5SLDkQkp/jstjUrLeD/qOMNhwqvOXkf6WGgciVkPTensaTC5Dc4Cf/dZ9XLXXBvBiy/tTYVqqWbcZ5JP0O3O3E6i7IlT7IDuXOnkHC4OO8t4mfh7hZ7Zk3JBbJFAgN0wBt63S89LkeDYSVCqpfU5M95wo0t7ho9cRkOWaumk8mQ6ZGQ1T6qC6k06C8g/7cyfzGhnAULt9kI28wwDTxmcJHDnfvvotPg60H4Iz2qBACFnT+ZAY2hNQyG1OpaiI98H2bqlJJ3n7IuSg/uUZOQmJQdNSjI6KTnwlSyNXr0xq4VY0qqmjD1tNmzQZe7fA/n2QOYqn1N75ybBuSjnO91okgvxTLyFgib+dcnVU57S5wj2SrAjlcfh4wT+EN8KpPv6JFdZJ8GLRI29iLEHH3jwgQfvefAewQkYAUaMm2S6gkxc0+G3Cvi5D445sExSrBdc7R1Nj2gnZMtA54kJcDm0yDMLpqLGwMtF0o624P3tfdNF8etGBveil/SepE8v/MM8fg+crnsCf65GXXtR+9Wo917Ubo3h/3pxe2hT5O1LOxU8AX/nDLLq6bzW4bM+hVHafvpx/2kx/+Ps6MPF69O21kYZbIO6uEwMAKsKV0dFSWXktuFfuAbuKzZv8VLNpHlDRxhn4kl3Ohn85ezw/h148AKJ9k3jh6tlhWGnnXtdSorhMk4ioIpN1l4e5avT89MPF49QysvVSXnxaP/Tcn660h1Cy3GgLurHdFHe4nQMTv0QnH4sL87zVH+v4JepSkofvcMdcsUeGIUreVMFvNTF7g0KXBX+JiFwBfbtGzbg8vRjmy6iCKqxUTLsdWsUVHjfdIe9mE+fHOBW6/hNMhjrdvASubS5nVzq0yFvD95Qe0TRmxsmOsK2w9H2rfjR8L74K0mfXDOso100rWyF2+lTLDqjEU75E8irEoWTy1ywk9JVWPYNO0sqXFflXUxvIRaXeZm0fMyUSvircuESU9pVSYMq6eJy/vq0dsUwiAl+cQQHB+QE4UrC6bTzGo/zs1WNBzgAesm6ZlXqDNTPf8F20prDpcuwTCr12miDqg2+WbOSiNFmX18PtzKxOgru2/1XP6F1ZmTaX6X1y/zByfOGHGgWDZyXn5sUbOZm4m9NmYDRxVZiW+E4SLnbBJQKWhhXGxurPgqj6zFbhiSzXgsGBE9sz4CO273MOm2Hqr0Ph7VuOgf2YNZTVFiVJ1nHJQcpLG2OKSoDTxftUBWKik2oLG4QO8TtBJzexIEDdDVAmfdOB7w6N7SimS6WbU24upXRaKObqw+2d1AeOgAwYfG/Qel+/leVbr9l4iJyx25ATXjBX3jP4m43C1zucJx5oRJikBE85+A5Bvp+SsbrqSTFNAn38SBErSDnKUSC6Y6kgP0V6aQbbddhOveRXRPDJ6zqJiOEhvu8CxrjRaMkyYIiGbjvqI0Z0HeA3tDgjAXEgMgB+gYydJABA3o8DeTGK6/S4uhTO5UKfWMUNwpIZSplK+aSZqNniNOOcukcZYha7KQH5SFNmE/IRS2pXZnurHXRzbKPCv+0JG8PPNCf0iOi4zAzz5CctPaBJ7NOsc02/WanXUfpRofXtPuf+kmD1J2hv0SVnKkmfi343II4aeQ3JeJZJynUbDsxyDT51bUv8EdI0fV1cl8p29dp5gYoxnJdKLQ1w3sj+7qsSC3gCuGq9HJ9ndtdr6pqdeo1hfClIEk9SU15X+eEXiKfWIL19QaZkDNx0O3yeyUF6UOarp/nmdFKlcxRJfMgM01XJ/UrZX5oCNImXGq2M1dnOylepNZWRFo1iSS6g3+cs7rU4ksK3VZdHKQnB3SMGqkKgzvTvs8aSfo7k63oS2wG56rUGV4go1VlkJ4+s6VJzUxaWAexGaam2lbTinGnMNjUqjPtLDuRr88U3VNxPQO3tg9cLwPwNdyWTYzI8ia8PExmfi4gCc8WCJoSWrXKHRniEbKBGrXXE2/bJsGA0g5lorrwjFo6o2KSxBnVSh5WsxamcO3WLGnl0GMmZWJmdZ91c66TQjs7XF/CYqUSFJ/1jFjDhgWNTf16VOF0zjwCsSXiPfNV7YdKfk9phrOAX5m442NujHYRoKCj8S06Fd27qQ1ZHXJq+gpXtopt167B+sTPmIaTLcjhOJc6ZPk/gKulONfTwczVgsA4Ja6UzANYslQ3me6SC+6SuxFCPqnpfDvFROdQq13hy9mR31WMxcNp6ps1b/askRmpCS2Twjh6xHrZKfFmJ4+kTnEfusRzuVXqErh0sR0wgGzsFpaWRGVqqZDzlMdaZRHaOCaPyRy1fiJTdV+Kfa67vSnRKQe/CwwJM6tBLi6o1cCcwKD2iFpWa5mMhM9V5nIzVb0nOcSP6AyxzQGQHXYMbicCRg0fsEJlXJECOmKGjFxfr9J3NVT5MGoEscYRUqESdLxgBd+m1ywbuc5k2bS5OPAwqVYY7HL80paAWB+tDLeTJbKK47g5l+gZ6hfF8lQ0ZpVlui0MFENL7pjt8Mgu1lFkQpHtMnFnlOYUVF9sdUqpIOiIM9dCorCZkqQ7eBoMnO0A5kaEZ2qOfsd/LwNyxqwAFCvCwCNJ5igXM/xltmBKqsEBmrHSx5jwdJ7Nt1HQwctyx6H30GxyVG8S0sUR/PLm2bE6Tnw6AK4S995TlwkqjHqRXHaXZqctHaeGASZZDO5OgRfqhLQEtgx5TgJqAkydKtkBjBS3t4iFyrenwJCK2cdh0OawFFJCFsaBUWfuDzO5srwwLvBeYpLrdi8PrVOLpmwifZ8V6PLwyXcd9wKD4gDnEz5pKSidZM4tw54q1QsV0reht/YCSriufUWx2HHY6nb34sCPu3EFkdJZieYZShWalYZGhfihecNfU1WoQK2vS9ffPmNP/0uNuKT0bqr9nZuM9T1XGvlsm17ITgPF4sraTt589KedrkdBFS+D4H2VYQa+3eu2gEBD9SzAwwIB6w0ZiKeDAkwr/hRhAgE/LUb6JDNOyJvABmKb9la2Y0DdbNLNaoqe02EnX01LBhWsS14ZQK5HPCape/pYAk1u3RwkZ5u3UmyJ2naH/3ShNpuJCu6l9I73zM4caS8lUPOEpvbN58S9+s5leh4HSCSj0TxBUfQwrIG1UDvnQZDxTAGKzUyZ5uoR71FBnidLpPnFzemYSSFwrmplDxVWeifK4W1jBGaAwWNHA07Kqd544AiBb8fMaZAmLX/QTBB/0MyA6ggZEH+EzIAeA4zwnEmnZphsNzFRk0WWowUzGsCW2BMPlRlZzVxDvHxiQr9LddHdWna7gbb2lhtZwqi5V8iXaCpnNJoE45AYhxH2Rw5HuE42zXLMfk9nR38+ni9OTpdn+O7t5dXHT5+/rNmhdR7o3ENjNcN8BRi3fc56oGwGyGl3pvJrL+Ful5LGBn0nfUp9Ql02GginwXqm0OnRIFfwFTgEVEhyI32gCv7898N1sAvdO+VkLVyrFhsuBn614oaixWsa9YFz6rilVT7ooZvqpil8O5Uip6tlhVw6mobJTmbRRc/M3aQcmM94MGSLSpbkwLqoYYkQaFUy6WfIKWPMdnaHzx9IQpZXVezsyFyR1ai7kQs7n0ymPrEDY/Tpq6YZjffVqYa6U31a3DEXLE6SzEin3mQ0xd8zH5267qnlzx7XE//D6Uc4Wo2zF3mCibRttJyZaaixEYoW568wIzmhwPO2cCZpqBU259VYjGTWDo0LgSC83b2GSfovFeiqFOAD51yR7N4DJlmB/l2DOPWmltdaUAS3e2ZmW3rgylJLzNi3p5QddvzAif7vfu3CzXf3rwg0zYDD+5eFTNLORnRoVRmARADKjQDcmqczvf5aKPFlXsqjMiup7C4y3JH9/vSjIwOORyZSNRiTwDTqel4UP334gH3D7cgj5ZR0wReCu6f646Bhqv+7v8FU/3d/1VQ/FZJXyYHeK642FB046PPpAdXr0/GCvt5AP4jUQJ8YGAIPZwkiOmqwobf4b9AHBNRYn7qIwsjsm6fwpmpFxE1vsifG9KTjF/gNI/zwPurjh+cGpQr4GPBN+vXxM4cYIFSPhOlt4EdyIazPPwAOPvzBrz5+gG1E+OF9HOEHGPj0IUw/ivBDOEKYVOrjOaAfNBz28cNzhPeNPn4Ij/v44QkZBmGE3yZsgF+PDEG/Pn54J6voYwXAG0X49fFDeAOwMZ6bgEGHYdjHb/NQ/ZzY3UDPXh28MjP4aLerfdns8kR/LLSpBnpjFx38/Y8969Y804D5KXlideeOfaYKQx6/pXqvRxTaT3hyS380xQatdnB93aM2uT/6f+z9cXvbNpI4jv/PV6Hons2Ka1iV7CTNkmH9pI7T9a9pmouT7t75fHlIApG0oiRbsp0mjj6v/TcDAByABCXJddLbfvd6G1MAMBgMBoPBYAZ4YtRZWP9jWlUJVQDIMjr2lvc2sBwEMfyx9d4CdLNyjtJak6MPEM4dUbYNOzxYWHfO8T5FGVPZCR1d09wuAUthwUQNlCaXVd2uDXXqZ0FEIpo+iCZZCMwdKMqDG4lGjscVemC/iR7oyVYe1ODlR+wTbFk/2a4Xn9RSeJHgSc0nlEgXlZOaT7DSVkeIzm4G0t/pgoFF9buElwceP2n50REhUykkzwasFwIygFKIRpthvZLVgWHoB9BwQhJ4jkjIuc8VdBxXv7pPYIbqFTBg6AxCX+9vkPJ1l0GukQSPl8vvR9KxGbgYk1DX+jBaoCBUdoYFrlIvxHtViH2UFXV1o4NoS5CzBsCo39OFXs1nGcb2vpqPJnI9DavF95DEpvkX5sqmVMHV9PKig/na8MTRd1If+t3/NuaaZxK85mQ/lKcCpZsPBvxzNMDDVDrAD7nLEKE00Vb9Ijm6S1YM4EQmd4yMgRFnl9/8LQ3LSYAO+OfAzzwsPeySTI2U/slS8xVWTd7QQ9JeNcTzmOv81VAFan/Gwq9s3UL98kFMPeAEYaZgpQAo7y5MSwvIX2COz0aJs3Q6EMB0Xot1bZDDuMKVHGcCbbZc4Cnnd3kssfNbjyV26scSwZc4l8B2tgJZPZfA46EDpyZ6CqB89J5VrD6WIMnorKTVjZiCp2yF6a7SGvEBh3JIdnY03fCPvyWSIZVRV1tO43uj4KD7RVjFgsyiti8GUCi2f2vioZOLnbxrkmE9yXQZNOl7z/F7IZSya7sipaqI+wULMa+GnCofKZx/qhs4IzmOZxzmxkrCsY9YX8giIoFC+vAcJrlwpviOZ3RK6ZEzTgOkYBFGGhUDsLl+tsub5IO7i/FQAfxnYkUJ7CgRAZJV7xfGx4MIwM0Qczo7z3T/caGqyTkNlu9mRAZA2ukIciqVo/7gF23u+izI6/aF46lnV5ukVfOwZq4/pSxPSvNKKucr1jCyRqmkWZg7duc/paQBKILZB/M8BgJBjU4Gx1j2AhFCPWOTreA9Kgoxf51mo2mj+egqu5yn+aVarEPG1bO/yNELuBpG6hp6V16+HXCvb7nrZEr2vx4NhpcdqQz+iGZgfXVoKi/CvOGz1jBRMQlVnQF12g/DUSGwhSFtMDVC6KHpJKtQwqE2u3SEViiU9KjXR/+Zav0bukGwHxc7O0+4LBW4xaQRjFpCFW1Pq1K9xNMSEaeOS0a5y6X+6lXdbGbTurmRjFja1NFoZzTbAQLhWrnxRz9J3NMPm/t2jbzEWpWCu321lq2D4avb6ukeWzK2r9Q3uDJRr3DKWqx/fLZBur3ES9Rq3aTzDvuwYxHZYPCxZnyv2AW3GM7mmmzB1gD7jzA4wQGoty+rDL4oC8y6A+cpSbkEyVSCD8bRfnWvi5qwjGmq8QlZejE+G6o7TjFkay9PCh5jeEqipVKqzwtyOi/ocCcgBYKUQ7AHV6ywkIr6xqmQ+sdnlUuOZ7kyGsmJ9Pi7/ABgdiygigdyNfSPd3PG3YMCbLWT00HB4zCMKmhhgd3ksTprAwIiOlSDAQw8KgDEufGegzZ2cXPAevLIOzBdwmyr3M6OYLDT+PyZ39OUDE03G8zAAqxRhX0TWY2NSBykYVVOT/0u6rV6khMjd+rj4uit/mSz6ul0pfWcFPmUPWeNZvDZfFMgH5uB/Lo5lCMPFOrQy9nlpoCCw2ZIUwLjeD4iJEZ+39rrm5yE9QS5//9WeQurzIVfntOOqqEfPe0VTKfju6hGKxlVmLS0sW+0bK9tofC0MN+gBVeP8FMSXWOIhqk6eHLmuEGplF1x6uTrNQcPVXf7Vvg5QIbk8uAdzYEYd/eI5SqMLJC5KDlM3mPMehzqav0y/QGmPzDp+yZ5D5P3yuJSauSAXL405NhJl97zvkvTFdiy1YwUh7OraROtWFbZ+KOa6TiiUnHubIz/N5PiHmjL45DfTzhs30DIxelOIpZ+DtSmJg93+H0sTa/peM/Izgi+nM0aHu+XTpdVbzJRa9XSNMgagZKk5qos0vmmlYPDqhWvGJ1vWvmoUjflq2QoZq+ZjFoNXwEEy6wCQhuxVUBMmZWQdBDeKjjWaWqm3w7yg5qLSTqacjHfEBrCWofY0yl/vRosyxtQDXID+jRj+ZnvKNfvd+3sWdBWiGexrNBbozw0dvlYJH1UdvrRA/yzH8FFVfD3QfTtI/z9MHoUFwl80Slw5WT4B+dkGFufYNzcp2SfXSQCpu04MabPeIIXbhauww1gBPlCKXTqbEJ712Bplodgnk/GcTg5/XSms5WTTc4gCZzoGOaE7BMIN+shpxT3oQx8wNBh5JmmcRl6dHUWql3qFfiogaf1xcGPiclC5XH34v446vyYUHml/O30lfp3sZuDvnUFkvXHz0lK7mplIMUOgAiV/QKcf6TM/RFkbhz+iEIdNL1PcU8qg5/Cqg54pR7cmkKPfzwz+6jzEHui1wuEGveffIpDQ6pz9ozo9oxB6U+7yR508NOBXSQCZNAL6Rl7Bg3HipJYAZuCWkvjVAE9Q5Sp91LzrbRnwQJldncXtVnS3fvYFbrP3bg7nftsFZCz8E3ftGQ15JLKiUD2+TOuo+URjGFpdQZinQilarOK80Bhp3+aSTGQLgusUH8+yUS58lhnYIrmnPAJedcywfCQZehLStgNym94Q+hcS1RsHQdnUArHQQho2JCC8zCM7Mp2WTawiw4Uf8XCwkrYBYTEqrCw+mRjVdhYFdDzsqVPgFVhQyoAKbuuVRTrUUn4LY0/lhovQthJ6fJCUgouktW/C5san5AaUUfon5wJWbbQv89tHAeI41JpX8Jr2yBWUJvG5JOztTBFPpFJKdWGo0/EUp+QRLqfjgdc6cdnFz+QxTsp0Mphcjy58y7T5D8TyEtnK3NjkPtW6UZfLOLsOIVSKZryKN/MAt3JzKWGXjYyBpNO6oTqt8e4xnBCNZjcOPlZ5TIahCd5aAJDiEs4etWm9m/AwDh0ZdasQy9AHw44+6l6juBk0dRbNLWLplg0cXt/AMiRtsIym58zZEnyq0odxPvwW/cvpW0Hb/Suqx5VJkFteFnuesqjAStHe0teWnISx2VBiSa1uXtt3yAAdcs6CdTJzkJjyotL6x4WKue1ay/Nkr4N0tbUERgTSQZnnqIsAW9KPXkLcvEvkI2mB20Pz7U5Wl6Bjkdgav/D/wRAoBQZGs2ctc3A0vSQdv+5yKaJ+oMXFumU7vejAQAWAzFP8n+t+5yC3/8uYElCEpT4K3Yzt73SCev8Me90wp55L3X6jXc5BVte5pQxjsE2Ap8l9DwyS24wA3S9HlpXfvJvhPMUbMjUiKqh1NEqvidcJmiFlvbKCZqPzddj9aEedxHli3qifFFvZxzGA9is+x7VM1NdLvyKLzD8P1zar2f3zV/Jubwrpjng826+SN/NUkGe/4oobMBM0A27xus/4zrDiYPOOBHsOoFnG69nI97qsWkyNN9hBDMWC3SLNBOFSYbiQj6sQnUgYUI/4cfgPfhPqr+QA1DmSfkLBmV6MDUEiqa+t4GDOQzoPJmCgLSGLOtO7U0c3NkaiyTb3fvL1BnJ3T2cMcYZ5TuhH6Kbm3d9X588PTrZ/fnp0avWaApXJrb04zItVaHy1i+ba0CJgcjmaLBVbSUCCDsGZMfAX9AxM9pj1p6nHyBlnEzLAY+RCWOxW0JSERX43hosA8OdnRD4o/0/v/bAlY0n9mMGO4Od9v9c9Xq9fnuHy2Cy6/A6qT3B0XEJEZYxC9e6QVgF3CJV2sDOIy1gFC0a4VB3W2+GQn4ZIk2uFkA4vJS/dQlZCqbOVFTD0ppI10Q5u/EKLiyYw3DnnWuW7VZGtM/mYcyr7wgrxxQNG4if5JBSgTk34ljRdacKAqeGQS/c4TivuFg9r3T8HoN55Z9TyBXjZODOo2FtHo3XT5trZ9qI1XOBmB7H2bD9tYftleTgHsYfqfHHEbyu8f01LsmgNZTjKoACCnvo//hg7JnK0bgUhdcwTa6TsVrPnuz9ZeyM1E6wpzGu4Wu/wC0P/FCdQLZTb3+b8QGk4yG0MZRTcVy+lGqm4jAZex80zRJuHBl7OEe5JYT7rIJlH/nQKbHjllAKjeJFN4ddI/QqAw6AAQclD18nOaSI3XGV/6/9/H9t8b9w8OqxGl5atgBzZDGpyGUxUpSvPydDQ5IsRGaiX0BGpQ2Pkyyp1B0/KSXbGKQZImTdNzdGw4K43//fPoMGBEyJA7TsP4jQTWd4PxngtW7ySXbglD606tTO6Pn3Jkl1nnI+QqFdqmA2QbKdf19yurVOrBQOUorlz7iSvYVaTEBALw7+gIqx7Nvq607xQy3c8hPF5de/AlXdIKqZ84N8c3DRHoH5+0CU2RE3n84dperpJq1cFskYE6T2jFfOdwp7WQrjtrV3fQOSAhsJkOkvQKhU8xTfX+O1cG1QseRLUW/AKoCICb0c2umq/C9J+UBRzGc3DgLfZVDN4CgZpqh5R1+Upq8hklyHcluu0vPTyc7Onx6fAZmXxtMJRFTZ6u4vT0A8e16BtQeD6LZ0bnTF1IJNrPG5sIcu7Qj1MPMA/fDOdWi/ittW3Xk/A9mibBF4QCiecJp8IuRwzRIcBM7BQ0Gp1vJlPd3fieov9mMIkM6RHPj2Ubj8VCPip5KIRfKJAhagNEZ9AyuKS/cFxaH4NSoYstaLWcqj6yWo9Z9ssk6Rnssf7Mevf7DiFvDMRHXoh7InCaKqXsjszKnsefJDreiqRyRT8/qusvf4hLNupZQuZpxUTU0MvKKg6OrZw67xW3cXFrAeboz2e3+5/uYxm5fFTvL56Bz8htpS0H8jSa6zwFzQxiHdxYdIf6i8dQzTYzSBETyczWHhr0RSoTERD7J/SDI4xAH+WYb4r3NtL52EqeHGBLRcQoW8DErgYMnOLeeKoeMbjvnsKR5A5fY47vd3cxkCeB2Se1cnhNElr8agRMU29/Z76IJ5sPdt1H8ov/qPoz2V1n8Y7em0vWhfpf012ldJj6MHKuXb6KH6eBQ9Uh8Po8fq40HU1wD2oz35FnOqGNzILf3T/MWljw2TmiENxu70Eb4Oo//3iMEB27Umojo3vS5DQPZ7ij+e0qJWvc81LsonCh0xRDW0TYPUFGJKru74YPiUoVREEWvZIqrpaTGYzeE6/gmw16vXxz8dHb88bHu2KEO5HbmZphMRDQHOsDs7x4YWSflVwh0k6j3Oz5/NbhOaXXt568B5qLGTGh2VBZUnEtDhQV4dk9m6Hr4BjDOBeiGf5kWES1VEkqnEF2MsvOqhHNuWpjjyX0mkqNXe0TDj5faK4b9fcB1Zo6F+xpVsVzEMVmqGBOWPaTGVXVuvGKL0sTXEr6sYatGjBErD66i2DdVrhMiM5Q1clPp60zZMAj0xtX5gW9nkdv7Vj4cn/9FvXfe7D62NHBtqYImByqSukCBsNoyH5ZNMvdD6IaRw3N3fNbW0j1kiYGHGPxjQhb/x8Raw2JZcqpzeuXR6t8EtS79+FeZheaD32MRjieMhs2GJZGILuEHIVOs7O0VUQbtY+ju1sMLih159PLeGJq8PTdPLPlrOZwZ59Cixf2l3eDRogVDCr+L+/T7+gfdCIWXvHn5hViKzXJEWmEXH3b7T6ymtDNV51/gUG89mhBjq+BkYziEz1lK8nk9HHNm4btXI0phH+9QMgO8/yew3hyAfOKTSDMbEdIGMPM7g3/EStM4S2t4aaL1kPax6z4DCkJBbPL1Vb8kfi3i0tg/hljAA8DcDmMvoUbdg7nKDcXekGadhDMWSHAcMJZPE+8LkT/AsH3/HCO1CQps4e6CBku9aD/NrR1BkzHKr0qQRk4skNwf659ahNqJglkTIQZQRTVlBLBWxz8n1oZBuE+hwADVFSIB0zgGSRj2thgMRKQAX2wHQT7TZhAkjBNz3IcOgVN/XCIPCw1GC9Ur3wA4WDhmiJXPX9QSRod6geRnrOeCwHUeoIGz8vWjsS9BBYts+TR2JDYICo+4iuYExv4bBhjfoonkXTO64f35VpiEeUFQwgX1EAjAJTNIoNN/YU8yrNIOORFcZrIoucJVEsMMl45JvNU4h/N/Sp3znyn2D5aCRkbKkDgpvSK1UenXu18aZ1lejG71rhIL6C640oN1yXtlJ2ptHmUk/8d60NqroaCVBHMfqAf1c/oEFxN0Ioi6aZO4Gvv24/STBoBO5kWzjOQmtNXrRgO38m5lZh5ZrtnPBV9jPeTXnIlSLcm0bFxudJl1M+zEepI4S+S8OovqNHJKk9G85vHNVkl17doJP9T6qTUx7PH0/a7PLdHBYpIsFLO/yb/fty+NfjsBa/YIhrpD8BrW2k6P/fHv08vCI5cAV8LgZnq5E4KB5jZvo6NQL3DwtvnEjxy/fHP1w9Npto8/y9BzGDcDTJPxFQ14yf8tU8qlh75VYBNv3tQR8zEGFHb0fiTnNpY27/PPxsw26+/OIt5dnDZ3dvK3DN0dvTt68Pn75wwZtygafG7YBYNTq3XKNC/trMo3bsNzmXC3aLLjzln/SoBtaVuL/CLbGU2ClL9DzV04DjWiozy+Jh/raAJGJ6H+R9hHwymb3aPzvuN29pnaFJseX6PGRgb2u8b0v2Hhjz/OZeP9+lI++DLcdEnQpzD7awsyoV3e9LBBsEil31zcN2S9QdCaN6R23SyOq6HmUlPpItyzxC+7j8BkpQ+yTK2mU1NjdkdqhMXsKSlLUXvhaoGFpxKLrWcL/5bQEGhtSEpp7XCXVxhh8f+zXHKi7mzfaJWa9A11C7VTSosYWwJbUyvIMSXNY98qXl/PQkLRgczLvgq/QIswS9XFqZZ/FgTSfKINGZnyW3k7H09mHqXZUKt3MympoIcwISmJBZOYK1SE29mb2DG1dFb+foXFTqlOoShwgwql+nJzfoh7vyvFUj0evr458ibwYbl3z5dsXL7Bquy1t1xs0Rcor1kt9LlJAKxsLXvmdkl2ye1kn9JI9q71yDMxBoRHmKpC8K1gAhkt1XT7sXz9/hn8vPOU4k8Xg4xU4fOGfBP7BfPhRM5yEsuR/Qkn8Y5W88Ja8ABsClpUfSe7YFRA8DsqsxeURYNHR2+MM+/pm9jfxa6dmDPYYY0M8ZjfXprjRQdgz6DhHi438oW8m0Cgi32Zkl+E28bB0qPqG5NHGLkOW0KLfK4YJ2gvMlLiwS/wnwwSIyROVS1VEIqNlESLiQqGvkEt4KeqF1LadEyIA+5bXJHC7RPR2u7SMlR1HKFMnsZVzcCHYYPUhxT20XoPB+l4P/6LDJtps8UbyXEPCqCv/AQgTtkEeKaD4AK/3wNFXI8uTZ+qAMnQtLUM/UPXwzi5hXXpyfrOH4TSDOLQPBRg8zGMfDNRNNDykOUl8WNKPC5d+rk/PxH+O4DniAfJNtBE6T1wz9Dr30lyDSAIDjOWlf2kyYXlJWf+phUNuFc+WVWaRxqwJLxchaO6ZIoMzZORkMm7gh0ky2SV6Zc64TeJw7I7bJB6vGresHDfJo8MD3rH9wCV60dgzogop3BKlo/kP5XH3ySWk1qSv5yBVWv6AdguBfgwZ6/eUpAGrZO/BY8fVQNRcAthwvUuAuAOXAN7o5FB1FuBhZttkOVsgIaIeQ3N1lDFAPxoy7GsEZlx0Q/2WiUjxm3TqYOcR/mUX+s/3sh4EfLBz9bnbwV9Q7uJEg4YQPVUYrcjya4n25dI5BL7hj3bK9zorQMVGVwXnnX9tzb4U5ytGnJwP2iUktBGDYdPWzBIiXKhVJosOce44t5B3Vo+JZicXdk4+efoqMYSWYHQyUgfv7el9h9w1eJLRsRjkynEKb4ZJWf4cYjYVzVN1sqBD6sErOlZ19BAcQK9gDDT2Q5Z20f7NZGLp4TSBtVWlkJdT4Xg5YRkmVDVT2/V2UmlyTap6PDEkzM5OiVMY9R0UTdPkWzc8KHOTXqTyqx6K006tXhgeWM1ENTSvT7nxWYz2XBSoOUzHit5Tq9R7WLQf9aJ9Gx4IDgsic4dNgceBU18sUAeEmH//fvl9gTev6LFXFJfDr0/d+8QYB3i3vHOsB5VDRAErIVSmWr1gZZshK2EjKQgW4t3HOtXuY90+AvFk4EFb6hy0YWGnjX2rDSSxrLSCpGXVCDGSPUcM9IfKSmAYH7i4TxGwgwbi56zWsgJKPLsND+gwekiwpXNY6h7ayS4g+E0O7RA3KIoTXw3IBQuGCE0SPGT6G8mGmW47q0/tCHiIfmskZDCybgjusefJ0MTSldyFOBuRKaUrLZSOBFNrI3Jb6T+j16SDugOYfDUlZWliYnx8J4bomMmdUns+6HS/NEH3gcvwAraMZdSmrnjPWcdzp4xEU1UjNPY9aEBNQoSaXHkSSq3gT6dhPCEN1BGpSknMle65ZEmlWISUKVUQyBR6PVaL0XmyXr9Rg6d2jeWuct0S2TlHcX0uuSPGXzj6yCbAba8tC0dS50FbnyrdSW+mEfyKBNN7k8jdm/iULn6ACs3lTN67epguMFyqJAeXNNZRUOgc1d/9pf/uYVt2s56MNUKe3KjQrqh6i3npNYm/95zd+VIpJBqqjKSR0EC/otiaRvhIeANdh6dWA1M7OQuQUFZLu6jcnrZfP/17m7VfghTEP2C5aMv146yLFwP9+jPaCLx9ohYtmB76OhuAP7+dLq7O0UtS8JYgX5lFPhQTASrWn3f4zp/b3T+riDDVKPSvYPfIk9nZfprMJQPpNXr/0aV67hvy/CBP8qYhV9fFINVPYCB8Y15Jxzphntx4msdTfm4QLC1hqMpJ+wyd7iMMZcyBy4XUh0VUNThYBtgBR0h/4zBt0HqAzTttZQA8S2gXSmQE65PlCaqASkIW7qKGfKSLFTRfaflJPEtSbaOLrvxszC7U7L02szdnPBKg+g9B7y8YfxVNGP/PaMzQlhFdMI1w5EK7/ThXp7aHMtdAFqQMzXofA6iQ1Yg3zOXcnctUa/1c5qI6l9dP5cA7l/OQ2lw5l7ectLmatMQ6qglNO5iceHtK5LkSDG+PatoJZ+7YSfLTSoXk9E3GLMxKaXW4ZHnSr0+kzJpImZ5ITk1C1SKNAmYeUlUFoSvXlanhF1MYJppb0+Yap82HeXruzhvPmGxn6A5O15WnEzF8cKQ7Ur45yjjfcyzObEsb+8Y2des4QB1DIKnIddJFYit7+1nItja3G4N56rR7JhUR0rKfg9jGsxcaopKHb5ZMvsIxRNE9UjdNsKdSmUFGJpnvNaPlViNo/EZ4McKTupQD87mEWTX2HaZTuGK1BTB5S4NCK0a39fTkZbffUmpzi8/EooXl8tn0MkUTxLTlHli3Q7T8CwS6SDjLlaGJDZSUhi6uxJ4ObkuzYJytreI6b1BNsb6m+qpXHaysSp4SVGOyWY09qjFeW8PgZTVzsXElq6V8dSXXE4CqadlRX5k7yjLD0WTL1HfGAvohrIyB9T2xvsfW94X1neN3Zdq8mclJ4yYh392hzPuKIs8FNcad8G0qidtU4repdL66UuCvdXEr/F7dqtZ/3qYWKoOljJYyZCMRjSLVkahHSqLe4HkyR5b4eYSnXLbfgbrUAxQs31K1ShYrIEoUm0N0WADlwQuCkjIWd9v2Yf7SL/k/KjzXt7a54JflvXK/UdJXPHTWSynXt2alhNIlSUB55ArBI7FCKT7/jLsXLn8UJYicXgKodepQ0mYPINwZTTRfia9C4zuSumf/vn6kjDINNg0znS/ovXL8ETtZW948glX+mNGl0LE2M6Glmm9a3W8w2KGlgkrhD050+IMbe0xVodEm0rSlg1C7i/MCzsnarXb4le8kCSymMZdGlbfnhT6/pMYwEB6qrbI/DEToMBBg8EogCB7OZ5BN/2KqvtFpLCUlK7QDJjkUNIYNCL/jndjY0bG5lS4ZQygS425b9rtYbtfWahdL6oP0sWTBipbhzAzyLsV8cftu+pxcCYdX2MKCXD3X0l5wOHpKN0Bn8zARFzKiMiwDjL4/OtkrKbO448GuQMdjkWcCe42UeQ7T9Gu3h5OtzYI74LIxf6/Yy9+04qwvSU9qpLtIi8u7ZBjs3AnCXNO77uhSH37h6ySbokBajNNVp/VjFzD6AzfiQnPtRNpvV6IR/HaiV9tDnrorwUUstUnDo+u7FhPH15rWZUAAruu7/b1XmXh15xztAX/3vIwAaRWoNUg8vGnX1gdgEEikZjw2I+cK/JoDnXGH45II8kV0+vz8+TFk5DgdEv3XeNHR+lnxZEvFAt4ta5dRquRBTC5z1ELIBgYyKxLhGpUGIZvouxPsRspzGGyrHUKbHP66ZZQy/4n9EC8+jC7zYcfJy1PYTxhMo0/JBF5hinkyPdVpu4ffH7bP4h8AfUjQGyTaVB6Ozodiru44iAnWX/fa0STZewCXgxE8mX4rePA0HMLb34sJnEreGhwSSPXzMcLpwk8AIQHwdQBAJU3BMycyt5+4RhPNZGQxt800JDvcOIehn3nYMF7iqP2ob4d+CForiOW9To6Od3hhWd7AT5/QXv1D50f4o9XtHD+1xi1KV35MBAV7tBhKs/qgO7u6BBdWO5RimAizIa7PR+HZdK8oHgjHVCHIVDFVHZTC1jVRbNn63RZfjeuPz55/aWSrZ0prm3DNE4WNHdpb2FegD9+YJoG/lzmiijaV8oR13yPQULIwFaqhrYTYpLYRAqF+TOSOjy4dwb3xHpqe8NnkvpxALF9ZaE8VGqwUCzDLGM0y5ptljGYZ884yNky+BuOetqGvfwfqnfzt6dMp399Fo9scfAzFs6MTJUS/Ij8Hd8DQ5HL95WWxNmBsSZMh23qWZ9IwOgaeW6mw0DPm+noXPI4YGDu/sO38kMkGxs7PfXZ+sztdddY7Ugb/tEV+Gw3baCQkN7b/AeOwGgk6CBl2HetAGAeDchpe6kk1gIGo7t9Z3hRlM3T37dZaN7SXOOl3J8pjczMRybmCk57o9OnN7JWYeCl/I1XSNgz36/969eboWQs87n95+uao9ePRf7VZNuMfI+GNnIvJG0dMjNsHZzdwA1oBJq8oX4Y1ZMhlwEUHfbIUHOMgE+oHnxsQk9f7IObmIEu75MBGr+BykPWzdX6+aCEFW6+Oforxn9ZQpDC2LYSHPNLQJjry5F1VFrk+CRQKsT59itHkl6HpMcfs+/cJDop+ypG13ACg2+E9WlAx6xotYpCsiwNoj4Pfraa6d8D5h1FegzT/WIY4JuO6Y05nXDvTlusFFvZuV3RLrJlLza1vqCEWGyj7PGmj95hR8uMB6tZN+xQMmiq23QRQG1rxx/m+9+BuGqGdgW4Evk1H9vfuqA2lf2ALuE4ePTva102s6sZj1QLfrAW7AQ378a1B+7cqWXWW0woJi5E9T+LWld83r+Qi6VJLTKX89FjWsHZm8TJXNne41FVMF4tCGgSFDqFlwVBf5t/pscchG+DGpsAtS671qiF+VvQq/9TBgrSjMeIZ++cIZiNLoht9d07UftBmFVneXjIuxjjtIifgjOzVUT1EeBi6/oVLtQjkpPStXgIyWvp94sa/8m8t/cE5TcnYpnSkmDePlIiGJWPzhQIrNa2crbb7E64RreGELBdwe0nhjCtfjKZVhHKs5Y8EJdTUI14XmGZmRjgz3en3TDTPbFdkRCgytqjtyOYIZTOJrY0qo9CllrerTMI0QmG6TeXXh3u7D3qm7kOo6js/7s7zvQZowOMPeuGyBvTRAwM0eHwrqI8eeKBWKbw9WICg4ZLYbZwpenZvL3KJPaui17Y/ekoxrkxJk6QemEzFSbCB1rxKYE+q8roAeY1/tLye4KeW1359HYWifrWhlNchT4qamHSfIuXKJsCTQIGIedIgQRIjsA4aNlId0vN4yPIwsn/HKsRMh+qMPQ67He5uG7xmhKqKyGTIrI4rUrZc7yH3oPQeH4QD3ytqKmp94D5CdAEJ8npY/XvqN46wuT/dvuT1/n3lEo/fKtRb+WCUly7DsxnhHMPd4fS9/6jjBHRPkDKUB9M4S+a6osb9KsnLBPahAZ8PwBlFgfYKTOxwdhHGAdY+Ti7+QnH5V99AOm+AQagfS5x5GbOfd1NA9U9XgKwLL0N4+Ybw8hLeXMHLsPMJVwQwHmsIjxoYfjMO9YOh/Zg/SfKYA6Sb44Ymj+lWgQ/dTNs+7NQ5pRJ6QqJnDFOWXerYsfAcl0ykR+b7tR2/kJC/Lzt+rDo+DhUAnibu2Oy4pGUnK1oooIXiCU/jAimC4F76S3fm1A10Kw3+njzs9zWW3xve0g+fT+LJ7m74d3iN/DH7+w5kI8Lhzkv1l71EZ0HkW/Z39cbjiTV2L8PlPDmJp1bScbicdi/nMLORnlNqbFhKhOkyrlg0kmoEmdY4Uq1fKBcUywweaVAVOM9nc5mtwcRW5Q3Me1G1+Iey+IMeBNHjYqgKNreOcTF7gIPGwL/LaLIuQb0WPnCj7rHutuwgIO3FmiF2SQp/y6yfAV2IRCLitNnavrJgVf9wT7KMG2hbkdpaS8QAisxjXlOnMVmoxbrXixbMfnCxL9/NgPx817u80+L7W8xucWHMbpk2rBTxMrOtb4Ou8ppQt72AgCfOKw81dM3NDYXOOKLiz0uPj/IRPzO+hRzfjBX18SUUYISKuII3NF3H2z2ihNsnKItOG1UW5dDBYT2HiwXp606ePia8PXX8oW7r6OL0kNl9YnY3WIk5/cQPJGQOUl67k0gZ7Q9NwTIVpw95Bw5OELwlZFJKuidP9kM2NZsmTbnszLEtaY16ut2ehbqHdTfesgS2LUhX3m7L4lKPmuYb19b1HrPV1ZZZ9TiXs5xN2BR1bsnkx9dSn85Inx6EVlzsCpHsFVyN5wI5mzvnAr+v5HIPDJTE9e8d0FciZMOGXPL7CFkwTIaGe4cO99KWH/TbLdfQAnkjBytApgZaDZIZ5+mAGGOzpbZIHmpwPgvP+l1yzM3xo4zLpW2Jd0PqH2dkodZ/9Pc2WaC5ElS4pywaz085G7A+RmMDeisL7UEhcuTOOgXjaAJr2HxWn+xVT4U0vEtS7qKG4VDtoib8IW2iMJOuY2jbL4qf5p0hy3Z4CNITBBgbg6ZeyLdJxqzYgZRwoC5IxHKD0/Fu/2wHi5f9GHT/ORtNOwCVtspi+yiBf79FldFLVPgjdrK2f4Uq+6O+QZUJb5SAWFCsAJc/JtyKFxAYHKCWITtcYJ7Ln4v09wgd0EeS2pHfPJH/Lf6yvyWv6N9JoD/sRFk/4XFqvCgPIVINkKh48ud+L8N8cwdKB3JXf2PtDVtZ7ZCaW/CWzNOgLuBp7PBn8Jz4x5t3J6+ODo+fHx+qNnsbXwdsIKP/JO/m1CbdWJ3qsIuqW/2XorW/CcSNiB7cPdXXN33kD9r4Gh33t95Nt8NjvV90CfrWFCEL80qcqlEcr8pay7PVTYtKIjLDxrOCuloFUkXIycZUPUUEnIAVs3PlhUKTxGBs594xcziwu/rZjg3bWO9LfU3PgPiaey3y0flIj8Fii569WRm/M3fBLs+MEiFCIDaNtZ/YbiBP8GWm4heldrXDeNtNQ29PMOvO+YoAfwWmctp6Jk3Spdz4TTwVOEzFq5CXLPUgcCjmGJ2GFt7FFitr81Jqw1uubvC1uJ7lKQLCB643b76/ovl54W9Wfs63n7cU2WEDoPa9fDT/AuoAAe5eb8CgwXoOXbI66NFicSXmsHU/ga1oWrxUlyl+qZ74m5Opd9Cqwxga5sZ97i6sH3cmChRQWt0dPGjG3o1WFRDZvS19KQ2q2o/mvm6pL3lbdOUdaVD2HPXTO726HMKiK0URf3oJm+LsCqXWXe4vonZTK41UuRsNO3Bxc+VYip+rB4iUDonTBghsHCRHKHhbvpr+1oHpbzQwze1gUKLScx3NrKaMkDp49+KeYJPE314lCTbWSag9j0j8on2rtPVVpP9qDL6O6HeRwOhxmvhfbBHwt/n1N9SrEbm7VcG/qa40T8IObPV3KunEVL8w9X/EIB7861jEyQBa2sUpKfYUs23k46QXj20T+TgUp2PHRE4V/6CGctO9NgtOtcEcTeeSSfBDmcvxQ5m+z768wRuOpgbvE/mvHO+O/MT/9TGV/mBuqA+wPE6qN+aELSJuZJyeahENDoFj+3WibzLHqzBkyidrTC5ZQz+YeKh9/vb3OkUYZ/pQEr+061m+M3SeHhOWU5VpFdKXgryrBHlXcYrQcS45v60MCf6/e6qGvETiA3/FTua2QgPr/IvIi2BbgYFdazOPqPg9JURNQKyZA/8+WA48c8CZAu4MuMUE+GOul9CxRu5Hxvsa3I8Xzi4Wify3cQn0P3wSdLLkZsKjMgdCoxjgbSX0z9giLfRyZ6XvnS318wr4jCJnHP5ATXxK0PW7H0MGQlDuJp6L58cwF/x3Oxun6UKGAhAa+JhXFhYAmNJUIAQ56Y8hf2yWR9/bY+ju11L50g9rcS5yvHGNYzSV/pG3sAGZPQAfmym6kFITgDi1AL+L0GngB6yhAKhCdCvsJAXfKpOKEQ1lUWxBaRFZ5a05za+eh0j09TVTmGCT3T77aOkrc3i3kB0lme8SwTiArnx8InaKnT0X85/oncDL2axVzKYD+NC+mSWKh/GheaxsfDB0YzALfKwv0+1MGzSiqRPBgNEyUJYc94+cX4cU72iFO04djekoyd2ObovAx91iV+zuWQ13+lUssOvPErth9in5CNX67IeEl25cnSP2KQQKtdtSUk7xJbgnn+IpqImHO4l6ZlGG1Bzq0JDOMztKZBr+7w/ubwycePRw73Hvu+8e/+Xj7hyd8QG+D9KhXbMX3v9/83DnUHtaYYcCLfoOd452fPX7jx973nbJGExm/VBmPEnAqyu2VeMJPpGJHoW6nd2xnCtjH4MdT3HvO1rgAbHlIIlM9urkpFWa+loSh5E67lGTD5HDcEu7i4BK/c3LGacXL2nmiSnHF5l7v35/iPD0BZdy9OaEe49Nnb5MmdA8T0Mw3p3gECBKGAjUmVeIflhBCV/wa2Xi42wqfcAXcJ2VxOiTmM9a6aJlngA1aD2zmWnIpshm7bYVaTKVkSafvMzkYjMJ//dZNQQp+OSt96nKOofhzieLdcaSWMXunoXIWCKi6eAAmFRogK8MTmbwkPUMenq58PZfj3IV1DhsZiGXaRiMbq8PMnY+FnPZxHtw1ka446Tsym5xa7mUOb/GG8ilzCuX6KFa9TzQV7H2BH8s/8fFgrRU+BE7WVtqqVjlD2rVWSya7TlKu3D3a1/z9uOs+Vnem8UQ+Okl2l6zpf0Gq0RHsGHSs9yUh0+ASOV5DI30MBSJnXM6PGOZjuRXf6G+UNGwPIGmumjtxTz8i3n4YfIMSliAfmApO6sDhS1P87LDnF5H2PotfSbkC+jUEfLIBjoMnmTUZQiiFUl2OjhTEaFFItQDZzBnNexXYIF+8/T7F0fKFh23Zf4bbcRGBRt7MVYVKQMAJAbE2zfPH0OZwqjuSjF9e/n+Mah/aL/aqItvvtZ9/2qEN77hf4zVC3WLVm4/+g+y00gMGlfhvPnMPC8732QJPu4ce2WtYbmOy5eoqahnCg40M6pfpyr7rIkdsWLwFME5tZ6eWkXOzlSAuR8fRSvIdicDIRSqIoTQFGHa26zUBFKUZ6QtrOHutTBgwpqbScZSP4XcntaQUp2l6fjUYCT7WM7ya1iiQGHAQ8zXIAthQcZ6anQP6TQmAR7LXMZPamyoCiAWBHQRhjc6HSOKrEejIZLZLkecwcPM5q551/KFOjLl9Q0u444N45TDEIbLxgAPDTdsHA7M3mA8lsTmY7Uc6jV6NS9n3RFX/xLX1FgSs8+a+RCzV3IhFvDxoI4O0l0u6dg6flbrb8yJpmVYKI9dupI2VpLVhORI5EGhf4sbDcRd4WE0Hxh7hvJZbsFHl2lxYvRUIIb4nEAoIOMJPPoK1ZArz6/4SG53VPYjvMXxEeaq004Z2IQrrcre34Psh5iNUUlufiDBP4ICD3T9p4O5EFQZG97XWehgh5ipHGx0D3Py1y8oFdvqY6rQ7fw8LT7qXkBWT6IhnKyB1UHu3XDwMMZtw+CA+zcyIvRuUQdhhNWQiI0Vw9jMxS1eZkGxz63LNbN0McqVbEhHoOBYI0zQt13JgbAgsXR9e/pvgOjPP784evoS0fT1GiP0wxCju2FjDpYxwlwazTZvdMOXvLJurSFniQ3pIUiYZT/WpwnKSDmjb09NnjidYll4r4cNnAoIUFbArw849XVbzeEaALmdiuTjn4KulgY5cv/+b2jC0Uscqk0XODWxmkU0KVaQiwr0RiBBEuBEYxn6ooDlxJYgmCom6aiw5QYmwrZyIWc4SQtMngsJg9uSAgEvisOntozQYDGVZISGi2kkHFjT/GfrJzK79UQmQi7US1VPC6khEDE/f9aOPpRj8+bt2dJo5amCu6io55SBejo3mjYuJ9+aDQlQBZjsXEZx8sS+Tg0v2jl+1ZG5LDCboOr1Y7TwtUfnbbXgU9yxDHVuHb+6fgAmb/z7qJVyDiO/wDuTnGWR8ViJxMeEmtzkIAsfWIxsfco8mCtWEvyM1wggv4eealINqRLOejxRpNBjKeXYAXa51KQkluqztKadeGp2kMd8IBOuX08jJtz6sVPuTG6/tlNV2DzaS5PCFlSHyqgmpLhpC1DlVpXr0/I535MTCLWWG1NUXOl6o+4wXViX/v6MOl2+6aj1vtbezoPmb3rKDfdGRAM817otCfpfjgSBS4M6ml/1XWFC4a6HojIYdOS3xTDs/eYnS+2GnQ4herd5gM++HGiT+kSaQNHG2pcVZFbadFaqXZfUk+pWs9Ko6rc40Y6WtrFmv5PBtpQNSoNTYVuLGqxMRdXKFMZFzcw08JiZBqG56w1fNK/u4l0jlptH1qmvbnO6E6NYULAxG6yxTqlzZB0pPq8++cau9caZPcW7m552D1+CfSSfTSazKaolkEI/kvbhyzaWwSJ49c38oy5Dv7AQlnkBZYpZnkJIvClEP7HUCyx18gaKLS6hez/PX81n16NpLnRpT2rSPnmDtX6GSnAGkU5Hn+QmWddwk7D4z7L020rxtHg7HV1SpXoGVn2LdY+gqtRsnyqVCJLsn0n7SD1a81xRFF9YpLc6S6d/9rEMryezjuUsPPQ7Cw83d892QXfffH9yly05btGX2cKBvSkWnkCE4a1jZLZu1YjxDWmx3icfdUkd7UnO4SsxodCA345G4ODhBNxthIq2Pv1W1qBx2LxJUgo2bnzlJQTYBjjilwY1eplsU4TI9WAlRqviVl0U6CnFDfBQ287tB6IhSotQOlaAN8FB7gFBMn8tdqAWu7CP+V6AQiFanavLPNwQA1QIDt8c/1RBoB7dS3NVN9jHiqMJxY9ti6XaPxbguME3x/aHo5dHr5++OP7vo2e3wnrvB2pVYx9sh/7T98DgX4nG+7egMSH5O5H4QYXEG05fbS24yzVWC3UNeMmebyxFQH2B86zjZ20WbLjI9u9kkXVb7474xuQgQ90qAX9sw+fbjQzRZEOS7N0JSaj1L0ET4g+HKBvIBDo53Jgg+2t59YiA2tRqGCdPGPGXWXf8jX0BBeR3Vj58ikewiha/ILnulh8JCdn8kdnxwI4IHY/uboAJqLQxEQ9tv6/YGHbX8yT3+i7p5MY+0ZjeFocNWTnYlJexQWRhesaYkJmkizEskdvTu7+e3gT+65N8ezTuWIDoJkl0bIkNPeDdzADbT7HtMfgyZPkbsaSHKckau/nyvp4JCKr1uTHzrQ/nJ5j1HuHpeQE3Fo9EwbdYoVf3ieCav6gh3lF3DEQ1Pod1Uxf5Wd2xlryYk/mpuVEM07/jhhtb2QybL2CM8jdUGqjYGoxoGxN8DUL59zZ+zOjc4W4sh2uJRre50Hhuj+Mt6bd9i12E+hsk7pJt0ZbEbmMm8dw0R2K8sc2vuT+gVr/CRmEx9+8TNkXnN28VCAHaKWyIxcbqBe0WNiIEYhDPu6+fvaRp93QhYwycuBXyq0bXBHmt+YCdJ734/EmquJJOIc/xlVGdenpODrj64Zxq8SLEZ0uYSLiuUpyxgfIVHtLTGkJn9s7UR8gG6iMxOX2dozPIaZgKSKgKuHJIwyNN5Qp7faqSsW3bn3ng+DOrvDP0hYK88tIIVTVklKCRDJk+HB/QiSDS+/D1cTO9HS92pLbHkZ2OgAN0aGcOrXiNVjzhFSppxyju+EMhxHM8hzxX9BfwoYjMTwe6ok4i8mIWFsccm7DnhrDnmrDnDmHPHcKqPO0Nf97sKR7enFPaIjmtctd5nbvsCqvcu8tX085LPgzDZaaqnJfjly1VYKAzPegpBBUclYKTRMWvp4xGinPoPRTEzV50Y7toRNfyCbUlBn/XciCtz5rrLFlgRYjv9ZZhnCMyqXlUY2g/tg0CmqVhuOI5JEKdQkP1ewv4/pF5BwP6Tm4heVdvYLGD8jtRf+RJN6/7pNhMW1YOQxsi7c4QKFIhkf8qkPi1AiJVDlVZhRR9EpR1yNF2qI4jEV7iSD+dPCem03mYz+FH9+lseial8fnsw6PXb1D3glcF0UE+MNEr7X887P21VcktM9+8fnuC7xF68zVjrHhz20J4/QOqDoqsVUNMv53qQwl9IJ0XuRWCLI/v8iVuf298728jV7hPbzO688cZR3qEkeVhZYzXvdXuEgxbiYb6SWEHDr0p7LzZG2zybvucHCW2eq391dvvXxwf2k+002O8lLX56+0Kiw1f4rVakCxDrfrfb/+Sz7cT4mt4JqvxDHGMOwh6NJ3BWcsrVv9ZUOEVguLnlK0YBaEAwV+ZX6vxqo6Ny8aNQG+HItYoQTwH53UxP5/DLt/Bj0KmFJ4g1CGauf5yKRPm3aUcGQF9020M29pv102MRLJt35zHufSWvCyLOz8EuulYxoHvHSU9695Ox9PZB3jmjigj5xW+16v6qJ7ojZe8jKLn5WPmKPU4vcCJQgCe5sUZk6sBAaildmN5amMYeDGa4GNXBxwWUKToN92bveU3g1A9PWSVCCMuIWejaTr/2ADc6i8Wtkp4u2tysZtUVnfVv/ySpvlb1uHWa9wHn7y53YqKvqRzhcQ2ays1q14d/5rLpovynSygNBIrVlIqtPmSSnSqySQ/4NtLTi1SrDNAwlChlyXl6/57zPZQi9q9XpstLINFhPEllFL+HMnH/5fLOOvqX64aG2BByDSOHvKN0Lprjbp48RngSLnkFGJlam8DBGO+kTLSYu7sYc2Gt2OKsTS06qSc1+uIzml6FlIhsn2pfRhBsDNxI0jJUsfXndZ2VUCWfqzFVpdDdKnWSnyplAdhynUxpnQHZXd7m5HcNwUmvOydMG4IlVtABLQbB95201jfh0G5V8qHQe1M68lJHvpQlf0S2jfE0z4NiL91nek0TqnUNsGpNk1uD17bicdsMu5Ia8kNTnS8zcIld4pwBxZcG6znfowUMDYvd6UAjBpGJNFIRldjQO9EQ/C5CHli50CgI0tl3DaHf6Eu/jjIEx6lOqqKm0sxTEIHcukOlSUOPQqKxL1jVbKOV+WRGhHaarCI9XB/G+/fARWGbnhuK2uCWRtE4lkdJucw1s6mSikP3ZZemelGKJlO73Sa5xsF4ZC4KDGUQLZYTBrEHpZzfaUTKadcTxC87IaUrGqNEGcbKULudUKERZLL7w4WltNdXdpVu4GHY4QEUk9zNIcMk0NSpyTpm6FA2wtereTSUtEZQeA1D0JfXJcPRwW3S8aYWU/+80JVnVdvwrss24MiGhtcsgPRNddC6cme12d2DEOWX16lhS7C7TzNK/FSSKUbaaCnhZBRlbkzotKAGGoV/PrUzSwf8EX+rXNnJBIPd9uKNjyv2VwNMv21AB682ttcUeU31n3Y31tVF/P9dckM19TUkoj5GydlSWYzCwPhzjR3JJjQL+DmlVnz+bNvouUhG5QTbQCzjmzl1rRa0sWO2nRQPoLrtm6CJ7tePoiKRNnniJj1QEueOMxVXja/8NsDpeBTUJMExWj5jcMCAVdV6tvP0v70w/MWQixfGldSDiAkW6DAhBL8SPtiJfbNiBc24lj2tFiHuYN0sA5rH8IFIlw2Z3hX003/RKHaOCS3Ho4bvdRETqeID6qjwgBKtCEKTK78fBkX6t7Xpn6xgvkhWsGMS55Yqp5eQTrCd2OdDYwV5cEEV5pxTR8zFjgMgU6MLhWnSWpWHCSkMs7fv5/Kv2GeqASkpvyIAxPCz+uBiliqnhqSOgQnoYIN8cgJtbzBExcGHUABeJFQpgzKx0e0Kylqd4r3T2r7jD7hwxT1FWJ3LX1Id9ur8acl0aTpLVsZoU4AyvqNxqeONaCMjGJkM1paysK6xoiY194IedZ8vRHFhbpqpppCQumYeRltmqymgMuKgY4HBYPQm5lKFF78QmxDsyo4PcR0mua1mts7eY29PCUuvMdZH9mAFeY4a+A7zvpHF88crIYanoGftvBw4nq/ZS1dKPUG5sCrYANs32wG6EaiQdfxwqURK5L2//yKm3l1+6FbzrkLsdihBdIphZckOsa+SnZSLAv7uGpAjIdLJSKMK6qKNMUgSVopNdE8JCP7dhcVAk0iFJ1SKVSXtnpMHHjVrwn7SwBRCtQ7cH6552ERnN56r5/GOm6IHcJfWL+TQpscMcNRWFTUrU2Xqre4U4Ukc/Ks44JiVJWKLiBAGAF49x/+tquhcnb1c6d5L1RWg0Ko9MOVFCTOxFPxLg6x3feksPmrcO6fQAC1CC58naLQkf/QaI5JEG+NDOAvH4Z+iNXoKoRcAh5QjqcBf/XmhvZL1DfCfH8t5g9ui7m/unJ/2HtSaKnQPDlLq903ZdiWsdm1LgHSIm5NIBf2dCDSLj/MVGLrg4C0cwzp5gL3WWqHaIs6hcF3d4EBAv8om8TC1CxeMwz8DBU0ffEor0IJKWKmPitlgfZ2J0e1Dhl9zKjs+QeVBOweLChTY0XD39Pm7Sdq2W72GSvWbEER9va7UKq5/UaU6t56L4rVt9uOUo3mHSmWoWX5bjalA1fGV+V0XJSLaJUZUNiSOadw9p2Fb8Smm9m3p7Z9e7qJfXu6yr7tyUz8LnpanByr1gutF7jheug3M62ZVX0FCS2l+xe0+TDrq59KGxrWp45hnWqtJtQqw3pA2ZvSSqu0RCyd4FCrZgH3FrWxayLY1FK4NRSyWh/4HdEW5YFXtUIYnaKIoxMBn/8AzA/PWXJpHZ4u4zXNrnVEVHssvzuizpQ+iVBa1P09RZht5IbHNST0CvRsF/y1ksAgT5fxyHvMXX+urOohCSVyULIAaIE7x8x1GU2SxL348aBjlUe1gCqoD1e5ZblKLYvtmXYjynEBqPNtsxrhD+NOialnzLnsVOWFN7anSW56pm8KksPRf5I5wyE9EbM6yv0Qiu9VCh94Cu6B4o7Eq16rihchAmIdfh8+sIB7rSrch6hyHz3AzMqtqnAxosrd38Pc6qWqcEGiBv0Is+0rVZNAt4pt2jeqJro9bM7cp5roVrAR5zbVpK/hy9YFZZheCezVqutJaUx8Q8IAhadJrzYWxJUNXGdzWs/LaejorW9m3xQ+xbcc8Br0aAXHELOGTNtsUXzm9ctIzdQ7VnE3Hb7iRtKcbn300k7bOapShYciCTwznJco6itI81O8SfQMbFJRDh/w13/N5+oRxAm1+WTCEVe3hLrzguX6klB7PrBc3XFkzwKWmytCbeZneXlDaKKhIkx1PyhxvAaIaRqiAQgpxOor7ujM/Xd0uqOVl1dp4lLho5peEWpjpy39xFfoha/9NrhyXFHMyFX+Mqa2jHt9HGiNXVXQKvq30QDu5nTu7AQufGXWFke5fQxlZ+4yYYotV192mZtT2IbJ7qtXwQm1Bd17Wu3yVb5J21vJDtdayV79eHjyH/2eo5Brt54Ge1lZxRu+sqnhbDHfyG6Gxfxms4DsZlTKYzbD3N/TatZkNCOaudYzxJeMZ/jDbztba/jCure1e2HN25u9qP6tLV4EwDV2BX5rF5bfwtgFGU2hiMmgMet3syP8244QrDckOA6Ja00Km1sUmlllc9vC775r3n7T7OswbaTXb4NvvWedInFKrJLATyFFGaQIFfVSxUsNlwoYmbcFFajs58+nZ+4mu1nIr/AC7d2Jz+e/rvdj1dvRrhRgLZcj/H3QuK9jiMyH73oHS+3e6PeuXOEpSbziAeYAwQq/v/+eX5h+fU++AAs2TUDl1HfYkOu69zVDuStHP9fXwnV149LVLVvl6pZt5ep2S+Xg1prBb1ELttQJ1ioEAb2ycNfaAK8zJf1kXE+1Zl76/HkdSzJiSWEH2jQ4wpmdnXGEczFqeEUgR2FwW+e2vOpNlZ8RuTd0buNyM70FCkx7NedA48FK7F3EAxvzQc27bbAO9a2w9iE8QIRNa65zW247tzUOyR0PB/HBdqOyekTIxc3XOzZg2VoXt9zn4sa9Lm4WMObcnUAHAYHHy5Qk8W1feLy79zRWvWKgtb3KEwZsK6B1z6vMcYv5Wq9N+NZsp2Ns2lCKZR5LANKBl4EgK/sQ3KITdK2u6giXYdRvlRdIxxcXhXS8E5jkqxDKTpKuHTJPeCelhHZE1FV5UKktjHf9CApdINPwulkv3KlhAyhaGvHtkdzbGsmgGUvCx0Gz5/OSrGDacERajg3Vd821q1Z+32blzmdos9RJfVIH2TBdxYYppYSsAMzPQuwmhze/geRXo8VQcDTEq+K+LkIDlahNT2G9DU43CiXA2Lbb0S/7GiIxpbXLIwrdXGb9fOXIwLuZqBZ4PXJevm4ckPUzdt+8tHaLx5Rj59XVPKy8bJPax3v5xg+0puj8TyzS6DOweae368fteKbCKWGclh4GeHJ7989Txko/ShXouH4wo3PwSLfcr+QOkm6/t36RLW907CDBuUJUNG/AgtU7sPR2b0X9W3yQUTM9gXd1XHWb3pPHXyrMEbcUasCGXmPFBhZojhvmIZZFYMmwalwuNwdCMsTiVBU8Ay6Qtje1Xb+ReWAyZQMTshx5bYepUTyXLOXcWnWoePNb+eoVIs9tTlAnlHY3UkmINLmfNJsb6R1Nsh6snddJ5pZojUrqHcBcJ0Lahc7MhmOkW83Dz5+hNG5G9S132MuooXaSLRl8NBFU38hCHVHk4qGJGIkrrXNsnSco6uMs2fx2pDgwa4x2T6u5IQxWQuPSH61yEUmGlgeDao+iXJYyM3SvqMvsy+lE1+WyTnZa0DGCqC5duNlPbrKUv7NSozY0MBCS9b5PbWhtdkV2gaYqZDpwq1rF383F9WwsuF3NKvta5bpVIGR4NG+scoS51SpXyiTXUEUb7NpMF3uXp3ZJnW1VeHp1OcS95sc2Ggu0vcHKB0E3mtbud8nRyAsKL8o/beujBDYsL8JgAwxrK5Sv1Rj1lZlknwkWH47ew3RjU5V7oeO+h08mnv3l58/D7yaePWKRUOwiYV1e/CIrtD6KS/Seh5nV0gTvtpn0uIjqnNP1jA8r8Yh8yDGDTuRBkQHBo+HSsnEXcCKe5Kc9kL5Zt5S0nUkY6wLwxPEE5nCZDlLzAuk4TaAMwlFz8DqZVif8NU746+T0+ozUxGdI2HvP7t/vPbk2swoxuDYjEAfwKt7Ns2SqRx9aXObyIqIPIRyfPQOQDWQmuzASfDTFzq+kbWVSLsOlMt9iwC30+t4FksSVgIANIrB6nOEG18Xl6mGlCYGt6pG4fx9btYg9RWI3N4ZlbttVhwPk4CQ3xj8Vr8Gt+kdC2pI9gzlDyD57MvGGLj5TDPE8sbNPn53F954b/RgI/Ly8WvRaUjTw9xLIjyF+llBsGRitEvqqnlPN5sEeAJnVvZCqE3r4cagHycS5X8TjORqySbUQufqWfpYTaGNi+bdCCzpnsIKjDByUGNWG8VKn9yDlUJwAHbmsgeFDl9UYIfL9OnzabR2/9+Vj0gwcZuEfUYYZobiV0BfTPyuo70fzhfya1oBMriAnE+aBbGxrG44MWUAjorgMSTMAx9tmAtWJYgixaCTCtogxYnkay3bNYxafTQVGGu/2vxt0a7kw+ht3oVa5dT2aFVCUb0fQeJIY1A/Ad7ZQfn3xIOEHvDNhYybCaCKVNnkOE6qVUXqV3sikSQVrvN4kPT8v6IAO9T7Bq6TeCk15GgQDrXBoK29Fa08LWZV1ZRAe1LV5nMO6hwAmAgcQjTamm++kTC3dHK1qOiUM9e0nRbwcwHKFHovLD8NRAerEEyMiwrjUHZfoI2l0EnszHmKG7g8hOpnxqwKwUn9BRKJwWuhwb/RtTivXeGednKnC2qu1pZr2voWO2hV2Wf5NboB7M/WtPRnZuHLvU24wqN19I9CHKz3vkLpFAfjwvQy7IIBgDOE7Ntc05l2NUlJ+YToyWZnQ/RXitcvYdfkrDtxcJIPRGJQvqeM+il6inZysuKhNLpf4VG+cVi6Umyaejd+BVg8xFiIrPxFJYfDSd16lbN5Fjv8oF0sm+Q9v3LucISxVtZunBZhZ54MrjGdYsB5agpK5wS69DYBlnHba/1x8g8RoszaehIPqp3mn1f0mFQv8F7Y38IfLHxOO/wzew79gmMCUczHBfxf4PV+k8C9Oo3Z3ATP4stNutUNmuUGMb4Un/Ac6G/GIZVTIOqn1K0dmZpxZ7sJDdA9St5qT4XCws1PZfaV4RLtI34vv00GpZhRQTF9+7uSfFu5BLOjq5d3kItTiMDsYmjvCozJM+Ny+siI7Qw21mgbWeS5+/RndSO/fH1avGR/Su+Jc21OyLno2zBY4C/Cb3tGm2yG8AeArHO9x4653suR8b5zjqcHEac+KkEpy2grTFemEu5Dbqgmb4saqIOd4NtE3eJpnDXClrlqqPn9Wl5Ninmtc+/z5nlKxLKxcn2zll77Xwk0g8JdcHvgJjCvuk/Q6M1MKhgHa+vl5C5ZJULvUazKWreAC6HfxJHfpd2G4Bu9CZMfG574gn/tck/TijF2zOTtedeO63bRzxfoxy6S0PU5u9E2a+t2QK7W7vEJ/clW3DN6JjdsxOWKXhZCQofYaGSrfdoywigD3qzXDcUXDUbXn+qmPBNf9WuCuObUu2pCVW6o2+sZfJbxzFaoulI5BhGPZdwQTqT3BlEnSf/SQ/oqhLS5ffKv80Z3a9DD4nH1cOSZHplplcIJydD6yDDBvpHOMVAWCWYR22iNaedtqHRIsQzrsgWQQBJlc1drHvpaPliBZQbZkQhrEZSAbkEaWKe3F7Dksfomu6aCAFi/M8wmVuZESV8Z/aa5sdlddWHpHIMxClyeep6NCzTouZDMtH5coTrjqzq4uQTLZdrZjQg9XdN91x5nPHca0Yg2LIp+V0DyAQN7lcbkgJMEYyIfiDI2sFtpKfB+HSxJ9Y/MwBBIFzMO4gJiFSSsGwLYpSUUsL0mYrpmG6WqpmK6Vig7FVwvEE9VzHBY6nDvVwb3VUGABEpGikM490zKlCK/n+IKM4ZHUN/uobZaa+XbOUikNJzo+rLBDTbJ0cMxDRstsNFWpZDMHZYirwZooJfYCRXMiS8lnOWsydCKp7QpMlCyPTwDzKy44HI0Dlig/5xiIpLn71Xx0DT3WruydOcvLvd+cBkUxa5oVojYxHrfcBljrw3w2HbTOgRs+zOb8oB06AnKs0ECD1wR/4Lw3OJCn/ZwMYLoYIsUmUkwm8yXy/mh6JRzQuMVC2BfJUXxNOrFkbWcAsCCMAAk8VDmt7anijtQzTZ3NNRKcKQOCuripLIZ8mCLoxNdurJkpXlrTSmfj3FK0wV/J0PtWQ4qhTZpAeajLOhRKl0uv6EmTYIXs0ZwsO6bYGbugOIul8l2CUnW8uH/fnjFzdrFmolAz7Z0LaQirzhdSzTjJJ+ssVe6pCIM0bL5Cl965YcI3vzHw/yNq5hsh/L01NZ1pjlRxpDJHioWEZslieB5zk52WP87sR4HMI0c4p92r5uwaSh6YUuVLR+GSFFoEVujgNjZU53wgNpSO0d9LAvMlX5S5No8w0lJuP4FY+N8wK7Z6Q40g2+vVxq2sfCnNgrdkzQ26jfndQ1Y+T6jB4CtoTw3JXj3/x92SCiEa16eNIa978dHAW7LgmlntTNIc9bPf3IPGR+SggTb1r9ou/r1r6rnQ9VlyqWB+3dbIffROGB1aoI4s2UY4uO8ABs1YVMeNmiJPDWT91c1u3k/ai63q7zMFtbndk7S440Y1TG+D+PSHNP8ufuvUdGcMtX1MLainL58bSaMX5d/MwQGxMIHVyuidsKmCtGROA6Sx/lYxbOB4WyDNeQs6vdnoAVgXOg7NRzM0ZfrdiheCK01xv214grIjM3pNtNoEEva3kY6WHAXKed3/UCnmd0glgqq16rthYQ1qyTxNbMrEmyP9i97CrUddJ28kyBCykiHoTqLUPd9NHGM29XmIjQ8602TMxglsMaLSpDyG4xWZFCu/h5tlVaXO2FN2jV6mWqEer1KoUbY23GzrlGmHbKx1bcRJNv6BopCvjcJUucfKNnlEaG4XSPOF48pF+4O4XczytJD3nuCBZnaAcXOUFln54JcmiwA5ROILbXGKhmFMRnnYL8GR2Xwkprz4iL7oEhAY1VHCIGcawByc0nTSWZJ3PjgWHLk5V/+UpejiT9lM0OEWGnUIdneZcMDY+BE+XTvVA8+pxDKnuAO+3N2ZEfkedvxUNnLPAHXpde1hWQvgCxq3DcEROTQwydv7QEw/f9U43OLYFswgXac1w8tD1dWm+8jcjnmAjQ3splaA3V27xbVj8fNaa8fl9h7vAWvZiI2mpUmmJQMu0OUMD9dEBS8yW3iaRayy5LpuyceDnzX2wGxbs3wKhyLyLES31uKrTfNZwjuZ2nyj5mZccuRk+Zj02JXbLVvXDY0Z7cq1oKG3a/Tc5/n6Mdnreez/KhaYquAvu9L+nr/S/uMHVAl/2ZUePPZWwiBlquSGLAcf4bKuei2Mp8Yq1dBqoE//kRW4/Nw/IlcLsXD8kn56ekjB9BFYdq7UCnElHRC1gETZqM3x10Z3D9n3SUXvlfeewa5lIeACtk7t4ilVl8qHDO4Wi/qA+by8CR5fL5yyK7bPvmcf4cCAXeHDAFCNCHOlnw58zj7SoYA+VdQHIWjO/ynNnVBPKQ3KjYmfOkiMvIzvzgRKArxFi4P/kXJXc6yiS9H5wHTDuBqX8vED+tNezl7Jpbu6bOfqPFkkQjoZCBm6egIXEif0CU7ljyEHcJleJvrv5897PeAj+6ID6xsfJ8ADGfrdTgW0/rgdt2HQgRo4PAC4I7rqNyoD9spJ+ZQmpx6UMsPzwlO6nleqGYPEBqbkofEfCwee5XdA18P5AMv7KUPt/lpzEz9Ah9Aoj+sqkXRjS4Y+h/lJGMYDn3gY0B07ykt76PHSnjgu2ghp4AszVg4w2Mw8nfLZhLL2gFITtCRqsgQDdFyVdsLC4FJXKQtPCMia4hQCUlAIiBYpNEROb9gmGLzZtHE3JGcQnoVnPn1F/A79t3H4chT4/qdX1H/hNKqJEfSeTOiOx3GyceuKiU/PHFbKAYZ3lkSnueXbPIUqTPkdTMhwfYF+FBNwKPDMJgSc+2dTHpr9BWrMFwdjvQGJ88Q3ffIQMr7SONPx0uohbgrE/2poVs+yXHSDu8O3MiULb+jdmfyPoTf81IRPLntPpsSn247gNGRfadBJuXZH/OtTkA0M7ZDjcYKaWZrp6zw/zNPz14uUTnM79rEqhRixIDf+sfzg61CRDn1vR8cM+j8+C6Ovhm312Pz2qA9Rp/KcsiufQNUvlm3LzfktKgX/YnMga5wDGKI43rL3g1BZjmKtvOIS5NPa2IeGbUtd8yJlG8ghjJLNsspmhLMPbJ8JBooa49W9CDPPmA9Yhj8qGuPYpTlPuN6YIKLbUCC4+wXoDmcbjsC2atPLty9eILR2Gzljay7jdnO3AfBhG3zd6y4K97oL4TI6GcnubgCCtUjsu/T/Q6+u47pk+YAx4868RY+JjLaQaicO6f9aYQ/B7x/3oM8fKPJB/Y6rBbYPfsBaf8z4B9W3WgQExT7gIkIRD9J9WOecZ1hMrVVlAAQKWB0HAX9we+CEQwRfPB7CuPwjkowrryT1r+QX4AExkWLBuaghS1LMQEfFGReQYszMiFKOUxyOTkAIvf6vV2+OnuFQU460NJORrnrx4hQMc+C+ePQTejM+O3od4zcalkvX3W67ZDafV3HWzWb8Y4i4k5atd7EbdaL96vXxL0/fHLV+PPovlCMZYowdAgnW8uaZeaq68+d6dzQiGD7ZQp9C7JPq2FCkHE8iLO9sp32Mdqw13P2zfFJb1UWaajzoley7HAsf8v5RyZLcuEzqYaBzJZ8naVYZpTczd4yYpuxYe+rWCMGwjSjXy4cLynNzw5L4BgdeTOXAj9nNJP21AIkXiWWJEW0JalhxPd4Gq2aMsvWtC2qdQ+ubrmLBv6P3ykVqZC9ho9jJ+sNG7gXbL12jxnWLFqxMUKBeNubv9/BDLnqe0D3fkvV1VizPqQumDxuC1wZJpkf9u+9A3UwGOx2TAO/WABfLS2NgeDs9VoSsoN8D+B1nfrDxoHaCBZy6w3V0wU/pJVpGR0VHfCPfmXJS8HhgoPeY7Z+ePWyzMW6e/Q1lFGPHrZiyKd5/8GQCnDwNDazSBwF6TSdothqvgCnQdKYRstUQMlV9hwO5/ACoOyd/e9pvI+GKxv7khUjrPcOOqU7lX7tTRUOnhoSg7suvs7n6PSYMsL71w3KoGC4Zr90Qg/GPGEpg3tRGiVUgSrh+pgOcDM7hEyX7XywRWES/pF7KNzys04EIw/CG3PeZWI/PaLopPr8dnXFF0Jrb+/Spf65P/fsRT/SYVy/+3jNZcDjdf+Tm7Vt5ew/cvAdW3v4erNCr1EoiAAcpxabOuop44z2XCKlj+o6XED95sg8y3OKtHOoWyY1+hWcR3bx5cfKu/64XgRrwz9k82meT0RT+9pdM5fQpJ1BZeyZrr1ppf7lcxkX3xPgAmFYS2JOb764Gy2pJoP6WaYkHyqks8FP663Mz+P2H+496kAYOO1MhiXE05cmNepEs6jH1YlnUR6RevX5eHmGD5lQs3p3P37/TPhk9LPH9VTFWAYZWwelsqh+tmOcPACQXi/2oz1KxiPawElbQSvANCGyRTqBQVszysSyVclUMzv+9QFF8v0PHi576lE4l/fIbcdsrf6EjyH75Cz08HkgUIMR5LhZIo58EXBjFdQM9pqe1IgAFYgKq+TCdDsS7XGL/bnEu8mivx9ICFO5or88gl0MTYxHt7bHAuuPinQy03QMsBIi1TKRQXCLxN1NDwR+Kopi90zfWlyPxTiZD/9QI6Z97dIUW4lrmgsIPdzxJTCHZKVVC7u87sN5x7Hj/gVNWXZwU9R8aLFzAj5iK9hQwVJIPniIVkpvys/tCXAuYMx/S+RT0L0D/PRChiPaoxDOxyOcj6SIMtC1mC/EOtjDYKrgWTU144jtzc0gfLxTi0Il8NofUVBJfh84hkd/LQFMcCF1kBn14X8w+wHBgORpwWRR9O/d7NGhl4gPVjk3eB3uNN6o92PfemPbgAQt816I9eOi9+uzBIzYqCjFIi3dlmEH04Fv7zrMHj1ma59CBd1xMRwjqr0ztgt+pe1IeltQwCX2mFHvACrVgOdejRz0mFbp8Vrwzfp/f9tgI+vcesJJjvRD5FbqzRd/2IQNwmaaFBvoYxgaYBzCa5gLp/dcemyLTTsUABk/yOwxVT7K3Yfef1BBqLjepxI/MTlucg9gStqA4uRqBCJfMhQLdSvRcEColRC61khyd9FwgZqVyU09zaUTg3REHeYkBu67r4P37Mqtfy+qHaJLgan2y4sZisBEjZxXibcnIlT0daCazczHFsF4gORAbHflcoawfj4TmdYAc1KSLdAhyS6d1W68FaKrXkAKLQ0tNgxaEVKMXJXyKebcNM3+KbtRabN0UOE0jZ9J25UxlnKZn5Jmy3foUXeJO3HT8byha6OEjd9m9l3bNxAPhgNdkUIJYyOt0oOKVgPJmSZcIwG8vxlrKrMW5yql4YxT0t1CPAMlFfz7DSdaRPUHnOdURzcGO1kM2BbUqJZkeSdzq+4dSOsI+/o6HmR7QjAZ0eNA2Xm0nUjrLhmlsNQpgYpu1FsMZ9KwdlTUOJfh1Ne5y+GvyCkZfXfuUJ6Rqar8zS7sS5G6uFaGcFERUidyUJVPW18in31m3kOzvwVAutHwf8WjcyVk/ZHR5HPitL+PhQUd0zfotBYgFYg+Kd+1lYqIUAwubMKrUXyTYUEPNRRIoNHDXyXc7g12ig7Q39J4M1CUuXIHBS+p5WSQORZfwV6e1ynp1yi2SWd9nDDUN6DsHWMtQvQUaqgbwZm3hvWtP+fEldibcr8rQZUhdxAIyEaYo/eyfSZg5It3FFhXm1DlTmhR/YHg9ODYKWgvBSA79je5XL+CSedVbRZTq+zgESjMSBg+Y767kKZClVMrJ+fyZiiKz1YpSTmisQZ7J2kYBq0u3lFKEllU+WqQFqBwggfkV2p1ajriB+Rfc2QSsruJLNeBDi9S5tVJWl84KI2tPT8UrnrlW5XuzDXdZFkZiw9a5Pe/KKxK8lcNYdmxVkVUj9XLWUiVbCnNUCmCuTgDCHYrDmh65ZBZ+Ud37ukJ+vMPO6lptdzI88EmYyLOR6eI+ZklXCZtxPNFKHYWhuhqJOVaiRcy/huETZ8Z9IzO2kyQ/SEvsF+e66DstuznLoQAvXY5ey2THJze2qyc3CofIIMNw20l+8e7GtOvuS1kGW1K9SaM6aueoU1GKqQQxzeXORjGwTFMbUSfl/ehX0HJG106iUq+qqbAvoUYpyS1SbzOwx5bqp80cweAn7IIWMJCor8N4K0ieJHcwhN78md/5kpQ2S/Go6WxZ4lGIVKZaadIusr6+s8yRpE+S1E0IK7+TSgUljDQP+5Tf4ykSBIQqXqFCshin9BcVsGl1qaCexTn0gjQQMzdoYcTHZpIkIRAjfhDANkCp0clzRjkw0ldACHnXtDOvnKGrzcMwInBDL7g+axYHUgqEsY1fkjsqMTGKpW96rtL2MIrK1Lfha0bR12z7iEavK5c0PUzzoUBVhSduGkqRE/W7I8qlhIciabfL+AVeUxDyqmLAXR78Lq/wrMKJSbAyApGcbgXFEjgaaZzZxBTWz5wIaKx3QdkglZPCcKlenS7nSF1hSUrcmVOVwz+SBHRfIuDfj8UTj6mw7M69ztBrShRnbGgmdJU48lrBmFDUuv1QEVfr9br2Mq53oKxprlTmB53M8PKPLPNOjaxxyUny2tQgcPf6AN+84qk4+eBZ9Ill204YFH3YadzI46Gl2bVmZaXXcpGABKW4OwZF0hlYIPX2siWSwnjKik3UMDvobNlY3XjJnEYPZb5W0SC3gw0jSS4hswsd5EgPU5oUgxPM72RUFKg0h0bBhRoVvwoAlcpuSygX5efaBCmJhCN8N2Cddxk0FVBgff58Bw3Q+IKnwpG2p+pmAg9j3r9/553SRhnd6B11iVj22WyqOwSMa4wrGfKwdyEhvGoLCRpLvuMrdHsyfxCU39P8gdt4sn2wff2SBBvGOUYC4WEdyuHqLh/NBBxKs6F26iodckTIhO91Ge2LMwTXzfIVFmFuMAObwgqSka8QrtHu7ebFaIFEylMw8UaDuyNWxZ6OdkKUDGs2GvE9jPHv1abE58/2PfsHvcT6Ucp4cTCPPkUdcUCiU+lONsPJCMXqmlwtwIqGN0SQTXHH67YJcshDdnGA+1CFgUNymBPXI46uWFGARRQO3iJfmH2dGUoTtCasahsDacjKw0ZtnaYpeqPRNUrdlgyqR/+w0YKC5u+ymw2nNtjZUlG+dq2+roZL/faKpwePffLp9h0PvkbPc0dKkYGtqnhjMgXahCi9eFJJhd6umGCh8U6te3V2uBFXIrxZLacGwvFnLAWUuDs+cQ+5UD5ZD7ivNi7ZqMEER/n5xdDSD9sorylb+UWPl6o5IOHmTtJObuK/V+0/cMwH5e7IA9A9E8NXNVCb36Bw370S2LGdzmdFkaX5uAXXJuEfDjMk166pxCCeBuo7LpiN4ZL2DGVIX7N8t4X3Dw3yzyruP83SespGArAO7DeqKcHtBH2SlfMfftxYAkLaxhZwhJDh8Ymdkep3tUY6ew+9FIm2dTJlJGOfwudq2v4il1ifjN3bSgUkWL+PApgTYXkX72jaTR6AxCXLhkrdgVTUFrkjfrW+2OCAJyyPJGJqvHWEPN8CbyEVlUelRCLsRlGmoF1mxUypP+AuGGftlz+/PGpXZndtIKw3tfhMKH/5Cc5snONOR7STH8orF3fKIG+0FTzxfcqtRkdTD3N8UdP/0pFDzWoVbZh8jN97shHjVyDR/scUUKrxnWoXFQ+b5dI5oakrAjIunVBfowq3XgKHiOnsajBsaVeUOx0wr6/Lcsl4udHAUeimsqIFjKkXj+WWhIdyjLh6c4h73hyCrNrjlQftqXykv51QMaRNvS0AGXW49f5Qbr6TMjVkXFVsAKFzUSzU+AhmEq2PjTJcjtsd2lLI3KBMZ78NeFVFV03EdhNxOQ8P47xy3qX7n67sPxVqViIqzirUm/QWpCIZBdWV9W8b+H5LX7De1BenG5r6UirqmvpSn6lvNfLbm/pSiSsdmsTkvuPqGCSPVjG4fiVupZYYljfdZcobXbuhyXInZplBdiP5XqVxlfcAO2Xrq7pqd8JN9MgqdCP0W3PtAGaJy+DLqDobnhbjONQPouAkDF6t8KXfy8PfwIioWtX4EBP1AaUXjw3RwKEnxssPPka/+LVaw6v2mq7vGOOkHYpSO1TbOVFqiII0RKuCrbB9aQ2RtovrRhevr3ROYZw9GhsctPVCb9yFwWdNVaUUZiujrK9Dsdy74jbShNTaLb2tUekz42Amx12qEI6n7XLZoMcOm/TYoexj5mG8AcwLX/q9Qdhsqb+7ZWC7Y5zMM0W+yNkOLeODg6Pov+EnuY/q5xUpSSxQ5RauqXewyhC8ygbsHmGMFnoa6NeIurn5ifleTV8yj9fVhqQ/yxPNjJbTnMOEjkskL+NsbH1Px9z42NXxrudJ0KbJ3MI8XDDsIJvN/H0BkscLeT0k140foeCGTaXgpY/rIdTc/hHIszKxpRJdOBvsYxDKa4WGSVoPwx9agPhQxuYoERfboMpAkZZOXA+nGsOAo45kprQqkI2tyGrgKWs7mL5wCZ44r9nq5M1hUYhFDZZO3gIWxWVUYelkF9ZGGhNCOlaJdBCwHg7Ff0iSq1/Opjk1r92vB+aGjyA/PJUpLZWyHoATbqIZnIuW/L3xnHWqY8Km9euxLAjkSKa2rFQX0iaOXVV2NvktzN8Ioj96BsfcyiBbxnp4btANAtIpm1LLDdLBDkJCyyRA/cABsD5UQslGK6F6BXflfSziV4Mynqk4C1aSJOsWK9oMYSp6knu2RVzrdX0GM2EwmkZrdyVGLS210bZWCfNl6FfqSwnsDXy1jtNEYjvnD/EXxbGif/Z3dPZPSq2pLgAWWxOpG7LSsswsjSO2oajdCnf2GIPSCj3cCR7YlmhpI83TU6Pvn50afesMvbAa45MUEfEmchXKVPrJkDJW9dSi6A/E0I7PuLGiAdQPCgfA4A3HoVrVrjnFquS6fme5wdaSMZC0fn+3jCmt32i3DJlAQrihm10ncvP+fV+RenClv5zeFqFZ0LunGITM3VNQRsj8YwiOe9KsPAzDyBOYVrFcPKXAVXyrp6K5pjLgw9pCEteFscp8DVwFxqumiWRC/bafSBQszjhlLvRuCl9n9sccdmshh2iAcZn082eamDQtaXJtt6uhFp1dDXW+swZTCoRkPFw6jlTqApjNOkxglLUar7Q2bCF4WfVV+rGYpdzX74xgqeBC5Mx6ItLBJ6sw7N7ZFSljR5/Nkz12neyzpyDEnicPGVyvz46Sb9lh8pg9g/xPkP8D5P8I+b9A/n9D/lVSZ172OmkyubG3ibMHY28Skua06UwaGJ+dJDWeZS/Rj+vlqX9VgTcIT6/YW/aGXbGTM7b192v4vmosw9NKBiLil8h1RIIv0DoOJVHfjvckyttWbaJ/zamIxsF74o5D4T83Y39PqmY3lqc4SHm6cpSumAcipK79DynlSScqbVT4arvCV9sVvtJlg/WF6b/ty/79juFSWRy+lbztiUPYGA1/ztstytJ/jd5iG8No9IXYCg+3bLDh+G0NePPxK+zrP32RZjzJXJf9ncyNbonrdnnULF0LM5qf675BrK1+ttTPNuMMfIPKaDVPDf2yhkbMRWSngigTyd5fsq4bxrWDSW40GbrzujEmSZLUL3BRWffvV0Oi/GUxK5YhJzsSi0poWhgHXNKkQg/ACi0hqdS1kR4CTxFudL+kNfcdWN4Q+8jSrKq9DLVuvU0Np41aaTH1wd+w9FJRous0cfxL4tSpUoiZWOMNy4cxxVL6j6J811CsD6PMqZZ5H/tmgevdNBcvpZdAdNpjvTOMF4Q5VMYOvlBhgz38fq4hqMxAb5AQJTvesSxlo6k6Bdc72bsoqlqmrqmsNh8nLt5Wxx7s/fXBXx99u/fXhyr0zSl42of9pScx6bGdnVp67yyMKNkqvqRbGpcw6QC7lEfyVm8cYPwCRuliqt4rVcSRztPEol2JSg8PdD5RhCqbMp8/k13C58NKRmJt577jwygaQssJKQrWIoUGuPKiEODbVBvg7w4519gPWOmx0uGiODJymPxDozP9tNeZ4YH+8Iygylg7PPpG1OrY9L+AC2+0GhPT0a+BShy4Q+Gc1YfmiCmxA1BZ6gu/B9CjS098XI7BKWNc/111APoOWXpaKfGWZAeqaNe7wug833plBpkArSgcrWhkRd+qrgdDljLZOW/YdnkQ54/Nj8jy6i1jLiBrEDuJiJtmRcIrRljHMdM5saFW6b059McMluUdiLEbrl9drjL5tsMzyGdZspPtPDp68BcZHfBmNBGfoJ8/v38P/vAdIFODuwIGLulr/DL9Sy3Cnoe5HtM6nBNmygaTeB+mzKQx6kBZZ9Rdy6xy8wypXHaUakURWzIdqK8A0k02xlKlM5Zy3STccAL6jVx+anDTfzCSy0nuJlmzu6TERqYolBvaDMWXIeFnh3AHzh3bq4KUNeUyL+WyCuXKW3wbOICpa2kye745F9PoEHGnAF5OQ8zSEerSrrCa1D8Ll8rYlNOQrad906QNjQmdgIkGYOr+g9H88iot/jZbXJr7sP2lx2XTvcoPrDVpqDWxC047E7bHfAVdPBTIiwaQwbRzAWAmCG8MHxeuP9E4XI7LkHd5rYF8wxh2IYBNYse5x8Nkosvt9Hf2dh7s7D2GP/hjsDOOBw3tD2gMKiZx+x5EXU4dqAztWhWWbMgaTZ2sRac5hhwJMWB9L2EnocrdY7kpxjVNVLIoJ+mAppz3eg3LHYRoyHiSe2jYb2Q60Ug9+6pHKEfU4/qXn3qBaCaf8JPPNEXkEw3ky0O3be+6i9N6o2L9pmLVmezdypHdxTcma7dx+qgNV75KaBFPqom4CBysckeNtrwmK1wdMULve3IZvlfzRweDCk9OufX+4DAJsAobgGQePOEkjAckxqwHGPjp4Kx8g+Hw6PUbfFIG7tVHP/ixeYPhH3DfeKsp883rtyfwxoE/X7U5aX6kwSLh+kcaHARZq44Xwz2QFyN8vWFiP94wth9vmMjHG8aNjzeMt3u8wd8p3+MNzfJ8rJ9y0O7NaCepRZdflBaxe330DEVo115oOJev2X51TbgOl3xVeHoY5werwqt5tCo6m+tYn/mG8ey4UWoOZ59/0XD2LNnfsRbHlRqvf40jeFCMhHSGpM+B9MKn/zYHKZMIW4fJCnWPFoNNi+P6sEaVf/BISy3uhrByj1U2p2pI1Cq3+APU9AzpeACq506MxTbeRB10h8lzGTIWp+GiX3BObZqyIC6slyt4VTNoGkhd3ovs0huNsN2+Y73TON/Eadw5lA/VkkgYuT8/f/Zfpboq+lz4o88b4zaYaIw+FxRIeMvo8+GXjD7XUlsc/B+IOY8CvBsUwyk7uY5/MS4j7pBCIpfJjRFNXq6k+bilcuv3qvGquNXpKHzT0aMUkmZ2C8HaD+MV844JqXNJ1yvY36Ynl7O56s+C3kVB5uWwisHZ15U83EbFzzyT5FYCJx98/wSDEN05rRd9/Wp6iGtVf4f2xLCroD1tY2RJsNkQaPcaZwwysxHI1cce8+rhzQGxMEMbsMoakardbw+FCaVeiUBGCDRHbKnxWI9E3wPWFw302+XxhuJ4ZWxOtt5JshqpEwW1cB7Gq8E72w+WAeaMETGlTtaAuI/IfqcyXFW8T2Shcx0JnjVR96T5OMKEV6VIZltHxCoNSD4pBA+IdfqPWLbLd/dD55BRu5pRV8wlE/pfuYfAUfPH0dRd6Yya7w9S4k1BSlzegkJgyt49SQLnSZGQJ3iDvnPPICSdMeFDwlDpOwdGHHJ1jVWDTVP1WpkxfQMl9ENePeaiJmOaRGKynUw02NAljr+xfWxoKSU67JzFE17C1ddd4gWJRrBzENaxN9DK0D5jwxD97NQp0EKhNgzxqRjtCeicORuqZ9B29iQ11Wj3TouWyYN3wOMUr85FXzeyM6sNqjenaiBqKkMbAQJD88bDT245WrcIU/IxXZbJwGBm0ujq5Hqq/AzT1BG6+kAr08cz93qROcaOZUJtIys36NXdnq60SczNSrAUWrMxeKqycTPeaJvmJnzFNwRPATibgKficbAZfArK2QQ+FV+JPsXXrIJKpcqDtc2ZYLlkP2/FhhvA1DU25NhmsKt5cEvO3S7ia3UTPjYMNo8C2xw+1dguMGxD8FRjoxiv1VD9bLg5H+Da0XCVYUXXwM22gukvTnsPlrOyqn7TMU1RG3LuUlE5uK3Xd6fceJ/35rBY1kzU2liaJ4G5PWwoWtbjWq25QDCCty4hw4lExAN63BdjAIq+HyW5Q7Mfu6PrWVgeo2N+LpXSn7HL9NCeMVOU9hGOVKxfNiNql82IMBTJza3MAmkK7QG3tLF2ezRF6B1hSBnGbQmNMrahLAIXyqiBd7WQfUOYXmt9yd4Z0l3fSeAxIZDRCFUmug0cfy2cX/IRpBB4UymrPJHPZecScvb5s/51nua4LyrVdLgjAl60Yn3gagUBVQ+jcqkNfKhztE7zJMkPdIq5nDXSb8pmqPtxC0uPZUGFRumDpQOR1F+PyMKo96Rsk64h10ny5IxOf4BBJZq6q3hFu/5EZDRilEKHQaqSohqAM9CH+BAWgDEILM6lcj1EErlPYeVIURqD+p7G7QOApQEwLF+2Mhy9v0RbRA3hpZ9EcWUIYqqR5CWK3OPW2TgoeVKKvoPKhCszwgMtjxVMlWhlR+Vn5CsYMl5xeFCX1MT2lZQ3tMciM5L7qBltqOxU6Hu4FKWL84HfyT5quO6Dbp6kKXngm6fVa/sjfahYffupdHEmPxJKJQ8c/RyIYIGGekxHR/DNDD1zZrcaDZlNxogzc1sD1i6/meUjAenWL0V4Zl8+HFXvIr7X1/lljmXaTpk2Q5QmC+aeCEMlN0E36Zi5VSH6TWVK2ysWoZ8GymgK26nIb37UO6aGXN6cZW21EDP7J+NWRvnNasFikFtLYxjgK7PUB1OhzxYpA/lWuQrxTcwHLEDppoasdmTCfsNYaQYrX5rTa3bliTg18eRN7bla3mIEo1wocXk0axpCCDHPxC7DIeuyfF3UPB9MQ2XS8YvS5wKkp+N7PaA3FraZQ/FAb5zVsjIws0f/rF6YUpa6xB83+oYXNY21xUL+QLgqFg8dBmoRyAN7tz7QDyX04Ysua8F61etcBs5FKwGmaPp20s+fvTa9NMRayPDlO9UDw5xWCnd/OiaYxpumBuFS0U/6M9rYO+sEXqC79jHHgeaOgX3alE7xqAk9TUd4rFOCb6WLVqrvSuy29ROq9/rLsHzXxCGdF/jfCFgxx/kI7eAVBwN0jakDvVGUBlVcDZd6y23gPs9oRqMfVscO7E+oSbXbMa2aYGbLSEkZ2CuDuhly0PieS4bPIuhVDxXkLGm3YRIiSgRyK4gh00qRApd3RzwMrelwMwIZxJwg9d8Yd+5x81kVj744j26WW0alx9gZEgy5+WID+zWYHP6hrnoeTVn1Pteg9srJoBoKPdj+8kb1yMnACXHWs00HDSdBXRUDJsNRV7OdXNHUDlPxZnm9o5FAWEF9deUsoN9kkBwtjibnlx/lO3aOuKTrTQkgatHI7RoP49JAZwAPv+MHefJwl0cETBHIehK96pKcuY9huinkimzHwmv0mxZ62Vuc36yTlcjX4tIGbkpozSr6tF5c9MIaTQkWpYQMBAJJpq0e8Qq+xCte4ZL45P79Gp/ccxkFx3kA49zTI5yr8WYisc9Nn+S6UvkSRVJJ2RVRJ6+yHHGvdY5WqRiiIUFSKpfe9J47D8v7kZmpiyxsBJ21KkOq/VMfJRGq+PvALWI+yTRf70ZYtuu0Fka5Hvbcc10flavHRAVf5nliwlONLepr0rFoNUdUGALKEvfjbk2SbXft9XsieXk6KK/nMHrTGeO4IotQgCMmzI9ML+6eizowk3bWUkaK83TuaiFbiufqO/XNqj+0TeeUJKwJDzqGrTlNqBcEoZ/Au9Mc9TXdAnK8gi9lSpDRw6JeNS9HDi6lLC5LTbdZJNnaleruL+1Q/cZdXzOxcDfghowS89WUGfptvBBQQRnYruJmBalJaVQl7NVevrt2LgOgaBNAbcEP0rsQcCYFpVr4wxvS3qt6NhayFXaU9rZW6mQmVWWf0SgF7hZscPvHvqv3SOHUp1Ewg8BxRIxen4ZLctlXJ5KJ/FfaBcsT1lRaWsK2GT/LCFucZukZ8Keshd+JTAkVsC4+UQp/+0muE4YYKo2KXMOz4qksUWp5sUDJD3Rpn/ztab/NshW+FhRZhU8YVRL6Z7Y3hhL6boqrC/izRlOVRR4R5aTMaFmjNYImNp1y05pnXVIuSh8WK1uPiM8kXHgSqbSznfPs8JDFfYOZht4zismMXxUwLdVffSndQo8YasfVC5OyTs5UYVBrrWdNvdINuEyeJsi/YJwOWaa+ld1hysY2dLSHGAwoPTfI4PCdd3x+pFKUowEM5L4MvUtyyeR5V6OUlF+YjhO8TEC6ljdi44/YyUISmLkyBp1p/ESQF8IY1rjxmXK5IwDLJQvmSRqnleVimrTxUr/pwCJQdpBrT469MMrKT8RQGKy0eThlc7m4fZR6EJNGWqUNIixVtZunRdFJ54Mr5NAFQ20gTebkV7A9AOTUTvufi2+gZ23WxhVhNBeab1rdb9AZD/7gzIY/Ew7/QDwF/jsewb9yJ4Y/cVq3pWUdJnyrHTLLHW18K7zgPxANHQuO+WxlndT6leNxDBvihdWCbGtqRnnNwpkdQH+iLEZozMCwZZUYpTpXz79nQv3stJ8enewefn/YZoE4GHqCcyEl0unVmyRCNrqO/LWOf/FUwmRcA+X3NtgeVnHFRr0oRT5kCFU/TtVKhKrvYoJkSl1wM7ipUN4SkZiSlDLs0nvUVvkSCNWgtIKWqmXJJZxO4Ia4jA+S3K7UyXVANssrNzbIhcuzAxrIOAPfhRJofkiyje9HOchpcHUA9wFOlaiSfh3VfPNOPk5zcMsL4zoIlGxKqjl5+jse68X5BsAO8GSz8ppwHdu+yrl/f9ydXV0CGRxSjDUlnAv2xtpXsiNwf0c5iQHBjGacUCZFrMI4kevrkIZSmJescjSn71pGjD9BBrRZFH+HAHHEDbL7DO3gxmmFoIwNlBRJpfwVc4JFMWYcE8EXVT0cv9vfDThsoOFD+silSYpHtekldDIBnpa/LufQClKD7/TLLVBKbTvHwfcQ0DDmX4RlMs+N/KsZRvgZRlgMw9H46htw1SFhhn0c4jSj2cwmiZ+FByG7SIRmChqBi++SwYHVQFmE+nKxC3UnnoxBGEYra9qz2qeXOh0r+TTwMGq8lSxplBkiMfXii5oyfeEq0wJT9ABMMKL5oq6FUi218uI/VE3uK/zVzJSboHEMPE1lYHqhVtTYOZ9VbAkvQ777+/Gbv717egQ8uvf4HSw67wBP3PvhpUAPvj1j8prU9qrSbea/lsM5TUq72VUx1mYKusIigZ05pCvMnprUbioWoFnrwtJ2ZLCXG+GsmOVjKOBe05T0H8WpyrNSgpRuWqJU7d1ZTcVhdJCDKzsIq3Jx0gV1xb2e+k2oYNqSeS70iPLl2nHYe/ioOg4P9z3jQKX/r43D/p5nHH6XYQhWjINSKHrb7cv+vS9DnrAYmPZo1Yy4qcrWeze3Ou7j1m7jgn+9fVyll212ajZ1sL2THIQfXSwn/+K+7+zL79ZSGMXsapDov5If9DesUbM5uiJaSQPhvYvGb2TNDnhSgRVlaPeqJEqPRS+E/KBSFJz4o6CeBnEjdjhsWUDUI3l8CKC6WoOJ8zP2NpVQE8p4WSFJAzHqZG2iRgMtNCd7SOLJIcIs/ygyMPhaQlCRkUSf/BlXsrcQcwQEhdsfz0Ylu+aVaHcmwYINDU6cCTYAliwviqtQmkYMrx2rnR6xifLXzcWo6OTfDMIdwab+orgzii+eTGC0L2AEyTJ+EcZc6/f4ZbZjO1PHTI1IzBOu9Xy6wQmz5852aTmmfeu43NzsEm+NbQP3MgUr0CSR/yJjl8HD/1xk0+73owEgKQawcZQluvNFCpOQfuDOpk41PXnKfej5HG/RNXtGjceNvjEhslz5h/q6F5uq3Wk3G12+0P345nHIJjGfwa6mg3TmnboPrnB3pWP05oHNctgFLkN4YfxhOCpgx9UF/ksLPC7476PXP4e4AdPQhuLXNzMJAkpdzk7kbOsgkHi8W140pa+jKmuhyUIXVX/kpSeH+k3yTi9k43BnAiCSvLwvYqLfM8bGiQ0heRhahErPF1eFehFlzNDiN1miV1+FgKlas9IkpUfYS/B69KkNKI4O92Y0x/x9vyKp887lcLRgKeuhM0WqmU8NRWjV22uq1/fV+7+xvgT/Oko2kplWF/gRO1lbrixY5Y+5rkDHGvVknJ/yQ8mgNgvgG2Xc19Gai9kgwX+1xoxf6rrFRdKezqb6OauWPmRugTfurCWXSfROymbAwxASYh/MaEfHmyXTMc+IsQb84uiXoxfvXvx8+OPRs2RPJ778+Z1KP/zb0SG8b6GTj1++OXr96ucXcN1U8rjCRjaaFkcpZp8mdjbwWJyfTs/wTIOLX6OxslBMQXa+PT8H98R0IXC10XVmA+3JYDEgLbYiyU8zBfisK+GxAhAq7IvBCrNS8NPiDC3URTpY3Pd19QAyMXJFPAGwYwfs/fsBZo7R58CMinYqAcPAlKdz7nhMtBc6tY16uNwGmBSAnRrY2PWdduu0vZN2cRkGU8XHnfZZC3+bKK1Kc89h9KpevfdQShYFtpWFxgnxNDMgzlie5EainMrDdSxerkWz+SS9VOysxHHe2Mlq69TR5wYB7KyvKpRWD3ISIPoJvZwmp23J2zD5NHfDF/I3/NGKYFvzeFvFACnmm9oc54hUiQfuuMpEy3thkzkbkhQLqgzZubkcTQR0YHIelTfNKn+QjJnBjHJGr4CVYCMBggAkwRQmQ6gJPUnH4sVsAApU5WqRG8mwUY+9jzI9Krj/lL4mIIylUKBFu1aEoDknEDoc7V4nowlREQhhSNOsF4uGSS5CXIASd46LM8Bc/UjyGKPydNwVbaUNOfNxBUONkH/fDkthfqBLfK6jHJne/L96nmky5ZzoXE5YHYyUqpe5rbbvkQIAM2gxQwWjDXCQ13WCnIP6W/kT3r9vfiIn0y/kZvqlNoPK1n4j60UOFKanQWQDYwgjsgEyCSdyoDI9UdzUJavq3/6ZmpuDneI016IKasK3ma74UxiJkndLxtbTBS930fJEt4/hk8ptcCMMUDogFro2FunkjuxAcEl15nREWJ0gwsiOkIa/LKx0Pt1IcgPZ9tMAIAMDClDsmAtyccvwn1di/vGXdD5Ks0JeLNMuMcVWkTdA3a+hMj6tlDvTBNvt4yWVBEbOCw2lDXs0AVOAKqtct65pDbOgZ6a3uoZmePFvo/WW+nQxI2sN/ogDJ29LhRqr/DEVaujYaoX67Ov6B+mFDrVegaFdqCRdd9GvW19f81TdOjZHPx90djkGQfqLyp7N0dhjAvszfbmrCYJCh5TWqx8PT/7j29Zru3a39fTkZbffUrPI3OmaTv2F2yELdCDeIhEs06NQxp+SI2OujQJPL9EsMFosQPbowNzXz14+vQSuya7A/PDUXEnQVWXkWzWjtNBvnnhfv+uqImH3UppDQlbe3qr9jqOb8jgtuu7i5bKzn0ccKkLB8mQtZPSOsMwpzxCR4leC5RoYZuJx93Jpu+nQXL02x9/X3cMiheivty+PfzmCc8sX7LorTw5Pjv7zLVxde8TAB/90fXHcs/xw9JphEGx3pOxTb/CiObozOrSNZ2xLDFbfgHeTloMTZXpUljDuW+FdNzNlXXtgwxDWjTsn3M/HzxTRZiNuCFbljW7JGtvS8OXbFy8QfLu9GfI/H745enPy5vXxyx+wmgcVzWEAjjhLODdP4d4XA6LyJymJ6DzMlN7HOymeaJAaTWDGFNd1d2QO/i8z6L8mf2rb4dM7YUq5Sca3y9G9FDdznAQtkg6UeCXbFPusLBvGTtnVXHFXxFiYUPu7oUe1D1tPWUIolAoMhtxeTRuopicozV5en3qHPwMP/uPNu5NXR4d4CzrrS2oBs6nd6krwtHnlqlv6BrtpZ0W1U1GjA6dwJxIYFAgqN9kmhk1ORRyiRTenoJ4wT4JbjbBCwxlUtcHyt2lsQc/kJIFWtx9C3fFsk9ZwtEHi4FM7eMhj7COd9v8PFKI+a/X/+rDX6vUi+f//rY2UvF5ur+eUw8HVeCBt6yqzCJV7DgLpglYCtkSBlUaLl+nLzjA86O9DYWGCIK9BeOWIJBAVmxVhdK1PPYrRJ8HdrBK7Ie4ixHcYoi2e8IP1pHz75vDN8U9HagxBxQSgb1XDuFeLNuCAH45eHr1++uL4v4+eVSH9QPhqiCVXfhW5i6TffpF6I1vMz5wluyBl8FbIEAcibVIXq69CjO11oqBpupVKNUGixXSlKOyt74C/SS2Y3AbPaHyGbgDYzbKysVJ3rKEU3mD3pCVSw76pRY+BueVx61TunDKWIQrW1kQ40hVMHFWeaHxzrIrWz9PiY+vDHLaqkHlIQFEGWOh122pHXlNKUfC125jn3sTkKapMrTwJ8Lmperbz5JS3LQjNlfMQ+lsfW7fLP6UFWvxrHWYtFamKp0ol+JYmJv4FYXuVYxrI2RnSRjbRUm3o4VsgNfKdxIuhEtza6OYpEme1pMS//xSN+0/v3beePWloNqXeGngAIumcrx3K3B1BNYB507jlX2S4bjNIgRylvHFw8nJM9FfSQKhyo5IIv82C/Anm6YfD9Fy+tiBIqMz1KdY1zNEW3pxSZwOMP3LJcvJxAqM5H+UtyFIS4zodFWiPxd454GgUlVambzj1NFN9IpFkx2k7FQtwXpfxVWeRN/eveytyweHa5AIlIYEizQAHJISO4mrovX45sQIaL2wEqPUWIX336NnRvtUm377NYMPnGhflaOQSIGvB2ginmCtJHC9z7c1UL0aLH8VPdFbs++U6lJswlLCJV3jZ8RZGsyvhTRye65iR5dI8NYRGQvZUriH54lvzV9qJnxqVWr/Z4R7buc9QZeUbVDiJv0XLe2Y9IJU3PyDlTPpN3pBSFeSDULn9IFRmPwiVywehssYHoYJsuxehXCzXPAqVJdflE0+ZfgZKiwiHpuoVidCi9JsZ0dk50NT31mjqMoQJy8WlUVCVtSN047V1k2qcxFQ9F8ZuwHuiGE3R059aJnycQSbHilUmZs1croE5Z3Rz7G1VJDIty9lAhuXcaEec4eGrtW7mjnJkBCGvSbuugHEtZqD4yDv4eBI81aLjyM7oNEglmqe6OtWmdF9t2jzWqp5gItXzi6XVVHSUOOj6UEspvtM2NO18FJehq9st8YoANfpEP7VanvYc7/A6qp43adH5xiyImm29XS+vzejbF3QtIjRjzgv5Vxaey8+K7euYiylW0bkWC0aIgK6Jv2W+6V9kn6uhrh/khosJsZKJUXLaqMEkwJR5ob+acdIlCSvzRiHhJcvkia0zOI2pAaCQTal45bbC5SCn7TvNb8Hl+MpguGRKVtjHwA6inz8rJK1o0Rwty6p9t0kbmdzfvjHEuhUlKrH1SsWmO75/Cfu03vqv4o+QOUSX5theObpgdCmnn2uU3IhKeYjA+G8BRvZGDsD8ADYmhMP1AO73Nd0EeP8uSzk/kUjRRKD3sPRBAcZGO5b+OLe5WF737KSwurlOlarNCnoFDS8bFrrBLp1WQNvCaTvUYXny+XS5FA+bdJaUlwuDInwMye6LZbCvAkyU+K8jbd6q9L/cNgzNU8x5lcM/f7YlPQYi6gV4QAuwnR15EmEb4Uvef/zAl/ywv1dLxpsb3fVzc0LpK/5LRU91sEV7dFhNgwFq9knedCTy+bNSlmhCk50fr+xkY/xnAgJ1Ygv0iXEmzU8nStnCm9DWGNdxWwkwe2wcyi6r7S1WHlPlRis5Ov1g5SLUtWWrcKXy2OUtfWGcplJTv7ut4/drioAWQszHWlimNbpsTa6AxtitFJ1JL1uFSCHh8sOsZc0IOVSt//irMQbsyl1BOuVlhu7brho0qdoY2aOXxxt5QwhpHsbbgLuuBKKqbkQDFtQPnGy9Zr5Ite4HgFlZVmkjDdSIcuY/i1FqEOjnEpC9VnvfHjBrib4uGwbcWV1CqOQkbH/Me7eGau0Hhugoj15ttiiRXHlN3UFO3TNnNVFdiJVl5H11GoraBb29fP+YKBKGrqq23SIZ3NIUnYeojaGUgHEkLjXyAnddFd2PCnne59d5qFmxYSKqgjmWDwng5SI5vh2AF9ie0ghB0pnBXy73E2hRniKtPl88QGDRKmDLdUoydlHhFq4qSqPxhdl2uPmphv8UGUZ07zsPP2mSNa3ZOHyV3VyM4nGu7R6lBfRyJsuat6eH9ua33izpbKhn+PL7qNrzsjAbJMaswMN4QDffxtfyW8x/wZI6BG1gNIGBRTVWyFEt1KjmEJNgQvqsezqK8iRUFl7F4S53I4E34U0pKofrTkfchS1uNcBUC1QmWnjpNI7CByiFw2MbJmiIyFplhhS3ldImLdfnG7HKm2LjzZD1aPwg2VQbx2pa91hHQtJJLprJjbrKxTo94+BCMRioNjXRdFbGcUYKzr2mc/bPnzUYEGMGYIFMagnsaecCJdgq+taKL4nnB9b0V4KwzrtLQa4eiUB1XG2YsTRrA8VPTp7u4rj3d3/pv3vYDpd5EmTxkNg4LlD0Ed8PbX4vFGbjzlDtknPHZlAsl/q1C1srcHhas1yJY0uWN481IVN+FLDCTs4Lga6n2gaEOyLrJnRnW+QurnQJbOO2BnegPutEHlbbeY1vi0nMXowWdvimv1OHr18Y21VTTzCK02eN295UJazaZK3qrXQhbToTWbKgboNKlQ0q1SYot0GyQtnRrVRTnf7gZIGx8B9vJGkY49kTkYTMm7ckCdV2SFJ6GaPeeksCeemj1B+XSoSDY6tLk8zSmLjr+azNadJXmg3wxQs7gm4QCs2gHX46wFmXUvVFInxWs+2tGMFdmjG+vsXsixvMBEAgqm/tz1J4ZgHuNfA/4K7RlJcO6g6LkZkz9dhhtGZCiPnVb8rWGrgGheqKa8jBw6fUSbl/f0ivb9VNBhiDoYM+czvoE/Wb06I8Zs/N9+fPmKz4HdPLH+GNfNql3OmXgR+ifIoLp79H3OSMb3KAff9+KZRy65uH2gqUb3Me7e6oo4ZjYUV/TjH+K05Qm4Sk9zHheMOD4bTpZHhVZ1ERRMGMq6HDlbTmOhynbBckbrXVIvfwq2PHcM2XG8pll/DyhgU07mfFSEU2hEsEtDWDkI8CTzieMjSTR0Uw+YdLXaTBhmxAh3trXBlgNuLlaQPHK0H1kDwE9HivdnsQyd6DeHhbYLTgaWDB/t7tobkeEITcYwmNr4N2a48HDiqWPdJ5mPumkOfVdWG51OblbSz3ErHK8WWYLsBFbQY+QFr0tQboBLBDAOBsM0P4xl9IcMgWO21UBldxWcKbJEIer/LX2LC3Q+xtMsDoOLGBFwhMj/OP8hJ2uobUdf4Qa50/xNTj/NE4E+kGUXo1vWGhE3KxcZc5ccZKHhg2tmFE//A3iP5m6MnQO4AmsUEtVnaA3yzgV3YJtyG3vd0l+P9sNKpyPqJ4VPkzrmRvEZJKQP41glKDbaNSZd+8l9yLBV11z+UPnFl01z1WxOzqjffw59eHvb/+jhff00vLzm1Tcftx+0mCNkp5pNru9UDKo4itx2cJ57kN4XsVQ1g++VxNppSqZGUVmaiRyJzQOzvyrv4gHMuTkgQamN5K5Np3Qwt5Uwr3DfQCR1YaxZaKzWHHsBiqf+WsGVsHs+A0dnV5+dFm7QKvDxsmQ/kOYJEU8q+C1EZWLw7UrRqRUUnyLG+zaQzz4dXVmzf/tfsWFMddgL37HNaR3b2oBQ3vglj+n/n/TNs7nbYlnkEUjnfaMiPcQZv2BPuDyUOTrK9s8z+Vwjtz1tbgoWgOP0Fum4+pqvzBPcF59KAzN2c/7NGDkOnHot8XMxiUD5ri3zx6FO704+kO9gr1190XIEYWiNpHjRpmfog/eFFDFD6gG4f5ODcfF+UHGJDDuDjofEw+kELSf7TbZx93k49/6j9iWSIAIY1ryKyb1DO6kS74uEP1Q/bBeuorw8750IN0q5jotP/n117P/l+bFeHqQle9Xq+vi61UQTsfCe3HIWujxomglV7jxc69tL7HYApjDc32H7S+g0larUEcPppb9K32oCLLasP/0R7+MKoX+GAXiB3+yOr8gcyg3/f1M0kG0wjId44zbfdclxzDBHmPE2SS5vgDSIlNNfH5R+Jz9TMYq79DqEXSZ06cENujN3dKfWgo9SGMh7W71ofmrnUUUhLLoR4JImS5ZFbpAXdMy9lsZFIZTK/JA9KI9odwEnUupicnf7PFkZAvmZRCaNhIoaErCYYoCczH1CBoigBO1UEfms4AbpAtHEHpxy0vVZdcPxuu1brXi5RefMaC+BjWIM0/4vN4tHHWe832MlR7aKc9NIZnIWKB70cbGj2H1UTMoRxosIGHTPq6SLQiTUBJqr9COm4k4Ngl4BgJaD6mxAfW+NtXYCLr0DBLd25YVnHBEIrGgLhRgaAkXarQ5aIYTUawjznA501Q4/+me7O3hGtAu/+cjaYdq0QYDSXkbDRN5x8bgFtIYWEq4ex9/vxWu+uY3Fb7zztUdufP0kvcwPw/eZtv8H9aHwdeIm0cfsRO1paaOFb5Y14OAx1rVMLpoamH8C/KX9/bUsEX1rEdX/6edc03tC+ZrnuZLsbQCfyzaDMYtjICsrmwfDYQSmuWHSc36q3bmyWKPPmNN2qfJ2353aZElEKQejXFw11Kz9Hpp0jaHJRTSpVPXaur8zBR1wLU6Ee1GUp2GqIc9QxD0pZ/BLdzrqY6z1NrUQgB7cg/lawP6VhcnXtrOd2idNWxgHqmkYGe0Q/dM8KTMrBvvhz115dDffPk6b55cnTXfFlu1yjdHTMFWw8a/dJ9Mz+pII2cL0814s+jHvpy1YcvjwbQn+n2kzKqHcV87KT60h3ET5OpOxa4iQpnJ4164lbHht00g7mbSBhTYhVb+YHo6k+Nr5uvMa6mauTcVETam67RdlM14tVkjXo12UVe+cq6DgOjRXfEE3jGSn7i3aNJin9Q9Txoy1S0uKpYT/wwLpMyC6dlkuK/6ufiKkM5h35qKkFR654Crx6BNiJHJWHXoXxP/bqCPbQ8ZVfFP6Tn6MWSBPLnJXzOQJfnCbUPuPOdnTg/1b/OZM1lPCX5ry/Qr90BqtJd8Zyhws3ap39anOH/WpgatZkGzkoayS/WNt01RcxvvaRraQ+5InRRgueRLyuaEGlZtJ5LP4UkZWliWtbLhro9Y9q5AcpHmbotN2VqeCJJgTDOFblJukIKwlWw8AuLXOX4YP0hLI5Zmo9VXiVRj3cumQm8Y5zCTiIVdsihDuNIrakPEWAO9WsXk1YCq7MQlb8cA/yJIA5USVioa8DgSZeW7eX5CbmAicqGK5VcoPV9/eo9QwrbUyYHMz78XTJNJSezXC06UEBTprEAHgsOgfOHdEg93NkJ8fb+9rt3hiS7cH4EvLfTho8hG4ZLh5W0uLQdm2iijU/px5ksWKmKHa3WpSnbDAnrxYavkF8pFzgWf2jY5R24RljIzJAN8a/WBwkjLdNdCUVCYicJvNuC9KAfpRC+YxUlLGrYqxJuuzgoq1reTVY1jAl202r5uOelijsjiQ7ExQTJQVGvBoTgqpHGolJOqHkSV8QnaKVv1A9b982qAjarCRB0KuoB1zZQoxelFbp+SEeXDs6pTJK9douadc1CiLQKdABxiKlWO9MJt3sh86wWbA35XVwU+E1mlS6q10kxh+364qUQXOCWQV8U66JzG+zD2urq4KtWeSKzO5F78Vx1814Pd4KQneosKsVSWmydpZel7ppc/gLapaynTqfRjcH0lfQFZe1P7SRDkdT83gqVoBGXlCBCi9jRpW9tun/fl6qZURmQXDKmJAzTcvRTVwz6J5MtHNOSba2u7ZSiEdUnbE1TNFzKKTZ01QO9F93vPQEVZa/3pKy+SzAZd68b2NnB4a5jom7nbkAnZL0naVWRMU6FVsZiOHqvnpxRJNKkijnBJPAxp5GjQYRU7DkvgYAbVodDZ7UhCGmSmpxAh+mQEtoxny4GzCT7EKFMDz5sWIJkGYqE/MAaXA7DEnHpgeQ8wQUahhGUet+gLSz5aYYKaawRzzRo6Xqq/N3BCHcgHfNPVcqZCRJR+qnsjqufupppS6qXLTE5v/zYwtQ2wyZZpnRUBTSMSvBwEIiRMxuDR3fh96P5AoOLdFvNrXSoF5o3mLdvmjpluoOesbWGUSOOgZcGE3DrAiZvxo9x4JjM3MSeVYXAQS0FH324RxWqSrGdRDWQa5QWmag/+sEO0iuTqqtuZqvyUhZodZ52YaDMq14kqdLba01Dhk7R+jd1h0rolLIEMaE4VYDP9M2V9mgm8FYCOopS16zlkSQlAkIRB6CgCv4Lw3lGdfSj5LMpH2Gdqht1mtyonRRY21BDiGxJhsMJ8AMFaiEHUivRTKepuZbg7ASudX39NZl1yVj/taPFcsQ+CzO4es7Wz0tD57Zm8H/fkY4kJjM4/ordzG0N4VhnuWTBH9AUjl1rvCjdPHLSxevUv/DV6XfH5NlGTH6zCXvz0QIv8HoJES/XAu8Pi+71l6Xbx1L5tk6rTdU5vtShxGqOj7Mkk/yclXyeVfm8TOiqeacBZOpnXMkmVvfeSYK3jHQy+7GWEvtutfMIi7I75ReIvbE7MXI2xaNRTxzSwZQmRu5MjKw2Mca3nBjjO5kYknorXLXcR27JeSuXqeXHTzOOuWoq4V/7jGmMvl04t+R5E/4zeI8wzjN8mc51/tJ/++avzB6P8N85aIny73SAfxYL20lsnmNJOPGCf3Gy459ise5Ma3rrWU1i0yIjsnZ5vJVOLjHU7F0xmo4xtMw9tSc/Lbmslw8nZLCqx5fzjzcqoPTXX92q5W5BuYmSlU2pb0Ap8nlQ5/yU4bl+R+fimJZXg/HuP8DT7pAKhyHBDHF3ovi986gXdufivEiBub/poM/FZ/z/efjNYIJxx2yK+3OaiFM0vCVJgq+QdZ8dvQZwYHHD/zt6+az16u33L44PWz8e/ZdMauMeHgv+AzFJOAO0iAwSRrjM5ZH+OLyx36sZY2BZUB+GWcpf9ffQcQzpz0ChQjIrqn8YARt9UKJE2UO50L4b2eUMhVbIBJWq0ww762Qr5tV/SnILlqObhHo4NB0sOjdZOsCQociuTB7HWP3xCbgWXHHBod9QZ0mv86SLBfSsMz7duDI4KfaebFNej51xlduiKuqm6NbMzquEcX1RJF3mIZvUi+EdsK67y3kY1wZBx8hOnBjZAPEdbE5oZBFJ3NMV+bpT+I3TANdqO8blwtdcYztrGgDxPGcDdmHkzL2e5vYP4c1SJ/WXNS7H8Fr0bjtMjXdQyjja3cEWoQxD8raFxJTXWwaa7MDKOGqleGsumALwTAKn2dZc3MbFaNBEgnrxME4PLP8tn3wzYb1Khnx/9MPxy5oU2UlXiBjYgk0JMLr3ly+vAvhX6Wje2es9eBwyG5EpfYfx2I2ha7d3LH++/tHDv8ifapFCD0ysIUP7R5cfu7CJ+l5A86I04Xtz0cEBX976L5HOO94CA6tAuFtr5Ol7cG+iNjyZ/iYo321hZ79n5EEgL5Q7fHn//lxHg8l9dTsHb9vZFF+8aDMZ5BdhqWWIhetlr6YgiSuFZdmTN1R4MQQl7KWscfLGFMQisuTPVagwqul09AmUuioePy/VuF2eqCmMDoz5QUc+VMJlX7I1feGyL1i4Xpb6QoVlWexLtqovWARLYl+yjfrCsS9M9uVYRtzhOhVZv7FrJhomP5AZR79eiinG6y06pxp8li5G+aG8wjgF3z90s3kagbxhOn+6wImJ0qzNFoviEDNZICbpSH/DtuXQqaGFI0wRuiylvTzD+SYNdeJAJLqo+BWLvV2kA4Qu5hBN+BQuSUBokVBn5W6ZjXtRYjMu68IXdgWvWEO8+WgwukyLE3MlAaaB//lrcX7FR0htLIWVjqZKy0UVEJMwUqeStmTCR6+8GKl83Tf8kpTTdEN5vQnlkEXH6kKHnCmRNeH6XjK6IyfSRabWCttYmkT8wTi6QamtH662a9ua1Dul972ZSUXZ+IErRZYOzJ1Moz6wVOa9hYF5rM6Z8xA9vphITBm8vzvmoCKmp2hksq+y5qRsLwmblBp6owMyaAMKLr1ZtcmMTqXTJJMuuS/sEIhUNp/vJL6XwTPAykJjkc9H55fvDDZvcAfZx4eCz1v/vJqct4BHW9KTtgWchDsfkKCwgZq0lPrcko/bwk5R7kta6IuqAwlb/1zMpvIBDfmFZVPOdbU0B6iYh4A/LDJUCMT0agLf51eYosYWPnB3KT/EryJvKWwX50JwSAJYmJBh9tWUfkFdjlSXd3TgNa38ajL5mKfOo8aBr+d7SVv5Ol/NRy0uzNc5KKgfZnMAKvJxC65DyFqoTbeG4tc97Bj8bw++W3oTh66I+KYkFMHxkvhISUlfv8pP7L1Mkh8yAXJkgcuZBFx+/gqUVl/lh/tIs687/9hLTvWVXK+PGRfmy+kP04oidqubwXdHJYQmA7vqZmC/54ABm+ueM9Vz+fsddJ/9BN3X84u9ho6dYEfo6//P3pv3t43jjsP/+1Wknmc7ZkVnRPmWzOTTXNvO9NqmnWOz+fYjS26ab2LHsdOmmTbv/QFAkSJlOse087tntw4JgiB4gSQIQr9T8Om0AFGAAJBCCDQRrODvHNIoZAK/H3rr3JL1GcjmxdUCRiletXxcrCFg/AnEEAxgiqQgF03E9qNCgEscjjmlakKgowE5PSYIjKz8Mp2rCN4H4TdUKTIfT84uxinp1tc+HB99OIV/F6QihumzgOPOFGQiTqHFca6EUBHBOawGi+G1GM/0SmRx+9D9vSUPXkHefeJ3nyrOEbCLxOD7nRR5jBXXEWubqlB/KyrOS0I7quIEeaIqriJvF8pnDkVeU8UfU8V5wd0TXf8trD8v68+9rwP+OYblLC/EX8aub8LCw5GWvtdlJfftFjtMSoFfcLQAGjMip68R6JYFwos4I11dd8NI+qJA8z1d16GVoliIOtQQAA9EQESiH7Xa4oEsBjRZQdxCTZnqF0QtamKoZwySaXvJuM9pNWOFLwNNK11XcDmy1R7KDQu0imvvRsY/DUw8npEt8yf9nVqZmattca2C85WZYfTMSFLLUQI30XSFjJYKcwklQsOM51B5W6OssqAxlLo/WrJWUuc+RQW/kHwKU8YQKsAwO3QxiO7wESJRmG/w3V3pUenqDeZoU4Vijbz7uTHS8w/do1stQnxqLPemgbQyq0hj2Hj5cwtSSlbBONwJwyHaaIdARWt7EaEGolyVYgF8G9eARtl9fHMoR9jcKS7kNNYZvFxCtuuisaV7SyCMKQFFcVQN9Xh0TAZGshztGoEjOhSyKimIYIT7EmuU2kYlFYW6fI7nohntnGaoqbR7caaG8gI1Dg2wp6uD8aDaedhoB7NDyo6zYjacJrMgUJxPfBycMH4kdcyadidBxOFfMGH8XB5Vvs56BJASVRT+Ds/V3jQRwyPdo1/qTO83mXrA6STNcBJqwDUA9DU7FKB1nYgZXAaQzPUABKUMS4SU5zBb7YpjkwSzQ2m2EI0jJKXALFEnVoBdI7uQ/evXFvwyHwm94DeOONS3yKkJnQQSGuaaegyETSYPyhYX4caMmjxTeQzP84OZdne+ldQKlbPYbW+MtHeEUeECIYwtVx8iBrTsIDpUd1nDupQYA7kCThuH2UHrEO7Th9IFywL+wIU/0HAXLDV4w4VvGLgLRijDygMwPFR3uyaaWLxHsZYoc8i36Rmqc5yUZso2MMqxDGaTacU0IeEVqlpQmBUGuHkejsUznhbuRWwddRXJId+O9WoRgWhQ5we8kwKediiCly0NIThm5dgOMBA/f94HGaLSX54Qzzx1yHZiM4epRvgDQ+AACUCT17AVYfxuyZmTrRtvSUQt5leDykNcB6unsehg85JGiIvR1xg0u5bTBzodD0PLySLU6Wr6OmkC0n7ef/mi+PLgUoeJSCMoCQG2Cx6kVlFCgIU7Ke0ipbmU0oEUKhSmpodk1+lKUI5CJDtZ38KVaRcObo1MDzDqwt8Wk3T6mlarSueJnp8SPLG/O42+n8Y2HRoVmdpd6Az8dHZoOt2ZnSj0k9mFE6tFBJrcQ4mHy2MwErG9baHJX9n7NPybH37nLZZVAHMLj/y12dfH6ztWCVPb+NPBn26lhi1/IW+nlWL8xEWFWju2ZRKxViPeMGivsAiE6m5Jb4JDs2Nx6L+UIAaxX1RjfNl+EcNWHN7VL3Aj/voMDOKsE1b9Wgm3gsQOqiS2U1WtqrMcXfKAV3b6+2p3v4sxbpzpo2IXzt/4iFzbQ0a4/G1uSb9W4GDUhPXxsGE60dthsf+Y+fChHw5EoVQleW/EaKT85oJZon3bbT186C5hW3o3fMq+aCsTY61wii8+TuWpdo7LuMlcfzf+nI3pZIjP86+vhWVqi0vshqzsSaEeuhtCro81LCkWTFyjmA40UmZZfyXVNcw5a1hr9LpC2B+fQi3kqDxaWYulWFUgFONOjcomnp+UJwGy70jKtrjEXO/g5AdjDXTJq5JQTQpm7xcXMxpv1IlgabW5BInrFF37oR4AMV2NW1j3TgS3qQxX6ttB73AO1jndY69QmqJ/rzuVr3ctjl2i6sOlYZVuuisuoMbptT47N6y+X9I4wMycwT29rXOo13kuzcEMvbdwtMvjUzyenODPnLa8c9zf5CrXTOYHc3LN7R5Ufvhh/7fHr0AlpI8hM1tN1JJyUg7mk4MJTLpDOUFJRyaKP8Audkb+fkIIOH4xJ1j4CZsZghPlZwCpHGqn5DPtiaB+8F/1w0f1rwf/9Z9F/TD46YimCRA90kSxuLguqTg2PjiCP9AFb2ez8XwbpG2DHcq0wFWPBGZeESLMrqyg8OzsUlNgSVNAAVBTf97oprw8HKqsgQTBeCut1o20aiWxiIhB7YmeUd/Adh+1NkgqR4/zxTDxSnQsgfHCs8e5LFWiDd26TcH4JY2ZS+y2I6Ya/9K0+tHB5SFSmaqD0wHGuW7v4FwHelDOeWCX0GGB7wqhxQKthG20o0F70O1Fg05xOkA2ra0klgVk5ZZiY/M8aNxeQGQVsMVY/GP9R5WdRmsZwx/TCFXaTqK/HAATlnXi5m42Fq8kGqwgGrKgRrVOnN6ascCKmUZvs+A8SQN5DrY+ZtpP0YnnFKb80jxJThRcHCYTOS789euz4OTuA+w0HY1PcXjlNLZSmepjUchPrNafsMCknACz2pGtQTAKT6d6EPNIw3y8Sh52uf4WNMydjOUyU2LAp5Kt/7Dm18Iqg2ZH7woC1dWgVnS002Waji4WW2iKeQD3xFe+o2ylDkRvxlqUFRYiDg95lakcdVjzCqjNOAj9oMsneAOIjYJvWAJZj6nn6kEjb3ZZQOuHuQxUfrfnyZHWS507VGcgJhwFMGjPOPwLzhnfkpeVb+6GUm5tTqBEaIJLRycViyLpR3QH46YFMDnjWmTl1d1xySFnCxJAMl5KGwqFj1EibUEVt8oaXvLxwdYhiDFeUNpiCYhUYPc6lajemW6mQcO7TIBNXTBRjRODCB7KlaitgyntSQ36CrwI8ISFl+SBPDHj1WwAcpnaK3uCw5u650it5lOJ/s85SGUYezC5gS05JYrxGJiGpjEAe1uBfakOt48nF+quZWe8OHHU4zSlSvOlRsoBwid8xs/5Jd9SA2JbpnY3j4IAD0OFP6QdGfI/ZVh8AWQbqBld5yUp3saNpdwBqvvAYcRstrmUNhz24xDGMfpNQuVkOh8jR8x8Q0tgKcTSvYmSw4hP6YK8oO1fXJ3iS82jUQMmhtB5G9sPo6gNk4QDFCN9yN1S8TkCWhDvsrixvbHRfxi1+yoJo62HUScqc7YE5QQAq6MFQAOrAVPzhAIuM6/REidVDc8SU9UhmNiI3ga06rlsJ39K0bFUydvUvFugxPI0Ru3W1kgAYXvzT3kuRdzekFBS41xG0JctJRuSneElmOIMUyOXEOppeD6T/eY5ihvQtDblOfT41gE0x+zhn4d8BxBW9mTUpxHjL+3LX+pjbKQkP1v7M5Azz7C9/IALSdTpSDlT1US+m80/E+B6m7i9XsntYOgM7+0mVMDpg3szu6LmWAcf99sSSvoHlHqYEEO94Yx9WV3ZmlPb6zvV1nXASeKBFjKoyIezU/TfpU21Q6wcWIuniL05ioUT16Nb/7k8zmFrVBR1GTWzOLoX/ihuOfhZHCaZDCsw4fJ0SxkfxnjRrAv5gEy17pMBmAoTjUM+ACegP6BvBaOpZ2a35th+Y9t+NFKrQFkWg7jDvcYd/UM3As8dd4k/aTi+J8kemaaCqV82m2jmLKECCw2P22BSY+rsHx61m+1qO4BkuBMffCSdojNmcZVzYoMlRtJqXPL8fJAFAcwhlL18Gd5ICznsSQOhnBZCmcU+moWc5t4kktneErX8TtzEQwnzqexXeg1k7lid8fj1qzsc0zhy403voI9bfqzKKIzDkokTYKLmcrF6Zo5WFBv5sarFtlw0m415IzU8oHBKYaPSiuK0xJg1lsVJMRHen2UfFxOQXnqLHz2ygNAJ++Np3vAeLLl7jKDBOUk/F4HjKQyKs8/Qx5PPrGnR5CG7Pd8V5ru6MV8aUIZ0tKCCmlTQDRhXTSLJWILoEtETBEsEq2l6c215qP7nlAGdQv0IS78LVf3GLDfJk+IFG75y1c8OyHiIqZdnmekFvEwdwb+MYI4WCXTZeN/dljpR3/xTzF6LWrAShohGt8mQbxMGRchiD9EdNElFst3byXa8FMAUfZbmSKJ3O4kuHNQPFFjflcAhGOY7NP4J6up5ytQzQvy6JUAwXyJ6LSBNQlH0ByzpijLa0x/QzvAoNDJVhhp1hog1CDcIGTBgbrBEiIjgImqXCd1Oq9NnSV8WkG4n6kN8YMehYNGyAAOQVDXRLSGdsMOAVxvQA0DfAgjIE1kYLcRotSxAtwOAtg3oAqBjAzBL1waEAOjZAAGAvg2IADCwAcBHO7QBbQDYpfQGALAr1wLGBl3VdGHHNF2zDe0kQoPZjjDaM9EWRgcmii0kQhPtYlSYKDWXIdUZYLSsmMBo3yC3MepSHriUBy7lQaSjA0iNxMBEBUSj0EQjjAoTbWHU5G0BV7VyxOY8NdoWELHp6QXZuDVGymU5efrTgv0YbawgazY/OwVR/ElmJkn+C3KgpQR9Q+EzHEwjmFOQTM8Ds7NTGUGkuOeAUJqRzTGIrWw+Hk9/Q0EE1QoN5AkJIdkLEURyivIp2UTBeQmdGzBtFKgssJj89+tnu/IBAsHA9XJyBiAVHYH757PpBJ98h3q1JjsuHbks4ViChkYW2ApnKVi4qobCIsk9hRQooqeqMvvHf45BHk+PTCnv8Xshr1M8YJ+mV0RqevYcOXx9Ro0EVzLlqknpJ58muFPc1zZ4gEJF/KLgmrIBvBpPcbkEVb8NfZydyFpTJGY5VWRO0wVInfHs8Sk86pWAOAZ+LhsswcWGip8Ql7j+UO6zK/XXLHKUCiaqp8j9v5893dKRp1PQUzRFB2ntuG7vUuclIkShCelWC7Kp9nJwQynTzYbvTP5DSP/VPWdkXPiKEcT1+GHcu6ORZlDpIddth9y/rUFcHdKgdhjyf+03yunC1rOP88XZXNbhQ5ZndRZbIxHWUj+uculPTfFqfoamru43/ka0IxrR4ZomUkCWjxR0NYKZ0bIc6TvIGq4eNirLpIi4npqCFxuJ+uu9rbUwbK2HYZ+0ROZQaxETS6Qo6mr4AkPTrxpnpvDIFBJZhbQrhcDK2qZalaavlG6Zv0J5yjr05oKNQGqZI3vLKjhaKtmZkKNK8ZHyZGXnGEbtYMSK236JkeSO486Vi0a7amqa3H1QVgRqrUoswtNgvV5KTHQGFEijeUeH/4kNCN0orI7RjS0dOftOy21/G682RoGh1IyiFiuPew8f3kC02NDyPvwvrGznezfEWv7LlA6P9B7ZGhdtCCkHSa5QAioJDi8tDY2rMZ/EZz5g44g7XczdXip1SG0zILWRoWeKGbNDzLBBCO5dRlIzEzwMA88IgDnl2v1lUixZ8PW9pKvzoM2C/tJEGGls5VqF0hIieVIKj9DMfx9NfmKIEa7r5M1a4fASWp5Y1wV9PmJcdIcA1NfU9P2MAh97ZAo3AdLJFHJYsRitOctLLxThW49Dbq9m9V9+fb6GGGtFCWsGdb1eXte6azMI1a40jH79ClLuxO5sZMrNgTuaj/NTaFhw81gEkLcckvEFFAr9KltNWBk/oRJbF9QUeMvD8B7KbgSAEp/QeBrTLr2xhOupTzhc3pMUtPTJSZNbRtT2xPjx5dF1qVkNkapehaKqnB75JKYaectjn2dLwDbj0yVgFzXx2aMpP68Mzr5qoh6aT2NgA+7Quu0h/IqNKQWnemFy+kHf7l2AynVtAaJhDXoko8uAKfQFt57yYEsARK9rWJ7ektIDdb0nxZvGLzpF1spta1buZsv9q7pxdBVQLTvKSgJTXubLisfMJjWof64HJl0XJe3dMVwmazhsfCop0uQwqxrdQpXaUVNUyQZj6AFLGwaEeMRWHeBfYo249S+4mX+b5y6f/gV2ym9UvoR+5YsqtwLTmhdOm7JvXVNqqxaVkJrqHMpIsKBg8ogW3CWpnVleU5RvkolySrK8CJ271xe+dH2nNrWvd0b8pORLdIkxCrlrjeJjXpl5IlrecoluMC/QoYLdpDOcgwyScpkj0PiUDwULiueBYFLOm53N1EA6yCTZuk34nMWNc2nOOfqvwrWE4TnkmzdDsvg5Nx4UARxaxHQCi9XByJIJ+ZjorqEQx7Uik1gv2wvbmsmjP56yW3wuBYV47RzkyNqT3d8xol9PKi6ZJUdECC3TbBpR2jA7Hw4J1VPqJmSJLe+TM17FgDmphpceOVSirLYO3nMUB1DnfAd5zbEUjJCZHZcp/x4HP6qXprlaXDzQggFkq1cuAIImuYqGJrFasqgA/857x6T23eWR1jG/nf5zno5ITfF0OoMhwLgGgsqyAGHXXqiqGp3K+OK1PjlVv9mdhBtpwtJAtpP0H+poJ+w+sg5dqdn0pc4ypT2+FO6lvb3BM+nvh1sXwdGKjDzzl1Q4VzWNQNNKN0h+lpFjLP2BttMxxhp1lVxnWhtscizr1HJszjfzdLqA5ps0lHJf8Br8gUR3CI4A4I66DCBUtXGjOQgflfVUrldePf1J9IFO6F7n5ev5PL2k9bg62DmVK+6O779NQiLRNxNZcQfFktZ96rOSCgk3Z6g4LDN/PjlaoW7K/GPvdoLZCoI1S8HgHSShrTvQ4wCGQer2vjPnNLrdZHp08mkDSfIT+sOMqtbLXqm+9VfLd45+PcadMasAgIMl0Q6BbaL2NLd8QKEw2q9+UsCniHY1t9UF/rUywb6berUpVmhrHQ929h6YqZd1Dgz82inm3cfJPiGc1JalcKm6UGs90RpP3QVX41AKqV+VOd+XVylQj8WAb6ezxTN4Vx9HId+fwWkybkX8Xx/PLiAw4M+Ppx8XcbvD1SXac7DmPwb3gHE7KiCP8zxut/gr9Oyh+i9ut/k2mh1jQCHBWxxy1VES2hlnx5P0NG53+Svwe3CWY2gfdNQf4nZP4xx/Os7HGN8fT47hhuFsGncGfPf8I2TsCv5y/9n4/UU8EHwLiIOXDBXFhNc4XigFEhZEdhBptCKxxQup+xwchkCUcM+p4oMuskCtIqAS+3QdUkQ7iia1FF3CcbDroxCwBvTmGAZqqg42ZHeRpTPIhHdqXD0Ni+naij85mxC8G/JXMPvezijS4TWM7cDWj+Jd9Md4dkm1xLhQ8QI7UjGqHAFaCmCyt4G9nEI9cH2BfvJiukXjewIC7V7I9yIKCL7XokDE99oUaPG9DgXafK9LgQ7f61Ggy/f6FOjxvQEF+kAwxBCRJtr9EEIRhQTfxwM/VYIuJFWc2CZAl7oFGtyg9DSkROrzx6eGhmhhzCSKNn8+vkhNqqBomRxdJ+ZyrOLA1fE4a/zQ2v6aIWoyN9D0g96WwV96SnbbRX2bj0hAlxrRFB0UODoSZ/o+AO2QrLnSZ3NZRBXvmFncuEVPtKQmUlcBgbHhVxoidIEvPRo0hEDqTcfhLg8rVdS0GZKtaraEqb65m3JkoXttNSyvrZqd3Rbsu1bfa92PSdKOragwM6J1+2J+CkMN5u7zxZHDJ1UhS3MSwzriYuhRo4a0YIkDEi0XpARDzQMLl3MSyKUfFqL+EtqYb6krQHdVqXpXgIce2s6msnon+OZpghk/ziCtCJXQHESMhmO4TJmcQZ9Aig4nl5KWbGeN83ET3sqNpo77CYdBF0C8EQhbgorWy2i1WEHPBBt6Aw8UoDmpxjAY8tMxelybcTeZyFsIKG0rKLM5XPDZOAvsj5DpVvAzAw1Q83FDdfExQXBfyZSwpadayYUjaDz2AamDD1X3ZZg0Qk6IbhP4UYVG1WVUPnsC/CJ0Rz1effiwCmmwwpcL3JrO0qNip78EAjTjDjSxhqVTmm0i8FWK4TAtANpa3hq11BRm3K8k81AZoTQbFjV2MzmKVzUk7QdS3+YsHXzp88Rni2NEf/m+WBcb/7JvmYsbffqqyNH49yZ6VWGPGv4d+U9O1vWz9+9hG6zVDGgSoOn8AXTEYdDINrPCPOTN2SwOGVD2HgW8hEmbwYpnMBV7CG1DjMzzscSyqSJRxaI3r9guju9kNZzfzYx3HIeJYiHRLJBZRKVEcacSo7uV6DJWy+NQdSBV/vqGVazD7dHnKnYgbxVwBSPjX7826vjgYw9tOurcNrHULy0NyPSIsX2krvHX1s7Gx06WK+6vupvnxDXu5FPpDCA+kVNndP7kJwr5pvZg+8mvRZjJf+3bLcH4+Z3mVnGaKpQ6LMHHru8vpDETbeROrR5NcJPRwBnYPMdpGNRnn+uQCwSWlWncrDm5pkUugbmEyaV4lyePJs2uBqlaW7DrFZLcXzvPd2GUO7SIHiIQ5xIZQfddCcNoIFPVwLT/5pBogUAm8NTEXlFjWZ8Y0Lxd8+IR0hGk+58hOd7VrpPUHP3lKPF8dwNWyhKFTNWYySPLlGVdW2obu0FsX+kNIFTsrV/OxnOamvgBNADjZd4C1M9j2G7mhPgGITugOplS9BdQT2OMIsezlBQDkA9ff6Hd5+gsnee/Hi+OIS5rlPYM9rC/Iz6F/qDQxdlHdGWJuagY1K7DoPuomrZEcVyUvUEI9aBqtOJ2UVlvmTjWhvzyEsyyeEktYz79NWmTl1Qnb2dQA2oJteyqfQtVYgGbDSBzrLhFd4bowBWCqOYdKxzQC8zmCu8ZrOynsoO4+1l6Ci2tICKM2gDb09cOb6h+hLeHHFDTErGqYWFaNSxE0GWZrCcLRVZZ7lHKc2AxtQHbqt22sdEUcl4m0i3NUhbqil3Vf8tZjhczuE1Bf4+ypqDLSiwzGLEnq1qi1Fa5o8VOuqwgSj2apOWRZXRyvjZhPmAj5U7rc7fleTnfykm4Tn5m9LWNhaJ6yAJoXSzU2m8pqA3kivZ5II17Lt1iI1466kq1egzo0RnJIaM/vUYpAAAkbZP36jhDF8hw0nM9YhSuFJT/cNKWgtuyz2o+VcRDENC+bVaFQ4bFPJO1Oh7N42Ok8dN/z8ZHyQh47rZ5PSDfFPYT2zY3r5cZZD+bnp65B0yrG7eLW4lSFg1n5JuhaB/SaHgEXPGqf8YjPseKHmL37Zwt4cEoYglIc+VMxmbC0S/skI83lI67iFeHLvDTq579pPQw5xolWbrWEZrqDVfnSEb6FXPmo3swopdzGa500hbmgdBGHUKSm59NMzS2z2ZXOJRhbCiHP3GkUPQy5CjTCYWToP0dwi3yKdQ+ZAr0hwIRhPFCTUxEua9Oixn5SxxxUSJzh+3Aicrq2HOGhY1JvOsU6dBYWvUYh2N8IdlhZN3Q+lCcw5x1NPM1p+fLSY3GyDWGg+dZHTQ1YIGbIlQKz6tZopVZWkWWeTVLe2WWTpFlVs3SXZmlV2SpTap5+ivzDFRKMqpmETc0gCgyecbgtr0LxsnNJ3zE53wGf0ns0Tnj7ZTuBSoLzUoTTTLNRI2UIfBXsosy+9L+wJW8fA4ihsbpEmLGkpxSnM0EXhQRtLKdmLPkRsagTlygJcdySeTHwhysnAI9iW65WNGaqunr8Xug+uHOTYUqyzaz1ye15FaXJySzfdv9oLPpc/ZVYWVfpTdQo+ruKi2vm4G+KznctS68STYzT5o2CVwxJmCeu6O1wf7WPYzd5o6C3vX0HyaZ5a8jC6STCV3dOvYxNBJcjOr+5kGjXbos0dJQqflkyOfwb+a45QgZnziAiCUT2B0ZSSyktDb17m3AhGs8IGLyKF1NfyhnbIXHabhE0E6G4OJgFtTXzt6TrSPEJozbRTh5yO6pLHNkPMBD5cu3CBPTANXykcaxoqfLp2LrvKxJ+Z3olpSzr1/b9NuTWBvpbq4matnIVq40mW+lmVezRJ4szkqTFDvVGftiO041MxDHqr4BZ0nNsxltkBx03aPeSOTG3cCKPQ2LV28Pg8ChwAXPqp5Pl2VUA3jW0xZOKAD5ZRtYhuBjGvLrb19x0b0Vo3crRv82jIG4FSO6ndNb1g/RVuK64pOV3BDn99pr1DBJeQbImeWfZ3nL0g2iR/nqPUiZypWvirx0O33uozW7iZZOTUjlLeX5ZlY4YH58erpWHG9BrxZrcAECqXCO/qwkLstH6ILCEd3WuZhV4vR1rSNW8UJbOc2KJR2IQ95zJmcr4A2XsltuJ64W47q4XVK0WL6k2u5q5VMtsBXwxhJdXltyimsT14oMZoUbVcFnPQ+dXNMRjfQFW6RZll9evHyxG4f82e7emzjir5/+88mbuM+fP93ZebYbtyLA13PDwt55+duLWPC3ryDL/vbrl8+exWD/8DvE2/CHUjuYE5US9F0g+QW+QQY5nr98u78LmbbfvH72+Nmbnd1nsQj5m5dvt5/EgrLA/StqlkhJR/rpu9myRFFUGLOI/qBqzSLCbmnOArGe154FcvarBi0iHFQsWoQItUmLGITKpgVCwjVqEUJYVi2i31VmLRDqrbBricTANmyplZYtURQ6pi0AEKttW8QguptxizJs0UYtwrVoEcacJTK2LO2uMmRpdbUVS6vFjQVLq22Zr7R6KoI4fdtwpTWwrFbaIZmstDraXgX42xPQdhGaqgjgYa8Ff9popiIEpHXgTxdNVITooYGKEH00TxFigMYpIgohewh/BfwV8DeCvxH8bVlGKaJrW6QI1xxFOLYoFNeGKKKvrVAobExQBrb9CbT9r2encEX7/CN2RV9cOytNZSdvpvKIQVB9prDmOGfgmeWZ4SQ5kRn8O7nJM8OJ4//gxOOZIT652QnDbRQ6LgWfE4bbSHRZ0O7H+cGJ44cBnhpVluXybQHUXDtj4J0BlEBvxGBeMe7Jo1tdiURXsdiSWk0Gxd24xvcqp712YDaeAR2pnYKdvr1HMZaQXAcZyWt4Fhw1BRChMjy2JumysUqDcG+0YflLHJVymjY8phQQDlDxbyVPFVZnXxAz/iQBSWW5pESvVOyGvZxai27bE+LChTi6EGR2svjepRBO99Ydbg1Q7sMs7VMATXh0KX+pT2gxrgx90V7hF5WPEPNYm1lllXx5JT5nS3xHnivBHJ19zp1vsFj7MTbD7+PMJfn+shPAJdv6+83GHO002hFfSpIg/OYy8mWKuhEslrDsweagz3P/F/FmTl3nlbpViX6+Jf2KcR8r8Niz0PtWkpLv1pudINeCbJVX3ZweELwkW0kUvAuHfWZUDuZrA5jm/+SAncj40q2mGRC0K/UuknbFiwVTB7Qah31Ry6ezeqr9I+F4LGOsGyn1zcpCMzRfykAqsmV8pVeaAfo/fYYFFSqkTcgKm50Z2ezMea5BfzRrswMBsBwI0gWJsRiZx8KJ53HkxL3cNudxy4/l2mjkcYjapkoB4k4FRHcroFWpDR5tZ+rEi6fE+dDf3njtIEHlm0O6l7RxZU6uHKQrRr9+dUEkfeEMC+4Rsw+bUD8dnEnnPLSuzkGr04uDURWszk1ZYa8DcwCaVMf8ZQgLoXafUlhcqZo6gOG8W89hJ3p8ujmRTRGFj3Q8xsqMx6ewJ6DH9RPZemSDmHbUDlL3SHqpb94uaehohzroCH58rT+LQa2AWgU+/ynqdFWIfnMTz+l3YuIT/GXxPUoPv7V0XH1VRpcKHn03oVutI+rXr8oCZLNRyOMjxq1kKVhsR8PYoOFBvEaCo1CBqO9pL+58XyCEvSHTVCzZeVv+iNNGEzwl8hFVm0jp1c1n4OkjBO4Uoza1HYREV4f6KkB0gSwtPvcmXCWidZ7LpsSOpp9uwl1tP4x5r4yp5ITu9EqaKjlQ1rsK2VX0XfLcT13W/FcT7kPYG28zGL/hduSbTTxcw5ziuyWlzQlaoACcoDBblmBqXT/7tPoY5q7/jeqk4yOWjJaMh6uQBiAtGw+PbjQeNuy9nd2bOVpmvoW12t14I+3KfbnTUu/vbbqdl8+pZKVi8n0ps2R1s+Fh1V1jgFn+QLD4QWjV/jdYpb4/aUi/tcsBx9Ph37lBa26LavP6e3P293c2lPWK3hv8/Tb9qfuKYanrhZSWdSK8uH0gc2VeWgyIByK2WYasDlGn60mW30axtEoC5M6GYyxpfQbKAdO9iHEhynhHSgehevNbc1PpKzp1XmdYZF10uejxgcD/i25dos+YAij6BI8QyByrzVDr/c2Qd1pCD7ZvamEiocg6LzFuIakJaAnnkPg4uycBXTHnzcU9CNDyZJOgvfE9aZCkIiIEWqhLJ5wK1dHWxkv7sznoXKfpKWGsz6C3YZuIW1n2ZXkS1/7yLKbR83z/laKPLV2XUDraVcMIMgnYAN6EtzMDNi4Jeb6K/6f5P2Avzefy7gfoR6PCmvx3PpP3OaibjH8kKyq4mSlNUOytJ6UrhU/srS/591WKIZY4ypj8EJQNFYj88jme86t4ds2qGq4GOoZPVpThU/bk+pOup3Ar0lCY5VoRFlswylCxKh5VFCYMYndYE8irinsjSq7MXVBhtSKG1d5XSEsSbQUafaJWHa9laR0/UqoRmam/xlZewf8o4H8klbV+aQlUPsYUB6tUMxXFTE56xhz1jFWWM3Uz+0ZxTq15IwZ03fpxDnD4mON4ri2J75MHJ5A72uYw2moNF0TD7R6TrOHvCypbqaTUp3uv4vtMwVvJ/gFkBZB9H4trdh0O76ZQlNJRJxaD8JbvlbozDqVQyK55J2TMni44///3my217zZdqmer/0MnDI0aB7L+Ger2N0yYajFXUMx3nkI1mkPs2h7HcG/+P2oY3zaAYSk0w5PrYUmDlOvBSEOTV4aie6zSRoHG4PK7DK5seXDl8h55PIMrXxpcOV4tRSRmbn2Cv6w60e/yyvGRjJwH8DVnl6oTaZdsbYANXG3Anb01pFGX0X29dLcOOo2KcsSkToE+k/a4A7iz3ZLV7a6NgIRuRHg7W06epp+OYf96NqdXZvSIUH9BdHL2JyjF0p+O2eZovaJ/WFZJxKZR1Ibe3at79Vi0ubrde8Ff6Uhc2pzuMwDXk4HbXTUbZNPRnaPjbqdUgc91TrfxCfQXG5zyuk1MMH/DkuLwJt8MVf2hxzmCxvG6adCJK1002CoBXi1NeWxIb/bYUM30/fw3VCnjw1FGDfY//1UvWCXi06ble1nn2pDpDGRS7kvJMCXypfhvGIlSy4vvv2vMNK9/+Hn1cyTuyVF0H478VdDturJZa6nzSalVzRx5U5pe5ldz0vQzTwze3pagHLpf02ar+Ytux3f5c7xUpn4vlSPjpXIEcwG9VI4KL5V0Tej3QZn5d4t8lTWBU1tfs2QrMgJFf3OQ3AcSlhPK9J5OKOcyXe2Ecn7D+6F51cvh3GVa5gCxfFCmq31Qlklw1W+9V6tUWpUr7o7vH0RIJPpWIgT2+6C8T31WUlmeQe64X3VNmHEvuzL3D77bKeYrCGbJnd6YbVd9UI7c3i8ZkCPfk0UzOPXbWaCrH81SmFUeq3m5rT5c89f1b34Fr2UHWdfDtuzNh/F+OjGaBveLge0N82m4tKn0xbd/VaeW4hR+uvur+oR0iaudaDQFaBiPYfVbnL2/WCMdyXR8sbb7eXZ6Nh/P61KWu7x0NnuRTow11U/P95/urjUOwubg8Ivg1wfrFAr5Nftpffx5nDU8G0SGAkl9vn0P3qpfNF6Pj6Cw9f9PMOuLxEn6P9QblC5XOyBxvb25FpKpPg/C8458fQKjPiucBcgcAJfjUVZkG0FU+w3JSxcamQkC9GxKGI4nCIQWWzY48GqY5XUDYifj8Swl13YpxOYXmfF1p/Br+bLjCCFlvuqdX51ODeRkuPrFE6dSuGsvrKMR86V+PlJhwtG3ISK9bbUQeGu3XbiiG5PHhD14PIavYcZzPkXfdCf4Jmq8PgfQ48UWfTNd2Xtsjl0vB2pcKGb2z/C1g/qs6jpUCIY+UFjAqKBF5USblmMJsY94A1nZOj0bNQ5O9HtT1KEYZNowb318/55UjJqV8fT7cOMW0DAssGuWOM1d9Q1Wur6paf+U9BFS67GAO6qYG20odO2R3/F36dBTS8aUndA9pc6W6Gy+NmVQv5Df0tqK0CErSb1fbhCXkpXg8EHTk75slNLIegtn1j4hGzSjLQKxPrq6GD+jjuDq+/YZfd9+5LflTeHz6ixZ6t9R0XJLCbpdl7JUezB13YxafkZvqI9TlZpTFxQTY6jL+Ka6jKEuqRwp3q1h9MAqXslGLSJB4tmvk3GNwbot1AsCHEpOxTTBkh7MGkeeYE7A5FUPpYgDEsXnoPS38ej1m23to7SQscpFKdfF8FQbN5WyEuhYEde7KMwxXY9Vc8vuEuNkZKlHtHqeq6ffOp4EQQYn6qzy8e9Mtf83V762VPvE18rXVfFerWuufedAP+mITDn0uptPp+lGri5kjFUhjZzrPMAFOd+5+9oEyLA0qaLchWbJbNxNZtyzOC4vcqjD8a1SNod/pY+cAVZn7kRp/Lz/8sW6GlzH768aX1IqKq7PcLRd44DUk844RpsUbtHejOcT1ETLmn1e1eG1DGI0dMlRLdm99+DXHnlMb2McqD5lnKxfFCXsTj6eFl8ZR2VXAomN/KGI+myzsSdzfiVDDgmC4QtCSouitkp72BKQLDjmYzGAVXI7LJJFB5KjIhkoUjJQwS1iOLwCpOFQdvleALjdFr9qNgEX1GlXLG5cyT0ZqqysOMeYT42NvNJurxDRwlu7TaCr6oWl+ynsHiBC75BBZbxEHj68A5VtTcU8+ocrP/1CGMT8Wt35IFsbYf/5GImBcBM6kFBTKa369eXGibZ/b1zKIsySLQAXOiUBKVuyjJritU+s+n9G9TgcXgJes3nJ0waw4jxVB4yLepzLfvPyH31aeJSPpZxcKWWE76JP6/FWEFS5mDYE4y4rTq55Pb6UYQHL1a4+vtyQdg1Dfv7wIdDmWwC/mTjjuD7zyyC4tr6yn6LEe3ywdXhwCTI5+VSEGhP8OnzQOBoORcSCWZkhb5RiP5WUDuPvEupf8EWtQBRHh9iN/FMRTu1v+zuLh6JCK4WhkhGV9PAg01RUeFRSKRW4Sa3sBlPlVHGCRcNPkB4CDQh/onDRbzayyUn5MJ3yHlA++puiRthwmBbUD1LNoQq32/1renCKR6OTdXjSTG4ZKVSomowGCk+lBWzr6im6WAM8c0QSiWd2EfT95zIeUvzZ8XS8hUOF4sSh7ENQayuiTqHUqof039rWFv0JQwhgjP4ABOIQwz+URjH606H/1vb28A/EIIAx+gMQiEMM/1AaxfC/OjnlusBpQb4V+ET2+BGOXNzF4hDegn+n8O8DtvFTCHzCwGP8Qel2RTWqHuOobfHTurLmqgl05dPNNLYbYLQ5iqERXJc0OpWGG8yDDPs5+aT+GtwccHPT7zmgIuZBrvudwtTvJ+u4JAFbuIaoCBp+Nxhyu3rLAan2dtJJK173gkJmBmIdV3oTDmTKqo7elty6Tb3i19l+jRg+r3JBRi6eGl+BBWBeAKJejEPUlU+g7GDXtssFnWuqxetBPYY+TrCzk1MZOTKvUQeSbQfEENRxSwFIWBRSU6zEuMqH9aGExac+qG9IKO7DwdNDiT+bInyEf4PGtAlLLPwocuV+P6lLzPE0CKwUIBCipRr+kaHWCX+A8fg0EHxbfjoD5zphUq1fVo9Vx9M3U5TOq+GK9sd1fL90hStRU86BPA83tjAGxbiYWyVmoDDLRcRZyCr5tk2+yyKff2V0c+2UuQxflxhb4isv+SLEpljJ2Mq6/bMsTdMoi+O9wVCFe4NKvp/rsdrp1CBvJCkvU02+jXvghl611CKGyyCuo9bH/66+flUlhyo3CXtY2KBTtwKRbJdiYZu+9rfNTG6VTyzlCyHXVlPoDC7HT+q4U4KdnNjAbFAt/CMF4wgQCiAIgAmmITVi2ZaIpjtS59J9yU1XYHsKCDDYQEC7O7xM6jFyrTi+In7nB9uHtGfDwKaQ6m9/Y4KP3QLZh32egoGqPdKpQ0nJTUzuFcCZjOKojIRxKxxKRb3V21DgxlRiXj6haLMVcpiy/Q1pCmNx2+Rq61xHCrsdxgNIrKnUwaBILWj1o1iEJq8Ii2QgXGQfRCyGsFqCgD+3l36hcQXNgENSPMBRonoLQBhg2tb9iqm/ZghMix3MHBp1PrxM5noHNNcrhApP1TCCNlSEx40trTCpSIgP9RiXRwd2SjBxbYSfdm8FABuxQ+Lx2l19zPry6wW0kVoRnGXmhmUka9xlBSnUmLvyQAwGPOpEPGq1eBR14V8f/rXhH8BbAv5BuNWBf4iDsD7863IxwH89HoWIE0IY4O02/OvCv4jXoo6AABKHzAIJAlI3gn8t+Nfh/VZnwNthBAlIvQfILUAO4a8AqgMuehAWfaAseH/Q6wIAcvcH8A+AXQFxAeEeH3TFAH/6+ANR/LbPoBNCtNOFhE4vhJ8ORjs9jAoMtfAHU7sd/GnjD8Da/T78DCKIRggTXSQVIlGEtfCni7BuD38w2sFojygTFSoIE/ohwjr4QygR/rR0tEtctfGHUIhTKryLbEBCN+zjD4aEwJ8uRpEXaLAICAnIiGRamNqCtsC/iI70I95v94kU7/da2DFEHCICfvohtl8PAx386UITDyL8aQEmwHvU4ADGQSH6LSQSQqcJ7BgkKbATYNXZdsdQ7XsOov8RY6j9/8bQ9xhDtW8ZRIm1I1gp6DxnPkzynURH1klUhdPrZGmjZx9Q8GU9LDQJqtNJmKt9iL1Tabf7TFMpnqYtbrjHBEzne3XVvE5WF9crwZkh8MT/3Rs0wQY5D4o6SDL+nnGJT4sH/k75DdgLiNaKxAXuvJyT6iboOFA3UocfFocPdD54sOOSLeD4CDH5jjefpvK+l22q9n2LqVZkRQYmXFq+/D2XsppH75szxWW3M7Q4CzfKiJCy7D9voza7bcbvwjm/I+faqag1SvTIcceDd0yityJeg8YECq2/SIEPBO/2gU5Bpv8NZDolmcE3kOkZMu3wG8h0DZlbmUEl5XftWG4+s3TQD3lfcIEiF1dP0YV/PfjXgn9t+BfxXu+QZ/KgPeCdkHcE70S80+KdNu90eKfLOz3e7vNWi3fbhzzXBGv9iKNAb/N+h/e7vI/rAO8P+CCE2h9itYUQQz24RdTeMANdmQSNZ3A9oI3sHC3ZQ0CPNv5qw/cGfHSgJwzU79D0g6iUcz/SmZ9o9E1Egdl8me71faWZXwT/PULuOqmVxxUj3WxNM8ebX57hTy4FH6tL6nL5DoKjEvsD6pf0+g1JH8wXMED7e3R48AHUIVJCvbekPEJDnK8yYjyFSzWIjAKZ6YK6fCxFhE40ICGHIMS7jAPKj0NwAzldW6ivsKOfynn8w4/B/CDd2MBrmsOgnozS7ORoDo5I82aBUFcIY0QAqkIVV0/QsLCZwwchlC/hGLKM56ewTtZVYUl940fkafgTlrpRDzJgjj5D+bioT6rVTw/rMZJ8mE5mSd05Pw6LlNOLSsJGkXBUTVgrEqajhSGmdXCYkl4fPXCvHRB9OJpv1Nm1re8GxyjT8fzJm+fPIPk9mFuQM2r5Y/vHjeEIqlMbBVkAtRttDH/C5I36dVKqUu0B4VGtIWqhcdXz5Jr/+9nTLYk/X79+gdFVxxZ9Dw2aWzYFmLyO3rHPpu+OgcBxegpc4RiglH+/e/Hy3d6zt/tPZMgLyKvHr988ffysAAsN3v/jxXYBizRs7+0zjdcysKcvnkK8reNbz15u/yI7Ovrm9e7uvuzq6MtfyoL3Ie3x83e7L3bKUl/s7u6823m6/aYsdPf16xcvZVO42RD88rVsGrSdx28ea6Bh7vmuQSwZfLunYYbLX3df7z99+ULDu4bo7t6zx292d2RfQf58t7iAETOxu+/iw/ECnl5cpKfvzuB9AEXTT+mxFZ3CXNAxjXs8LVFVTGNiJEwwqj4JqFIm2l6sprLB1mmuUtAM5R32v84FJcGjgXcIVxjHUxOv1wlHOVXXGeDVCPiA/Th5p6tFJV2rOh/9+e4DWW8tVfozfEf7aKGKwLeYRQiqYDhZyKjTUWEAz1NVhTL+Dj6HJq3o6djUHb8lpdBNFLF1MgxynIYWRn42LVj4kM0zabBULqiNf27gRXOycjI9fKieXNcxsna8WJueXawVqOtra/uvt9f+PD0erf/3Ym00BmE9pmiz+MY4gOssqdnvUnVwbaTudrSxEvY8SMAIPRmCadHx4mJ0fLGISWuFIT7G9exsfgLLBAEX/IPGnkI0DvkJJKD71AU/TU6lsNI0HpKNxSDBQid8ymf8nM/5Jd/iV3yb7/In/Gf+Bx+n/CjlH1J+nPJX/FnxlER0QRhZYVyZJtAbogOazmQSBOzZweQQAJiAvTgdwjsiAh8dfAimh4dBkJzLnNJnUnQSMZQz2uY8Q2eGs2aTJecbAGmcy5k2V5jpjcLP8gt8frLb5tQsgoNFSAydenKQBcGh/LkMVFpQCtWGKsxVQ8uMKz7RgXg+1Fzkh3gTBlwMc+Ii17W8lMKqJ3B2ORwCscumxDqjjr9gsymIb9Tz15D9EajlH0AldC1M8YBImu5QlaDoK/Lzg0kAKfDnMEDySw0aPpCqRYHJ8cG8bF5Qxy7d/YfxOJUfUjlOjlN5lAKZV1IMHBfiiPE0gbRm1OklgPsJcTECuFGn666SiP2YA9YeLyjyV7IprqfyirQDeQJvjWH8nScoX3YhKdnCz62eJ0/klmofHJqgIe9EQwmLWUSxzgBjS+0kqPZJwr6oARCq/p8058UISMYH08Phq82f1yEuMRLjz8arzcbP62czqPrBcRog6JAXOGDpV0BYTDiDbnKJLALVJJfbGAS73LO17aa8hIH1R9C42tjYmLNgGwZYArvG0zEq1bfV8CiyiuTq4WXCLgFT1kQC6ZebjauH8rIp+FUgL1mM7QP9V4zsZhM7l3b2ExznqpEn2LWKuWtM2QBjCKDyhD2Qu+xLqNzoz+U5S/4IZA7NjDwbLmDeB/PhDFqLhiZEDqm0DShe0T+F8mnwXm8FKsd9+2NXAjsJTrfdQ+qSU9Ul59Qh8L4fbDGKGwdsuiuF1G1XO44lmmiwlVQn7bmatCqs90BhaSeRGTsJnknHYrJQ9istPxo5hDp75piIcHq7pKsHj6HJqexmClnizLUNWS5+rI3sk3JFl+VSKv9/9p61uW0d1+/+FWlm1mNdU3tF6h1Zybg77bSdbLf33Z1O9o7spM/T9Gy6Pudm2v73CxAEJdlQKq+z7+14GgokARAEQQjiY0ITkp/cOhPl2wau0IC7Pejp55vmR0rhreaUopXghBln3s4U97MVGCURkUuC58lJlBhXpqNPO9Xb2r4yzQkuCRJ3KZxGKMldQk/cJz4LC/osevCzOSVpDyGl6QsMpVs8b+FWMeYZJ7Z6PYtNFBAApzwAmKIgAM1wPA8lSRLQK3zXOkRsG1Ah0ORhudPGLm9pceDClpUj0jhW8P2GUp+ba+gFcWUOfEWb3dZXQGN2PHt1BP+QdpkR8Zynpg5DhYUVElBnBDR9qE4JrIsu1lhLGLQRoEnxTRFrPqOk4qUrrnsMa4m5MhOAcY8cY82k+mKDzS5nlJMlAmJjEoldibGiEIBGQqoTRlp2kablAGfaSC1JM4nfyHGh8554c0kUUSL1XCRxnGcDvBUS4liST24kfpNIkq/EWCEBTdTyZXQvx+SSkJNY1GGJ4VRkOIpEAYtooawstTgTlVgSZiIK2AjQrJD4jcXxNjQISgmxkRBrFo+JeohFQZhE4jeS+NWsaTvmx8gyFoUmDrsiEXmTgEkkQIVBwFpcSEKW+C1EclB9V4N1FksaHKeiBicDPZqK47nMRC3WkhWWBByLAs7EITpk1WJJxplo1Ywo31ziVkJqxOHGc9SuEme5qChS16WFqMRGmj91KSpwJimwGZo/5WlcBMZSz+WJaIbFaS6VFHhoJmDxZEkXGokznexISOymIrtRIqpvOqRqkdR1sWjWctG0iuJNJPGKRi1moe2IuJR0WEIci+M4zSQjXIqKZjKpZUOKZkwk6bARh4aof4k46kQ3SScicMh05OKgwwlppCss6l8uGuFYD7nCsqqJnkBSikY4Ge8KS2KPY9EIDxpcUSkkVclS0Qhno11hCalJh0xaksnusMiv1Io0F41wtIcrPGQ6Ei0aCUmJRX5jiVweizbYyK6wzFiRSjLWfRQs+WIPV1hiOBUZjljTxrrDWlLiXBRwJHEhClgilZVDVi0Wx5zYnRJiIw7kNNnDFR7StEyLSgysjXaFJQ1MUtEKyzPakOVItKTF4qhLo9GusNiIUrTCJUttrDssQVMtWuFivCssCTgetGtZJhUXBS9Ry0T5xtFoV3hojjLikMOOG+0KS61IS1GBE9kVHnTVJIJJLCqxEbteFLDUc3kqmmH21ca5wxK7Jj7UFZbYTYcUzUSZ7A6LRkLqurgUjbDo4IriHTJquWjU0PMe6QqnErda1N9CdoUHg2pSSzJxojNmD1dYS/orjrhSCg8N95w4X+fioMMJ6cCoMDN2/5FhURTxeFeYmRsZGdb7RIbHRoVTiV1m7JDIcDrkCh8WFfaj4P4jw4DgwKjwQExNHxwZPjwqTLyNjAzr/SLDY6PColdHnB0WGY4HXOGDosLsQ95/ZBhV9eCo8EBQLT08MixocDk+Kkyc/akiw2OjwrnsChNzB0WGUzkyfFhUmK3avUeGAfHBUWHZqun4HiLDggLr8VFh5m1kZDjdJzJ8aFQYGTssMpwOucKHRYXZrN17ZBiU6sCosGzS0vzwyLA05vQerjAzNzIyXO4VGR4bFY5lV5g4+9NEhg+LCqfM271HhgF6YFRYNmomPzgyLBjhfL+oMLI2NjKs94sMj40Ki8OWODssMhwPuMIHR4WJtfuPDAP04KiwbNdyfXBkWLDC6fioMDE2NjKc7hcZHhsVLkUrzLwdFBnOByLDh0WFeYD+SSLDB0eFZVUry8Mjw4IVzsdHhYmzsZFhvU9keGxUWMuuMHF2WGQ4HXKFD4sK8yi4/8gwMHFgVJgYu//IsGiE8z1cYeZtZGQ43ScyPDYqXIquMDF2UGS4HHKFD4sKe5ndf2QYih4aFZZdNVCViwCPX5w8gnXEj3bWEbPw065zaGIGEo4tzyzte8l5F5pEJZfuwXleTHsoIpPuruekvIxr9IlmMbs8fc5jVzrpEdUMjnplGVp0oYUuhQ6mPFaoHkkTJQw3DO9501mPmUhi20gCjwvh6yf3hST0TCepJPRcFHoaM1z32sjQPsEkxRleVpdEEnqelZLQk1ISujamYDPQz4glkccRv5gLYi9jUeys/43fMxBVTbubINXG7+SA9OnK7uVwW9twR8ct/OdLxDsF5lDpon6EhdpNJKWjYB/Sdln/B9qF19BWS7d9o9ndETnrlVCvVlOTQifCZp8CUxcqUiZo0d4Q2hVUuvlYN9UKGHn9h7ppd4YCyG7HaHjPJwBwV4YvgxDaGsGk8QFg2AQPwwd/M1NL/8f2IqjG8lCtmI6jCADPC4CQPQZRIWQGIC1phMEfhjEf+Kcl/BEJU0HsVSoUtflvIJ+vNCIa7U3a9ByGFdWf1zPivd2/2jugi9oBPY8dECwWRMzRnNdF5RB3qP+eugV1x5VbrKoAj4RBvjwnQs2fexd2EIPTmV4sVkGo22IPqRjlg3LUK0cnrDu98wMLicpQiWnuizKgrfEWaxDxWQN1TGIbPbcPxTRLTRHB06yhJEijoEcSjUkCe37r0/pVrBKVqkzlqlCl0pHSWulY6dTeHI6HTimTq1irOFVJbA+6KFUGpWNVQnksF2s6WqpMlYGyJi1UpKILPONUZ0r+5e1vogvV/sr2Z6LOT7c/nQEkVllpT1AFkKJG5Kq0rCMLKgYYMJqqEogYxBcDGFpSpCqFUnmGrYWCaG0BHxRG26VwelRorlWBVaz5A4pYzVpaatrj+pXQnLYFfa6N/cX2l9hfan+Z/eX2V9hfib8sgd9FZfcnu43D/7v+9OPtjT3k9fjIwY70L80vs6Nfcc6RLss0NJE2R79ubj4cLXFL+NFxD489VQBPKt+9Ia5CtW++fn3gTAlv9RO22VcrtjdV025fpyQZkBWlcci3O9VXdnubvaaKtqtPHASPheZtbiva+YYJ3hqHD7R5LjZ5VsCD3wbHJjFiO4iJdhZZtbNIxAYWErSZS0PC7u8KNVtMfyrBt12ptRJr92mrq32kdsVSk7eXr+xB4joN8CKys9nannoeroITSM5wZkmCuVZJcWoLTrFkUAlTU63reg1nxPLz1g52kn1szroPJ+buOrCBHmv45MklNhwZKU5xT3MKdu/OprvNh9MppLCjHtQTrM1wd1r/FW2AXFeuVL2CFG1njDCFGkEp15VMUlJx0Ox+N/JBGz29p3sdeqc58Ixmc652NWG2Uk3QTrK9Ai9u3vVudaJtpXsoScNKQht1V1yW51DFc6jyyooldbaAfojNgrLnqztp8Hy69lPW7ny5EgYFCuzW9pV6RH9+RYbQGr9IFdYGw3OkUpxIEqXROOtYGaXhQen0opp05dUV1Zp65FJdqZ/UrdqAdQ+1eoT/Pd4eZ5jq+AF4gmnHU7qr8ZdewNpeRUG3UMwoUWsDWoinmqPHdhVUP9VX5PncQsI6RY/rVvDNCe1G58N3CInfaU9+zaVV6uCLp+AOYMYW/X52pXQWBBZy1GArqTgexxOnmU7rmrwtrD/sjUYKe4PuXUMX1tWpPs6gDUzY0b10248jumYDGUR7CjKgBB2cASphZc786ADeTmc/A7+F8yaIBvobQfCLWAdfyNQfvwPre3MDd9sc0TkhR5bd42ri+DBlKwDElwQP6q3zVTyuzfWHazgN7giO6bB3oVqX8uoPbz9dHlfb6B5aXNWyJqTzovLyR40O3N966U86Xp5yXss7vJHAmddklewRPruELmkygpGzrHgqG9k5jItkN021OStPtKZ+6p3BIGkH9xzVxubNHAj9unsSI2BlpGkeJ8k2Eu5VW+QIzOEuii29mjjFoqNgWrXBed+T0qDwQ5prSCjGCyU2rVBkJaYDaBhZj8ps4+Bq77e8DcpZbZB5n9KZT5qE3/2SoN+CmFoQi9060IL/63a2peEyPjEQ+RgpwoRPUu50r44M9K6oaLwzn1ANcejP6JEFPRGYaevVx8d0MPRdyGvM9I1IqRHpdiNsnzLP0BNksi2UkoHawNMWod4jkYNCy3q7caHH3M2Z1535B9Rks6L7fWZXdHQP/ZnPlvPNaQ8jmI6zbUC4PNkEQaD6enqHTeE81WVCOdKASlG7w3rDjECK2wHQwD8InR6xvDOSd9aVt4mSgt/Yici2Hk+6Aq69gPHAJupdfgINCKoNkvv0ZVk326/18ErveN9Asfm88tccAdIlUd3WTG7DokMGBdwnPK+Xvv3zefCNTnDZLFx7qnvrhsp3Q+W7oW0G8L1k4d05FPzRV4HQSTl1Ut7tpCQqs4FO2rTzvthPfJCWp84A7K3v9tTkj+8qPpprh/DfWG8x233TVVAvFdRLnmHZ/AKMzOaDmnmGOE4ap4GfjNm1ulkffXz32V7FvzsPo839JnNJZ6I5TmAeKadadd0/Hezj2ky6vo3WXU+mlCbtHdxvZ6LHGhEO3brSHBNgD/9HKL5zWOA+rG9xTvQ00lvXdfcMw69fPYBOMfSNoTqGuhajF8GXH7reS7bl8MetHKi89VhB4ujBtrd1IdAE/mWCeYz7fiJodct/iaqzzeaXhxZRxbrbqW48Vscjuylb7vDqB7jN8ggDAsfKK5l1uCem77fGJ7bpUp8DzPWyU+YHtXu2XhQBf+f1vM8BnKx6c8WMkC34LHnmlFV36fRVKumKSO7JxEsldRD0ODouRvBF8jEqBOIrIgEx6e/y3rSa3zmOcawTAUa14UMj0SiJhooIIqwzz7NcpJGps9YbTboqeQ3VrUqmwRwPfXtok5iB0TSbM4Es3cnAEBu/dyUWntimmyJbEEIITkQLh8L37h8+fTr62Fzfuh49+nRzhPnN9frq6PPtx9WnH8ROdmEgblXu2pPT2zjlLxxXVfBFGHcbYBYBJKvPr371imrN5xcXILWHNvObRafLU8qrAqkwsoFdgIlO5PHSf2nKUQ6P69XsUkW7eo3FXevFlymhuYVrbrHdXEAzdxKGVvM5eai29CXM8zfHxnsOgwvkcEOfP0BvLYz0hL6EXHm5oQnT2elkgwfnBSglqhYoEk0rmNoW8Sel66wmCPcG15x3DEQHX9W19ztCgyKsMfY8bEFqy7rHUagvoM/jOdlUS8m0VyDrfIi7WOZuWUceXUzoYkK3jSC/C4HWFkNOGPIAxeskuDntd+gfIQNS300YVsFO7yy/IS1TcgCMmGSpU2mTZheyvoYhOh2fwVAdXV1fhp9eh2CXxRCPMDYI1BkgZTtA9O4AgXv1rm6aH/71O2MEZdRH77/uZi1+s4uf7c0gZnlmFaaN8oQrRwQx1m3JFjXPFSYtFjwxfEHPBXSgqehD3KN66a5bU//Bieec+B9OrBtONT71G06sPOjXnHjCiWec+C0nrnzpNz711qfe+dQLTpxz4iUn3vtCk9cNhmlf4H/LekNRE/UIUh1P+yk8uo/O0Man842P14YptHXjpzho7/NwdhtyAQAF2PTn81kHhAeSBiiHJX0iUL/BFEparSwQ0YEolu4bAwhjSXGfZ5BA1QBhLMk2ojSWrKIokKXXKBTKDGN93l5CG98RjEo5YLU6gTNC19Yq6/T0GbgBT+b17FH3G/XT9vP0M/VsXhfq+0UCEOtvX10189mT6dsmuECjfl6/oGj9E/xgfF49C+E/BH760Q3i82DT9zSko/RfWKOnns/nPiZ6PtXw6viytlkVAuyXpmeL88H2TPrcvpzXT+x3hXOUFDGoLIP3KpUKpfLGSuUdSuXSCn6EcKiFoLvURNu+SmifzNnYgkFQvW+6kuhzAwr+P8jM++b0HDl+34TnlrnT30ynS/uBEqZu2VQdodv0Gr9dNWh0l32Thcs+6FhfoImpul41Z69BUA3QCE4wtcJUdb54CU15CfyoLV35dccVfd0oqHKOWgIF3TgH9ifvGzeDtrD3DR13XL9ugu+ifGlRviQf4RwS56fPwxfAEQrnRVBtIeg9dpC9UC+Auwq5q7At1QtMoS5Y7GbxsgpkVP0IxgvoQXX/BYGluEI5j66hF/sUD4Jv3zr3PoJ2ZwnMcjw4rI7PZ60aBjBU1nD/wLvrDdzJZ6sO6hmaP0m/6O9lj/CkS/nqu5TXRPl8GpszR0Drk9nmrsmf+FGen2CLobULDT1d/Md0+nyxboLqZf0MRl1cPQ1BFZ7Bf4tFXD2ZWuP9DAeln5Hqp1U7AdXPq3ZyqgHfWTqf/Uf4NDhJw9nT8D8CzqbCQOrMpPl8tm7C58EJJMPZ8xDp04RTP6lowqmf8XfF/rdHXocQtJ4bA6M/hQ8P2kRnnFMKL2qnFwaYu4foLak/kSw1Zr6EugGId0LPxIPLG8fKQ48sqKi985qebdZmK4ue2xgovWOQ/mFD/DdWk5IgfVtjA3ks5e1AlS+V8ceuOzVQchLpY4VFolOfr50faMNJrlD7isGAnQD8vP65k1097D6wKBwASONZxVzTUzaOsjmRXgNxgHsdosf9lYgGvaw/IrFhBfoz64/Q3aLpEzqaT68mzRvq99hJPx7b74R1v34nUokjlVCElN8u2jjHbUggbDUTOt1QF9FTuLESwW/h9Jpy6dyPZoT7IbzzASbyvc9mm7B2abXEFLrp4SY4WTI43NCNAFiHVLj3Lc85GG4dSBsDC5l31ZaVw29yVIyclGWwFYy7dG8KHe9iqZYQflO98Bt5LH0QeP47kT1hxn6E10nQLBWCIL5Bj3UazpLs39prUrlvm+/794y7Fz+cs1DCyhPs0cuQHq9akSK5t2E9IRy8/o/EcFtd0iMmbzsL/UZ9lOk2p//EPXerboPAr8Tprn84o4Dvif+OEDxgosK6FMTJq1LEbyYMzJ1E8lYi06kj2RON/OmGhDFNDF4tmpsyDQRmqG2j2CkcO8XJ43rn0qSKWaAyJZXpX4XULxNHJ/11Uv56JH+3x/A6qm82fjFBudC4/vr19kF3QTuEO8pT7+KYjNJQbP2g7t0VFQR+YSQMZ6njlftC2a4inHESv0oqHBvEBOVgCpfnQJKik7705pRLnjUD7xOb0JUITiBBwbgFV2JE815tKLhjOFzdEBJs9oJ+LeWK+GZxa3l5o8tvidPzSVT9FHa3BdyGXbl3luTO65/uGKCsz4cN1EkkjlVcmtq5ieqSZnX3fewsS05weXrrBJ9pUxCorGtWFJ34bJNmkF2hFfzJOq639Dmup0fT6eO6XZwHrXpcb9/x5ZdtPu4v23x0fdldGbrXgk0q0l3IyjB6kNcW+9WmcLXgJ+gTkNLumshVZ01ktX1114ogfhvHbK2O3cOx4usySC04m54wf8U2tYsD3Awq9/qHzee3x7tXv8F8SgW8th2rSajpyg2wase4QGDrxjOYaEF17b6wZPc+MqjiOaDi3fvIul00Q7i6DNzk7ftkG2X1Zl5vw6hOnzEy2e6VsUOz1SCvLG+Gu0xeIQ4aNLQymZrRwFt7MLv/e8bccu7v3jOm1uqaNOuDuqlgvHc+wVbNtKYEXQXkV9M283rVjXmtbcRLQVmjF3WDZiSs7VOgwFVtOOcD5HzwOc3XD4uFzhC5M+srJqAr+r507b5eXeO3ix2qLtJmSVQSce42oPQLygd69DUkhcdFfQ2vKNdhjQ/VTR0nObpvd9JRf0O5kwMq/x3nerf7BqamX5CqVB9cAt9nWet0ZjUEFERnf+/9/k+tGGloBJVprQzZF38X2UEGFq7d39eiTv4Yk2qvR7x/G9pFrP6OHw8wKfdGf/I3IiVB8UaOqe4Wte5OIdwidM0+1jG9cXUcqMuzlS90svbJb1UXH2yp/LgCd6qL1/vb14oWQ5yueSC1L/Ewmtc0Jqp13bghfV1/+BcPndezFcGDuQWFuroGYEM2gDJmq/aJi33gsbiGsbj2Y7EPnDiojnWU4EgEMGgWPXJhhvZH8/rrNcr1T+N72o2BY2+4VR/cVadr+LuqgtVUY+t+VzevPlwECmRTa1CSuee8b1+5m/xdqLE5vbaXoTZwVWa9mq3VGhK0y7mpX0VKl2VWpmVRJiouy7jUZV4UyqRZnpokB6g2SRYnOsatbEUWpXmmUwXl0szoDHf/ZmkelyaKIZmUJivM/3N3FkySIzkUDob+F9dB1xEZF1KCpLyZY75lZmhaGmb+7/spq3GZaaBsp5VK6b0nuexq8J7fN9yHRKt4da+qozbBa3d1D8OroRvWZpJyLTGVqqVFuIlLd1zV6L3ntx/3GaPZ6FHUY87qZla6xBQ1Y7TW6mJatRfWxC5MibW3Ooi3la7iI/jfMFU1d2uz5NkgYylk0d2dEEuvQ7USfH5bclWysWaltWGt9XBMTTMUG3ido0n1MTBlWEdTL3O6eJNpwBZpQTBlqw0nh9Eabh04I0ivqAh7oX1gnKG6sUQblYATHmwNWmrvrZCrTIBkluqUnAmyFjbUq1ipMUMgokYJwuqgDwacIwO8QYIM0eEDr6xuJEIOOducmQV624DCntmih9FxUoAgKB7UUQYFI17BkHg71HvDaw/wUnwXcp69WQNvc2XV6ZA84Bj3qYIGSxilCsCI62JoLT5HNCrR8YpYwLPiKjOmo3h6NdE+WRyd4qsbnJQG2GTZ0RNMioMLeqgNbaV/Zaizck4ikob8UqVB/i0TYErvSCaxEBJ3sCaqRBIV22YPW1/aJUCRznksjaqwRCD3QxsqRfmpHfQEF5XMJ7mQMdxDQtnqGCJSw21tIaxnQbCgL4gdSQMD5Ezy7qOxTVwTdqtDchB84ZLJqB80AtknAl0yBSBoUA22DKIU/DtH6HQE/4inoE1AQzsp02pAXxumlOqkvIAIyui006TMoJNDBLF6d5EMq6D9KQ2vxAreBBFKigyZdJjAlsQV1YMsuhGfWdWabZfI0Wb4tBzE7cRjb8gnwwJcjWGYkiScm6PdEcSWwcaoMGZtaXdB2CfBdhhsk6qnCiEZgQAGhUz8DDZkDM0KdWjF6F+sWLBUYmgjlSN0ogl1GcWoFeuUKV2BM724wHO4Z6zMx+kQvMJsyq9iSkdiPfHiqVwNx5VQURBCnQIuhFTaKVU/qbQJ6ynUyWodh8VqA0NEgEKc6iJfFIltSjZ12hk1BdhQSIA5LDvSIQj8M8j6q4x6TNxGiqASIMszKOg2+QIWgkINq0GBxcxSaigj3XtvmE6YS/1n8WBWaZK4AlgcIIIhpAKfZE2JCILNDpsIUB8Zqg4gmaCAngwsCQM940cczhlENUrYVsg5056VBYLhVCJeIRPCs++SUgorw0p23cECWHwqXGTUlZqgvdAfU3aTOgiUl2I1XJRJ2pReqykRlGu5QEt60H4MTDlpoImGsuvWAEkErcgigk5ARN070Wd/Qpw+8F0AjSGUwizWpAAUtpyiputKy2QSb9AtwbQ6SbdsKeXbWNzQLgiRQpLUlOptPfk2pI1bQQTJkgwWxLRm62Wh0hgGw6yIQZ+yyhkEnSIjCIABS9wNXFXSc+bhiw3g0XdQ6QB1BIZXGl9SNIkFCjFEiIVre8qNDJLDVgV4kR4VD16QRDkNAJPVTY1rLtjCEkWOOAJLRf2+mjXaHHnxVCyVSoB66hiGMMAngIGB0axTwk7nmwQtBEBRV3ZZPdVeU6StOkGkygmYPpfECXLIrpL+ETy8a4qUkLkmZkwj55gSqdMPmMcCA+XSVbKtK1wlh1pIdFEEgFm2ARbC6GoUA6grbGZRESvSBQbQCrxqvkGgs216knJIrEKxUAbOfLSQFZXEkyekOf2PCkzQJGFFVFQd/S9pEkkQSkJFIRsp5OUNSdNglyxoKsJ8rnpkW1P8Fa7RPr64GHv2fVSWcsMklK7HfMZICIMIMMCkoGIW+FeKtEMQiSEsigBe0CpeE0EJFqChIzAqMFtpQ4d4IQDghUIksLnYZIcopoMV6QGYYkgus2E62MfhEink0YtmsdX+e0vhyWRVo30Qc3eyyLYP5pqSsALEswZNBdPKtTGwwZSogMsGphhmfaRyqSvs/Z0Lpz9149wHA4V7lPVBxefvf/YZP34UsL/DO+zNJ9brR2S9+6czdzLBowTee/OmmxP7Zx9+5FvpnfXdzO+uH2pV9v609Y2sfstGPHJZP1QA3HnY8U2mnDwhuLTzZP9Pe++eYv/k5Mbmu1D1Fgu987kEfrQzWz/aQp+H9PN23xDH00L5wnv7wzMP5Mr1cmVzf3/m4duF60e/Rb5Vvg3x7P5b8s6fTt/lrHvOS3+6+SfNu85LFy7B+RXuWv90s9y8eJHR/d/jfofNlXJ9fcvs0cDVdY/LB3cc7u5wnDe5R1++dnXzcdRm0lnTK6emTzYgyO+wPnk+9+7h5m5+K1P725XbLzF+/e8fX13b/9z5+ODWn97afvuOyN7IV7V8/WDvRm7C83V/bw3N/y+r/rc1tvsoxv3N+HZZ86et83VN1NeX1QeXbj69jpeLqfm6q+++8Id1OJdNP5q/68vd5tXWqfUaR2ab8f+smS1fDw/Wa12vK3ipb99crjapHBx73l2vs7+4THVnc/jP5f3gmbdXcLq/PPhKYu6/tP1OOYPWq7s3/wdSj/SP/ONpwfY/PqXtervTxpn9+3wKlnNuDmxckpD02TZZtocGsuVuE3gC3T73pLl7jBHBG2NT2YTQDd/9/kZjYQkr231zX7RYM6PR/NNobEvOUkoc4q1cdd8/VQZ+mq4SOUGfpsJei1UJc3J2e+xVr/zYvxf+OMTGwXXlUvjwkqgMRSRUHILuVNFdhnK+8oH6mAR+VPm0wGtKUfX+OjqrdsLUH0cC2h2fVbsxX2Pgqh6sMsDrR/ADeHPn7b22GTKryr+XfhROQyGZaTta+euUWEL4R4KC4Y2gpUMz+tfZ7alXHSQrIaFX8AA9qncb0OUmwaiPYQolsNhABJEi7eFI5m9iXel1KrVBr1MnA32HFoSDIRGeMOFvvUrnelgZLqfT8InMw+ZP4ml4v5Q+GQ3mkxC5cvnvzjUolL6QfZ5ATZswt1aldnNx+WudNe9Pp1Abv3GuJDpDole9GO/oI6K+wMMumCqA2VLNwtX3J9X3UwpROvQ0zOy6K8p3XNlBQMDfYPoG+v4N0/ZkEuaBc3ykxh/2Px72Ot2byg0OQksOq52xERTH7LMPSZrR1wOoO3umk8z9MK5c50CO2s6HiwEkPjYlbhYSQ8zjUx5cBBTPu8FWG15+/lR36lxweK3G7436NC75YSdMrrCEIjqumA+6ZkIuZJgKxWk4h7Mq75dhGos0VQx/KodaHimwmiQqEMG+TYNIUwwSmVWul/OxkBhzOOjXifit4jjMYMagMvj9FPNAwlAQhHg1jxT6949tCsNmPivawyG4RWGA6Y59YYRpsqaDx39R64Qtp2bAYQdOI8dOVDSzplsYKwpCtljzlJ2zhgchD6bJ9/MEJYSmOUMQVelDliwqtd9+v6pXoNv3+jfZN/1F9gqBoiIT4ZVSNgTMHdvgjYh5/ZoSTaSY/GQyyUXpjbac2GLfEeQNp9RupXDfBz/KKm0E/WOuxRC6qY7QTGaq21udiZECKyrDV/x44pqf7WWWzLeW5x7E4gSePoHPlosFxQn2U8axiCq9CUTnpAoa8n+ZBuYOZMh2AhGHAgVdGAgIHiTLWAce4U8ID6VlglQ0V5ZBlg8wFQh7CjGK3qP1QkFfmzzZNhM4yZRus/H2jOXtQgr3viKfPnXmN6aoK4i7+jwpcgoWmYsZvvd0QdK2jrbAD8LHSO/XmdjFsEYKMPf/TOTvmDIYCQwBCOMCAIr8K1ZBvkPsRjFIKTKWczEBhQF3y4Ga5m5bAW3MhbwD/MTUlPUMoKeHcsrYoHeEJIQirdCd30cQ9aSCmHXWUnW/1XIibid3KNgMbgeTA/6CGsq1AoyvOZTtewOrDmcIov/AMSxU2dxlwjcgtK1P+F6ssHvNI6B3fGHeqTRPgS9cU8a/Bp49ZY/bhIC+OVSTBHF50iQ6aZpEL6t/QuqbXiafTNQ3oCcH+P9nSJnv92bPCopg0chg3GICmCNP6kCzHib04JTggVsMoN8QevZ3DoCDj4goLhkfmCZhIF9I2UwpQsIi/L0HKwonB81T0L9GB6UqoqWWi7vfrCOkHsx4U8nFn4MlW7EDe9YecH+QG0O29mANSXsml5EIJ6bAD7j/AQpkJfhBUx+4L7o+P6OZk+f3JqV6+bYgv7vNaWkayNxFu8Oc1j2pPNX6Z6xw34UOEyj9TzscowOuo6VoPRhWjg/eePh3oAWre8dQTomyv49LDX+nO+e/5oQ4wsGuolOz3MnUNgd56HRSdDp1d0LY2F1Oiy4a3LpHlhkl2ORfk1CqORNPGkUfDtszgq2xwObNmkRU4J3zm4PTH6/8bIaQShBeW9ccnNQPT+sbs1sKyWu2nQmD0J8vUJIY85JHAGRyQDOTnmAgLxbo3MjbO3MrQ3fjUoZG/+NfxjpJQuvi+hdHti2NQI9Ptsk7wGTz/BeydMH4FUIFaw0o/QPlNGVczN5Sfq6Xacr5uSCEMw2yIjsz1nVKY2ylaW9sZWXX6Co9EGKvPFxh/5I4rhztYO/M0nX16X0/Z612cvBnsRAVKhr8+tYDgpbPrTS60KhWvbi1hd6Kux3x4p0cXi/hldq74KMyoKTScRnUPN3td3AwwYz55/Oh0PeB9DV66lwMjRctA45nRN68teBZe754KRMujMS2KDLh+dHPizwp7J3+oi9rYOjLVECP2lylNQPjCrY5skXTpjLMQtgTCwvGBa5+fmohkYWalI5qRXaaN9IFnn3Uqq+q9cafSRjXcEKj7gRiOTqwRi80d6BgCAd8nkdkCXHE/gF0fn70wzbv/tfpeV1uYxdRLDdE9mJ0oysiz1iPETRWEYlAOjBzTXl9NulBDbW3U2b78HJrlM353najy8uxxwV83nm8tdovwfby3fFZAf/ZgL8Cgm0JavwCtIWAjiEgMv7Wwd+rh/xdpF6EvE91+s/bKs3H09HAfTrNrDdhjIPjn9QXFBxbfkol0P+bDM2TtztC7BHXFOdu2mmLf56fdxYv506q2H8M7/0skThGcng17HUrt8ev3t59aRw2Mjx3q23xjSVusdv3AklW36wgByfBcg5QI1C3bl2+Obwe1qqzLFucHR6uVqvG6qSRyPvD47dv3x4+zbJ5hAeifpUSWxVHUeIo8SfVEDpgoTvMl5Mvh7dfJl8adweNH4f+FM7+G2k8AUFWYvwQZjfi6xJkl1g8h+s0E3PO5bvQ52cc26G4+1bu8GAdj4DhcRiiN8cSFEI/9KL2KJwLOpphbh/LZjJZ4en8xjuqbzyJJXthcsotZnQovw/z32G4TzcfMUquDzfq0OAxeRD98Z8iIBj4nfkAzpNHUaO5SOGBcBHvglr9rBCwFnivj0iceWn34BjlB84+x3igg+gobimL+5bJq1fbexf/tornBAdj3D6q08+uD/CLeibXf6EWxQMwjBI8PyNxgD0+EXhf/+sB/21QYd07Tp8c/u+X9MfauzP67vKXwy/DH5/9BfIw+qpIeJpHzwACg/8O0KqD/LzxI80I6IpGC/+W2fTVm8OQw8RXub/+jr6M/z5KxjV6tzAV9JjUv/P+IuQZ02xgyY33tZDqwYs8fDlv9vyMe5p7dddCNviqDuucz1oPqpuCPbZ+OPZW3qW3Nv06r331bqsrGZIkeNaDYMc5nHv1oM9juP4VMZ7Iwz1dsz/Me4nTm/v7xnT9YWtlitQbVc/pgmUPShpgOm+rphSYF2yLv6oDOXBi8vyyESVs4MZMiilmIh0Q9LPMD2Y0hQ+n4AiPN1I4Qqhp4Eu48vDWO787hFG+gpM/WasHda2vjU7/unu+pmD0FaKdUsajWH0o0eIY3Gj7FbJH5J1VfdV6KfQ5sRShD3aX73alX53xB55aCN9kIeLayqv+MY78+KFaV7YE950eL2pwvqitEKreheuclO0nkwNcxDyKv4RAUbzOD1LJe5UnU+Lcaf3FWp39cOSJpwCn2MJHNI433jeXrc4jBGNkJEt1G+zDaHv/3GpekCuOC82oFXlGstgJFr9FgXWVINF2HyF6rRogFB4wOBiE6YJmtkJAktxubqNu6vyyWCep/f0ZgtuY4odJkOF8Px9ao1gHvvYNM41iDzn3IVduSE0k6G+cYx68Iw809Emtl7nVPcxSFFkYtbAfhogwRITyqWEb9WVGLYiFdaN+iWeF8Tsq2PKxY/hg1L0a9G/aN//jSe+iZsYNZkOSZI17kXXUW5BErmtVrM+Y1F5nh5anqOEGn/rR1K5FJWI/9/FnSiSyZiDHyO7IATrDtPZMzO7MoXO3FCDu6YBcZqQqb0xO9jHHiT8fQywFzbihEEgDuH/GrMAI7ff9mxEdQ93f71KG+H529McJUHcNLEtdJCRL8TGvRf5d66u+2tQhkerL2UZ1N0UbM8it5WYX+PmmN+pd/7qpe906/3duemI7eY83ZWfzmgx5auhaQpNJWmSS6/7oj8v+p+sOmeUdiM+61KFejMmQjbeCQNtznBSi5rJQruL297eXOME/RKD1ZR8ZkVbB+m4S8709VQwEyC9+6x4ybgvKl7mgF/6ESzGZYJ1V2eKU9UyrUlvHFF1rH1Nvk26lMl7rCNDcDa1jXFPPVhMXHHUrxF8RQ6qpo6jAqSuMkhPs9ERA87nnslHMuxbKgV9zGOoXt/VTEU339+l/GMZFoL8HwL/Pz8oa9JEpQY8s9px91K0Q0hb/4nsqC2iSvrObDaviP3MyYkjxhwTMZt5q+HMsknxdw3OpwpHaDjzAJt/A8Zg/iq8eNX5qYOfEUkYAp+rtxTyDU3D+fpWqX/77O+0o+pzOffRoX43+oA3ZTxdSqIcofnRBhnjKKhr1n4FMqPxQAH6JhqmXCUkhEqZZGKSMovKf3tqLOBAX/oK3M4TCge1hBDn1A8Ev9MoE+jVVCfGZ1rlJcv8ypq1MxfjIl/ML+sio5tcbDA1oPwjUhg09UErLL90w201bmuUkzD6yANxgHW6WkSbIZokMv6msbvZ8nySZZRYNHIosC+N7qtAUjG7XI/HERu7GmVy/91PBqJuP/CvXiwwzzF/MwqDEtNu+cLuzG08WSRhn7SAQaUoYmURaRiZ4DGUSU23UERlvE3A5y0W3q0Y3mwkZC9hHahVZPCpTyIRKtQLCm2CkIQ7Dh8sxvRwdC6lgLrMwrBfzTWNHTEWcmuL+KmIh/ciSQsPMLiVLfphImgLMnyFiKVXQ02YXkTHGZSInoSWBm8KeVC7OvQE/Qk4NsX4Tcixkku46gY06N+YJv1UftgeMF2kKAniDm4MhvbqnzR9635CCX4sM1w88oAkh53b4sy9O49uULxrbQejkNbjodQSFB7e6I5sJw1jKy0SOUOeLzAJrDzDQ2ARibJ/54Kczxi/HGBnbjwykjSjMawvipjFDm9EDGT6CKagGfsiGNTbomPTstnzi2mPZSNfMtynYnm0qrUU6SuBzN4nOaTbKFEo9XmvHE2uThEVwfTVwTWJVXYykH6chdUF/3rDESLfzXfCeNZpFUEaoTWrDYCbmDB3NQjkZ+DJb03QZZomEn9qTeRiHaWbr8iK5RRDOxXAd021V7Mj/o49Dh28YMaCSMkginaBfgl8kUcSxoSl2JzyMuuC4v0ysXErzuheHGDwT5LC4HGOfxfhTzwKElyFNR6d/L3pXf7THZKkg68F/AWPZ0Qu6ZhLevWJeu2eNm8IajZH9PM8zjPzF29O4HQlpiMOwNA3vYzHh10TZWgOTQBlDxYV7RFrMAdK62Ri9zNuI973+MH/wum3rHZ07bYM0ZVyS5LbWaUpDrRHsmqGAJUsZCLOnZV4GyAlfzHwYJQfOwgVfFNHFzfkiiVkPbi0zIdn2DlC++zPHxIEUmbBZaGhHLEQMXwRrDc4kDS3zZhKRamKrcDFtzKYxi2yo25U7gzJ7LIO9+YJdUMRLN3IGp4aThxI5T0eJrowN5MckKDGynGWAk2lG+yGtsNQ4XQb4UdGNN7lhrSZwTujGuMS3CjIFuPRZTF4Zbe/bQNfEpl2iYqLXizDODKhlbA00vWHp3Ot2u3wTYohsY3ITMtSY3nbTGkHv1HWaGVsPzYW2PVBQ7NHUmZbbcAGViR2RYnQ9ohP+eajDTvfVgcANnpC66uUGu8sIdNuBJoh9ZrdtazGOhUj5LZcCMmRizyENNUbSIJ7MFoLetrCftawKSvsT+lMzbBicsH5GbUlNs7yz2g5NLNxLa09fTgSUslNMf0XFXCGTqQfj/jsZG0CqKHfyz2C2TsnENmMNtfraMMvjGndJW4EtCFvIApmpkwsb45JvaA0AV0s2rGeuiUb1ZjcdVEOR2a1tXWhpqrEWB3vhLHvx5YWVUbQLNmJVqRAOI3Ev7NbLzG0axwAyoYC1U4WGJlK3rOqKgbwzVte5th1uhB+F33IJeJJdJpIjXAN0y1HIM3gq1DOHiV49GHpPOUVaUKvubtMn6CjNWxIxiZ3bGMTzTDd1oWqka0Ymaii+oPvpiauwsSledArTfAznYSYmo4TLUAVHgt3KD4OZCqjDARBdD8WwWPvIBFs6vF/rrO1QzQRPpyLIUntIxjgtqrHgbqxiJoJ/Skh7jecN+TtZVy9FejgTpmtEB0w3rVrRuay5yob8TqX7lOkheQobl1SIGk078zHMyPxmuacrzU+p6E915POjON0IL0NjgpkARwCZSGvN17ciVsPq3hsM+W7AvK3nKalwF1EIldxIVaGo4Fa3tDroNKY30LIwaDQagM+TjlkbaMYhIeAgORQpjfkpBQ8SnBE46kENi7ddmBhRxdjHuZMVH0J4Qbf+IuvFpqgmnXqEaRCbuCKfEebGT51jDwMpROxapg30riJDEfT6FpmTdRK54P/X3t/3N5ErecP4/3kVjeY6iXutGNt5ANzp5IYAZ9gzDAxhzpy92Hzm00+EnCS213YGWMjvtf/qq5K6pW617QRmd+/7uvbsELdUei6VSqV64Juxb6yMek+NFFgYDbJAhJJeSTO+9pJ8PN5QgnCiuIQwyaXM2HLv7+fFx5iCFk2SnOr9kZRjYnGQn/8RzBefL4sYl43t5JIuk6OsgGQumiY5ILfJnmQ07E8/HeqivV4P5Q4FJPBGPt+3PqhZ/iarqPniNXWGPz/S0l9izO/hvjxnMxzzd64xJf6C8ApoZzSQ8w+Tj+9J8Wc+uscfV3gkxmM2PrIkx89LEGXFi7zhxzI5nqjH5DeThXk9o2ddhPqmw2f2ngnPPBaOjD1QsvN5YITgrhFceR2kAeBptZGwzWaL9eSfJy+ukjNPBW/pJpgmVA9f814W4+u5sUwyf59PsirxxThNxrn52n5JUslz84WBAifK3HLbGXk0/7DvOXOlyYEHtxnZEM1yRW/p8hcoU7oX7KCVjDEnF9vU9ytqmwBhkbZNopSTc8rTjGzZluJ7NMPpfGw/zv9IwBUE9qEfnKArKFr92n6Wn2N2NV0PHKlX8FZjdPlj+xmZGqiRbz++tJKff3Izfj15wlZPWufrt2Q2Rru/aYQM1IvRE1KrIkGSs7E2cOpcz0lRDlbDT8tthkd1oSVNvCXoW7XBP49LsFPJU87uvOcASc/H9ONS5fP+jvtlglFs5C2jppE41EsI4Gb8wnWh5eH89Z4lwkAVKAkt5GIoSVlpmswZwFKfxBMmNV+q6JQqdcTK6POXWI+3yRlsITtCeVYWrLGl3BBX+oPkMz9M3y1Oe+fQeOG3xnc64TTGjzAyL3VU+a+zSxrWvBNGZZOTMXQ8XBW4D8SbWvsBD/ilEiM0is3TXpjGfm3AjpiwnVkoU46tb4rAiWRKnYvFbydPtkXXTv+ls/Mo7BGxg3qapkYxG4iRmqU5sTpWCpBYb7WOwA9BlQx3wrAsT+NTcmAYwdHFM56MNbyVGv3yrCOyQV9IqI3QFF+ChGjUx5q8INzviBp9FGFI+s6dOtX815NXP/eU4nNnQd1QCkGmSYbB9JszYfXwzF7qCPwSYVW2OTQD64yts/so1JYapuSzq+vLRNGed2VlV71G7ikKPzCF34njN92fngsp6J9Tu+D7Tz/RI/ITWOKc8lzuqqmk4mI62BFqTZkAapkGTSbN7URZe38gu0mVKe8NVha5LIhO3qoMbDBNXyFvKpjw/5iM4WwR5cu9sLSbG26b/jLNfq5dBv00AN5u8jD3bz+b+3eYzf0ls5nRefx7Wxd5F4akYgTFka9ff/k7ocMDoXLPJp1BH1A/diojYFuiRQiJq+IfoqsZGKWgpekXxa5AsNFOFpsE6AOHX79SivgXQRs3LXNAdJGTqtDwrKXUjwZxCbC4nCuNeerNhmbLMs0YxF/Q0MhuVTZT0PYok2holEqqbpTIDyNlzzSjCZlcgWh2XHbQVOCkopsumBjTvYi6zX/j2Mnd3MSMVklPrheLyZjnV2SXk7mnROcXTwmzrcUxCkHFL1bqJc9JXw/XkU5tWnjY9UQaOLX7L9RmPQcTRKox4l4jB3N2pDvTyXS9PSiPS18l0lfe25FRx3xeIhr0uxrMqbxWNuqGAwRed4izMPnHukvqNG+MPtQRf8wi6gEcQSGKLfdNvZ1whETzCXJ/PU9/hwLlZfLZWAtQKgwCXMvehslNaLILbzYpZ8N8YOuAj9tAL+lWN+8KOlyL7pY43Or6ir0rYJKIrSjywT7HT88ctuCi+Hw9jT9gd+Pt+NdpLRPaYFX2U/qqAUyhm1VBvMZnxCwKAdAXYqHoKw7/oTlhHg0XHFjN47h8Ai2aOW2nin9qpZNQdyypGX2AfLDSE9uOqddgEo0p00o3SZnfGQM1o7uvUCHxQpLdUw8qDETpflIsdkInPkcWp7qtq1746xTo8HaiGYpOS20yCaug1P1aHUhMeiQLmv92vvjQEb0rbcwviH7UMlJMGNiTLL5ioN+JU1A/oC8e1av653wyblSTzf9ADY4x5GRsbx3U1UlVvIhBf+h0d3PTqYvYbOhkg3LPU/RFIyNqCCNeH606RlCtw9xoGSdX7RmptfwmWElc05zPteZ8nNFPVmKnjiWzz2yR07ZW0Au08LFJAzBBJXuPNv/x8qcficJp45MoNe262uXDfh9m5HN11yGr3H7/0HxplLT5yxSa/VO4rXhLLLYabWaU/OgHWHWOi0YagcpnVPilftYBOHKp5mlJkhLQnHLmsnfJaZQrck0TrkPuFDnuOpRKpxj9GzsHYChz0GVk4W/cD6XdFJua5URYfXRZh/DMmCcgFeazjnienMMrzmISQOY7Z38ppsoAdYo2TeW71QO7AvHXZ2+FrJF9uQH+ltaGMLITWh6giaUaq5tdtmMOWEXIAhIjQtohIotxzjgNaphwuhM0syroE9xxqmsNPh2aaBFqbft179On/DyhAUNYEPrJyu4e6CAR62MVDItYvuoUi3b3nUzupH2s7TulmaZmi9kl9WJzk+/RdL+zSwx2nBJ96o7JfXM9hiyAty8hf/1YLkDTPecy0P6hU+s96yputg2xQKYMPzobBihqzYkzx5wy02cDggq5BZ7TGtBaDB84vei0VyyE9NWgouwPdmuklGasWvRkoVaS6t7fCc0W1Ere0UZJ7kjK9maR6WsnSEIjsTcn0b6uN2zNIUR08UpWGUD9vxXF9PHluVJ/V9tVqw63FOcB7jQHaGG5FdPK2g642f7oVuXDfXAhfuz/tpn9UycWnf6mqUUF3z65bmVRGxeyY+81l09SBwcfGhaZDxtbNo7tfDpWeh+OqlPLkc9qZjwcbWTNQhjwbt/uTtmBNO5LpxOgTUd0HxxKXwONqsNwtE63YWUWD0KHGXAZXj820szes2f261eLZH39ao/p69clhKQ1x+/NoZwnP/mJ/gdvkvk37ZD599oeXBNbXmtWAJPHG8BKINltXeirc5WDXB33A25yzybKIQDBztUjFvGFn4mnipzao1rVF7Ys4+KPq81NyFZ2eQWdHFT89aubhiZCLqCm9O3k7IyezAmy4wG0myIWipvaCSNj7KHEtyf4CcllqQRQjTOMjIEIXEp4IHVNFRwxcFqJopJtugkgNdjN0XDvMI1SkoJDLHI2Ed1UiUL46yGLIfmDJIRW1mBo5w37+uvHDnmRFkL92uNf1tua+7LmvKtt9FXvP8/V8wLyiF3CY9CV+rhkjapCC/fj6qEHXA2p6sRszRqZp4a6IQdj06dPWj31eUFPkDFZ10dmacYTsu0jigNOvPleAYt23LCJOHTQX5WtEF4Onu2Garw7Q/tNkpP23aT62yF1yDzdmAGg1AMzhTs7bvmy/+oNHa8btXFB9+UKr1/wnYUKHroVKCbwinW+9JwAatc0COfvbo/1K2IJu1/C7u/VO2e/NFYFnDlgHBmoOuDbjvlwKqu0l7BQnz5pAwcYN9CXV2+eBOYXyHQVps9nCaXhD98mAaGtYArHDMat1urrg0Zf9x/VR+m85XFRJzEr0LsiZ30sLAT1Ezc0qkOXAubglYty6hYl8TuyCPtyc+rJYlRUj+JtuWz6hZrRdXfx8bSw94j38DMWNP/2VJTfoGR0vs05xaJifxClByUDS/6MDi7kS+cEg7mwuVmxKgFQkKempElP8OqP58yOEPKd8KnHCCn+ZZXJgjiVUyZlPOX6JVRRouFD1ff3fB9miYZzySuluBAu8Lmqu11udRolLqGzcrvXAcpj1H3NtM+gzc3aseDgOrfr0hhfww2IUFpJTtOo2UYt5FXSwN+5YQ4RzfdDFmJTGnNVSvDdYQI+MFTbCJRaTxU+tcvsY4hKLunC+st1MaOd3CHyGpbZuqflBT+yjR0jfYE3wFG9qU5f1h9ANtZ6AbFkC406ldHqLyedYUghfnNyajfo9/8lvZ91xV9EBB5yc1OfCTxd8w7wnDOs+ekfVOeaupJ37JNtc383PHJSvsZEQ8tDhKlEJ5RzW6eBNzcTJgXbVHugIsgwelz0yXlgzPTy6uUn17qXeSkJJqdA/VDuOZ1WZ5pNvXXlFpGkpDAcNUY3CI/w15zHHR/IPsMYFQ4fzA48MOGX0Vqh1jSX6ArXpE8CJ1uEIHE/Kld/QXoqhCPX6rUetwqiF4Nd2bijRUjfo/RhLZ1vauZRidBmQARQP0pE23w/Qlmmj/Z9RR/t4QhNbW7aWcRsOJCAOKJ9M+IikivMQtk/jOk1kDZAGtoEzXcP0VJTN4uvNa6wXWYcp61x4wRTd/wPegBxLmwZXdikEDE6gn66eeYsoNvXQSMPQk+37R69YxSfXr2n8XhL8NOAt4Q7A47I7UttbvNd1KMve/nuIjmblx/ok5M71caUlZAp38UDmgUkEvBdQjIJN/orR+oVaHeulWSFFO57Uv/w6TmxW4vgfvAzYc/Bfc49dKEGFRSpzrUADQ+NEenyynYsOKc6EY7+zN6KUFZV93SFUBZ6Wi5LhxhI8uJdKpIJuWMbz1vraQ6pm7D28siV4e1RL7BSreuEFrH3SU/1xrg3aEX8fitaK0kFyL+/YEupOCVGSZz8q28rhRWQhc4NIbFH+sHDAC1s6c1gyTBSfjao5fOxpiW0FZBLa3GVLYGO3EUdwJ05H+Jl57GytfE8+0Tols4ONajomuq6ohzCEbymjP606ueo3xF/NiphzqD1GYcWTzNxzgSBhfMIvYA6vkOLUekTnVGfDuzVMKppn7pdF60+nerqHOj5VHmb+iRJjAaPE86zeeNdqJFIVyJ6zJnbbzD03OYUaVBVIiAU2ZAUH4qEX3sCeiC7GJMvN/Cul8Q0nUUwTbWnPJS1BeVQG6ahAC1hQWuNv7pwiH0jFwd5/fnN/0a3s2touA3Pj7fR6omzJwjPWktnqDZUus7DE0xzsKjIHY+nFXewLKBKQY6U9HJnh6YWKe77eylYdp9rs8azaeJ9lk6kqdt9rKdXvcz/zGvAnI3VrJmlWnovqQdX95BvPqF/yeNyheejd6f0rkiDXSizFe2Zzei5UgiZcemFFD85g39HyiE+2sWJpMPLKlG3jh0UpxRW1pSQIizD9xg6MAP0RSgUkgO/OdBDHF+8m8E3dkJ/YoFpoiWxoMiEYLcOBebDhdL32DoglNK0XgP6MMUg0CHdmUTB9g9QpqTenek7pJ+qmtQ4pooD+/p1yqvIQak4kcD5R6wzpckF70O5/MOwPlU22CXK5h+xgI6xyWLtMPU3HuAVu1xAPlemoSy63Zsbmt6CAHMalNYOgj/E3Hmjd5fauEe8Cr9AHk3E0Ko8/FLt8ixa/VRvFWV0WH6sj0/rD/Sylm+96ftpr0tn9Ji1OC6dfOowncCGFcANGgrdAia4BM1m19OF+8YeYM/1gl+VXTEe40ExeiK8WbL/+Gzz7vkMOjQZKTVh75/nn35H9Vhb8yZiE2LkGecjTOo4fgmRQqXAurcrpOGn1aR02iq1umvPDrrVrPJe3w/eclDV6PBDKWAm0KTDXJNDh2VbZ+xZaJYrmUzSChwXDpflXLfSUEs8Ur5W2V8aidw0Fmxczc8idivVgV7NMIVzMbVb+Jn9/P3nzhd6DyKtaX23H+m/sqKh6Y3aw1IEgYCfVLrAEgNx/9/H98+kpqGhxE5qrDrU68cZ3BoV7J3XijYCj7Ekyu4IlT/BRSBO9E6BH/V5h+QAsqC0aXqRvx/CCUcnkznCTD9DfFQpKJQUOWsGidHbjCTaeUf9nE4+QphOV+5tZwf+i5M7DKE4y2cSJYTaEyc7Cdca9sfn0w8FmaV2RFLMtyke8PZZdiVkURUU5PsaneDe8j6mkQpyl/pQSM7tJu/Ee7xviVOGN17gvlwl9FIxEjsU9nN2/XGaTQjq7e7s0UcKGL3oF7vXZ0KatRkQll0uRnmj7fM/RmNJt9WRcqIHa096teqEDTjlgbS4cZfoaXGLJeqAQygzUorVhQMn7D1Rv4j8ooc8aPYafP6HHK8uRX03hS60+p/M11h7e6VoHP61as4X3sh682qmrCh6ZgEvuD+8jO4CcpKN6P7rpt7aFKnkF+cGXWrC/B3JuboXE61KQ50COYGQ+DzBpxE8iPCdSEmEeKbwfJtsnCczcRr3D+qyCXPjEh8/wNfjSPx0fvZh8W/F5eXko4jSo5I8thYNRx1uG0f5irZdkUfJVJCS8r24nuvvkuS2DP1vaUv8r//1aq7esUTcqPjrV/f0qEtnSGgkUMxNbu2PmaAN7wzxAG85djAuf8YQQueE8UhDvrTh31FTOfBLTaVeonsjZZdY/PrmRWlD7AjKQlbX90Ihx4aERM0PiRwNxcr+NIlgCbzgajxGnFayBsosoC5O+svwJhz9zx6pF8pFjrBtKppoIjfapuGW19asZrn5+5+v/n3X22ezbu8dFGq77SrGHjE5rDKbGkWuHtbdxDKpUqKuZYSRKyj++pVNPdSN6v9Kja3qI1dSXzS2RabW/oj/jARK8MZbUgL5Rxv8Vxdxd7W/GGDCqCHGznCd7XbsFRyO+mFkJ5REbFm/2ICH/6BbowZ18BbjFvgPikmXUqzZWBg1hPHYFAG7jhDygbQ3p7VvcLlJIDgNIz93FCkizsyFEcj79yDqYr4UKvu0d8oN9Ub5gqZLambJPJJv2JYZBCnNbZkAjbwTZuMh4IA7fjjkVHBAGsCtPEii4WEdteh5WK0qyq8+OBK1lj7YJisxMjUTki4t6KJtiBFBeNM8ddY6c6KNNiGzcxo5Sw6y7JGep99Xep62S8+j7yM9n4yfV6qoGJSlmeq89Piq/wLNhr4UQl0dHkm8RzUHh8yG4qrs3/PDgvl1hsaMZHsBvuW0PqnLbM03MMtdAGbdW123K51ijqiDhIikmcgW0f3W/mIyHsh2S4gwyvrmJfKgBeZoQ0WbhWF+oJPESBCM/oIvBLQzGLT34qTzkKQpuHbE/mU76pNYoE/+R0Rk53I0MtuXuuFGEj7zEs9j+CjxvKnLPE65SOorknqKlMGQDhEsKjvQAaKYcYmb71t932bzbFEbCsyYRqp3QpxKCOL9KFS+sbkoobmoHMSYcELpWpTaAJwamjdL832TNuZ1Iy1dsyfuLKgAD1YILjcXR54luEveQSJH91dxq0HIAi+2YxRzh9MZ65+alcj5oC94OMJwZCIc5Vokr7OezbNkWkC1r+Oh6QwMTw4avE9Vg6gfiZ8nm+N0Po2MVy9CdeLGBC/ShfeAMEwR8Ip2M8ySze+OtwTnhlznTDvoOc9jpVZC1XUFUco8vWTnGQ5/rvPDQyFn8ayrih4eLCDl1i5+tj4U2Gej4e70U6RUt0a0fhmRzv5fwuiKHgzOx6MdyqPxERaM4KmKao/SCdwRjqDCsxVkJByYT5OMqEDcV1/sJ4i+hNyY4iXRRMjJXVrWmfKMGucoP/hNrcw4RChNgd+U9W6RB2uVlDQeu/S29Vur+6+qIGwWCV6RLueKcjt2OeMVY0WZXSoT6im7V58yXRdTWaapZXVI46TGxFnVOceCqY6LBa+uF1QTEekfjMEuvCqZA4+BGKbj1u1b3Q1TOZARdXqRU6iwhCLIruIt0Z3qR8evIuyKLcFZxjPMlnvx1oMMTE1balu8MNvikEsfLHKk/2Ttl+wS7NvZQG8CCvuaLBQuH/J2Pri/yK3SDMW7YwCvVwfKDw5qhUKKrlRFqlQCKnp/KrtcXcqP+TGiE4puZbN6JAL9S+BO0e20H6wiyHUMeAYVwf3DWkeVr674sni/ODxIzeDIe842DNxHg33quuhaxO6Cajm4n5pq2k/+I7cFdTbr+o1LMJU22lNNbBR6FWWAjqrqGxNJRMVXlhSamK0allRBSLGCLkhRtiNGdRpzi75jSf9RIpA7WfbGaR1UYwgcel+s3qFl/0Mba980sXa4DtbeV0SeFhYUn/8VUUIPq914hudeL/dBh7pzFqchTiec0TyLW5ZvOGHhFc4OPhC20wmN+wrzEMwneHK9xNSekcW3Pky2gZ0jlNDfcCVHiCkIY8lBxIY14WjYICiPIJTUC801RJrBR5+cNXj06C+0BjjtdKGb1TeN5iYtdZbS5dx5Wj1Ve/XTUls/7caVRjv9UY6S7Zil9sj07M6S/Px6jtkzW2e0U86kmXuk1B8JRj/keX7YmCqc8lG1kI8U9qZ65vzgGtdolCUYT3PzPuaOr3z0EQLCUK/WV/PeqhmjFDjt7X3DRyHwSHSXc3S+VsIaqkXUZtsqCbilCWA0JOTq6pnjowohO2iMmXnUtNvaluuUX0hRCv5uO0zNxo6EiP2ucG7RC5ub3rhLuTv0H30Mw+UrU3List8cJPPsVDnz6UEJHEYNUL5RLGvqr7TBphoLbjcQVB6GbOZaz/vDBNdUPnmGnpUy5xoBPD5+KaQPhgJ1aZBjAqGWBDCPU9TMZ8unsVQ/hEaVkILMQDwd7W5k4U09HXt/xcz9lMwXmnFnrFCv4E/xuOyrTekiIFc/VeuZWyKoqNGL6YQDr4zen38q8kgTyocgd7LWoMMdM+Fhbo/5O5zrpQx+64R446DOOW85RGr4cHdacYMrmerGNPP9DZq4IpRLe6OZbJdE7g6t1l3229+SWN6IXrSljfg5tQ1fc4Fpj4kuG083N4XN0H392r5it1p4cyH6fxMC+PvszM/KPlsXx2U9XcKx+hEntFfyBtzZEIKiqHZna1E7A39gu7X7+tVxfTk3ri+zSme9pq3l8GhWK64HNH6xtFsyfInrarPZnqI5qYozbTflqFgapcqsoUvt9yzkedQ5to3zG3p4JHW3n5Wl30eFbNGp77QwIMhrZQrguhDo9wzcVUCneUDdIZ7YvJAExCk7R7mfveqKHtXCiCxT9zJhhFD7zt06Hwy0iSlskwPjB86dKK1N+BO61Amdq5G61UUatyEtrpzS+aYAHuqUgMyEhLPZ2y3ZtKJQbQaVz3tlRlHrnYKh4YpbjBbaoGuMlrdjyFvcLMbyCeDxGW1Te3zQOab7i9uJ6vVRLpv0cOQbdKdP6GvvwyVVlHL6/gE64ay7CGsqRK4ukK/T+nmw1FXKKukX7Z+a4ye2JKwpuPZD6R3ToLRGJN04R73IC25pDK7Lnss8XpcTjrT5QhK3ThrV1j5BrMJ/Z1+bIBgJmi8V2qPMnPlcrGBXmonMfTU4z+MDrku7AtH1GH/KYRgN7yF/h/79+rWeG+1WhXfKwqW3YlomYADW2XZOAq7561d4YWlxQIIs1G2K7bjL7dBdDmTseb2hc6S0qcxC2XIzDh1Hd6vfQBK8gbTQ+ByPs41VVAqTRjTq1yIsjsQPSR//EyPxQ/YI/xNQRSglp2FPiaBwdplY0+JsIMI1gOYM9WYp1HAtoPmSBuGxm8aB9kZl194sgxwqyKFwzmJ71dJKFNR8oCI8algjxnEZ67qWF+lkrFxFF1exhH4tqzR2OxmlhnFlqFjMrToez4pEsN21ftiMEHYbH/wc1TzdHK422MaVUe7JVZ19dSHFAWQyCbWIY63ei6YERx+Hgz06oCL2xQpVexXVJZhP6TVJUfr4fcKelZIcLjTo3DLNgJ/AQjdHbJxT2UJFm793Fn310PQ2dyfaeJsZag0Lmxc/yuzWYiFGHTeFy0o7Uae10wpPl2fXY+7p08sz5nBbnxGWCTb1IVyTX0bOkOpD7M0VDZZOohmDn+nlS56L0fCVaFVAs2zcf6YrbXJTyyY389jkpmyTm5UcROa3yW1uAktvAbydb7qB8OBpAZkEJmJDwJDExWHfNC1nO/PQcMMWC6jrh/ERc3XQwGxsmCDJsmK6iLdKl7RbEHKvQAuvzaPV4F1sH71OfX9GmMir6WIN88ZGh331oNu+fNqMA3cveGEyJp5LNoTm0GQOjMPtLlnDam7MVnPEdiTlMoRfPO8I5clerMTjwsLj3IPHBeNxXuJx3oLHSS9jqzzF9Bz5ZobQAfz5aF2Ud8sy1OLD+dxB9NyL6EdCJq5fQn+lPlPxXmbxQLKIkaAZoHH85Xeli5AoR02jvvw9s9yujAbydwhBR0LHphE3EXw6lqulrCV1R1QIlk6ymKSdCiCUY5Yz5mFl3hgXcnxXjlnmvVWe6sZcesyMs+ciUPAtwZvFtwJZmMZW+LorewNYBPAopuWGZrrNq8O+2QCifQKVUBl/y8I+voRwvufxBlKc0yF3v3sqCA1UTrSqqmXG6aBjacfJhdlqs7QXu7lZrrTfOjZQGOWzoZSflcvtOdSkrxWnGWdyDM/gES/GaeRNn3fjtMvmgx4APjKVU9+2TMP2+GtXTp+EeuW2AD7I1KamTemffZl1bzVRUmMQEh+DkHjm0qcZ2nQl7QQASj0xgaIme+z6KIKj5JKJrwIFaR+I2Mkqfh0t/JTw7h+S//5bGNlOzLUenzIjXNBpllKPOyK7IgQMM0qHwtvYBE1yPaDrH97CZk7hJMcLYAzpv1JDpTiSCNqV8PTmUl3wQed45LXzJw/FNhXL6Sw5SiCD+zAz7/n8xOx7uYeiyRZxrqqY6c0PMDA0UjzWTMiusCSlAFk012mrC6vo7pZ+7IeddO3RdQP31KwqpOK3TGO9IF0Blc8mCHQKYr14GuZHF0YmrOrrpMEJjS1N1YSEgsNZvEljFF+a9Qys/a+OcKK47IXAkm2lZupAstJYsRcvINsptToTO3FwGsrMThiqhMGznX9JuhnhSj/aU56sBmTFlh7l8WC0r1i7YX9/cBBnKuWBShn0H5UpD3XKgzLlUUzF9w4TpO6WqXtcizolByExnqrc3p7JH2g+UhUclsn7/eGDqpiZUaUbZm1rn9tB46VVRx9Aia9fd/HXJPFPjwvTd0avlbqif/R8ThGX55YhDPDs02xlZSlpKl/ldxHdWA/SVE5Fmh1i5u8WlZSvps26DMNfBidQUQtIce/Nm1dvRvRUe32ZB+PJQkUpqDxtaOtrILTtD9IcyFmMZxQd+cEzpXJDUC20fzUK8B2hvB9iy3wEo4RT6grsjIaT9+gkoh6yBJhwRKZlm5UvPmvvWDtPbTbXe64fbnBqHGHWd3RGEwkHe4y+HA2wtGeoJQ7u1b0YK7+GrpNl7TWQPbC+n3RC+fAgtp0KIpdjUXbC0PbATCWtL/s35NN1N9B1N9Fhw3dzqwD29u6cG1LaDdd78zKBLaNAucI5eBMQSNeHpGLe4nuWZ0I3X194PYXuxZTlqyy12IS+TNYNh5gdJMZaJut2Q6GrThdjyMiNEz4asfpt1Djje67zLNcbMh00hoFXKGM+en8tFq+LcY5gtpl2XwnyUHp8dj56SwNAA1TXyu5kl0ILltg7tNpZI5Iort10RTfjRPq2TngT1ubGyW8sYAf+asvhgCjCdSv8I3wgp8VugO/faQ7JLOFxlhGpzD6XgB3nYEKycVb5btXUsLvdvyI6XXJpwitSMlKf0aPpbFws7OjHpkQzbDrloC1dsxVJWJxGrq9RLccSvujKqB/V1AIsP36NjHqYZKQtjcZMOP7I2/S/LA+JLMIWr8WZdKaaFxUMGUjSRsokzzj0tm9xjRVqxcVhH9ruKvSe0S6SWfUzhU6BqkCxVL0nk/xz723S7+4/2/2XFBsemf85GVOk7/cEiiBCji/1dDtrQVygjA0qrV0hm8cgkkwEYhj0+PkkXb/DJtUCVpUX/pgpn1HLT3rLV4n5rJVgJvzTKjg2MnXbX4ZcaH41lNN6O5ince82QKPtuWVj/mz/CJ0thfq9GabqZo72R851gj300wdw+P24NbsM2WXFGoBP8bjvXgWTUHOh7wpS78a/uuRhrrh3K4VeQbGXKH0JuW8l42o7PH359nl1ts1jEUX4hFZH9BNr5F8WxTR6Sv/wT52ffc5IBt4B202+Ed+HEe3GYFuFp45+PE+hqbGgfKTOCSaMDKRTHvnbH6hMGL0k3UNKT6/nAcJ8LyKSf56NJ3D8HkCeyO7BOj+/fBFGPxPHm0xh2Apqr5tWDdC9OCuIBbK6U6Y1mihz3D55qgtdCE/lYUt/X/z84m1YxqmORGiREd+6gD44TMM9cjJ+YLtpNnpRfSY48VvMwYkS1YVSOfUdx/Zx7zn/ykM+WsTi1zEcW46N0d4tmJTOIq7hz7s78BnwelFVcWpCbBDKALdNYBmeDOih7O3BUTKN58e3L38qZe619Hsx+ueGQpP6YJnQ263LBcu9fqgDeqDdse7P5HqWFRhml/gMGby+vD47K/JtuEemz1fjgI5OWujPFOvYLoIxbORdXhitWatyhUzyHJETOgsp8JypUplbVC+EAreIeNyD/BqcbJTQx9PJVcKRMMwKYR4SyzK1G4ue6CYoa72nHZGu4SF7qjg/FCNbDyyMat1D7cFmwE2V3aRDJFdqmgmV4R5DRRXA3F3ZjNZBI2hELsFKuO0xzlP8eiHPrs9V5MtZp1FOYZCRQXKR13SMJmfV3bn3+jJZEP28+uuvL57WjFr5dtQ81403TAHrS6NQ2ASTAnJ5DP8YYjTWJxerbvXY4MM4nvXoleyPczBltOE09tY80lMPAvVIQpkc2xWTGJiw/BCYBh3SJKd53q3XiExfFceX59T3Wh3Hqo40fhQ2Ft5yZ/vyGeuTL5sRIzTAwvlkBN2LMPLoo8ffUmfkV7T3TXHk1bdvTl0TMEeNpbY7hJsvTl5x+60uEZrOLnXUBpM0CkS3I0Rs7ejapqwyQiXV2N2V0Kj6ViKq6tr7XnVpIZ9T1VIeJ9SOXCv+GXXGg7WqKHe2CSr+bKxu5fLKqW9wGtPx0LlNhboi3ozDUF44FQ6/scKNQSjPnBp3To0Oirvx/edsg5ml7a1ZRXYL2qx9P15dS0tvN4e3KquD0urSdIe7Y8soe/deh9GUJqWg404GFnyA+7UIo6syk1aK3py2Ee9++6fHP1PeRZn34umzbVOYMs7KDOqEYO3JAmlEWZWfJ9GgmRyBKHiuV0LIDc95WViRQYchH56mxJLD86aBHMuvVZuba4OaOeVz4/bFwFu+np1fkdJIoIOCCPnAwWxzRYovehSrJyG9DL6N4iVi77CeiEl+16wSpmI0kW7aziwvv07f1Wo6Bd+7dTCfJuOAZP94NXtL6vA5wwQzDqKjiwfnc6Usv9WteQ/hSOgFHr5Q06GQAwzkxXzvUb8PFNOoWCIM0gJkBgXnQFlblVG3Rw57U0KLrpOuGdGuCOZquAIm5j6IIzE3duXkSwzMZyirGk+KOaa+qo0wiY4ers3JdWqac0aw4BwhHy2nUCskC0edzoVLPf1FVlPRQRiWM/bkMhlfEBbCZw0tE6aXCOJ+X16o4FyD0HJGHY44i35Jd7uaGEqa1fcytwXvTw2ikd9s0w3fPuXTeijvTb9+vXfFXzueHc0nsYY74y8v3KozoiGVMLttOZS96YvyrhcoYCGn65VlrHzDznBzGHBOuTrcw00yFNXKDJMIGxQQ1gAvEASxO3y0+2j/wfDRXgn6+PJj8nnuVrNetxCOi5g5sjGq7bfYu8Qbao2PUXK8aCfBDfxRRi66mJAEUJpJQ4GHryXMLhE6koqM8qZfOEPwy42tJ8opSYGmB4V5rJh2u1BhLt5NT3sOsaepUYkv5sfMwJJ9EFSSRvfvn4OTx4vc/Y9pQf/Ms/Or+4P71I3tOTqW0AcYmkaHha7T7tmb4n1B1WfF62RGkwL2ltLmuN1CuUkN8Wq9YsYXJ8GVv4l76/1d2UGc0cDPDrzzaCbjjCbDC/DujFpXP3H5i2Oc/75rd8CY4T+nW2t+WpSByIz0ZqSeH+VWeXXnioFLZLt0RQdIuCX91MIWOze7SZOH6zfotG1zW/4Ktdgbp5RdUxiqIwzXKcsEt4jJ0cUb+xGmI5rvouocEFHRBbQB4/nS71dwCeaXU/jKsuN5RcV1Qfqm8dGmxhwjvaWg64RMCq/ytC5ZTVzeKUxM0hxiVMH+k7TOC90yB67HI9cbUlPd3XXl8JD9pZRtsYsm42NhjfkdcI9VID6cYfTMRMZRF8FcHy7BFbEiWUJag6yvCR0ZRDhIC0okYcz1ODFXNPWMH+ddobSSPwwPtTQvMAfVwX1KFF1bEBhBEBg5l022Mx/gNnpCItciR2wPpsEymKuU4CPFJQlenYhQ9v1wRG3VFl8EiButQO8iTOoWTXHSoE2elMXiqfGwE6n+P3368wnbqWnm4Yhg9M+gSLIPxBsx1Gu6CdARkTG0CTxZ8klzGbx9+xNYQlOAPrsbZbYY1dp78vnpj8evOfZqxQ9S65wdpJ8DAARzBdG8Ozz9TC/OJCGmCleJ2Z6Ol10UnJ0QVnHV3fur/42zOnigz3+7EqTiy0FtfqOLFXpPohUdcvYnMnxk1YMkdMMAJyjSV0ZibgZSRL+/7f4/ULX38vExbbMZwSkt0IQ9JdKoy21ATG69tiNh3ibFSP3M1S5U6/4+yQreKajF2iyNRcKwDIsEhj7rIeXF/NfpEecRvlxPxaj8yCE/D6OVI2lSfsoLEs4U0hl0PZQyZqCKpWz/VuzFb+fPz7FidkToctWa7Sp67MVA1Pv+XOW/a2nDz7ufMuqWpZexWPPYUzVhMtzYWdUTir142uDniUJP+KBB7erT211/nU6XuxAWnLx4qiR186P5yKGYOEw3nFUgFG7O5RtVdQ7qPaXN4p3VdyUJg7r08cvXgekQfb95eWx/c/5m4CTzGwNV/0Yn6HF0STf9zVU29WQdHAxCvSjI5fP7FowvojoF81ZEURsDxM7QYPiUIZqPB7DrOTXoUMIRUA5ZL16XCM99I/4e8vQlHQsjX8/KWs7nL6Z613Qyui7o35I9ylBpF0CLDv5K46KbB66bvtrPOJt8stCr4QXRgXrBLvtrceum8LVEOVGibB1HcdbTUg4i+05vCjRPxbTEA/l8/eXK3Rz/AuXqmA2gyGTmWhahX2rrU0jRMlv3dYLPBX9B/5lg3rCvYgvT/0N++z2oeQm687WD7xxxzK8enVkY0LgCjKtkpWjSscP/I27ctFhR7j8UI+QuOirQX/T27kW2NxO8BzRyK6xoZLkLf1WyNzKodpnowlR2k1jJ8XVyqWU7Zl8Uc+HbN/tLdvQVb0hAlRSc5oOIpOj+R1d4dydjGmYm/KL4Aj1deiTQm8RzpS+9VG71ZcYvkwt6nHg8I0V3b63U7vSPfQzW+MZj5PHB2vjUPzDlqhdUk8JitVBW377agBZlED0orkYbvnnW61DOdNlKNcuo1EzylqQ7pK85da00updLG2KS49K7skYXE71Ub78SmSooIVtKtzRhobPaJp4M6S3oILtLAH0Q0tt1Px28ubEZZfpcV/N3mwCds98T+HxjGNY14iSupPsyZ7NNT5ldFClvizqkPZVrAD7ETAwGFlUm3poqrb5dmk0bkqs2znKgHtx3QnyzwwQ5sG08rQWxvRwGqRFCpti/VeBcMRoJJOJHH7+O0lGmdIkUVaW7Pl/62TzNk3ac0ExbWjAeOUF7SGAhLF3ByFGU6VAu2U6tq/pSvbzC4RpKKqMduJj4tyKZkaQFaR3Rp39Uzkt6U/9AyYPQRF3bHlpACkaJbZbk/0gStPkygJd873RAomxnz0R2xegwNOUO0oR2dW1FH+kYgDyn9YC1mm/ekc1pf3XhqD37AGhlPCsatwTkU56bIKca8bzI60WmPp2H9l/fHhvhFVGHiQbwv8TfRDoy7/OClFbBYxY8StbhDKaXRUJU8mOiXK6Jhun4OlPTl6yD34a68Y5PdxZlJD1UKAtS7+QOVb1K6c/WGX98nZ/DLU3HV2bHhX3JBpht0LvhiuUbGi1V7zKyUUdBo5nHSdQs/5ROF1vl19thtOCvPcFA4Zghu2Pdu+11w+XS3evWEBAzbG+3LXvDF1EoV8Wp9FS1VlxKvdsdlxL+96l2SnmXB94syhwvfZYPV/Zd7fOV5TgM3oUvK3a2oJyMXKe5eXZd7gCrHmqp9ircGmyJ+QIfpHA141lNrh40ynpWtkM1KdD7PA571FqYXA5Vc0WmCttx15pzBUsVM1X6UVa/yS6fMOL5P/GJHO+xT7IpTvB4q3Rlc5XSyOEIX/sj21o2kBP3PTjo6HModB1V4waUuq/bPK23Hywm+79lqK/wiG6NlDHIHalGgTvh+2VxlmQr0B22uHgYKGL/tjaReBvbwlytof8C47tinBd56+Yor4w/cZ/wEPsHsYE0W2WZddC8VHSoYcPac2QQHI4QXDzgtJqvvIRuuNDMQ3DgmFTG18aPh8Y938p5bR+sUugou9J5GNBKzeob4dvUJbBr7ohe8/RPxqxVyHQbxNHKOFtv8cClFdcgLofBKmnXF3SqXU/htKPItw55ukqlD3c7alzjL58/IEfHo5TmgM/1zgPcA2Xsm6o6okq3VKmrXgSwBnm2gF0tm8hDI7kCTFyzuEflhztW0pISFjU39JEQ1aj/7Qipx5iWjX2rKk8YLcdA56qxDJIN+0vyodSyvPNjQjB1+i0AX78+RE5ZV82F5dev/WXZIe7BXlRw4YAAt2e+XIxBR1pxppJbpdB8qvxppqsZxkb89tv3NIxq+yP2b6OovjPiZZMXeTA7bltp3x7zbaQlkxhG/t2kanrz/IlxxupDCOtS9hquoZfOGy1LKw2iu325DrffblTY2XHxRmkx7+5mf4/bW1jWZfK2uQLFnGsme4c4aqqfjBxnQm3kWzyDvwO4sMJL3bUaLN7Z6ATgg2neE+sg/Y7To3vUI6t5boQaqx1BQVa6V0gLNCmD1GRBe8NkmDMsmBjfW2zd0lHdDqmHI/sSv3r27Uh5MiunEbh5BzSJM2VD22IFKPsQBzr23HC7AokEbLlZiOk6u3bElF/jwb6sWatD7FaJKoQxKa6S+qFsEWs0QAe4BYNgNSspn43Y7LPEAg9oHSEh/jaWmPusXZ9Q2rI2klCy+PHP0DTSPkqWtK+o/SBeBgK7jRfwf/afxfjI0q/6dbz9nrDkP4tArYZ4rj4w24i9NrIgn/vBBqGSS3RjVx2qyYlarL26iXHgzkCJOT5MLmnUMSfposzqglU0jLtdrhNqhSvm+1ZrYJWYy9pXG9bIjkkwOOOB8W9AAchVYNOqa/hV1gWolOX6uzJjLSxhexZzoOue4bGwMY9KkxyKkY0S/zpXcVSLjijFRCzEQhcVPOhf5dNF5fIInNrYrN1JWrkfBixJcwtlkfG32JdFVPwJaH6wmKnIXAoofthH0hQp1n8MwW3OBm4AKVUg1TjA/6pZgaeq1lKDgS4GnmA55L6GZCvOOixyLKVQZItK74qmM+921RSO44G8iDO8ipO/mIue6uMJTTZC2qhomHTuD/b9WTshtCMFTQR20Scik2qV1DOs6cpO6csL552qw9ikkc4iAYZOxzHJljuwc5J3iO64K/TgNds2IglmdhHxboa4zwkMtldeTK2gcPo+1u2UfEeC55GusFs3l0BYK2AJGhqrXbF12Mi0osqIYizkl8+0Z0eCjheaqkzIKzzGjMRwOz8/O18ImdMAytybkHdpo1Z8OLV+oJW2amGtPyuBbTOqhJva4FQTz5TDKaq3lOiKzgyx79TTgvAVAR7dFBZBVVySYJzGQz6rtu7JwtCbyHOo2ZxPRa3TOglynK9U5X+3ilQsR/jl9of5jUUMmbj6utHRTzeA0AQroMwjEcrGK41F7HakqfLZJ5vqVqncZ+8Qy96YYsv4QLtV8WvJa2aoQwaKSRyBFQ1HzlnjOsRp7Mi0TUSfuacCuUOWSZQsFcALxPOCCbdSZOkIVhjP/PsqjJJu7MIzYUOJVTjrKWzRPtSATwX1cjLTipTeQuBFg8eViiOn6ARPCe5Z1cdWkMAYDlewJoUlAbnyeapINDv5ZXKLSxlpgRinuKwJQSNXagUVDPxsNJvmG13u6RR7oxFyQ1fB375FoAd/utO8/TzlngOY05DkLcDngwXNCa0r7FbOaS2VO5D4aO/xz0rQDmBO4O8SB1gRubmffqADIlXHQqD3hJCJFQXS2jwO88diCty/rWRzoXVN9+yA7S5zBBbfOkQzKUQM54z9g9ruy9jiw623DMGdhv4i5TZqLcfsGS7jZvPMeSTMpUknx5g8Nzi4kuCc2OA0R8xe+qr3+hDjvOPJ5SXLKUpy3qy8H7Y+c7PTLdNZmja6aCdcnbcVu15x2t6kfRFtBbLucrv9h8r7jfGC0/F4wvHOfOI8rbb3p2yKfZVTe6X3S/ytNxeGX8pb5XDI/n1wrWxZY3bYEaWWLvoQ7JCfCTbCdebHBuC/wBm8TMaEjPo41Q3hOawK6uS6F/L3pdeyoJalQBK3F21fcacOeC5iyFuqbLYcUjKP7zgcdEVuQO/HZoxJMPIkmVVRrXGW2yOpmOwCUa0P2y7BoGxtzyKIAgu7dCrwcfvTiLzY5sXY8MjM5W8rl+1Wt4lD5uipCXvl9UGsatQNOSyzblfphjVjuPrRTKnFu8gTvEeYmh405XXdzKgW8WpjKT81o8JNBVPqoWsu9jOpBjkURYpx4awTQ7I7HTW61N1QjmVXUR1FSrloADF6g2g/LS7PadU+g30jZ3DDEQ1i/oG4U/7BhlOPj/8m5O5IPNO3972RGqqwXcf5cWopm/jt+y79zvsuufO+A5ebR/mtuFzngElstFcKzi6wZhNk5skzixhgdoVsXd93Sc/+PvWG4bEKB5rD8ahHH23sjQYyL/CU3URRmZfIJ12fo20lWHCDmDbW+f6rWfe06Kw+gKV/+7Fm0kB+4cKjrYNkZKxnSqw5pETNuh9qu2M2Lp73Pl1dzifJtDeZnZHx8X26Xu3e7z+8nzA0UZT75JCouJ+Qfu3nq8k1aSCUVaHWJmJS8seRZXRcbzAnZyhozbV3pn+NvfPwvm8uDu47taIRawPYnwEWMLb8E8E/xLdvxuyOmxGoUnWOaG6t4/dbJvG+bx2F3PgRPvz/P7TQHrrz2wmzRzA4ufW6N71/HbY38/hnZ3GateHfZfjjr9lFG9TR3VrRED/weDrfdKa2Vk1c2FjMQBT9HdFwy5Gd+I/x5sFoFBx8vL2+Nkbp3fRroIjUrmGz31RVxOl/iH+8ijOc/xsxB4+zi0OHU7iVBhYu5jYDd5ehvVcTtGJwInKC6nlnOK0rUoJx9UECZyvqCS62Ha4im0A4y3nSYIdecoSl1pmuqZzJlbt6W+ndlBXJYGTZvDk6aMO9nfIxq4bQRqHFzJqmc0vVFX9989Odh+Asf0IB/5cMwtEda/bbrzQGe6NWhbGn52dEyG6F5o+pj1DozxIUqWkbprfUNvyEiEzuOiJl7YXcGa5ax2VD8QUrFtGtxwC1E3cMSPkvGoPRgfkue4iy1u/3YPhwKZ7MzpT7/3kNRZpsOjEe+uXU5YF3pPewIbXANIz8U2UbTbVAfClVsbSmGChHQ22rkcOBtuY4JjrGnQ+CBRlFNt68lRZbWbkvDLPJ9GmwcawdszeEHPjqr4BQRQvQymPbUjTjUfj7e8ROrEZNAJlxQXcs3oIuQCW2XHErEpIL48wvW20sThuiDMsLU3XE6d68d0TVN4wMvAUaw2jmjFS9uOc5+ObtQ1OvpUW2Uo/ZAKujW+j47Ax9Oj5cifUoaBL6xtm+/mZRt/myddbmpU+y6BX8jkQ6MzL6yNHJBxqs8iYAIHgce1x6/jbQQUpkhh5cLs/HBdltBW/p4ImegsucUQ2/XJ8X86yIIGFFTS3euOtjaM6t8ce5xxpDWZxA5UYVYOOelARqg6PKAH4kdAeFzDaHWtYm6YURXutESIm7ZeLjyysySAxgf6hyHpY5ZdJgv0z7efK34jMSiRZ/GByiD+rl0vYJNHB9AhGw1wdI2sxg+1EhMT5jgcuvPa/ew/Bgls+7IpipX515CFeECpS87WQESmXxttwVfwmgeCQaDbwi0cpHxEoLpto11zDmySxzWI+T/LnMkuk8+EhsQfAe8zAi+R/BBBMDOHeqz9kCd3+Xto/0mtm5y8z6ZX4cKPVkSjQuVWT+JH9TnVsoWKFTd1GwQrklClZBm8C2nMDBUrWpEgxQyxSwbECjr2ECYWXmwMrhY5DJCHQF+JnDSJ4FR6XkaPl9iPv+p6kssfKRo7C0jiLS0CgivRiTa4aEdqNPF+lxVqkhbdh6SKyDBP0jUkMaM30imiln9FHWGBVaW2kK9wn9g3Hv58J4Hahexqexk16Kg/v0f6OV/wyEFKPRAGL4MT8ww/Ws9l2qU0Lt1J4+P9E7qguAFLjkvRdTBv5MKd94aYhyV08KWLJMTwrzYOlJsZqUV1Fp3Kqo5CwlAL+/0pK/hRYFpo3vocE0606bKko3uaudVDjaSXq/3oDU7snc4lSwCp4nfCSv/YRv6G35eq8S3Nf7mqmtKUKihHDJW3zZTYdU+XU2TZVt6poortU1FahHZ7M8lkXJ/NinjUMHwYk5GlIl1Tvy2bFbVe9Ip6Jnn6xx1nLKJXEUpkw+Ahvo39kFNdKXTcUwt4yrYuWH9Nfel0O3dis4h33cSIoCFd7gf/bq6e0MAMPwNFbR3wntyZztupW0ozOkgdZrO9bmh7m9Xq1AXnsHA+3aOtgLJ0qdMqcZh1gtfxuUSYmmd3lZY/2xxE/umPAm1ZHBmlJuDWWmkBakKWudHb7CpVaYDUhlm4DM8ZsXQHOieSDVmQIY9cNy1Zvo06RZ4tNCWdEGrNpl4CIT7bJ/gCTDkGhuQ4iKWiE77JdOq4z7anbTrcrCgvSYFu3xopPxzBS+6UAHAvUbPuXhWWlo2uaKEY+dUJ94eSTLfhjHVv72sLVSXlIenOOXnkhiEzdb1bas50r9RP7p07EV252veZz2eqaCktAtpUx+eznXO8dO0tcLlClTfzqh94ucUgnfdYzfsu6kqrlKo8vuP4usjLhsVOCdK6/dU9CoVuUm0IvX1ylhHLVhlRLSyqp68To5n+ks6rhj+cWJntFUWlCofz6wt7+T4WggGT2ne67W0Rd9LWVDlqi2JkmvbTzV41LUXDMU84/VLuasKRdx58AF9q0rl/JluWWbmBKp3emvttyvaewHwGVTu6J7MdZpt3yQdRWr3GkP3c93hf0SwhGaG2OiLX+DKter7u3sGgE53kwmqjTnwEJoTVDZhPvHXv9RlYbbyJg8m/aIoqedldChr8IX8/l1MeNIvsjE246nKgbz1qB39soqNJxSWswo73eSBV24SF0r1SRUJtCPDeUaKru9KEOIf7mRSRlHnFWJFXLkHNAvJdlGfloyoiImgOwd0ixijGDJp7GbCAJcxurOrH7AHTh2XnYNPWAwM6o3fHt2diV0f7QQKuSKLGfK3PvOwFPm5fWCfAq6DzJHglO31VsS7SoxEuwKuUoJu97qSC+mmC7ovUj1GYHbxyyEnR+JIBnDynK8zTWKMFq3Q5ubDTCN68fwWJ06TgTbQUOS0KZuPDUZ6FzlUE7QoEqIKowGOLe090960u5QAaT0ROhdLw9eWYFCXbwsXZ3Zb+7BTy9PML+VbWx9ivo2hTnqjwYISr+dysRxdQyGseuJjoGq5xqdvL4hfRiX6bg2J05euyPXZuuK47xb4+m3NJ7rmehoO6Fv1sBtOBPLrBVFFAy2DC7jjRntXEigede6SFBiI+e4dEpnhsnamptOd/yKmyxMM0da7jmDYP5aJ9F5y+mC3WfvIuSK0FP6H9W4TBmdErCEO4/j+klZSsGBOBgZgSXLdXmBKShqrlRsmr1UXxYKt1bQxGbXzdnUIwrCirk018oxH6bWfZosT4PmoVNP4bqR9vXrRmeNcWm+bO2hoZu/jqk2uhcWuT3dAeoB5597xhDe5C2BJeyJadfizR0tXvoZWOVYgEz9RBrD1CXIikloljlHslsqjBK/1m+5+3Ol67u/LxPneG/OJk7V5quyPVWp3KvEGKybmVm6mU+VImen/ebgvB82cSG1yfqNrE83m+9LoVzs0P8nwVQ1cn/KddgbP7igbk+Tc9CiZBHkk2KufRiQB4ozmLol488OpegFqt4CxBqTA3cIaREQDpLHg4QCdIrQugbq7YDlJhXp459HCIR4RdPKoTNfjcSr2VliQr5Twq8qJfh1DEHlyYgfpO6rWI00XEp620z7acSHhjoqjtHENXpHwD8TMJ27qq2/0sdfSYGX/cE2FLDR29XCFYck2wZ66awhSXGuiVmdN9YEuysoPgQWLThI9NakU2tOIiClFkevn9nkkr5SqrLc4YgtQA9AamN0FHUJD5/qNFKqOxQ+oy5NdWegujLzk+gj8W/FHO9pE8F+YtsoeVYj0o3mdC7wS0j6KhAqSW/DLcyWRYuEfmNJJ7Rbr0YDepma01OfCqT8WYA0WfMWaJRyj6qtyDmlspIQh9VPoqHc0w2nq01EJcAjb+oolxb1d2oO7zo0vufYNMw3MjMqhg7LX+WYvtuQynrD0Kfjbq8ETE7sws7pZ5PARJFAmD01to+LR3cnke21OrRyw5Ius58T6W/TK+tpbn6LMoJr/qPIVaVEfhNbN8jesKAuDS+hjZpXXqVTh9mgawZ1RVjycHXhxesECyi0Zjca/5Bcsl8J+mCPR+jH21kynpOoo/eeyljPfb5cXCxARGuvKiQz1QpLvelgKMKj2jnsrSscEequgjFHylPSQXg6m0wBj7E1jCKdujDYmpKwlwvx1ZvCs0v1so7ZnEyLcaUP6bRklL3YaSH6vEKtLVF333gLqyZ70+KK9GClpx+K/93ifqyoclYkOfyUB7m+y2utS7HV9VRsllBFuAylVzV60LcdOqyp4MfMbquenkPKMVEuP9m9vR4rlubWKtr9Q3roOR+7ZLdFadW+r7gF1ldjdYaN3jrDli1aig7x2ZE2yrFaovRioUUFvPlamIAA3MArLfLsCIPkwvIfdy9V0ZtShyz4G0Cf1qlcZrEHISPIPzPTUBhlKrJhZhEi5eMdsHjzoG2T9iaKqMa1PgwpB5vh8fzJ+Zg4Uv14lRHKO4o99WIgFyl1YEGoVihJM7mz0/KwtJLUbeP/njz764ufg+Nnb96+eP7i+PHbZyoVTNNBdtRBLZXALusOH4SyWcezn596apBUA0brVNGXWYhNmloOomfsIlqE4YgyFpOEyTlmnkm+M/W2QuNReeQ5R11lF6Pdhf1OOOjyfwYbO6l98hFYkYejW9S6vCp7kfgI+VNJ+ho0e8dRhec+NbZVSdRx+n0TPd/5HvTcJdkttHTwX0iyedBa56xtEu2V+SY3wJjDdQmyqb5GlNM78fOOzM/P129JqvpPmbZsfPcZsW7m7kT8WZ2d3L2vttTgv6az88Xde+sKLJpY9uegwt37qwUojYndQhln5/yq3J5owOtLs0suyWxxW/3exv4d0UtOEZVcZd/ydzDCjo4a+pajoNpaP5DaYJTSwXI2g5B6mwUiHz+Q3LPpNkHP2agf6UGN+sLst0vaf5cJibb0TDJtUa/m6USZ1+SDwe/Z9W6gg4gfQpjMr1lB58e3b1+fkM9vXcN9qk3crt49Vd/x5Tkdhi31bdyqwv3DZ1cksAqqeJvf0r0HtO45yVdIBEzz9i01PYQ+qwr8ezX11XP/+pJ+NnnehjgXXK+L5prvbcH9JudwV+bXPoOYCyb+tMkIa/YQ+cNDNw+8WEcXrJWC4irsWNxWNHem2OB7A6WnBDBvT7NxZfrTCjRZA2a+WAMoMzAhelZdDjLPfP/5d4GjJVcB7sS6l4FRA3xHPb+GN81ROdeEfhwbnQI0+3owRGc6tbuDbFlh2WyWUMJSumpuBMf7XF5ks8/TxX36O8kdcX5PLF0R7fI4/FLTmUojv8JUFq3L03NErVI8B1XO/u5DWUs2wUjtTraAeJzyLZ+e5wmtQI7pOUON9ttGL2DfxtpTH1WXKPfHvTfqVV7JTL+lfkn1NmuExuCoaSHlF2e2zdRQ6op1+i3VkdaY6NJeTBbq1YOnO/xu081vyCkL6oyQfsxKMMm7sasDxW/EKvnpszfU0zBK1LPRCiJID0nLKSDejVbQP3o5Wk78bqJC9YV24sIvEsKrkq3Bkdiybe8WCzEjajYKaAz5YYp33nTMEr1cseLRadwKwxaQG+P4Cy6II0FabdQhcG7oL9EozfXQODXfA6+zPQ6YCOWaGCqEJdxeDS5T/EwTbr8GV4BVqTgVF/hBDRiETTMiLuDDGiBc+Cs+w0COS8qMt2yIo48TKHql0l0QQvlCjsOIFfvHR+uTX9RbI7qjzjimlTwretOL856V93byuiAlUiuwVweCm6/4/1l4/+wKAhx5R8nJ2NbbfSDHpdLvXthGT3ZD53G7DepPpL4N5QD3zcIRBNW78fXratpNBVtXLqE8qw0ZFDqUQEcPMx/56fjqbruPQEvnj2FaOznjbF8//fNnrWedgJXaiPkku0ZKjyB05vzJ57fJmVJaFIqbF6Giz4u4Hy0OMsPFLrrdEEF83y1IWzEnBjjUumxIqebASB1v3fQcpe7StjVsv86X9xX/1j5gSqmftxH70r24nGPRbvUOsT2AJpa1nqzA1Ii85PhgaWhh9ev6gu8yvw4WMfn3mpDWYykbOt3zqFfVU+7FGZmEN/2+iG7WFSRSbDTjPlfaofVQyS3fUO7u+IYXasYqjkuXas2lb7ws1dRfqZrLZcEKS2BpFF6D5JJEGs7qbzw8dAIXpp7AhY4i7vJ2d0pgf7u3XxszMasXRosJZlnp4hKCxySYF1N1cOQBpEcUDMzRU8pYOAkOZs66Sh/PLy+DtDCdVm65WYU44NW9/NzbsoyjwT+g0VVrzsK1pUvuGFdvoU8Dqbo2XOq3R+vVHv+85Top8ahZOGq9cmNHevsDWYixj15q80AHZ1M32OiAezIHZWbYfE5iOsd8M9MwNowqrZ/+RPsKudwGImuaVKzufxZGUIvufKtydRh522JkNK15NOuzFs36jeGoH3Y98EtV5wdUKGoUsFXgNS89q65Pfp34RtnQ0msPIy9Gevzi+OFcadzKRYLMyZpMiUjsKXulYVrCSZDRHayxCkTX6LIQrQVLtlXKiOOpCiY/90xf6A27hpHNnXG/LsagByp0sHSzWPeosWNcHUUfAVh/CmUWrzFamXDwMRcNwqh9JMSyrTWW0j6L1+7LOpZa7LK/7JCfpoRR/q1kpaHWae9tN05au/2ezGuLaq5TrJCraGRZFRWnlpbVtvGlPqiRsDxw3leRuW/vSFN0qz7oh1Qw4kvU3sLu1jc6SF02u3d0YSqknh31qgZk/K+aJCwXNYp36EvjvdJyIHWX2dJDYbeanurNbM2DqqE7zdoWaUD6cXTZDu92GXlXbFeigmsRgpX7WYfq+HZrp4KO9TxC1A7DzsSK+CDJf+jGw4M4Q/ayMzbGY8RfhgCzTsd41SlB8HmjIw5p8dkLwwXSErqi8sM16tlI3g2WVoT8pVgQD6O5kuQoKYbLoSpz/M/0G27JSsMt+sEAMMuwBCbOTEHryjaUZIaWJqc8BZyrbxpSdkp8SYx/eiT9uupAaYo/Sw2rQITgazlVV8TCg4jjNhyU9XM61WxLxvwTZcvKPZIdWxCGGhwrNhnw7AUxC3K8kiZiNmirfpjkbMudhErktb3dviw1pxYnVN308Tj3hX/8HRet8wW7uJizabt/nEN7sfwQZiq+fSIsLx/+tnbkEA4/Vi3Ojo59ci9eiwz5tc1bDuO1apS2cnkYNSV1tYue0Wr+Dd4G8smZx0GByVrqnOBflDeTM+oL21lkxXEyTdJz2lDnBTZnI99UuyyPfUlpCKXBopSyz5FqDDFNdBf6zmY0JU+LKaEm1fJZnEq7/76XP1++49vA+NhTf5Pe0lH2GKfCL9Z0Jq41fpXT8/fZimySxreARuCQTqaeuckMil6BHxM6ZECO9flQKf4fNony+BgP6YKxZA3pMGIuFgZ136kXHKQL7FvIdcvEqpkn4VYVb5Q1sxe/EoOQWjZSdd+a/taRVytg9ZdwRyb+atrR2K7J1z+ZhDLvLcqCRHU7znf87rQG0ZuSZ+9OgiCpWL0ljTsLmHz7Aq6e5tSzlndv43HWaOBbFmCjdQXSW2EHuuVU3Oyu0qDvJZlZUv7Ny8k51lKmofEFURHlSLtZeQQ3K9r/zUfO/R/l0lSaTr2ckGHlhMA5Slm9W68gglXdYEf/jYTgCV68X7M7mmYuRpFTdSUE+Yu9+pjMCrfckxevTtwUy5tTpLkVkzeZtThndRfDdZ5gUi3X/67j0yh13Y++TD6dX11fBabgXMiqlhVHTxmvnyp5O1kklwoU7lA/lrW1NqgKBIyU39QoV4FWGW3dNvOOcdCHRMe3ARK+h3uDBH0Nprqz5djtsGN6heL4duSdjN77ty1juPvVoazgDKGt80v8IgTOteR2nWO0TG43JAhjcUJen+dvJ3RX6Mzo7X/4ofjUUd54kp45A5Utaq+21a1Qnew3cykEOAnLtHMZLDWWrnZIYEZTeiTAM2Ho6JGm0FLzvM+Y0Ah42ddEvdfbKmunBXVJfkd5XZSiu6GaEFFin8v68ew2DTO7b/ao03iustz252UHuH2en1VuJXJ2FyEDS/Zk6tXPrnyUUCQq+/u09L/mDXDqjN34gXUSEdNUCB0sUftIYE+qdNqaHlRHNhBv3Ht1yQcbXMFtzpLZLKJ+L4GnAG0MH43Nqap0OssvSG84Ruq4Kqt7FIwClYXLJJxrhjemv/6JHQ2Gyqplw/JNx2vAHzdpnDIxtNw/+N1Y8HiarouBiyaPfU5Qiklwo8wJ5VbikUztR5HWqWLB+M6gUnYQj8kDg5o87ZwJK5xUUcaXYwt0AzrpZhKWToxW49dp5a/I1jBybuCeLQ1Bzm0pWnpajilKV5Ks5RCdbGl4YoucLasHxLNRUQkeMLxoY6jeNao+9VSn51uvqlyxHqmz3331af7Q1OfjQFGN9e2tRjEE11N1rs+I9gmZ9nSaSepuiIDdB3fmofDUoSU5Th06razDraL5+G2mgVC17bBL7cNO7kkPPtLjeCZTW5Dlg3GD57nyoGVyky+m/VFWduXGEXnY28UhDoYlvX3IlI9nUDJo12DYrUVM2S/VGawOrBPlpWED1u3cobNYvLU7u3PXzhotEqPLGBA9zSdXgVkVRJjS/sM6lphAGHjT1F+pt6Dc5sxwTo7bD17Fb1l79A8dlZKd/X7/rktnNnGH99g8vGvIJGc0C97CdxzP/p1Ho0lH22j8ZvPVLt2RVnusLdPsgEUi/DjBG1ZmxsVvGvejwf5hSpjRDYkCsk1J7/1scnWs3fp2GAk7w729UGkv824oFS48dC0L/Z3zUhGTW76NpHFH2xRp1LNDAykXlUR+O81syBZNSbPM/rI+AEi34r5MYneETU/uOYIxHCRGsTPvdo3b5MR2hZyH0e4eu0LefXiAv3sPDmPqx6MH6mvQH9LnUdbtjpTCxc3OkPQQHfWLHFoRzKYJmfqnz9Kb8I5bZp6JjDBLKdoifA7xpVrO1G6FQsmXhuR21JflMaEs9Gmdh1jwTrX+zZkrVcW3tX1/MyWUtXN5lEkWwfj6wDn6o3YYj1LZzgshdhGfOZUNhKvBsPyQTN3tN2xdjeWvSQauocttGB2jIP1DqSFtijj7p3FTRKt3vorbEV8gOnGDfKiwIM+JIlTx1rM1uHVcd5xTJFG3SNfQsv3qW5LU1Vx+dqquQMH9Q6GjZpC56+Qbe5v++b1dRfT1NV0pTTZapCNA3Ql50TBYCk9Eo73SpZDiDEjd5N3xGOPgNcb1G4IRAVm5GuqyHoNMwqi1WGQ7aLppx96aDl0fpPgWF0OO4cYolthGNcQhlEQf7xclYFoDzFzAJvntHxC9VP5MuA4zoaKsZcn2xGrZG7SPQ8SINm45vsLudmJ1u3DH5wLmLmBJ+toJBCx0NGmBloB3yBwjTv3zuD5i8wzK2X3/LcPCidYKltNTd6u0klUtSF6TunpFYbyAzR2rRWq1nszBsXnroY2ry0DfW3fMcqJrunwk5K0JeduGa+kID2kNXOD+Pr68NHPBFd5hxZvT/J1XnW2O6gs/X77yrLzAzAVeoagDHH3BScwK3LyKnB/f2MgRlAvPRroUNuycGDjK4XBASDifk04WPcRRgS83p54sMDIz3aA/EwP9o+CKnR4x9DM8eY2LBQIpk3NSGCyPBC1X8OJ18JqWtkDknmF/b5dTH7+pkm/8Nb54reuiIi9e/7Er5L76sd9WALxW/KWvGph8lIFyvCHkYCRgD19+D0fiDW62l+dX5/S5o+GF3GXAtuqpJz/mM6NNSDg1kPRNjZrAKqOhSXiZzC/462SW2bn4djJfk8Wp4j6pto0qiWSoVfUljJvEME4blETxA6GQRA0IDdvICwTlvj1+/fwyOZu/Go92qo/370c7N67SjI2SOB/duJW70fIwH05pxlqtBEMBachL0AVG0g5EQ3jYHw54AXTai9c/Kj8Fc051q9Npp7LRdbOtLZrUCuOJTFnfm4nkF9Pa9Ej9hv1QvWHbpMYD7r6yOlmlj3oRLScANVM2t5be6on2PaPdvQ5+VOsazYLk+6rNOBa6rmJKs8tL+yltnWqZ3EFvg3sULlsdUlCNN5Ib54WYGNIMbL6O7H1+KJbW0D9Vl+LlID3+hUlrPIxTiYScZwS/nUPebvaWkeBlUrBRngbj/E4fTy58b4n70fAwi0hGYNCjcTxg0R1OMsxjUuYFIgximAF3RTBVpF6Myt84DdyuqrCUR4I7KkbqxyXRLYR9KBABz3l+j5xXp7u+vxv/SP0lD/FzVsbIGZE4nup54b7Do++3w0H3TX1jjUf1to6selRvpQvLiYGfDqyx+QX2E6OIEZ+wu1w8FrfkOCZTLTAQe/mzzEzKnF/kgGQ6QjTCiuQmnkgo13ha50E5D+u3imKQ2LuRX6HRI1cMfiskXR83edA2am74cbNxtDawcnPTV6x5+t5ZRcTb9ZWRMxiZ1x9NmNxm7EDgTh6v5G+hNeCwgqjsNIQaY6y4WwMcGBDCSk8RQmn9iNzKz77TKI+S8N90qgI5u2nmYT9ZoBk3D+YK3Q1DdIP7eCwUoRygEr66aD2Bl+DedE1SawgQ13KFZLHWzuF2zc7pyzX3TqdfDegp0fyMAyFt/vBw79EwopOAf+7Sz9DdaNYWk4Fnk7kIsy4eE4d7K8QH1kTAmvY7DOMLffydTc5XoYoLHUa3x5KIsGTjtmhSx5LotlgSsUJMv+IF/BepEOzB5ua420Vc5LI60R27lHtcUu7o1vg3+G/Hv5ub1BMkZbWWjIN6PlUZ7mupKKMhOVXBb7gFNNtXL8CpKMCxWh7K1DjwaREB0EqxmNQWNXTC1RKD69kloca8N57MeLyE/y2F4nlRPqd4WpN7ZLwS2so/J7SaFgTXUhqvtI8kQ1jdsqUWuHCpqCSMVo3cuv81x6LVk+ATHB1dUlO4op0+vFkfpaO+XHZTSE8dX9U+Zu537mXVTGfLMgC9vennh8ViOrp/f07S2qtk3suvFu975Nnp/se0uCJz0uz86v7gPv27zRD3h/dhHmJoIq6btzb/LC+Nh47BY0lnUWmw1U3vbCpL+NxcS8Ra7rthNJathBNzKBxtePCPgCDf80sZWpA+vFmCbo5vOh1G2eNRj3Gq3hvhGfMOVTRq6clSxN+xe4L3/9I8KfzimYgCE1H3dpezYzu4rFRyPVmZDCHjDjd6+OlgMYOxFC5L3kF24VhweAcFq8tcpnQIetf4ZhVtifrqBX31Aviu+O1BmSCfuLUToKmqFbOAJpe5hdn3e20aF6Jc4eRuN9bM4z0p6XaW78PNzdtfcxPXL8raG/1IBDxjRa64GvbsdPvmbYFP8/12o5T5cDWBrqcU/uxID0JAv6+7lm8iXYyrq3u1Dm+W453zCImHwhrilDoj+bJpBced+zUMV4qVt1YeIJXIUuCUaxCD4NPV5Xg+SmNRO90ofT5JpnzAze8TRdu93394P+ETE0ZEuijtsOUHI/ws3B/w396neS4OrVP4tq3en00ui/vJeDL+fDW5nv+/4hBvmm0e+uo0pe7OBmTdja078QFIb6DG4apO8aHkYtb/xaxzrFCPnJK5KEX7W6MUfbTQxW/0pbKRO85Tvj8m+KsScht366PGdW/kGr33DxDnzVUSW5POfanI2GjrQC8LY8kd0OvWqHFwv8QEz5zdvR8H1mJzLbfG+O9Czxycs5b2rn06uBv52lCHtoVnLsL6LzBMhf4vYjQW4dvJ0Z+NGA369Y3c6+2x58bPPdo+TnwAy5VSl7Osrr9omkpmGhuOfJ1xOzegppSsefu5uyEJSyyXG5PsLzMmcfp2F4uSW9/XuMsrAv3t215bPd30O2wtSVSp+BNwCRdwUAE+frMUcngI7Z9lEDuA2Hch1rnKQDbfeJfb2FprNjGL51OeR5RldLBTlyODY9IhXk05EH/w5preM8U3IYeS0VMC12WPbwvju/3l3gxy9t1x5dX1IsWDH704KMNNUsiqY8mLsYF4Q+wMST7WWdhSjt9Y3buOfsrvJN99BixVtcbQLa21+o5QCmw/nTfma4crdBN3VU3rzBu/9dzVxsnClWSROJvCSl+bRj78pl2glQuD+9o88rthAmtzfmdEeJ/QCzdFHQ/IVwn2bh0V3Je2dZaSS/w0OVvDxqt+7HJXldJ/vf/a7Ms/Kkf60yzJp+7gEHIfnks7jmapeR/784+USik0SCVpeVp8UCBGfansccpytpGNXGnE027r03ixH6XSeTdFkw6BKFutPSiWgKCjJVDzbbWCSxyB2A1edNsaw2tW8z2Xwc22K6e5YXPkU7TMPAs/ZK+repmGbcu0sTva/y9dofKh/L9vcdhmzxz8JtnywijzKvB8UhrrvcstH4sxQY05zQ5VW4SyqKcW3UEoL/waBwhSE13Q++o4hgKw6I6XQYbRBSEPrSX92Y3pDbFTxGW/e9QjSiwqj6QZFYlLG0ufpWZl4gFPmnLD+h7Qt/U5dD93TkP830g1QUq6fy66u8oc7Qh/00rO6vZCB17U1lOHEGzLB5RWxjH+cUi0QdXsDh/tPtp/MHy0d5jaLrLZe5Zz/Aq5pE2GNyjL0ActlHkpVV9+sWs9XRp2MtyuaySx/FbXUPpAT9puduq1UY6jvsLyceyjekUszKUE/Oh7cjUpZF7XBiIEramMJeuojOUtKmNJux6Qp0iooiP5cRjSgdd373hTayl3tZas3lI7bj8tOO1x+CK6gJsw16EFqLbjPCRnLRqiQw3fF8BAWXhyygtOOdSNxANWknch8bTcVPHx3D7ESDQuHOxDV/mQMS+UsyW6Tfm72alyPTijBcEH7Vw/KPLYV4ZLZYu4tGxW1L+wjbr7YZcIc9dJG3jShp60nRB++JQd9hyxvDrqhAhVbxPrfAFcYzq501Adk971qimDSeh+e5THjsS/FVDq+nni9VZSbgNuDnTAFtHLPdnY9cSSblzId2OZn9oE24Fb7Z4EMSxlRoeUNplzqJwl3PLkrhOfiiF9ZmKG7l2RCnQwJ9/Ywfliax6MJwsg2TXJ9ISfELLFWF2fS+OW5dmvDuEVfrVVBOeN0Z0lYyyow4Fo/IoccFKAtMOR+ZrO+KkiKwLSQ0mL2eHWt4nSeAh/viitHOOi9JxiRJnMImKhF1hZGFdODMFZMOFqH+RgB/qJXmGBT0rgpg0ZUHokBzsK3JezaxeSase6AHtc1M7X19DmbMw+LR/ZGnN1Pnan6n/+ZKyvOvH2Hzhd/tEUPfIGwzTaW7AE4SAft9blh+ORO6nyf1lfTAKoxpo7mPGJCV3NsQNV1QzHtvYAmbW7rY5/lPo0hZxXkUMkgDTc3FGJ/PY65HLjFt1yIolZBJcQjqtm9V/bIyNXCRrpLAFcaxg16nrxTsiotwynK4VkV/l5paDJVUmqk25XzmRSPQGRGl3+Qo/mraeZuW7jkvXJva2Du20vB6fFvkKNjvuCp/NJ73QzXXLkqvt3BiPUwZIpaD/gfVfT6iSuSydGIiTWR29550LJtkPt3dRUgnTHhUOvhBTs+uPwLbwJcB7CyREbNgZnY6x92M4HoOwl0xIvCSEzy4CjrQ+h3y5A46qmUYoUjfptNEpU+vVDw6/REJqLxtZgllOzdtOCiPiTbYtfiaiqGTX6cfThPCdGh00P/losdP2fX+TtyAevCmrXdzeUsYF7bjSn33WO6TQCvPuvJbbAIpuIWXFHk7sSV1R5e/ra2ov2neR6tjKcnuvYynA8ZSo7V1m15yDPzas7X1LJf3JIysIobYpQK7XPUU57Vn+/LpnnUSLfftJMhmJNRoODtEoCyzLCPfYvwypRXcoUBzPaIeA39fIZktzyGZV/4y2f3ZDK0iqCAWlXixloa1G/GM/vXSD1HCbDZfTyDjIsLtiQYfGK31aG5Zqctmtm38EiNyW0j5I15DCZbbYaRjQHSHHRi739uBVVuUI2S5TBp4A1PQcRj9jXhnG+ETkQjH2lYZj6EiHDeDDXMUgDYKObFudtHLbkYaT79WZlv96s0a83a/Rro7Vjb5yOIUyzf4soEVQKktkG0GiikqR0uileDtwTwV8PUIcPHZ+UhtcZVWYWUbXdM/SNH1kGrUQ1iczs08kFWS6lWbrrM1duw8n2TvNkryO4YUif4IY3+50FN8a/gettxaQ2HK0MI8Q4o7SPGuL8Paan4XtFCMQwgsLib+fPz6Em6IYvcvPsb63DirR6Uhma7FROOY6E6aclGftIoZm0OSP13qZfX7+6Q7vZ0FNAJZR/sfjLzkiY6B1C7gwf7D8cGUfMmM2TPqc+qqXK4OTT/cfHymXPmyQ/n+jqhiPxaiwDHWZO1Ukp798Luc851FhWZqI0+uJGr3upQofFXwZUAlJJIVErqU6qyk5IrEq9oOiOynHQb68fB69P/ibkHv9+8ezZs4BYot7gE9pE2pABHvCHA6E7QPOdzT5PWxv/7dlr1fbbv714vf3meFe1fHz88vX242cnqmllSGM58KmtVoXwFf7FxhRs9MfkPA/6jjUSpvN63uH4tKbEi/H7SeMQczNxhFVNlD5fJY4iPMRETn6vDV3Lkyz8UmhT2g/DQ1Ms4Nc/6DhRat0PSNF0sTBc6mKhrJZfykxkbNflAgfKvp6zkGrMStgmVPb5H+Tx0/K+wO5tE/hQ2TMebkuW1xm+f7tZLG8e3woe/C6Ri7znQ+nNzbxHQeonCL7GTliL1dbVQE/DouhgEO0XKueB5+SE/Ip32YC9dZu983f1lMt5dwfKOEkMH2yO0/k0CoQkbjLLcEQ/zq/OVYwiHqrvurcF6sUf5rIH45AtEW6FoSxMuIPbeAIp4+haduKuuVRC+IAHyUQvAXvGaKB3wM7wFua2LDRypy5yw09G3BzzUeEYnJvRUQwJ04CQwqwwpepEZRc+ssoK8C902dx5QNMhuB83tZO8JOgUTdn7zOC/3JfFwnowkRlounosQMR55Ub0Ut3CSwEZfotuGzEpd4Tjrl85GmIHko4lXtkP4yHVqzBVro8ChfDqozXsmg2clWWHHXQ6+fub4j+ui/lCwXE8yU4+ya6BOz3KmX02etkdoebmnZmQ05EehblgsuND07rdIDF9HeEe/QbM6+1s+XTGHG9TNil/eIP/bTTQYun1Jr0ldUtPI5+tKsJGbieX52fjEUj7Yf3Wo1E7aNx+UmeregIxgIYh+AL+erJd0iXkEjqX+umcp9KKtgk/e4DK3CR/RYbWYwDmdxjZvG6d5AiZlcFeHHRuUMm0zul1iEQ82JNbDEUF3EM1ILJ627W2F4co8tFWKGu7UnpGsGNvA2bZMYfc72ef4JzUtpf3Qnxp3D9aOWPH9v92I3S9AciqJ3CM5sY9t5bCBfMG1a0Hv3Ws/ZeNpZy5RKI6hzLcZmhx5qUQ9jB8J0/7wcE81Xk8UBzVeXRu/NJllISsf96etbrdYv3z1OKdzpV3vj7tOfrhe745VyfLeXgDKW02ZLl6NtzrMcA+/d7Xv3fp91D/zoY75a8H5a+H+pdonEpDfl1ZsQmIKmCmy2m+MSEYkcrVuSq89QKun15zKHiDI1N3kG8msPPl99+nxooImj0jMTPWRUL+/vvMWE3NzkctweIb19SQVUoFEgOTGvTFjWw2dq73F9rC4TmfJlnhbWnZHg+lRYlG5XJJa+c7UdZHbtdMPcSvVGV9p8GoxBBZp++jEmEkzqJRiSnSYCUl7eqkDbpwvibm8PWHWTIvRiUu3TCbUP7TRnLsfdrEFL0n78FVetXhJC57CA3DhwO5e5iF6mdf7hzwzwePyp8PhwxA/9Ae2onj5OvXXfo3pK9qcwzDiApQ0lAB7DUAdsLyETn/s0lA7pxIcVwuph06g1/RIG2H03aA2AqhnLZTS3tAaQ9qaWVKHG8YElD3YftjMssRF9Qf11oYIQ+w/Jq2BF/tYSABl4LIsVOgWMfgHwh16P2Of59PdSq1xb8Qd1TPg4IpI4zy14fPc0Lqy5eEWrPPKullQRT9cQYgNm91AHV/yvCkgQiNsMmML4xcmdiABUlPX759fvz6V5ZVlEFYG1Fhg/Rz8Ou8mFUJTz4HGETQef3qhGxrIbQPoxck/eQArk7MVzRCYwE5qcd5ffrm8cvo5DOZfMwmY7KDD1TCcUIHL/989vQV/Ydff1eg+Ef99+plRH6X5x+iZ89eqw/+w/8eqxI7XDv/+1dVSv1++vQN/tseRk/w+fzJ9tMXL1XyDn08HeLXbvTTa8Cpf4f8Z4f/7PoG95xiNzxPcNGIhR6bGekJVU7/vI6ACdFT+vG/6T9a8unsnDh7rDAtUqT68Pbk1evozeRjMHkfZAQ+j96o0q9U7gk+dH8bnQAOPU+uSMZCvo0HjwYjYYlfjiezYpP0gfIiCobB0+uJFdRWbgweDZdAn0wuJ8G0Ah882lkC/ezTYkaI7RbYXVLgl+skd6H31qj+akKCrlor+8uH7C3zYPnA/YUethY6f+BCktD16XVyuQ2YwC5DFJMwnj+qEjfS7NcXY7x70Pa3tBHdLe0LUa/NI6LUxIPREg46dAZBVlxeasFL3FdfOMr5y9Es6vf/or37bkOIcD0fPVSqRo2+xYmOOz2Ey243yq+6XB6yQEl0/e76ypEMaq76TpI/Cva5h18G7Ccd/lIEJoWOKwRNSdT0EL09S7DziDwlC+MlNUV0Z4RV6gn4j056Fn0uD6YoNxlUcZVqgpS6JNuSjJxM3i/QD53x4qnxrczS1teXyQL900LW5zRkNT+dL8IcKIRf9LoiRlnvJX5IclZ7/Z7oCL2JzJBofcoNrSVO6fqXFMQ0Ek+hVT9RDSf8rL4pmyeBbuCjKtJT0vMcXOWgVARU0/O//kqXdjeE1o0UHIuuHOYTSk8nNHM8TuRZQ3VGlLsjglghv84WSkwlKJcnwYwzbx1nXhvn4zmM2xfJGbLeJmdSvOFQVejDkRgpjerjZPykeP7m1yK3NKmbw8FKe0fy92KcT2ajdnxwB2dGMUZnLguapAB8oBh1xiRAfIqX+CVV6SIA6+EfoHDIS0EnvkpnI6KOwLPKxhcA/G96wxiJX9/Sq05tnYQdiddhOWw3YHFrHjsl52ycY24OWsHUlQUhV7RC1nShZs9zKpdghyKipHl0Me+4iBJKdbJ9HtUOundZjzNOzWy7dejEUJZRzucTZeg+nxZFju1C6ceXlHaCBKIsL3/8TyGZHRo5zBE1Vf4+XTW3DgPnTrAHwD+XnBfQjiBbdMxnt2ifRvEkGV8EPyUp0xJ8qQ+5sYygmF31s596nJz/ZzEqV5HGn+C8WHy+PyBz0r0H+yHm64mQAsxPgFonVEmDIcIilR+nUt0qLZaQsnmo+Dh1tnLGW/k1PUtZFA6f3MPly9Bkmt2V8MP4Ud7ltG0grEq1aCc0RNwMVLXrbwJQPUP9GrQOAf5cendkuGhQuyVL9pKOw94MuuCdwbOdf9lQ6K66BrhyGfU61mcTDxY7Mg09r5qOGmnjiP7iCKA2Nxt8w+YmyvzrfDJ+DuEIM1OPrxYGUEjxofzJuZAJVMf+i+rYF02WidUEqD59xOHsOoHTmGKufM+6agMquzTv8Hj1bNQi5LQq44mN0sy1eDV/txLfJDeVncp68STifQ7AFiiDc+P5NDnwtmiUVhOOHLrV8nKkhsLaGkYwt9X1VNhwjrMlyMVSpxWSf4K7gE2hCBovSq0lraiQ7e9MtYdnVYelMd2cTPhwdOR3PhAnyikQScccLR+cyIuqPsfnTz4T6WKZmJpZMJ9V2FHEBBHW3NIOT+jhrDdWD634aYfB47y6Ta4XNX8nmYv12fEN4ykxCY141D6g5uMW9ksNRTEbzZdTWSa9KZLLK+zXKklLF5AIN71l+vOC5C5qcX5Umr46GRG5og1nz0IWobUl3NLxIGJlJU+fokaf0Lw7oRApkijwPx2B7F8LruRxdsnxVs7chIoGrFEZ6IoK7Ysx6ArOCzhdL/w5HgLT1r7nNbI55nfbA3IKzEceBZ28Op8rvunRo0fy6fkZvaWieSDiiB8qe+ZbqirmI2D+jUdDIK7DM0kzq+jq9S8frP9u677J6KvnYMB3TxcPTF/cKCelnJOZBAckTJ0yfPyvhxvofflCjq6fNRL1uLDv1qvUmpbPzz5xnW6aVWVUm2mHkvkKNp673Nnb3o5KBHImJS6k/mZcOFJhZ3rnc/W34+TRo5mbEL9zPk/DUS371EM1aBX0unjQqRyjf8LdQfo2hS6xfkPztRoiHWbG0lymmAYXce+GVcUyrCqcvVXrP7MJMH9zFjk0rxCO7peEAONO8XUWHxoxdq4J74KE27RiZGZa9lGqe7k6LQ0cMNYTzRwVNkmqOAlj8Do9l4IddfK4nkbQ4n+Bo1YBwvTPASFjHtOsn5zn+ladLCYp4e/fihnx1ZM5ilNmGEZe5MlUXf/r1VxRQ3FPodkYOtIt4D39eTQYDZXScvPY+/r1nn69hTcAwBCNvkcDqtNupfG7gWAgZFle6oLKQEcVmcV9K5Cy2Z2COmkQkdNAw+fvDAD1kcY0U3FGYpNobMCgpKybe3ydI2i3au0i9sHuhEcXXaEm5nxO13OCVgKZGZIHwQzQYnTR7cy6gr/mgv3lBGjALSgTQ4q2B+tENsG6Vbp3pvAyDTyOq+JVgEN7gWPzRMMYH5kpF0bDVpjYcLoObFaj9aGC8Eq7K1IFb1GxRO4Va7csntG8KxnphttYWzvcQrqGOp42N97Z6dNvnhvs+NIQa/uTNsUytsgqgMsWa/HlrK23qg2CvGgEfcli4V+VyDFHewjCk5jG307OzkhAwj0qqY2xD89Ihj8bndHpFGXXszn9Vk+TRYUlC1XenbyQuufZkQht82m492QYiZH+eRyxTVtiRrxc6l3jUmhDRy4/S7vIiwB0R6tpIGogrD/JE93+81KvCKFj6Smpu/5D1/jNOy9ffNx5M63JkLi6N4brW1v9xpkkq7a2bcZ1hV/sgMqRq221+hQ+aZ7CmVTOp+8NRvR2384M4DK54e9k1b+lvevwDDIp7XhPPkPJZT681oebfu72gtfPxnWARs0j0VuscUyiU1NCOVLxzge6V1XKsNTGAVh5ji3rfePQq+mxDaUiiGZXsJfw7Ghn9MDSyAq/eJaCuGugyk3o8n1ct3tpae6zL8tW7d2pZ23uPi/DxpAdOuAqLPkHqoQWg7XG6q/AeInC5Bq27B3EpPVxyiJuDkGOm8OXF5rvevKZ+oNrBGzFq+oqc3EOHKVNq/PSQcP4XnMGwy+OESIPgrUUlECRgM7zoPLNLMKITVpvOIjXxdGMHkPptedjL11Mkg4cCv1+le916HQbiS5Ix+f5HDteUY+/FmO6y1429F14NzEeq4Jj+KDK1Tho3Krqi1Cxf7BQqpwkTcGqebizsONj2aanX7+S9s+UWDKaOjKn7U7DSn6UsAH+1AQoS49WUz46amoX0FxuzOSFLGQir723yXC0PViv8hNXesG1z1qrXV0hG+03bsy5XNFjOMojxajVDbxpnFlUfftBZp1Pbsu3PunsDWmTFsh+oQu2LzlUG3sc0L95X4KXuiSjh0s8Ax3a4l3VVjqxPK16iQEsBmafdhDl7yBObW6+Ia51WPSD+7rJ+2j+wyy4D3MNdQNJWtCae5zjluO0VT5kJCGuGwRQthxG3svLKbNK32XoCIGUK2G0v6mucIYqlKbqgwc1QbK3AaP/NzAX31vt94z3e1bt9yx05MVKF2OTLmMWVXZV4wy9ZLxrEGWquXlONcms7fJCC4KButUhTUIdod6racIvYQmqQ2+YT/jD6zDAZqDzQnEauXJ41LnaxNvHN8CGe7mZgxIfZDW2J8JRXnjkAVmT0WGLaY+FeOEVFaBPPmNwbRDTJjBIK4GB0D+EZfbJZ0gRe2yYwkZT1fII6d6ubT8iSZx028s1Fvpd1uDQiPsZs+ACFCRrigXCceN2vwFIv7BhrMzBWdxgehqUnmG9i79K1qFbgloqFoUu/maDmOYEjaG7sqyyRLPLxmxN6sENLiSkIpzqwjzWka5vfCyL6BYyabEnQaCLX2DiRPSEKM/uAJVGTFnOCHV1vDT2jz8nrmrnURjKDPyaRY7TEO/Lv5yQJcvJk23RTYmyhb38nLQLE3qozZh7QKp2bVCOkjb/bl/eG1Cd0Mk1OX7T6iezycc5e4tN+ac5DFmN+l7f4T5dGOs5QDcKAgfccgX6eNW3VSho9vSLu0UCWJTAMsxhH5IImbIhb9abq1etI/xuuPQ60opdnWdXUzICEqO0+yr9J03x24kmEVaZkH4q/aPOfSUT/ffO7N/D+2fWy6QIqYIOarQ7x+KKWZEfPjN+MEyvKizg8Vkxvnn107COHWXEDkaKTFNyV5/LPoKIHv+GgiHeVhgfTBJErcCUFC7RYivVra3ctKktNtdGvm9BG8bJJYukF/orZI7efPbYnPFL+b24nP8xwIFR7UM1OoSZuapyNeZPyaxi/pz8Kv84mS86JPOZ0f26lDh/oERZS0QVYWQ3P6MLOYOmtI75+Uz6WsbR6s3AKelthIWaVkuTqcPiTcZmhix7Rr5zZbv6FO4rC0xtnc9ngJ5dwoPO7n7YwxlH+QtqPeZnWsJPcA04rvf6UrEO0fzjOW3ODqqGZlp/lPauemie9hwRj2xWFGNCDpP6dJZ87IQo6+p2uFdSR35EpciCgoQm1lpyZSfFOCfr/3kn35kCAj1OZkXS0NBfVMCdtK2ajmY+TO6zq2vSXtTcx69vnz8MzKwKKUh/mEoVefD45PjFC6Ndwl8O44HaWLQIvSR3DI2W4s6y3O4g/MsOFudRqBex2dV3yyo4vfF06/kn6hRV+tBU+k6PpfN80A/i4NnJcffdq5chDnn2rb0o7Lw+cv7+lrR9u26RfyMOzO7O+0/ecSLdGaG3l8cz7uWDqpfHb7o/Pae26Z9aOxSosnhCeHARd/zpaGd4au0YA0aqaVBp4zaZvLBLhji2asoYKmwmKbtqYzgmsDEDXaVglkgxMc1y+mwojezeuv2hSmOj7BlZUgMt0d++hSgB5Ix9yuiSGdRNoET2b0VCk9xFWkf06R+V85IowAdKHoRhb6584m0PLSAFg251luT/OCGR+TKAl+djIm4uSDQn3a7H8w48qQ/TS+Kam9OGI0z0Fp8WxNJofY0mULRhrQiIcrkkDpXhYr9Dk4xZHn7vmHXSmoCVlnDHPWawEPrS3EN3lSvr9whxPohrST3lTsBZbl5atPtGeU6Lsh6dQ5Mkj8tOQYSwuJ4+OR8DhABm9Ofx/C3Ru46vfjj+9w3OrQcj81JO6jN90boAbcg1Uk0zageqlHO2uy+pM9POvJhfENIz2Qf3zDIqnUx6QZdV6Hb5sUjfLLKnnKeSLLrpZKqzhLcjz7OTG37xJPbmpFOv26Vt0pqnT0/ZCqDDzPub7tEXJADj4jL8QrKZL225vexyorTeM/CymPmbNlDV4E17e7NF5m8LOSvbYTBuw7MAZlaueoiL1VGWdJ29dm5Aw/MuOOV7hcOr6dp58TS05tScsuGXqul0Oo0HZf7c0LBinE1y+gWpRWsmHsKrUYC5+t9vfnpGjobbCljAEBIgimrRqL3MsaAnY0Zz6MAyixVnBZ4EHZi//XGlQmNUnh60vJvnG+uYxP968urnnpJSUbZeupyWjjEgMdQl6SWqDsJnQTsTtEzEZepRx7dnpDU88DncnY5qkT2Fnb//3PnCVYzElP2cCElvtKPBTRiGJs1uijsUu7h5tOF2IP4y1dYfo6Rnft5IQWrExXs6iXO6TccQp5GN2pu3x6+LYqbZUQzGj7XFxyao2ifhyFsvlbs4X7hFeAJb69dF/K2EsnXX+nej8pSIGT9msI6wPoT8ctNeIyHPZFqMY+s15np2Sbgz39zUP3oXf1yB+pPYA74BacvNJ5dFD7JB8VuR0iACNBfo9gLlOutWOxrOf2CdtP23v78UdeqA6/OG233+MgHy+1E7WWUnksBHa3ba5kIy9OMz6iyk6IvC0BWBH0L+0hnuhBayh/6Wy52weDNZJGpWq9SZTgqj+vb/D7K9I4OFpefIlTJhnxVKZvVT8QehREs1zfrnJLmkHyvqP2EoXbe/imXj5htpeLMM49TxEdtPnX5U21iJa8eoCQJ2H1W6kd7tMhkT85cR33VOTbndYIKT9Mrco9sRtsl74o40WZPzfDrydUAB9SiXCN9yAOKdk1h0rf5Uv7ri32f/PhZLx1jSFcWy8yOCvdM99PXrV0701fr1q8htd3p+tqFHLVcUTTOu4j0JxG9T5OvXjVssKVPAV5i3jr2erbMbJ5G3ImpESfgtxf1OIu1g3bLZrdCXKL9c0VIlMPEYfVE9ezvRgWYgFp6M6D3FTf77eV4g+QZ4IYjTJjlV4zh0JhBMZ9swmIDZ49Dn2gkTDzvnCw6yskmFuAkj6MqhhzcWvX6PJ+o3CZoleayPu7pEKMvnBuyIJJmjvlXBePIS/I8im0W8US/tZJti/0UiN+dCzCthX4dfvD75nTk1j5sUKkHS6M768H53ZpuDsHyx9lbgvlvrhWZdoAEihO0Pyqc34mD7thKGpXdMXcWd3wGHtwsz4X+q0DEcbfwXNKP02DQeP+XXA37CjsxBNJ7MWBmOHtcaF0tCSEivZnSP7fhrkoNnu6EWodbugNllkcxM8UbdYcs1tq3Dnj3pSGnbyn15cEAz9gebnOJFxOHIjlodzlZop6U+OA+F5Axi395glZiO2wCnUlvbNvsCJRP/hZ44yIeQ0ZOQ6ce3L3+KhbCkra31NZz9+mv3tZr0vMOrXkpY5b5RsIeBnzxFef8s+OthVRDf6tgr2AblGHgJoc27+tHOYaIM5WjHNzv6Ys5cs1E+6Mq0Zk8nOIqIsohLUIV/rD3t0Jozjrb4RUikhDNnyohzm1+Hnk7yM3JATfIesaUUMLaMaR7q7w4oQWjlWHGipPwq+LuqNShBdKBsxfjGQjv0V7F0dQ4pP42bGawzK/QYuHr9WLBF+hJbodDar1thRB7wj+oIl3YF54tRExetJfI1UGq2HF/COq1tHsMoc6cyTitlkdfXi45YvrEI1z2tP/tk7RRvvsf6qh2tb4Ouk7GGaL4KDfprPQvtLX0WYrHGjlKGumddG/44Lz6qYx7vRo9kEuKHWnpCj7kwCejcb0/x2XxU8pHSKIUoP1IQO6MBhc60yWZ6V4HHDQtxOjXDRt22XmDlHHw6vfzcSK7JSh9IwexeoCEDAwrpqadiXpbcXrd2KOpFm1grzgb6mTbyCbPek63pPM4flL8NOxG1ir40NKu/LwXPkpyB8asB6Wc4qYCb4JTzs5pczPlulnLv3gSfni+ukqn+NlPkv02X0PpbQ1/iHqJN9HvgOBYFHcK1OoSsoVwtPwyjFgzawK5vWzNDDZirRwo8v9ABkxk/bEob6jlyRPjtN4D+PVdOi/ZdronKgxuaEEV0Zb5yz1XG8A/3S4mocbuItomn7TMU+fB0mUTXxVQ/LPKjNhRdMZNRC47GSzF7iRDKi8N3kTZ50btdtARtjvwBREpE1Ss8d0kv4S/gsn0hW5cIVeEoaJlofkt6T6wgcxtQcKy+cJS4ptyoRj9mExTOd8Jut8BRxxFYuSUGola9tE4vfIfN5qFiV4M6WtLEUISjSkLTgf52rcpU2gOufkuaqr60EkKkDIeNpL1BI0lke8KT+Mgerz22o84vJxCk9iCg7Uv9ARUn/tqha2fp+isc2dAbYv/R9JNwyojB3j6nOSXFQ0oMpTlnwxvfQgJNcLx5aJ2PAHb3d8O/kP+56BeFeqWWgEUMpTi5Sqyvn/DEqb9O33nqvL+/a+kigJk4fvxUqSHs75TX769fXTkkoa+JrmE4HELv+Et/9O7d/t7egBDnVOpf/dNTOail7+zvWr/6DuywATu0frmwOw7soP+w/OvC7dbgHpV/Xbg9huvvIX+NElJDo+y+Krv7oA9I/QvpD3T6oEznth7qdB4d/0L6I52+U6bv8Bz2dYaeOvzijIHO0L3GL84Y6oz9MmOfM3Z0xoMy4wFn7OoMnkj+pTL2dMYjuWFyHnGOHvdDPW784owHOmNQZqiB30TOTijVm1hX2UE7KyaaQTOD9JYKvxGHWZio9Ibrh3pYuXvpR9mBC247G3FxnWA6LixdAxAVrZk4gEKCS7Hhu+fFVXLm8za9ubnTeB/W12nNQPwfqRLzi37uAsl9ApUYW6Ku9WUSpRPzz+mZCG/cOVfsDq7jTZfxNZLW8cqzV2hZHC19vLIab7xJF8X08SWJPnAs+kuEN7VhXE//mwaBpm81BIYPGwsBq5//tjGg8duNAiV8C/HxQ1FcrhzH8ucsX18BsHIc3PqygbgTr1541ayncfPdt5tG/ifiNIxuvw4rAdDM5qY/09uHUjABSkgvUjOJf45pvp/A9aD6UnJpizVGmn73/dL0b2XczFkSLIglykJDuaU8cygbAmJfL4JzEOx5gNtc3UtHKcZHvNNgjvJFLuHyGf3GLVj59vj1zU/klRjFnz7bfhOYLuB1xHLl4Qt57cS1n3O5uSpGjLiRXX6cj+7fVxd0PE6MHj58eB/DEe3B7Pt9HTz70O0Lemo7FtgyRhHO9f/MXP/RCvUDru/UE42o97BkSlMrSt9Apvp83R44uFqtAa0cf+C2rbuAVjET2k2YvzG/rMLpbE1GgQ0eIU9rZ5D3NIMaHSsF8qwXBFWC06O2JVPM48kY2VYSQ0EfijHw9YyQZaHh7KTo7s+A3ET9berDYjH9Tk9T7urwgvDa0IKXrSNReiaFH06888BZWoEVEGFk9jKqdp+lypzQKsEpFnHmmW0IepWh3ZD2+D3o7quvh+YLt8pd1uovSU2Ez6OO7+kNrTbf3NCuTifxTz8MpZWCY+VOA7On3qnvi55PFoBvbjqf1H3YEuu0lOzCFVoRCh9V6zcio5fhnhRWpEKEO/MU6goybannvZ1wDkm/evYbWBOzjSsJh2bTJJRe/1L4sGJrYPKMS+pVDqQzKWUq3ij+OVfGmmU9rHFRUgbWJYC1jxLdxyjgHhyx2wUS09ERyl3ABl/z2EiOktGObI4bLhFpF15duovYBNNym/RIW8yjj0yJj+nafqRnPben1AsJLPMBcyqvurYyZVLGBoe8CT99ejb+45xcqqvZI2tRHp7JPD6fJdxSCc9G1hQrkSY9R743w4l99oWja7rhNhFYU4VCKMZV4oP+SJRJnDLQYJuBBXsj3cEczxD9l5omk4eLsqsvX58oc8ukGq1y1Xhe8HfNO6JdYae8f/0L7lJ6kpw5st6+AsCwPy+AcPC8rOAKTx6/Vvne/l7SLgSaNiDYp+RjEiGfY9fRUFpA3sDNseqkswC8uy09DFWcqjHGuq+1TbId/SIaDJy3+JStGPlJ/ce3b18Tan36rCsUUjjJulMcKCfyPNurJUhNhA0eiRNfys1xfBnuqgd0emdzfMRtbrK1ClSFV8/A7aCtQKDaY+ID7THR3UZJ1LaH0MpK1CmbaaumV5VSbMs8fplckMUO+/xYt1AYuZs56a1A2UpDIPLs+dvNYLR0s24kvZXbw+qNu61R1ovWToly138B2IgseR+TpcsCP14Tp06PLhn9vqn7uVy9Jx3P2LcqwD7L9ZO8YaqdNZLaIN5kZj1ertz4vH9jwllVDll6JmwjYVj5W4r/h2viCsOesqkOcUK+nM5VeJnM/JJZXLXH3UdVt2+qIk52oxatgdxso1waPKgzsSndcjrk2JHsNPNtW5mWLVFGBI6tcyiJXdTsNQkd6EYDyE/21t7C0HJaF7YyHKee62MVXNktyxPPlk+ukvOx6HYGt238SMyVzxK2HreiHnfs4CXw7yIschfkpjaa6DzHbu9kUhATtfARRXhfa1SH/RqcM4lRjBRb5Qu5oWskApGfI4046iU8yDsPEXM0Gk+5Yw2gTuiL6ksdzXTw3HGBILnaXUOFzz3U5Nq9Kf9UkeV6wYENbVcAncy4UaAfNcB3ufHqxep9sQ9Ab2ddU9A5fvHTY5rfmyXTW+Rsw+SsmDO/mdzCHFHdqj1dXoRbd5shRYPNFJlp4WmqQzmTs+GfHQ3qnZ4GhH9+Guin4O8+QbqCO8+QOZz8k+QBXIVEDrB/phpA7ZOljsryvKgRyXZutToDG8eEFKZdwa5ZeOuMY+VGpugZM3RwTqw4AsNOuDoay35YDrlISHlPdKu8XcRqmMMMIZ+DzW2UK2IbWI6tz4ehHPQPx+yfpA9nZJJbSZSfEXZQBvKaUECV5hYzA7o97piSbejjxI0KyxBK9bD0ALuLZ+K6vHPGel1XJc8YzJlRscLPs6Gjw8YY3DVOZ5e2rHaDbslUH7yHEmcPO8R23rHhOrJx2gyzGKvipAGRETtUNlKPf672SteTG8o1HOaihO0yN++KcGXodrcxZzuydxsnunsWOp5febqTkP5B/6yFA2+Cy9Qn2sgBHpUwTfbCWeY4tjPpeE0+x9rA0J+8/QqXncu0wUDRXF93ebNwjTVQ/ayWYGOdNXAm2F2CUG3tzCAOr0hwP2iW0S64no7nJ9fv359/aiwUfLT5HdTmtn9a+mkeBuChGN/2gnAW+CSZoGi3XlZNgLeoykHJNRzc+oPO2bWhom6u3N/uP4ADHS1femYTMBwZloTFJW6pxRMlsSN2+Pp1MIgd3dZ9W99K5rGnoTiNmBnRCsQxszYlK6dPq/z7nlZ5iEC0XdH2ejNX1yI83+RDpmaDJe8yVKRysOdMl5HvHrrBnrcHhx0wD6GQBQdx8lDCZohonFl0C7DuXump8upeT+lxsFmXShWcfCQCHp0dfaYBWW2maEP15D4X4vcnih98hTiePDXujkmYJt9majNq+3tOb//w+MWbx8E2gmdCuHDpZg+8cwguyk00/JNvyoiTQgMvxtyAf3og+0N5e4KYPRoceI/aL7ebuOG3TZqI0FwbZkYb34iYgwZiDr4vYjbx8kQxit8PM4f/7Zg58GHm4M6YyRPUjps3RbzRj3LFV1NcyWsYSP90/r7AK1bIE77qvTsfXlKBBRVY/pK9YuJs1DKYij5yn4KyjQ4PaR66a13x4CqqdieJ+7KId/b7famOGb6X5O69RCbl7SGX/VAW1uduqDyho6yVylcMrhFXjJwKUU9H+BXKdZFtAaupb9zLsrktqT9g6hMPkpjZkYGaxHN+2mxi40Zn4K8ACAHtiDz5LNG3IkjwW8jmpnxLgzmjI31Rw7Y1MAmdm61EI1Lgu56ugUVoEPWq6WZHti72N18Q067g59ZS5cRpRkVRi7wtW1JPbz4LNW/HQGXx4NB7R/v6dVsZ54rySDVqFV+/+lLv2bBDWx9zoIyirN3j49lAkrgGNZWmPI8pQY5eOuTY0uMRn35DPOToIy+DhnzphDWPKxfI8A0lEzthcKqK04b7+nW4c0D/9g8R4f/RQaLqubkx/nmxLP4zdnMTMNXYJRyR++YojFbOQoer4qHKjdaaJLHbosI6Ifu+6TsSZqeY7VgRN5o5a8cFnR9/HL18iesE94DraR8Ka1BUlHnZqFM9Loc7Q4ED/9jWmuZlddBEIsODkG4ANXfjmR3kW5nyRoGxpJ4bxXe9S6SWRf1TpfrQEe01CfnFrWCU3tSJyjAc1VPaCQoyywfX2xEUbKY2whE2r468TaF5zdLR1m1BdGr17gHYMIy0eyn2TN9JPPtC5jFtf47k3SQt1rG8lO7YtZQkJQeNCbu+jAFlhDLhmAUlQILbs5afyjGct/sRulOQRTRdx2FsHHy6uhzPYwEFL1L5myNQZTLvUep8kkx7k9nZ/Y/z+3SY7d7vP7yfcCGSdojD25a4PyOjnvsJmel8htLpwX3dg8OD5jPg3buF2uakFZ4Vv7550VJLfrV4z1WkxdV9pbN2f8B/e5/meTk0ULpLaLMZwOz8igAJRbe5KvpY8d59cN/qzuGB9bh5176VdQTqtsKPr4db3Q33MuJbeb7JQIhk6iDmwuoSfXmWAqxHKyq10Ve3wNDCvfH/Qbj3f3Fv+O24l8fv2Cj+Aj/SIyARsyguE2AYlZwf/ItwdGF+yXGjzNBXZlyWGcNlH1rK7TpKMCe0rHuYWkFb/GdsJ5O/OOyO7oTyT3Mh6yebloK2PW+/vZq60lAvlFIKVJZMnSUVxeu+3x+xfsm64CFpwYSREcy2RlQTz8BZkhoGHGTsgs+cJeNioRUMgrmSgfeCF++hAF/qyQfnc6iNzkkrEenzQsPPZf2lSelwB0ovOvh4TiaMKdWi3KsFyTh3n4fst4wSOFGeRaqnDRVoYMl8uk+m/EThjgq9LOfQVm0IclYm4QcMbq3UI0qolmUIASHYhu9Vg++qTvS+fmvkRSe8IcfcEe1qFgyAoI4qtGF3dVjDq+TTtr4q7/fp28QzbEQzXDJSxH3hUIcrwaw4iPyvHxF3D9df0HRmyQMQGgQ/VZwB+HUsZrFZbBBVPQt6xA/2beEAFz3+gGA3NC3cSry/40TLYbc13BQtjRYe4Jdd80NMpR1UgV7IytestqFRJZ0QGLahNIcROOehzMJRQ+Lg6OGUxX2qLBTrbSDb2qOY5rgDW+O2dL6XFGJ9rGZj5ra1lCyFUdqgTMt2b81LzRpKl0Kmy4Y8lH05cDTOlgE3vDzZAUlalkE8V04IQT9ps2lSJgOOWBGIbm4FeYYjISjPseu2ZvI67TVL0bxWsTZ+R4iNQNBJWj/UnPW2sODLetsPt3e1CYTs426uqzAnqYZz2liC+F+WNMkHfrOJMGo9ah3d4xXkMl3eOC6IGUHJwfL2nOaaumZtQZrSWLixntsV3fid3KJGsyQ/nwRjsIH5YACq9PFSdLOu0HSJf4tuZ5WGnPKUVItgJrrLdO6yU62Q0pSI1oQpAcvjIRn1zgzoUOruSD8YULMkB6tVlIkh/I/rYr6wDYdK6xDKmX02nG9HqDl9ZybydGSmghGN4/G09n7oX3sXpukJqxwKmRh2xOrxiNYO7DBNW9mJnWYnfJjhxnx3KYaxNjmpq8VwhAE3SpkLgX3WWjBONWvqXmJSxGVKYiFqcbe4OwFL1zJbryPKlEKHL54Y0oXk/BCAxz/7wMj1MblA0XUDiCOJQXna2Cj+dr74oLXXDQ5x4WXK8FQX63ZlcdbTFb0YczXra2GzrjVR3KwMKySMfrwIj5rDQfRGdCJjJVsI1oTeopsBNOpJ64WnexugwdufTkQoG9XwuMjQlZXW4euXOttxNPblRhb2GPDFUzpw1u3MMUkKz98jsaDOvLxekLcfuzNZ7DZpwdOsNjvrVMjrqMR2SMZnJ+udXKs4VSEvbxYPWi5E8Z7nycdMBk8bAlKRlhZifskG0tPzT2IfRatxiI0bnVsGbRwEGzNIQ/o+f5yDi78t7jjWJd+lxuo6lKOj36dO2mzfpSJob6kphRmodtqIim/0bxU3YgnBYjO+oXojaIrvl4t9hPyiJPcuOWslfyyYufHhj326+LIrmr7bfxjXWFQXUfFF5xm2vzrKwaKykWbJpSZMWIlsndO1VyxnGt1NVap9fbmBUNwI1qUIbc34JEzjBCtTUq8YO/wd0ixb8r5Mw9PYTVSbLNKLl7kr5+oHmq7cXumRw2N6D5tx47BhHcKeqk0dKrIZIfLpzydKaFJ8QtmGMqGnhKou4Oe6d/VgkILCHtBPOCAghzAkURDkkqYHOnoaytuSMaVLys3VaJhKtEiYG0ivCcFESxGs2885/G227LK2wmZ7Jda+UTD+bePmrto11rws2zKlJu7ntbaNNX9+/U2+DURpvLWOQsht9EE87bVpHw0P4akAqB48/+Xpz27mzuGL13/sBlrY7ubtIm/f5LnqHRUrexcNDzg/WK7gYYlrhnt7pURn+bDRcDmT82kyPrxlvyDD9DkM7hSIrtWjuVdm6UEcB/3g69dG+mEc7D4MNjeDWvpBHOw9CEOxfMzrj/IQpMlx/hGlLJpcOUQWj649+YNHg1t0iykjqKDdOd99EuK1ak/iIumrnehUGkbL2l2+Bet6N32t/gD8E2EtWLTJ5BmqZbOpBAAYS2rZX7+SO7mdvYPyKbkBGIYIhG2HkoY6tqhwFSeDkPh/7FJimtFJPqCEvUf5c7/8POVnIfvt/NQilP5pta7dLjW3XlnqBLrTmDrZaFkumQDpmd2WVR8uX1eALJfjldr1mk9qiPCYyDsSPL+0bnmtdxfULRkhV14i7btTR5bkXJVC9xNWuf8gPeQ/6INc85UeARpQ/Gqk7uF/8snEg2k7mvqD1YfTn3EAocG7EWMej+fMuUSdtYeQBC7y/8cfO/q0393ZucWgDzktmDZOoo2kVQGWh3udjZ3hZ6uOo9v3yhL4NFZkLYxPIKr4LhgvSMkjrR64kobC7uDQ2pwi5C7WODgjDrpv/CW4m8GVwWBD+IaNU0avACBM8mr8hC+q77dEZixuDzfW7AvcX31HdFnMJnTvMrPqmbT7mLXmDGaYwVvgU0ZL/L3wqTwL0jDxWGWkOAWMaO3FU+uyvbPLjwDuJR/wtvCMx+Tgl4Wg9hSVk+Pn7xxJhYfF4wzi8TaSMFoy6NVnZakYqnmCiNUbeRuXyijpf4eG1P+HVKJeX6f0bEZ8hYMOf7YuVIXJ4lApnnRmoVI7sXoxCljmNqLAL2rds6JiPLsbt1aOGnUyxh9QvkqPiNNAgUwaNPi4wfqFgXVT3az1tJteTjUDqEqDUi7htxtstmzgvdSbom37DVdvr9XctrY8omXnIsvfzNfnuJ2a/3ym239f5EVw1xeuBxvLwRG1aem5qBcxwmjoEid/Sca9BlJN9UnFTrWa+Bh+p4sqK4n7hl8KeUci/PrVPwtlyWzsLcdN8P33ku+4dBXwVHUkzPVAjPgWrKmp0OEemJUR0jenJQj1Qm64PXUhMq5k4K9EX9mbAlOot4NI4R07bVMGyOJbe/qWyfplnqr7NEpFZTjm/kHialT1RDfBk9jWOr5r8VyOGa/CbWXdrbUc1KIX9ALJXXIvBSV204+1x3ZCF5kix71wXaO6weD9f+QrrhO1O+hidl0EEJUfCdfcbeuQ2yeahXElc/Jo6BYVOl4YKeqiOBUrawCj9bTIcTqhhvwcATuh5fOevD2iIpu/4olDazT+VcZp4tgoaKIUq2CUaAjTNDu0vpPVsb3yDwbOyZLFabVDewKPGAI3F7bPcHwCZ3hTSJ2kPrUaRiZi2brrSyVKlI/TKLNwOU4i7iSWU4RAYwsbzDqbHeoqlHmaFDKz45G6ahp+eD3J6AxBsTYG/rVpQA2oqYqx9lS4+hkn6hmIo5dBP6NBdOixiVZ0if7Ruu0i9p/am72nJLvl0+/J56c/Hr/m81DrB2nrnjqknTuk1dw1kZIy+j3Uv7mAMQvigsapLoHtOGBv3/4UuYPUWj71jTDckeLpZ0Lh8yyA1Jn0MGl3YTfYxYH1jhqSm2ltidtirmcaYjqDyik4utcf0RG3Yl7jQbOIXQvN7LLpi8tZluX0UdrOLfZF+mfsC+8Ksndn6rGQ9hDDiJN33OQa0j8vaC/MCo31tVgc/vfRwW4ZyIrG9V5XADeG2WDfm7WDrAferCGyHnqzBqcctWiwJ6RxWOrWGkoXdx9JUdOgN8MD/pqCjLz2tDo5nbatzl6P/Y49095P50RaxhUCWtNEuY7+oPIC3O10MCdW7N+w27Gm4mhIKRam+Xrg19tzW2uNJ+yqy85m6sW82YIMmk0EChxOv8JR2cHjFy/rQTEfv/b1j7HEDBL6eGUXE5mt7GKjjaU93EAXnd3qn0hnwyb0kXmuZMtnKnj961tuly9hncau97VroyXBDdSWl25R79TWS7KytqEZ+J8Pv9HEiuPU39Hbnqi1zq1o0zvCNZt0yeMxCowX65/ieKV7NV28aAb6VqnALepTHmWDRyWZ6sdgq4b9MmHACYMyYXf4aPfR/oPhoz3k1HjNvtYp1H0Fccr4pzlYyyHZ6TSgO3Q8XkuPt9/Q460dcvXWhFyrL+2nYLNCPdZ2rrDMb2ITJBIuYnC0lOkf+xDucRxlqJayUZV5+opYyaie+tfLSWp9YrEsF23Rz5NFkFyS5Q/9fvr4aXCuXHafKViau3NEIaUHJ3VFiegH3VCo2H0rsfg0ZaSikOLnynZ8XNZZeSKPRFhTEsYDNS7q6mIsszYMT2LHNe0iziwNs0oNkVjU/GBh5C55N94JE9dpo7JTgqNQtkbCLRey+vIiOBmTKPP8P4vRAPc/0bXn+x2V6w5OqagMajldZA1Pu3uUaWTdUnguZe6TfDFXDvzYDwvdCz9iDsVI/b2kfFwO2dvD+wQINWBd9KRy6RY2mFbUrw6O1ind3LQw3cxvHflRDXRHGhwttOQiDJ7ksKSqq0gHwobMX0y1xKWT9FBaf5Hox83ToajfTMAdNnK1byxiURtZpXMiZCqBzMMdieb59668NzBimsGkD5/u5eel+fyx/OSFMEZ+osobmLzC+GQmKQ/dN+nRzIIatkMF3YDnplxmKoc+VeT1XqYSKvKKSNPVpKrMYZm5QblWZrZjIuS2Tjpwj+AeOnDeBdCQjxzI5mIw2G7fBWsuDAPyuUZoRILXKfCwcSkzG2F+PYVI8XbbYMcmwnWcV4q7bsA4LwiL3G6J9xrZnbWj78ye+zhzZzjOrHmMM2e2YjEaCekeTL5eQCxRH8VTuGELpYMqzb4YXJGNXhnskG7/DCrIWk/Lxf+m7lbEOovr/JJW+fbFUJjLBI7HktIJcpR0u9AVz6ArbpXY3Kyn3NK4Io5F+XZEQwsUlppxEYpqxMm1HACt0ebuvZgfc6Cl2N7ouA8ManyHf6RC5v4Zs1gnX36dcTiyudCYb5myyUuEI+sK4OxER9mVNi1PgKpOBoW5DDQUgmkYj9Xnd5I2pXFHiZBQ8RtONNITulZy3purbOrLPzgYgN72E4e9RUrq8LdIycqUoU7Jy5SdJqc77Ddu5OhBYLoA2uTOh1+y5ObfWbgks7WY4aGHGfZOLV6UOtkmTV9zdl2Q4Xoyowbq+QRA+py4HeY8W3xQb30ttLp/qvmDe/2SO+i73MHA5Q4GLgfwuDzNDZ+ccIiKOdYb8jn9UFnjCTDMlkLqVWpuSElaEG8swhofoBAbtevprnEC9xzoFk4gpRPA5QMe+KCgyUET+DKZXyxhF1JzbPyVZv5j8llutDMM6XoMQ3p3hmG3JMVmp+kyjXtms8YvmC3D78WYFOvjof3xqPrACMqPe85i+LHYv59vibth5CBB7K66jp9mLbNJste0SnMX0KTbi2XS3JUBt1PndNBok7ew28XMlslu0xbPIcS9itVAvV4eJAQc1sCC8zMlYZMe+edZyI3UQRw+R5ku+Rf0+x20DgY3TtqxvrpPSz7FOXGpvdd0m549mUwWx8k0Sc/pAlxGPHO6ruDs89iNadth1QrVJQUaMCy6dIylBrXKrCbgeTyUTfFfvStCTquWzcHR76vJtam+F8o7w/4Ra/GZort7iaqHTz516UYQhldTJHqyebzXUyGH6wBmnzP45NtbBxYhnoV8uByUxlvQ30GfHdO1jLD3fDLLCqJ/Z+PJnM4T5BP2r+7DZAxsysuCRCb7/TV61CxFKyYfOUHjljZ/QgF/tyfv39PQlk/sBoPO9DzsLu/cyWVR0FqtgPrxPKWNDqVY+SBcPrEIOaj29VrTyZ6QUIa6uvZEGvjB8r6AlJH47dksmRe36A2XClQxtLK7Xq8a5fbCNQtyfOPnl5Pp9DNtG0zDuojoFt0g1Z1btXn89M2rl2hyeNsmy5I7azb4+h/PCM1uMzYusWpEx9dzYiQDTgUdlY8ePQrlnrOzllXAslqWFOvyD+vvhHuyTsd35NQ5AxRZd08jp4h9GMFOXRuYOqdAy/3P01DJ/7ij0VcPQlnicr9+JRSEuAceWI/BLs+uguITISkKwJNtedHS+sEOBh9BdMvuyuzkwKi9Befvg5l+MVgSjHtgKTQpmXpVPo9J8Q2flpHbzhKX+ruldpNHSbzePMnJJ7MR9Y0yDn97/ObnFz//daTCkLz9cM7+zuifaREQF5sohPtQGP9ovDQ9rldI3ct4IBvC5lVYIVNCCTep0760y1eVLm6E2ZDGggN5nP+h2lbFOOSLAngIgOXvJl4mgnkI9jBLHtVJCDc8gCRuJy7j34PlIjqq3cY95dROKAmEsITe+5PLGsxbnUxA5j2eg2Dv6GDLcwavwu2GUQvrZHNOqhS2qom2r1dIaW5WHx39C0pW+OkoC7OE7F4/2j90jmBKg3YNdVAH9v77efFxcxPTauXec3Npwqzs7GjV/G+0LsDIzwM6gixPYX4EZjeKj//IDWa4b0Euznzhu/lu/uR8Mn+dkIqrWHmuK7AwsksybQD06uIVbFUHCQ8vk/kHVLW6Ag3s9kAxG2I9nqQqqfi/1/oN7hmMtVa0rwrkbomqOjpE6Fx8s7wKQFRFfqKA2qTBn06SWb68nIFCCbe8gmcPhsursAC5lg27GnVIr1ONBeh2hlCbCOMr2kc/JSvqOHn1k12u5NDEuqycOwWKgV2n7wzo6TsYAHOiPPkMMrG8oiY815Xt9ZcX/HsxSyfz88XnX67Pi4UpNFizEP8oTLHhmsVOsllRjJ9cJmOsek3os1vyTy6t3ZE1evGKCrtJWpnMOc78EExqzvP8d5pt7AF09mnBpPAXtQZm+4RGEhJGVpk3J88w3wbYxpnwyJNmKhmBGvOJCpiS0AX4cGhXmQIigQ8PeUBybc8hyd0/nOSiJZLszY7vJg4h1SKG+DxJ3hdYp6CaIfx09lrgDt6OSc5BMbNdLUQKy4chNlj7RZmblZMFMwBAmNxnKhvPv2UN7UvNIjnr5CE3NZH12WPEwkmc7e6aU9iBKM8XAFmrZa1nA75aQKtQlbisJBbaLoTvFnhU9bKgy/sLaGXzGB54x/CcWOyPyawoNx8DP/IDew4UwPuxr6Vv7nbi5h56m7MxMN7gduy0lgZqGK87WEttL8tbwy3rpraX5T3kljWpS8vqbYR1Rjl3Y7WU0fsr9tOjBiwdYgzq7sb2AmYv61Lm01/Ac8Tocs0Mfw32eRkvIZHRxj3a4XFLSdivcGGXf7Ys6+ySmk6jb7G32G25+zvfY1aIQttN6Jr9Yv3MH5SCpq2jxyJSV3OOLjb3nAx9Hdr1pB4NY09iJ9/XOn5v4YxNG7eI2s1zv64OOBjYc3FSjHOdFUq10PxFVdDpQN7pKJUT+ITOIUbvtC+N0grD0pDJzfb5uCasri/L7wpcpXQ8k3/Md5VwhLuq96brrIY7TkdYE0ADblwUOZxCLRvAhiD8UQMAqSzfB8w47n7hWopnGOpdEW2lOaYzLwGK3sYa878Jy6zJfja+vmJVDY01j/8gG1XIx95OtPKG8KhXk3yMzS1zmZD6mvPwt7Sy6vUvzrxawRIxsW5fG4JUqnXUO32jHKFWMa8yNTc89AzrhjDJVoX2zzJ0qpT+VvvWO4Z59iXvvbIZ1L9se6MJbI5ra2+t2uMooxLg3cSHTtK3H4Zr7Zrh9901dz5EvgOFml/Dovn99SUTqDUPvz+dMN2ZLnX8sklZejVOese2Yga6qXg9ul1Ill7Sq6PF63tvABLus9+DB7YY/HbeXyYWS+9l9AHhMvHt/L1MPGz8UiZfJn5efhWzL5M6+97O2cvEZeDbOHu5kTRY9iXsvEwaTPoSBl4mDbZ8CcsuE4cRb2HQZVKy3h52nHPBbDf5b5k4fHULvy0THzO9nNeW2ny79n7ofLezzGtKsSTg3JItvDSadnjrFjjE89lwdte9gXcrIdnaMo8eQdJPj0aHaXOj9L37od+C86i6gdX0uqieo+itkP7CcK2OzSjVQFskuhjIiU0kRKKDa0go0WrA46NneozP4FNTwn8vdqEMBqE2HxIhfR1E6bjPceH6GKKuZkn9QqbvVPoK1kCODZ0fhuXDFXrJzNjksugRe9cRaFeT+JFSunWzT3z8MgBfwTcRx+KjpGEnoWaWcRZcTYpq5n62+/V12+mW+M63ISXjfFt2vJUMhCzKA66z5ISDGZ6nBzKwjj5nfgrw0KuHPSZuSI29NmTKR1N8Ur6hSjsD31B3Pq0+ywFVHeYtL4eZwgDrAdGSCqpXq3dCbWZ61L//9O9PA37N4TS8wrsJP9KO3c7Js2HhplfKNJx++q5sZHtwqp8WqQ+0xdR2IA0Y9CWLW8qjv7sadteCdTp146Ats9jIeDXLixkQNgsjx+C0mni9Sr/XCnUwV4jYkY1cH1X/10eVH951VUX/GldVw/tmwk9U03rC//v8VI3gHiS7fYA+7+Zkc0ESdZxB/7HMj/vR8u1a7VYHdb2gKsKMFN1E/Zt3RchS/XvWPTgNwy+tpAgxYOn0v6Jp585YejJh1K5oMND7jvSJzNHNe9bdj2k8ZGgDZUoNrR0O6D5DD/qsm8L+Z4Yhfe3xF/LCCORJfzYfD8KoOdlpNBjUKjikG4Yzs20XcTr11ITKlVf21IcAu0uVfTbEz4b46ynH+dcTtga1r1KP1TNClZX6R0nl7gQKxRB81bVSZK0rfQWB6NVkl2RLBdxy/fBGDqDLGEZNW/LH8/kkUyFsVN1VaIZlt+i9ms6vD6QabwVXlxp9Kd0+7cdxQ9Tgi4WVqaKuOEop6foyoATiE1/Z564n32ueTKwa8Z9mTjylyhs4k4+2Hg0sIrKsFg+68EXcKIbz629Lchna3ZsbhlIn/3x9lZLrufecDs0af4ZbXzOftTX9Yz7qtM6F9PY939cQTaM572JwJcvXBJJRt9rY17ZUmgP7pEg2yzW0kMODtkETIumwTnTM0L5R3JgsP/9OorTJbA7n0mXa4+n0UruQRUalfA4FeA3DCEh3s/kCqV/jh9HHOU8BkYernib9j/+ZEHUS0ippBszGzn0p2MEkZ94XUvz12Vtho7+nLGOeEkhWM8+CxCfJIvugI2lMgC5kz06MyAe+rc079/rqEFMYm7FywNlkOGADYvUETYfozvAwi7JuN/yST4IkNm574e2qlGjzJaQHP17H2tFyJwuVvcvHD+fEVieHaUkcyDr9S7UE/3ry6ueeQlcYs2bocedj+IW9Pd941iZqXZs0LrNo4scLQiwMT8UB6p3P1d8OTukEj+LlE3tp56icvv6hGjqyfo+EiBChhaTc+ENlddhzLpBMp0fmhwF9VzA0fnEBBTFmNzw6/V2ZdqpqCm8a3Y830ji5Mfx6+k4od2S9D4srQQ3QN50ZkzF/h/QpqDEhRl9ubiIXmFpV2fjPyYhdOKnNY9zUMHKacmpzMmIXrqzN7ehNQmjFU175Ohh2EMd1QYzgIteRZGcDN5orxxgdUJBRpWPKZ1898K7ePMrMegEFU+OdqQqlK8fyQuKZpYEDs7gvpyp1ilSsCqFit6t6e0WZZyrzzGS+m1L+FeXDPvdePP76dXovvghhyoOFzrtxgYZUq6Ecx5m8iKeUAoDsqOg+m2fJtEBQnA4iGN4PRHcajuCd9Y26eKHZ/4i3lLvBDhcS99kT35QTpmXCWZfgqO6i29nyhOM1YVmhLqKxzIQR0t4MJf2d6r+oTG51/6MrwtaYvSE3JgI3eu9Tsg0hsFzI8udzoguGVgqqdKtsQjlnD7dCXdfKQL4cfdeatrOQ3VvI4OCccvSivDs77cG3Bc1p+nlRzFVcY9eHYEKrtq0OQZfClB7/MpIPNTIROYByuKSPDpXFpyjuhUAdlH1DRPdqc3PZSbFhvxy1nBG4mNC/U5rtZz89e/tMqIpnyyteq16rRhuhVSDqBB+u+0n/JuVA1O/PL5UDkOtx3rPWgiNNq3pSd+MfisrxB5zS2udWRzhnrwgr9KM3oCkQTlkP6N9vJxZoGIGJ78s8VFQ14C/LIAAlShoCjXSqijp3/1DYrej+CFnvin1We3ZayST6bX/V0++4eYqRPwbgdXIaCaEDq9dDATKCClxCFVDmA7LQUCjvlA0Idp+ZeHJOaDtR55xtBbXv3iV55vE1Bo89QnJ+6HMPowcZvEB4L7knm/P17JMsZG7f1HwwmFWOX7cc6ee6HM4kP+flxX5nSX1V6PYh3cyc5zvdUcfgRJ+I2BBB59mbN2r/hpLvFnRgJYt6wHm+rRU5UXC8XToIV02Mh9QytjUsIj8klwv1RtBJQrlsvjxV0oJknslKNaO6rD8obHrEc/X1Kwv40iNbSoCJhyFIHCCXBjxP/igezzvYi8P0cpISB+fGmiQGd1wbtm+DVePOdKQXimJOm+Zjb0IVdIysS3SdOUFon64Y1VLhPqLrmYXfU2j34nRRlRYzdcOgr/eTDLoNFia/plPg7cRdKuZDucyDZzsHme03/R3BWO5lKT88lVlsp/UlUsP220cmnWbLTZD7FrXbwfPIkThKpjSWPFZshpLRO3vCWyMPaO1dgSPxG/aEfvw5cuc0gV/LBL4o7/XdfWN33zkk2rEno52TxUJYQYJwZrG4LkgCkoFeXvIQaDzXqlL8MkdJMs6DAjZcBMvXChkkFTlGviqN64DiVAU10SENk26nzUF133FQfaVbQiXLLbeCWZHkk/Hl56A09zc/au6tdWwSHgwqdvxXh6OkK1b2jW3NUPiWvSxDf5A8WC+OCs0RLu0VHCittn+zesKLEah77IfJZU579u+cRN7dFjUwJNmB4Abr2Mjp6vzhXW7XWQtjnB7Twc7d9QDeqc8Wp+Dp+K37bTDb6fRznXjrznHBb+4UENPpkDVp9yfZogA1pL1y5U4tiiFhnZ6+fPHyGaI/exZ+61Z9BRO1RoPB4nxBIOLFewi5iYJS94lPI5qjKlhMzJV4vCj9roO0qvCHH4s0mIIyH4J1q1t0bvEE4xjG6JtbCKmHwg2UXL8/hWrgrr/4rW4dCj4Lt4Rp8T43icr9XWjiu+mH2wcLp5d3xAF1erNl9cbbD4Mch7W621BL1AHPr3D6/nNanDWyEBT6PklQLv05hMnnY8oqe4iwY+1cN9NPGBi5JyB4vASRGImbrlFex4t+o1R5cmYhsTDFxwDb9E2R0M6SeW8yBnjcKDWkPEMdoKpuUwyjrE4gOLIez5+cjxPy/KRd7uuHbGblGkUhkgH/omo3OhqGw3K7Fy3pXmR1T9cFTVN8R95uVUA0WxafUZtLxDonliJtdlym7BrJ7vdR6jY9EurRMLVsjHr/pHiUHcOgZFXeNiVBxabkJQck0EVFzveg+u6gS87WNgsRo5xEdnPblTCoS6b0Z3jq9HHb7mPao4rniA3fEb2z/1TRDOrhE4zEeHsnrBWgTYA4K/W0SzZCs/ci98rdPSOn3OLTQrXuL+hurpAeOcu4dZ4eDwbU09qC2hElSJxrYUQT2UpfjVEWty6CvrssXwWZx0v6EQnBT1Q5qXGYPCPU9k8El4EMaBk14zrGqMM+uaw61L0PfxL6UwqF6TvvLSY/gas/Tuj6QCvCAmh/7lEHvcmUyowRfeC5gQVTSQxJByVkMQvHEvwLrdmsXpHi40m7IAHRPDz4AHoARYMop6XlV+5y/0c5bdi8uWHdrRlGuQe3ExWJ+MPhMZ+828/G2QTSslFw9p/n04P7H1gkGdsw4BugOFN0BQDov7J3mMCxCZyIGSbx1Bhg+F1Wdd8MjHLNaKAwT89nkXtVwl2tIu2/v79aULFicc6ESkferJ57xFuh7BeqhP9NCc6tEHWc65AMitjFTnFAW1vHirPyWoTdAQgH5MpWmadoMk8+z512f0TqB9JhcZNfIpl0Lei6iIzIaT0Y6Hqk/kkQTq6uT5rf9fyyYll9oRUzT34qNqjNMGaXZKaYHPAqNGAabzQsH8qikJL6SDP16ofqx5fJ7Er7wnJfBjnHOK/4Ho8rH5OLIkhUtdX7SeQYj/ATr2qafMBlF68y1ubMCuEJYGCeG4vyuXEHz43aRDY35zRmpBxpriKyZGWueo1MYvZwneMRTVuD4GTVzwHc88kYrnZx2j9FCDMFiwlRShi9pxrHw1ARhSyh2eJls9ZbqmUmEYSoXGeoekzAEb0N+YafZB9E18F9B7b8wQ/wKo+Fia/Gx6xJQrOla5RGWPiR4pgGdGNXzAFlrHjdeXxZzBbl2w70rJY84khvoBC0UnvWQewSFqujDcpRi8OKUaEIuWernm/0hQX+oyPuBrAumpDNJn1+3P40+nCe58X4UNFs99IEZs/Ffpmu/QJhI3JAb4WI+DErGo8RUc4VHm6O0/k0El3/24PZZ7TnfdOHlxHnseCKBggP8boDQuq0x1ZVzisG/axNND9epCueSnIzafA+j7eNIQK08RMPdpmtwEoYnswKVTm2rNqxbwvCQewUS22XqQ89KY4UrAFhFcERTdjtImZalMJohOiq5quqOp/Oq6paiQ55uR9VeoeHWyTIpGubnQaIkgocHkxHhhDojkxjsZ6GpQqoLKiJBE1U9RBKOS2gcd73aM38vnNrapWretBa+YHGGhQF+4lDfvoyqXxtbQ9FdVQ1MPVLQ8vNQnBrm+Fq6RbGe07p/2pGWZiEyft6wSNhnZSNGsrTzZACfSi48eA5q3K/xKNedlSZMkSS3aA2hRwr5ZrtbboR27v/xt5Ozl71xj2E7lw+3FNj/J3jO95L1blnjpXSU3vZl5QE2HF5fGW+syv6pV5teRGzj0UHbA7uroRLesQXPqeB/VuRzMAobIuuzaCo/JfElH6gzEFLvupgGLrNAMJt5kewVmhj5GuD+apO2JLP/lCRr/QtqsNUywCy5jlbneOvmees86AOf/lU1nnLH2WdrXyJlCoih9yglxlYKdLFuFAYWAAD9VvOOE5I0afkACNqJVZJ78anOCfo0lCp6iHdYR3HcCJP3XCLDFYXeVkrMlxV5MZeNsO6lCuX63v7ttCv5kuhhXCQIJ9kZRYiu3n4HRgiccVZiex469JY1TFpYYlowEPZivhCyHZsz1Zge7YC2zML2+VGO7pny9A9a6B7vy/kimmVbdPar3uQ3uNY45g3BS1kSWKOHox2pE2sXsElNuR9CdhGrqUMMV7R4WauocPLem3Lfkq1wf5B28ppGOWVzruC/joZvrkSLvzIgu+wOjwVS1tj2TpzVAo3hyhS57IZpQHjyCTbhinztUYni7UGRbVZFxwiQyAR2wOJbS8LJBSUIAt89gFtI2IORPz17XG1IRjjfTD+TeGAqE6girf+fOwHjfB+AGdP+EGqU6ALsUOxLgJG5BHEcpdSGLJt5F4bdER0MV9d8fQtfg3o14/4MaQfRPrHoF8te1Am8XKGOmF2mqhtxHsRhk3mnf7ZpyJ7WSw+TPJ/XF1Wsec0hWSBsfDzzqEUBkuFTNaKg4cCTBfcgOQmtRewK4ZRoCxdWP2JLE7P33/GYxEDBecc0CkJ3l8jWFyAZcJbPN77G6b/t2lewlbM5z/j1l1xmbVRJ9FO6i1Wj0h4UnFV8dZ3uAxgzpzLAK1LyY+ghW+/ABTuBQAteI7VeNxQxfczv2sjDmQAnqXjd/pbIA8v12L5ivGtlf/5Ul3eRkmv+rhpBAVz6LKfEb89jy0TR86AF4FtemI7GyvxBYQVHiU6h/0OayC/JRc8aizdWsInQzewvVzRk1uzyhsTBZSOGMrDG4NVbBR//J4y1W1MyDZ2TXBawFRnJP5WFFP9EZYCiMjZ8sgkjHDmRCY+rUA/6J70n7m0fWVq8yl+MFtF8NvvhFQZ7oQuebG6kM3Op4vfZ9fjE/XLF5eAYWAtiI/GJLy5HgdcGLdoT4Xg2mhrWZoCDAStM0vjhvGVhW6Dfv8vQZJlxXQR964Khj+079redvQeMsZ9OACrpkQoG2+Vod5h9UfWzDyy6mYmuhVkU6bnKbV69HR3ebN89XAG45LMMSpxHz6MiQnRgRsli3acD5CeV4+rh1EbjbccbUL9KxluGyiMsnI2uQD01EAanSIzum8NPxSfOsmCVBirImGIClJg3vyoo4emvCycX+ZPVHLH5IcaE9BTLSmEpVRLKQ90XzXGyQx1pMuqL57P2IUYGQhUTavCqfQS5in57rQKepbgGtyEUZHM4mb6uwSPxt623mW9T8pKBq9IG3yEp3gRJqzP6J8o5fxYw7kqKGmPfs7DDH+gywEkNr/NcrrfYeTtXpzSTlFXH87uhCaWjLWZIxXsgcvoSdd35iT+wtwpDEf/KEYD+XtGZOr8/XmGKvF9Rdt/JH4r0hMS64sbSe+bDm5Z7cTVml9PGzgl4QzCgj6yi/Y01xnrv9LOM8Qxxo9GLm25RTE1bfNk8FhPkF+DPWatXgOe8acDNMdZCxtn14TXoX90oqnArHqalcZfz9XK9vcHV1SrMWzOv3eG+7J/UOvCAuHFlHJmJ4Sb1UZ2be75ILa1nd0havdg1qPmi5+fvxoFHi2HfdqRLujJr8fHz05OvNCPGtCkLfvqjRf2Ads6DB9IFcM1bfYWft4bUzRwh89n1uZm3ULZXUVU5CbxRPVl+9JoW0zvjjfFjLtDf65LeTyprJxb5C9YpVrabRUz0EXqYUE8rb2B62j1Ex1Zph/cfin5wAH3j5c//UjMuzZYj1JzyJXsgnnyPMDqKNaYvFDCt43+aj+4St92OGbMuZXQuQW6oI8EYOayuYoNoPQfEksLg7lWI1LBMOwh2Qr71kWAjlmzS7lVEaIC1q+HhYAUnM250L3hx1+ajGKcO3rZ9cMLm8qzgKlyT80ZWErYwJSBck1rDC/koMz4g8o+A3jps92DiJhetwi3vKoM2neG4pt6ZzzOkqVag0vA8QqBOSdqigP00R5cHWXa0vbxotMvma6s2+GrClhCNc2/CzxPmWAcJH8hi9bpRB1FUUoU/mwGs6xtDtPxQ5Zl9iOtflId0WNqdEV81Pl4NFS62Xl6qV+ceQzvCVA11xHqOUyEQU6qJWdJigvT7Bpv8UhQFL8sZKV1lCmghH5qqGEJJVxIpDhwrO5KLaYIhZrT+QcjyFDmMAfO2dIO8oYfGr3cwqwQqAgNnHnhLmGBTg3gjJRAg+wKbRqx+FcRolVkCboLbqi+gBEp70I3CN+ldwRkhNWg6DCjdciMg4WogfVeFIHA3KXn7uAMN8zyDm8duPfSaMBDvUwWH3qzhJSorjpIYmYq9XBBpfnjUlrbzKweQBwOqrnfnVlP3UuT557EAgnRbRkgrwJfoNy6n33isqwOrZKOOBzNxFjLc2AasHOAKhgoYBKjdD1A5q2cjPqEyM0TpPEXA/eETJcO1KjO6gw6Vezrlwcn+toIReZtDPMp9NoEkYIffrj35KdXx3+798MP/z779/EPtNxKY0N9YHboM2dk5TTsIZWGHzrNrcOKQq+eunJmsPV7F3/RGxNEC2j+74/fOI0XbuNjT+Nju3FcZlUafnCaiMa90mZAK8v8UCYAuMrmEqwOPGb+fl5S1Av0v0xV1fBvEm9fdAVq0pnvLk5N2xVYlW8m6uS3x6+Dv/zlL2qY9DcgcuCAiBt3WpxS/z+U6CPNM+1YE2CVf00i/0U18eAdseWkbqPvKG8n/zqfjJ+4VOPLja23azc1FsZ0LoXGsIZAsswrjfvEWLPC0YEBiqnoMLYl8Nk7SNstlnUQnsYQu4c3fCNDR7jX9HWOk2RO7Q5NldY0ol9l87Ui5nW4loyu2f0fU2vyAv/UnAAkIQYytQcinYGgy/i3fwqngPhbjbFCKCrhjrYvH5Ie60V9Eh7qSZDkdiAcjVvniPbAOVR4yQ0h/WvwNL6AsBJZckPfTtUHTyhusWPMLhCJpnKHdilfoTUs/8a854DNjOqhYku5ByTI7eQslRVB4IqPvKea9VDIZyDnGhx19XFtLQ4vbQvB+2Qu77O5Cf6s5HYyuuG1EUY+Etw2y9tUSjrly4qCKrUWZTdC1Rwo7uhpenms/tLkZgv246mmbikchM919c5aAT4xSFkOTnogj35ZjK/prGhKu1deiyJWo34Ph14JBGHQXH6Rw38L0IHv6Fqd+ZOeY1w3l1aMku5lNKyf/VFlkMtqMGvMXbysUQqUttc/dLUFMJWdcHvldIca0StAHM8KeOlAw2iNXi+rIFqNCRueITki7yYzzejhck+ta6xuBnRJSzI4lBX9Hp7Ce9Abf0tc4Zzc8PWK9++pN6SFRaifxwIqWQ0YVtdIapeu+wpjhEKlhsTE4eu/ocuDXl8sqZuojbd2T91c8zuRTuCBEmqr4jQW8wnkT7j4pJd0Y2Lhk7exyyL5o9WGGIfqhPRuEYhPIT6ZsOjjtIxtX/CjB+zZX+OSRmIA2OT9Q/LffwODDvO95Hw87yThbUYxVhrENy19n0zbuu1dhJIDrWHB2TIsCGVRKSI1SQSbpRyZucDbAW+UH4nfvsQihqOOS5AM0aeTNFl623GbOg1lUr/6IImvPi4s2qx6XcuTiU+WnfukUYp/yAo6PAc0D4dErort7dCViIhYUU4azOZm2/UrCeUdr18bAxpLe8cQGXxV5UUoa2Rc2mTcwS4fLW1/kPXNY3q6/KaZNs4UqpydAWSG7WPOh9Se9iSOJb5ZlKYMKMAQoXOpyZxLTWYuNVrZ4wKymTLRuYtcQHPevot4wMAIW3XiYmNKTsYXxeepijm/pY+ksfJiN39FBvsd7S7JWDe6lRBJa9QbjmOh3whZVrJl94gnY6t6PvyHGt/v6voSqN9uAZWEEup+1HheJE1i1RZMnOFfuNEbPZ/iYI5FvHWfmi2WAqq+EU/1ESdWMZEzXkin7/NwTNNcM5/tzrqdWVxf5SNqTaMaO9iCcKde3bvZKaQ8XB8NW9V+n8uR3GfXs84Yvi8KL+RtxptoTOHF/2sXLIz2/H2lnH1/TsO/Q9nhjXV7vLpXOYyuF7ixNcAq6V+tuS0BAwkXXnmksCG1gG6BsMTGei6lllVbTBj2/PibxzmErNeX3kEZSauACfa2+r2NsiMcv5Gx8u9Td0qzFxa1WkjN5/ZoQAwHsx4/9Pv9prCWXCsuiqbxTLkTqs1BSkOhudN6dwUWGtemWobjzQxrHuhoZbjws+3h4cFlkhaXjrcPBUQPefUJ+kQztFEo7cFpV2DSvXtqqvaUrvY+NSGABpR0fUl76uamIQfMWNCXyOaRA1FfLtPlBxOg/NyPpfPZem5mcrD81GRL1ZUXMUd3tAkNqR51JnFPKxa4cBqjbFK+ZjPKJu7rNiTjzlFXy5+HLEpyFi1Xa1aUweo2N2ulmDUp9Fs3dWS/2RGm/bXaUbk5zcYeW/2LuhrJReOFLW2OMV1MkobmR7RRlz5TZR61k7GldsLjqVfvGwNnuSoCzjWtwURrw8/oHjQZYO0JFh/5WvGptPu0UNet3khWhGjITRzUMXCp9ThkrvKQBvsfh8iebdv489mdfvI8FoluZwXeH4kkScRIZFmGV5LVT0vNVyP3mUl/+16L0GkLrkxrwvI1zYXlNAf2z3ix4quWBYRP/5uWlwTwCbehXrkS7OXE93rlErfSSLMEZtW3H/yEcChLeNgb4rULD2DWa5fYEiqLib7HEw4fAymeKwyXpfvnLKi/n46tKl11t+FykB3j4Kj2z0v54Jby2e0Fspj6JO5LbAihmQu2ptyyNJ/+TlDXc3rsKy4vNa7GffU1h9wBX012VN+4Z0l+fj23UFsZwD6kEQhbUL6qk4X/GHCpUbSxG6+AY56tf7C6NkdBXvwL/g+a8+s10Fmrv/N3awCdguv8jo0eCSbxSnsI+jDrT0Xp7HIkfubgObwxYE9fsrzL6zNcsGJLFbbEQ3CAjD8oTmL85MiS19i8X/Jw0E8e8h0EdUwPVzTHe2EDzO2dWqCTHu5xb/Qg0WvXSRUc8ZacMsBcU+0bIYy26Ja1l4Wh+APsCz5CzsgltzhU6ifBZ7haMOojn9VBEGwGoI9TKqU1SiqfVVC9Dubn1avr+VyXVtCTT70DdlMHNShXyiKx7xuutx7SipghhEuP019OOqI6P8Mez+pP1CGDi8esU/ojVXyJylVpdR7ulNPOskS4DNeFuHfklcP/Ou5CuOc/SJ7/vcSvZNL7XR1h2tT/B/xfUAaXVSAB0vTL47IqrEfJ2utw2+wt43BRGwcx1K9t+lnU+A7KwjXpp1uF4mCtatbY/WFUzYyCGwXLj55qwtxVD37/fRGUj+50kFqTddMys8WYWOwNa23IuP8WK4Py1rq4/eFVuvE/GLOPkWVIHNVx0s0ur1FpHNdU68IvSzdHtlJ12Nl2yS22XeLddhZv7lG96KzWPvm5+NjU0uc6XC19FTePaFlGPOZMES8G1hoiR74HBbce6s1dFPgir6pktPIqat6Dayt4C/Ukprrla7sytm5RUhDCpzVtzYgn90tKNVy4adFK3XvdWw3kV+6X9r3S8VvLS3bMhU2k5xTxgtumCx1iTUlrsN6J+ZEZ+EpD9ho50NCdFjkB0O24qfy4uVkXf5N1kHcSHL6OO+nXJKdZGmK6Oi3VhPK2WuyhRIPL9M+R79VB38AvF8RVREdyqzI6Mv0K6ZzjKKUvq6k+Y/YzJmxlXMTE9mmQvs1NDw5H/FLRAEWCV0neateD/l/Wrg7a2hbto5n87mPoeDrYWBG03HFc5gOiqUvf3EZd3NxwflqnlaqT4sCUu0aZUY2JKtEvRGGlpNOo0ZZ3ydGqo4S7uckD1em4eduMSNqr1I3cB8rff4enQn3vznEDn09oNUNbW4pamahoniKOcamZvLcrfActqtMjKPaq6y8++aIbxI04oHR9bxSVQ+0TWYQjfy1ORA09JwtdY7O+sKzuxiVlUG3NYjP/Mvh5Yo7HqJpApWziLNk7VoUvTkkArX8CqBuz4ULvfErMlcV95YUh4AStkiSAoGKy17d9ptedo2/s9anrJIRopbiZtS8a82BcITUX68jVj8I7ddo80eHIXjPu6VJ7QKCbMqubfzh/v6DYvEedJvPBNTFHKCQHwNU2gdAHAtGuxO8nZdOlul9TdmFkfeptYlYoqQs0BYm0Xwb3Ee8Fk9ZaoZArNQy9By6CJTeHhwZc5sqdwjYDSECAH28MT4uhCN8WpaFUcOhG7PC00ml7sE7j2qJ/qWwCR37OwjQ7gnh6LWYEbtUcK7ylFjH8MWpydzeWvl7ki6eAxp3pKztgMcnX81RxpWAUSJrSaWrrDB9xqXhXZjt9/Xsga6u7K8Wx8kutHJSo6nrp+ViJZrDWtXZeXThr1MjFZtLWqXMkUlXx46uFAeCmqr5VPSN6gcpyjhtXDcsdMYxXTN6qO8GeFAhG4R2TUxMG5W+GMx3nKoM9My7Hs7FrdbvK6Fa1UbZwa5tbFAduWDPh7InNTdNH+lVHMGs1lN/TolyoEPovZrJsFa5md7HM3gV+WqDKxmtPeORbXMfMkBcLs2VZGU5oFiez2TVRh7mzjL2gileB1XJtEL2NwcXl4JG8Vw43QsIDWX5jKctco4MIq72+uhYwDvSdxx0NTMOkbubzsB/HnXoihBLvL+mZYnNA77ZptxuVEFiVNwwFdpgUraBGk8ZGDm7E8xgPOCT2OasVT4yUnBZ98I2ycQjDI/fB6VDLGknCyX9cf6XDdi+PXt+WRvKODwLE25I9OKqF56FarsMDcgF8bWS6yk2JIlE8q1uHSOEy9BRNksKkcuhvPFEeHtCBMBmfHdai0rkUIaDjcQ6sEd1yYa6Sf05mf+d0YlLsnPOxlXNwX7fQM41T2w4SmJU/Enqh2ZQlLYJMr3hPjNy88WTh5peeJjUY2K86lpXycRkYVALYMlTTjKMRn7vy111bqtyO8YYD9yA9v+hgHXw1q+VR1X9nPL4j4jbwX8gNfqO9NUJvaYw2vDjvV/2Ot9WG1waaMfvv+quG26G0+uS0B/LAc6+bC0x7vOrBD2YziG6Hcgahjb1sbsXlg3NCMAs4MTh8JP4OokzoajBIhFX28EhI8IjJFXUbQMJuQffftUwp7zLlC5uVBL3NcVzoZzXriKGpeUEIVvRItnF9WZwjfCeK4ceQrD7WBmWHfOP4NgXCaIN1UCqQzc2H9MlQpZqEaxPB/pRjisy2cxhfhBzc8h2dKztDufvw9N3F9uBUTivR2Ni2MZEzWqxQXrmVDrozmMnYkMPuTNJ/3Stk0M37x8cDIfFnuLfPP3Ye7gpurauuc2P+M72p+e5t4Lbeqk2Uc3Gckc4EZd8yO1v7Rf7Wzb3rPuAOq890QkKNK6RUWlYWHVi1e0E1HL0zPOoV/E64nDJqtMb8bSyFJBjmJGzT/8bJ5+fk88GO4oaMvk88kJQ011utTO3XWfsdFoqb/Q/O19ci2N/lnXKY4C+4Z7/IizHkjNCLI/s0JgFxo6dK9tzteHp7NKScKKXP6/HFMVw2x336ZAbnCb3wVmmscoufFXGA3Lx+5LBUJ/XfI1zu0OGm0vagfJQnq3uUlzuw7lb1M7951WIz1x9Vu0I+kG5PJo11sPPQT+i+HWnxtmlt1PH2K67uWG6/4rLD688Uz7DXbMNo5TK+xJk0CeYEi7cH0pnQBjo3eAe3TsM9O1h/28LD5ubgxSh3R7eDQ9FaFK7Qvyg6z73uLu/IHfcI1NNRf716o+/otiIH6y+q2UzsXtwnWamvbdRY24QjR/vYP1tQeVoelrJYDYuPPMoH+6A0em9pnccytQyWd68f8fVU57CdY4e9RFDaGQI/nmeoBT6eB2VGdj2nM8NK53NdH+fhlzz28K5DpffE0wAx13n+6Xeqi2rJlgRL23ci6JXdVcv8ISGiFdZiSA0OcXhbmuw7B37qowP/uqWHh3zml+Xd7J1D5gTKbLinz21VeXV3+pE61oiW5p8RI/dzJ2S4akJgXXE99c6H1YXOj8/+Edp9YP3j2/Rk5xt6YpmP7Aysbv3cCHlH53sDr/IWdNNOA8arN4PxUevnKHPFURq202Ypc7CURRtLeaFYyo1Znae8aPKUF5L+687Ug66N7pVD6lrOsMwpajk7Zc74xjfXrN/r37j9kE7agS6e7Qz515rz51q31k6Cff9JANbY0DmVmLjHg2llctGQzTnZts8+Ixe0aJvrZDiJuyqqV4a/tIA5tIlzzw0loRjUyCaKlSiKlR2xzLAHlaxjvaadljULu+XTsnftALG6up3ac3bYbckfwfvxUbl8o3L5ohWHpr2W9bPn1KDfDR+Qa1flHp1WjWsdnu7Vfj2WyD3KxGB7IGTzIBv4EBzr7z3fXJ6qidKWEAFC0jp2V3cBC4+XDHRSXgBakRdImwJ5U/oL5E3Q+cSDvNkp+3mFgZxC3vR/MvImLcgr2TVDydrEGX1gviDDzXW1xP3Sb8xX2zzQjEXs4KUVYgAI7UPkFlumfOZevwi/hzv94Bwo2iSzgjiF1Tukga3ro06iUSf1z0Vyele2jvEs4Y78H8Xa/b+Ns9v4n8ja+Xm4NpavnbchZGxlb+BMh+OwEbHh+vljyIgM9RdLyQXQmS9ubq4C5HYBQDJU9JErzHQfTAuoVJYtuPGofCPQe7iFKtMWXkmWNU2sYjz0D5YT5c1Nvlwrx8AwqMbHzlB97KiPXbA+ytsLn1iX0w9JWixi0R8Md3b39h88fPT4yfHTZ8//+uOLf/3bTy9/fvX6lzcnb3/9+2//+Lf/LSJnwDqk/TGGTOJtYxLGLFtfJiSCSsqAo9DJx/ynNgOdmLCDTmfeZX/Z2T91hQhq+ZNF8Ua5O3h9nndMY8aEjFp7cJip6HokXXTq0z4SdvbDU9Ne2vWPAGva3ux03mhWDfPhYaLG96XEOQDklLNzSDdzjHxJl6i7mbc7tFBu9ESLb5Lm4zn1t/xgbbV5+f02ObOUxlyup4ySJscuS0bHsV15nEe16ulUtRqIxwZBrU2Ij2RzYL528DVUXw92+Cdn7CFjN4QbH0R825WZNl6IB9FwX68nQLk5+EfKjFNLkybpU3l/BfIfoZqHsghH+LEnHYVHLpBdTuaWkpwzkUlcn8o8tifTncIw6iSbD8kRCj1Uw68pzWluo5D2y0tU6qTsLXY16Xx34Gtkkv0G2tsJt8mpanh/2BXTT6J6OCfaMdwJe2ROT83+qEj7doe29nvShyHhV1GMjwbD/dHeDjsfoUaG+2FPMxtsHbEzrPJ2PXmUvjMIe3xu+NpLGy3uj/ohdxSjelrML0T4TtDZoO0txWmcbad+CHXUEIDdkJqCeis7Q9MKqwXvPXDAaQBtVTdgiQezKu6oEVOZ0vL8MxUSbHxOqBR3MhrzL7pudzJohaTbrHlcoSp4xL58fm0pQcJRSx+oh5PLS9HehOgvr184joQqXRG+dfF+yBr3eZnKgVWMHfuuLuXQSii8QVMO6iiGsJg3SiGMezrjCUqFYP08N8qSRQxZpZXWQ7SYvyrSe0lMLVTG5qU/4d6PkzmHVaBaKep/Mp1qhYSR/itzraqGtER+IHgVdvz2LVwisgUCXYw4NpC8XmTq03JqtZggrI8OfiHP55MmwIuTVwbgRv6YzPKPyYz88eAyOplhM4571DF69CNe7ez6PFf6sJ0GYO/4xcvfj/mMmJ2oAq9Jv5zWuOr668tkQfTz6q+/vnjqenuDhmnRVVN94Yki1hF9+ufCjR8W9ubq5r89tIA2FBBPiBfgogwetgyAgyW5INGYbi1x3tTyq2krjo1KoB3c+P6/j++fSe0xM5QpfHT0/klIKZjfQZgaZfegAo7GCBEzEq/+JuRufzASj68XH2iadWDwQAEi6+FIwGfZ5Hph0vYB/tvJy8c/B2QRP6cuVTnDkaj0rJTbpeDHt29fB2Z9An6dAugOQItPU3WxZKiCnu5KUMDsNmGmNPAK5sZWCZ/NwH1WRkysCK8NFb5+NfYIcC/EbAW9BdAkKLXmR6zcXDvepC7cQ/SeHlxlkxc1Ndj40aNHsor1hIA2yPvlmph0WlTKVQq3u9KddbqdHzVSRkJ9QtaShvJsoqwFJE6ssMf2pn1JVJ1ClZNvLSCMYeK48xYZOpucP6c3oSVPNFR7pu64jooyeU5EcKydPuHiLKsioCdhWKbGCXiOnYG5PA8fqTuA07rfDcfXr9QYpetCKM4VMbO0Lwf90lH3AF9D87VDH33zMRzg6zC1olSA9ewb3pNAxJToqExUCeZAcVycTSg1jHIVTVHUHSHQuYECR+KHJM2SYgBNlNXAMH1VkDdWABJiHDXH48zLlGQkc/iEA13lKeLe50r58dc3L0DUJmOWzbnB4XCRIZbj0aPhCP/uyKJK2lVJe9HgIKnU5nM7WOTgFO+BdnZhZw9PS1z6glNilECmosJZ5XJGUunZqLCjCOb5T+djvb+4mDhI/O4n2EA4vbScQMC1EQyUNwkzruYRrAO6ArpKotEE6Qvl50hILg0qa5RPjuxejNKqqC3f/JL2prMCH0+L98n1JZnK1lM60CaANc1rMlFOzhIO3d1IIjBNKwZmRbmbr9TxanrHyFb6AcyU2rL2BNIRfONWzsqh3R9nlnjuFyw51dfJQ2canrKc97u1k1eS44G/UePLShNRtY8flgHtQzMNkXW/BYICI+VY7cmxEjToxyX3pjsOo/3dgwsitIPDi6MsHowe7eOTbt30ndD37gN87z2kz5w+i3hgLn/ww9VNSE5RWEtwhYh7VV81qG2pkqowdOQ5gb6aMe06tirxMYIYG5vAHutb9DimX1dALbKTemPaOTFofxdSINQX6NqI0KXsahXJv1Pumz9RldH1UmDUGoWvP8P/og5Vndhwe/FsTJEzXILiql8OUJQphRs1PavGA05O1WbTVnvSFXKe6wAMhBjvzk/Z8bjVh3OJ5OpsTaq47LZdUZmYNns8wdyM4yF3uZMepUapUc2tvQRltHh37JBY+tyvbKkZ2KqTUkf7Dtpj3iaGTDzu3oqyenfWrhFYP11Wu3LLOWP4dGFa0xVUrc3sGued9wkJH8MIffKMlDqFG7NbRln/HQkQOkun1J6Ul5NZbSdurT7BIEK+ooKfPn0alN0Ft2EShdSdtRKHQsIFUni4+cOn4d6T40i1jePO+HAygLp5LZpQnuYOlXHUh9nhljXpKA/Mu0XPfb0d+no7cHs7jIKfiDyWisTUj4rLK0p7cz6b5o7gE7aVCZ8LcJjLEEYGmh8UShqYVFlQ20165oGJZEjaTyofXOV2zJwOmBiSvHuaIVYQxMMKNBmXHH+AHFMnTgq3WrpRms1SCjGtSnM8osdxUlWWO5VZi1VeY63DyQkdJR+GXTthV+67CaSW4Sb0Jd8hncRBXw6GLtxDYpM9gLtyUGthMJSDXQ/kvhx6KqA0Z7J+nV3SQ5sjEJa8+nQkkHD3Yw/SA0D3PtA21Zdcb1YZEOtI4NZtOOBN5oCjvGRgFfKkHJmgLBSLELanKiYBcpwpS8PTuJaYdgcSSYaxsXCsWj9HOmkWkDtPLZPcRGUdNVJGJW9mfmjubHOzLadHW5T+qOKKW1kH8GglkNOZs8Lkz598JjkuByVOiaURIfH8dqHGJLDszz8LnHfUTLr7PHD5dSZCN74W1G2ngktVCO/EWbXO7C3P42PfsWryPTUOHQeiLHslmm/5ROU3uUzrl5cvrswKuf6aNryd/HnyFpW5/MV366tYr2u6Z64bZKtHCKStLmXlVeHrV/dbPd3tPjyogdFF4cFhLe0Glvtwg0EC74P7OkLq/x/APlbrM0kLAA=="; + + if (settings.localport == null) { settings.localport = 3000; } + + // Start the web server + var http = require('http'); + webServer = http.createServer(); + webServer.listen(settings.localport); + webServer.wsList = {}; + webServer.wsListIndex = 0; + webServer.on('upgrade', function (req, socket, head) { + //console.log("WebSocket for " + req.url.split('?')[0]); + switch (req.url.split('?')[0]) { + case '/webrelay.ashx': // MeshCommander relay channel + var ws = socket.upgradeWebSocket(); + socket.ws = ws; + ws.wsIndex = ++webServer.wsListIndex; + webServer.wsList[ws.wsIndex] = ws; // Keep a reference so the websocket and forwarder don't get disposed. + ws.pause(); + + // We got a new web socket connection, initiate a TCP connection to the target Intel AMT host/port. + var webargs = parseUrlArguments(req.url); + if (webargs.p) { webargs.p = parseInt(webargs.p); } + if (webargs.tls) { webargs.tls = parseInt(webargs.tls); } + if (webargs.tls1only) { webargs.tls1only = parseInt(webargs.tls1only); } + if (webargs.port) { webargs.port = parseInt(webargs.port); } + //console.log('Opening web socket connection to ' + webargs.host + ':' + webargs.port + '.'); + if (webargs.tls == 0) { + // If this is TCP (without TLS) set a normal TCP socket + var net = require('net'); + ws.forwardclient = net.connect({ host: webargs.host, port: webargs.port }) + ws.forwardclient.on('connect', function () { this.pipe(this.ws, { end: false }); this.ws.pipe(this, { end: false }); }); + ws.forwardclient.ws = ws; + } else { + // If TLS is going to be used, setup a TLS socket + var tls = require('tls'); + var tlsoptions = { host: webargs.host, port: webargs.port, secureProtocol: ((webargs.tls1only == 1) ? 'TLSv1_method' : 'SSLv23_method'), rejectUnauthorized: false }; + ws.forwardclient = tls.connect(tlsoptions, function () { this.pipe(this.ws, { end: false }); this.ws.pipe(this, { end: false }); }); + ws.forwardclient.ws = ws; + } + + // Handle pipe closure + ws.on('end', function () { try { this.forwardclient.end(); } catch (e) { } delete webServer.wsList[this.wsIndex]; }); + ws.forwardclient.on('end', function () { try { this.ws.end(); } catch (e) { } }); + + break; + default: + socket.end(); + break; + } + }); + webServer.on('request', function (req, rsp) { + //console.log("WebRequest for " + req.url.split('?')[0]); + switch (req.url.split('?')[0]) { + case '/': // Serve MeshCommander Web Application + var meshcommander = null; + try { meshcommander = fs.readFileSync('meshcommander.htm'); } catch (e) { } + if (meshcommander != null) { + rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Transfer-Encoding': 'chunked' }); + rsp.end(meshcommander); + } else { + rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Content-Encoding': 'gzip', 'Transfer-Encoding': 'chunked', ETag: _IntelAmtLocalWebApp_etag }); + rsp.end(Buffer.from(_IntelAmtLocalWebApp, 'base64')); + } + break; + default: // Unknown request + rsp.statusCode = 404; + rsp.statusMessage = "Not Found"; + rsp.end(); + break; + } + }); + console.log('MeshCommander running on HTTP port ' + settings.localport + '.'); + console.log('Press ctrl-c to exit.'); +} + + +// +// Deactivate Intel AMT CCM +// + +// When called, this will use MEI to deactivate Intel AMT when it's in CCM mode. Simply calls "unprovision" on MEI and checks the return code. +function deactivateCCM() { + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.unprovision(1, function (status) { if (status == 0) { console.log('Success'); } else { console.log('Error ' + status); } exit(1); }); +} + + +// +// Activate Intel AMT to CCM +// + +function activeToCCM() { + // See if MicroLMS needs to be started and setup the $$OsAdmin wsman stack + settings.noconsole = true; + startLms(activeToCCMEx); // TODO: Fix this so that it works even if LMS already running. +} + +function activeToCCMEx(state) { + osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], activeToCCMEx2); +} + +function activeToCCMEx2(stack, name, responses, status) { + if (status != 200) { console.log('Failed to fetch activation status, status ' + status); exit(1); } + else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { console.log('Client control mode activation not allowed'); exit(1); } + else { osamtstack.IPS_HostBasedSetupService_Setup(2, md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + settings.password).substring(0, 32), null, null, null, null, activeToCCMEx3); } +} + +function activeToCCMEx3(stack, name, responses, status) { + if (status != 200) { console.log('Failed to activate, status ' + status); } + else if (responses.Body.ReturnValue != 0) { console.log('Client control mode activation failed: ' + responses.Body.ReturnValueStr); } + else { console.log('Success'); exit(0); } + exit(1); +} + + +// +// Get AMT UUID +// + +// Called to get the UUID of Intel AMT, start by setting up MicroLMS if we are doing the operation on the local computer +function getAmtUuid() { + if (settings.hostname == null) { + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.getUuid(function (result) { if ((result == null) || (result.uuid == null)) { console.log('Failed.'); } else { console.log(result.uuid); } exit(1); }); + } else { + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { settings.noconsole = true; startLms(getAmtUuidEx); return; } else { getAmtUuidEx(); } + } +} + +// Fetch the computer's UUID by fetching the CIM_ComputerSystemPackage WSMAN object. +function getAmtUuidEx() { + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); + amtstack = new amt(wsstack); + amtstack.Get("CIM_ComputerSystemPackage", function (obj, name, response, xstatus, tag) { + if (xstatus == 200) { console.log("GUID: " + guidToStr(response.Body.PlatformGUID.toLowerCase())); } else { console.log("Intel AMT is not available or not activated."); } exit(1); + }); +} + + +// +// Run MESCRIPT +// + +// Run a .mescript targeting local or remote Intel AMT. +function startMeScript() { + // See if MicroLMS needs to be started + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { settings.noconsole = true; startLms(startMeScriptEx); return; } else { startMeScriptEx(); } +} + +function startMeScriptEx() { + //console.log('Running script...'); + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); + amtstack = new amt(wsstack); + //IntelAmtEntireStateProgress = 101; + //amtstack.onProcessChanged = onWsmanProcessChanged; + + var scriptData = null; + if (settings.script != null) { + try { scriptData = fs.readFileSync(settings.script); } catch (e) { console.log('Unable to read script file (1): ' + settings.script + '.'); exit(1); return; } + } else { + scriptData = settings.scriptJSON; + } + if (scriptData == null) { console.log('Unable to read script file (2): ' + settings.script + '.'); exit(1); return; } + try { scriptData = JSON.parse(scriptData); } catch (e) { console.log('Unable to read script file (3): ' + settings.script + '.'); exit(1); return; } + if (scriptData.mescript == null) { console.log('Unable to read script file (4): ' + settings.script + '.'); exit(1); return; } + var scriptData = Buffer.from(scriptData.mescript, 'base64'); + + var scriptModule = require('amt-script'); + var script = scriptModule.setup(scriptData, {}) + script.amtstack = amtstack; + script.start(); + script.onCompleted = function () { exit(1); } +} + + +// +// FETCH ALL INTEL AMT STATE +// + + +function saveEntireAmtState2() +{ + console.log('Fetching all Intel AMT state, this may take a few minutes...'); + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); + amtstack = new amt(wsstack); + amtstack.onProcessChanged = onWsmanProcessChanged; + //var AllWsman = "AMT_GeneralSystemDefenseCapabilities".split(','); + var AllWsman = "AMT_8021xCredentialContext,AMT_8021XProfile,AMT_ActiveFilterStatistics,AMT_AgentPresenceCapabilities,AMT_AgentPresenceInterfacePolicy,AMT_AgentPresenceService,AMT_AgentPresenceWatchdog,AMT_AgentPresenceWatchdogAction,AMT_AlarmClockService,IPS_AlarmClockOccurrence,AMT_AssetTable,AMT_AssetTableService,AMT_AuditLog,AMT_AuditPolicyRule,AMT_AuthorizationService,AMT_BootCapabilities,AMT_BootSettingData,AMT_ComplexFilterEntryBase,AMT_CRL,AMT_CryptographicCapabilities,AMT_EACCredentialContext,AMT_EndpointAccessControlService,AMT_EnvironmentDetectionInterfacePolicy,AMT_EnvironmentDetectionSettingData,AMT_EthernetPortSettings,AMT_EventLogEntry,AMT_EventManagerService,AMT_EventSubscriber,AMT_FilterEntryBase,AMT_FilterInSystemDefensePolicy,AMT_GeneralSettings,AMT_GeneralSystemDefenseCapabilities,AMT_Hdr8021Filter,AMT_HeuristicPacketFilterInterfacePolicy,AMT_HeuristicPacketFilterSettings,AMT_HeuristicPacketFilterStatistics,AMT_InterfacePolicy,AMT_IPHeadersFilter,AMT_KerberosSettingData,AMT_ManagementPresenceRemoteSAP,AMT_MessageLog,AMT_MPSUsernamePassword,AMT_NetworkFilter,AMT_NetworkPortDefaultSystemDefensePolicy,AMT_NetworkPortSystemDefenseCapabilities,AMT_NetworkPortSystemDefensePolicy,AMT_PCIDevice,AMT_PETCapabilities,AMT_PETFilterForTarget,AMT_PETFilterSetting,AMT_ProvisioningCertificateHash,AMT_PublicKeyCertificate,AMT_PublicKeyManagementCapabilities,AMT_PublicKeyManagementService,AMT_PublicPrivateKeyPair,AMT_RedirectionService,AMT_RemoteAccessCapabilities,AMT_RemoteAccessCredentialContext,AMT_RemoteAccessPolicyAppliesToMPS,AMT_RemoteAccessPolicyRule,AMT_RemoteAccessService,AMT_SetupAndConfigurationService,AMT_SNMPEventSubscriber,AMT_StateTransitionCondition,AMT_SystemDefensePolicy,AMT_SystemDefensePolicyInService,AMT_SystemDefenseService,AMT_SystemPowerScheme,AMT_ThirdPartyDataStorageAdministrationService,AMT_ThirdPartyDataStorageService,AMT_TimeSynchronizationService,AMT_TLSCredentialContext,AMT_TLSProtocolEndpoint,AMT_TLSProtocolEndpointCollection,AMT_TLSSettingData,AMT_TrapTargetForService,AMT_UserInitiatedConnectionService,AMT_WebUIService,AMT_WiFiPortConfigurationService,CIM_AbstractIndicationSubscription,CIM_Account,CIM_AccountManagementCapabilities,CIM_AccountManagementService,CIM_AccountOnSystem,CIM_AdminDomain,CIM_AlertIndication,CIM_AssignedIdentity,CIM_AssociatedPowerManagementService,CIM_AuthenticationService,CIM_AuthorizationService,CIM_BIOSElement,CIM_BIOSFeature,CIM_BIOSFeatureBIOSElements,CIM_BootConfigSetting,CIM_BootService,CIM_BootSettingData,CIM_BootSourceSetting,CIM_Capabilities,CIM_Card,CIM_Chassis,CIM_Chip,CIM_Collection,CIM_Component,CIM_ComputerSystem,CIM_ComputerSystemPackage,CIM_ConcreteComponent,CIM_ConcreteDependency,CIM_Controller,CIM_CoolingDevice,CIM_Credential,CIM_CredentialContext,CIM_CredentialManagementService,CIM_Dependency,CIM_DeviceSAPImplementation,CIM_ElementCapabilities,CIM_ElementConformsToProfile,CIM_ElementLocation,CIM_ElementSettingData,CIM_ElementSoftwareIdentity,CIM_ElementStatisticalData,CIM_EnabledLogicalElement,CIM_EnabledLogicalElementCapabilities,CIM_EthernetPort,CIM_Fan,CIM_FilterCollection,CIM_FilterCollectionSubscription,CIM_HostedAccessPoint,CIM_HostedDependency,CIM_HostedService,CIM_Identity,CIM_IEEE8021xCapabilities,CIM_IEEE8021xSettings,CIM_Indication,CIM_IndicationService,CIM_InstalledSoftwareIdentity,CIM_KVMRedirectionSAP,CIM_LANEndpoint,CIM_ListenerDestination,CIM_ListenerDestinationWSManagement,CIM_Location,CIM_Log,CIM_LogEntry,CIM_LogicalDevice,CIM_LogicalElement,CIM_LogicalPort,CIM_LogicalPortCapabilities,CIM_LogManagesRecord,CIM_ManagedCredential,CIM_ManagedElement,CIM_ManagedSystemElement,CIM_MediaAccessDevice,CIM_MemberOfCollection,CIM_Memory,CIM_MessageLog,CIM_NetworkPort,CIM_NetworkPortCapabilities,CIM_NetworkPortConfigurationService,CIM_OrderedComponent,CIM_OwningCollectionElement,CIM_OwningJobElement,CIM_PCIController,CIM_PhysicalComponent,CIM_PhysicalElement,CIM_PhysicalElementLocation,CIM_PhysicalFrame,CIM_PhysicalMemory,CIM_PhysicalPackage,CIM_Policy,CIM_PolicyAction,CIM_PolicyCondition,CIM_PolicyInSystem,CIM_PolicyRule,CIM_PolicyRuleInSystem,CIM_PolicySet,CIM_PolicySetAppliesToElement,CIM_PolicySetInSystem,CIM_PowerManagementCapabilities,CIM_PowerManagementService,CIM_PowerSupply,CIM_Privilege,CIM_PrivilegeManagementCapabilities,CIM_PrivilegeManagementService,CIM_ProcessIndication,CIM_Processor,CIM_ProtocolEndpoint,CIM_ProvidesServiceToElement,CIM_Realizes,CIM_RecordForLog,CIM_RecordLog,CIM_RedirectionService,CIM_ReferencedProfile,CIM_RegisteredProfile,CIM_RemoteAccessAvailableToElement,CIM_RemoteIdentity,CIM_RemotePort,CIM_RemoteServiceAccessPoint,CIM_Role,CIM_RoleBasedAuthorizationService,CIM_RoleBasedManagementCapabilities,CIM_RoleLimitedToTarget,CIM_SAPAvailableForElement,CIM_SecurityService,CIM_Sensor,CIM_Service,CIM_ServiceAccessBySAP,CIM_ServiceAccessPoint,CIM_ServiceAffectsElement,CIM_ServiceAvailableToElement,CIM_ServiceSAPDependency,CIM_ServiceServiceDependency,CIM_SettingData,CIM_SharedCredential,CIM_SoftwareElement,CIM_SoftwareFeature,CIM_SoftwareFeatureSoftwareElements,CIM_SoftwareIdentity,CIM_StatisticalData,CIM_StorageExtent,CIM_System,CIM_SystemBIOS,CIM_SystemComponent,CIM_SystemDevice,CIM_SystemPackaging,CIM_UseOfLog,CIM_Watchdog,CIM_WiFiEndpoint,CIM_WiFiEndpointCapabilities,CIM_WiFiEndpointSettings,CIM_WiFiPort,CIM_WiFiPortCapabilities,IPS_AdminProvisioningRecord,IPS_ClientProvisioningRecord,IPS_HostBasedSetupService,IPS_HostIPSettings,IPS_IderSessionUsingPort,IPS_IPv6PortSettings,IPS_KVMRedirectionSettingData,IPS_KvmSessionUsingPort,IPS_ManualProvisioningRecord,IPS_OptInService,IPS_ProvisioningAuditRecord,IPS_ProvisioningRecordLog,IPS_RasSessionUsingPort,IPS_ScreenSettingData,IPS_SecIOService,IPS_SessionUsingPort,IPS_SolSessionUsingPort,IPS_TLSProvisioningRecord".split(','); + IntelAmtEntireStateProgress = 101; + IntelAmtEntireStateCalls = 3; + IntelAmtEntireState = { 'localtime': Date(), 'utctime': new Date().toUTCString(), 'isotime': new Date().toISOString() }; + amtstack.BatchEnum(null, AllWsman, saveEntireAmtStateOk2, null, true); + amtstack.GetAuditLog(saveEntireAmtStateOk3); + amtstack.GetMessageLog(saveEntireAmtStateOk4); + +} + +// Save the entire Intel AMT state +function saveEntireAmtState() +{ + // See if MicroLMS needs to be started + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) + { + settings.noconsole = true; + startLms().then(saveEntireAmtState2); + } + else + { + saveEntireAmtState2(); + } +} + +function onWsmanProcessChanged(a, b) { var x = Math.floor((a * 100) / b); if (x < IntelAmtEntireStateProgress) { IntelAmtEntireStateProgress = x; console.log((100 - x) + '%'); } } +function saveEntireAmtStateOk2(stack, name, responses, status) { if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); exit(2); } IntelAmtEntireState['wsmanenums'] = responses; saveEntireAmtStateDone(); } +function saveEntireAmtStateOk3(stack, messages, status) { if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); exit(2); } IntelAmtEntireState['auditlog'] = messages; saveEntireAmtStateDone(); } +function saveEntireAmtStateOk4(stack, messages, tag, status) { if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); exit(2); } IntelAmtEntireState['eventlog'] = messages; saveEntireAmtStateDone(); } + +// Called when the entire state of Intel AMT is fetched. +function saveEntireAmtStateDone() { + if (--IntelAmtEntireStateCalls != 0) return; + var out = fs.openSync(settings.output, 'w'); + fs.writeSync(out, Buffer.from(JSON.stringify(IntelAmtEntireState))); + fs.closeSync(out); + console.log('Done, results written to ' + settings.output + '.'); + exit(1); +} + + +// +// FETCH ALL INTEL AMT MEI STATE +// + +// Get Intel AMT information using MEI +// TODO: If this call is called many time at once, it's going to cause issues. +var getAmtInfoFetching = null; +var getAmtInfoFetchingTimer = null; +function getAmtInfo(func, tag) { + if (amtMei == null) { if (func != null) { func(null, tag); } return; } + if (getAmtInfoFetching != null) { getAmtInfoFetching.push({ f: func, t: tag }); return; } + getAmtInfoFetching = [{ f: func, t: tag }]; + amtMeiTmpState = { Flags: 0, TrustedHashes: [] }; // Flags: 1=EHBC, 2=CCM, 4=ACM + getAmtInfoFetchingTimer = setTimeout(function () { + // MEI failed to respond, break out and reset everthing. + for (var i in getAmtInfoFetching) { if (getAmtInfoFetching[i].f != null) { getAmtInfoFetching[i].f(amtMeiTmpState, getAmtInfoFetching[i].t); } } + getAmtInfoFetching = null; + getAmtInfoFetchingTimer = null; + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + }, 3000); + amtMei.getProtocolVersion(function (result) { if (result != null) { amtMeiTmpState.MeiVersion = result; } }); + amtMei.getVersion(function (val) { + amtMeiTmpState.Versions = {}; + if (val != null) { + for (var version in val.Versions) { amtMeiTmpState.Versions[val.Versions[version].Description] = val.Versions[version].Version; } + amtMei.getProvisioningMode(function (result) { if (result != null) { amtMeiTmpState.ProvisioningMode = result.mode; } }); + amtMei.getProvisioningState(function (result) { if (result != null) { amtMeiTmpState.ProvisioningState = result.state; } }); + amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } }); + amtMei.getControlMode(function (result) { if (result != null) { if (result.controlMode == 1) { amtMeiTmpState.Flags += 2; } if (result.controlMode == 2) { amtMeiTmpState.Flags += 4; } } }); + //amtMei.getMACAddresses(function (result) { if (result != null) { amtMeiTmpState.mac = result; } }); + amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } }); + amtMei.getHashHandles(function (handles) { + exitOnCount = handles.length; + for (var i = 0; i < handles.length; ++i) { + amtMei.getCertHashEntry(handles[i], function (result) { + amtMeiTmpState.TrustedHashes.push({ Active: result.isActive, Default: result.isDefault, HashAlgorithm: result.hashAlgorithm, Name: result.name, Hash: result.certificateHash }); + if (--exitOnCount == 0) { + amtMeiTmpState.Notifications = lmsNotifications; amtMeiState = amtMeiTmpState; + for (var i in getAmtInfoFetching) { if (getAmtInfoFetching[i].f != null) { getAmtInfoFetching[i].f(amtMeiTmpState, getAmtInfoFetching[i].t); } } + getAmtInfoFetching = null; + clearTimeout(getAmtInfoFetchingTimer); + getAmtInfoFetchingTimer = null; + } + }); + } + }); + } else { + amtMeiState = amtMeiTmpState; + amtMeiState.ProvisioningMode = -858993460; + amtMeiState.TrustedHashes = {}; + amtMeiState.Notifications = lmsNotifications; + //console.log('getAmtInfo3', JSON.stringify(amtMeiState)); + if (func != null) { func(amtMeiState, tag); } + } + }); +} + + +// +// MicroLMS +// + +var lmsControlSockets = {}; +var lmsControlSocketsNextId = 1; +var lmsNotifications = []; +var amtLms = null; +var promise = require('promise'); + +function startLms(func) +{ + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + var lme_heci = null + try { lme_heci = require('amt-lme'); } catch (ex) { } + if (lme_heci == null) { if (func != null) { func(func, 0); } this.promise._res(); return; } + + //var amtLms = null; + var http = require('http'); + + // MeshCommander LMS v0.7.4 + var _IntelAmtWebApp_etag = "W7PrsMdzMZVycLmuKL5r"; + var _IntelAmtWebApp = "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"; + + console.log('Setting up MEI...'); + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + //console.log("PTHI Connected."); + + console.log('Setting up LME...'); + amtLms = new lme_heci({ debug: settings.lmsdebug }); + amtLms.promise = ret; + amtLms.on('error', function (e) { + console.log('LME connection failed', e); + setupMeiOsAdmin(func, amtLms.connected == false ? 0 : 3); + this.promise._res(); + }); + amtLms.on('notify', function (data, options, str, code) { + if (code == 'iAMT0052-3') { + kvmGetData(); + } else if (str != null) { + var notify = { date: Date.now(), str: str, code: code }; + lmsNotifications.push(notify); + while (lmsNotifications.length > 100) { lmsNotifications.shift(); } + var notifyBuf = Buffer.concat([Buffer.from('0900', 'hex'), Buffer.from(JSON.stringify(notify))]) // Add a notification + for (var i in lmsControlSockets) { lmsControlSockets[i].write(notifyBuf); } + } + }); + //console.log('LME Connecting...'); + amtLms.on('bind', function (mapping) { + if (mapping[16992]) { this.removeAllListeners('bind'); } else { return; } + //console.log('LMS Bounded'); + amtLms.connected = true; + this.promise._res(); + + //console.log("LME Connected."); + if (settings.noconsole !== true) { + amtLms.meshCommander = http.createServer(); + amtLms.meshCommander.listen(16994); + amtLms.meshCommander.on('upgrade', function (req, socket, head) { + //console.log("WebSocket for " + req.url.split('?')[0]); + switch (req.url.split('?')[0]) { + case '/lms.ashx': // MeshCommander control channel (PTHI) + socket.ws = socket.upgradeWebSocket(); + socket.ws.on('data', processLmsControlData); + socket.ws.on('end', function () { if (lmsControlSockets[this.id]) { delete lmsControlSockets[this.id]; /*console.log('removeControl', JSON.stringify(lmsControlSockets));*/ } }); + var id = lmsControlSocketsNextId++; + lmsControlSockets[id] = socket.ws; + socket.ws.id = id; + //socket.ws.write(Buffer.concat([Buffer.from('0900', 'hex'), Buffer.from(JSON.stringify(lmsNotifications))])); // Send out full list of notifications + //console.log('addControl', JSON.stringify(lmsControlSockets)); + break; + case '/webrelay.ashx': // MeshCommander data channel (LME) + socket.ws = socket.upgradeWebSocket(); + amtLms.bindDuplexStream(socket.ws, 'IPv4', 16992); + break; + default: + socket.end(); + break; + } + }); + amtLms.meshCommander.on('request', function (req, rsp) { + //console.log("WebRequest for " + req.url.split('?')[0]); + switch (req.url.split('?')[0]) { + case '/': // Serve MeshCommander Web Application for LMS + var lmscommander = null; + try { lmscommander = fs.readFileSync('lmscommander.htm'); } catch (e) { } + if (lmscommander != null) { + rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Transfer-Encoding': 'chunked' }); + rsp.end(lmscommander); + } else { + rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Content-Encoding': 'gzip', 'Transfer-Encoding': 'chunked', ETag: _IntelAmtWebApp_etag }); + rsp.end(Buffer.from(_IntelAmtWebApp, 'base64')); + } + break; + default: // Unknown request + rsp.statusCode = 404; + rsp.statusMessage = "Not Found"; + rsp.end(); + break; + } + + }); + //console.log("LMS started, MeshCommander on HTTP/16994."); + tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 2); }, 100); + //console.logReferenceCount(tempTimer); + } else { + //console.log("LMS started."); + tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 1); }, 100); + //console.logReferenceCount(tempTimer); + } + + }); + return (ret); +} + +function setupMeiOsAdmin(func, state) { + if (amtMei == null) { + if (func) { func(state); } + } else { + amtMei.getLocalSystemAccount(function (x) { + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + oswsstack = new wsman(transport, '127.0.0.1', 16992, x.user, x.pass, false); + osamtstack = new amt(oswsstack); + if (func) { func(state); } + //var AllWsman = "CIM_SoftwareIdentity,IPS_SecIOService,IPS_ScreenSettingData,IPS_ProvisioningRecordLog,IPS_HostBasedSetupService,IPS_HostIPSettings,IPS_IPv6PortSettings".split(','); + //osamtstack.BatchEnum(null, AllWsman, startLmsWsmanResponse, null, true); + //************************************* + + // Setup KVM data channel if this is Intel AMT 12 or above + amtMei.getVersion(function (x) { + var amtver = null; + try { for (var i in x.Versions) { if (x.Versions[i].Description == 'AMT') amtver = parseInt(x.Versions[i].Version.split('.')[0]); } } catch (e) { } + if ((amtver != null) && (amtver >= 12)) { + kvmGetData('skip'); // Clear any previous data, this is a dummy read to about handling old data. + tempTimer = setInterval(function () { kvmGetData(); }, 2000); // Start polling for KVM data. + kvmSetData(JSON.stringify({ action: 'restart', ver: 1 })); // Send a restart command to advise the console if present that MicroLMS just started. + } + }); + }); + } +} + +function kvmGetData(tag) { + osamtstack.IPS_KVMRedirectionSettingData_DataChannelRead(kvmDataGetResponse, tag); +} + +function kvmDataGetResponse(stack, name, response, status, tag) { + if ((tag != 'skip') && (status == 200) && (response.Body.ReturnValue == 0)) { + var val = null; + try { val = Buffer.from(response.Body.DataMessage, 'base64').toString(); } catch (e) { return } + if (val != null) { kvmProcessData(response.Body.RealmsBitmap, response.Body.MessageId, val); } + } +} + +var webRtcDesktop = null; +function kvmProcessData(realms, messageId, val) { + var data = null; + try { data = JSON.parse(val) } catch (e) { } + if ((data != null) && (data.action)) { + if (data.action == 'present') { kvmSetData(JSON.stringify({ action: 'present', ver: 1, platform: process.platform })); } + if (data.action == 'offer') { + webRtcDesktop = {}; + var rtc = require('ILibWebRTC'); + webRtcDesktop.webrtc = rtc.createConnection(); + webRtcDesktop.webrtc.on('connected', function () { }); + webRtcDesktop.webrtc.on('disconnected', function () { webRtcCleanUp(); }); + webRtcDesktop.webrtc.on('dataChannel', function (rtcchannel) { + webRtcDesktop.rtcchannel = rtcchannel; + var kvmmodule = require('meshDesktop'); + webRtcDesktop.kvm = kvmmodule.getRemoteDesktopStream(); + webRtcDesktop.kvm.pipe(webRtcDesktop.rtcchannel, { dataTypeSkip: 1, end: false }); + webRtcDesktop.rtcchannel.on('end', function () { webRtcCleanUp(); }); + webRtcDesktop.rtcchannel.on('data', function (x) { kvmCtrlData(this, x); }); + webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm, { dataTypeSkip: 1, end: false }); + //webRtcDesktop.kvm.on('end', function () { console.log('WebRTC DataChannel closed2'); webRtcCleanUp(); }); + //webRtcDesktop.rtcchannel.on('data', function (data) { console.log('WebRTC data: ' + data); }); + }); + kvmSetData(JSON.stringify({ action: 'answer', ver: 1, sdp: webRtcDesktop.webrtc.setOffer(data.sdp) })); + } + } +} + +// Polyfill path.join +var path = { + join: function () { + var x = []; + for (var i in arguments) { + var w = arguments[i]; + if (w != null) { + while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); } + if (i != 0) { + while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } + } + x.push(w); + } + } + if (x.length == 0) return '/'; + return x.join('/'); + } +}; + +// Get a formated response for a given directory path +function getDirectoryInfo(reqpath) { + var response = { path: reqpath, dir: [] }; + if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) { + // List all the drives in the root, or the root itself + var results = null; + try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar. + //console.log('a', objToString(results, 0, ' ')); + if (results != null) { + for (var i = 0; i < results.length; ++i) { + var drive = { n: results[i].name, t: 1 }; + if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons. + response.dir.push(drive); + } + } + } else { + // List all the files and folders in this path + if (reqpath == '') { reqpath = '/'; } + var xpath = path.join(reqpath, '*'); + var results = null; + + try { results = fs.readdirSync(xpath); } catch (e) { } + if (results != null) { + for (var i = 0; i < results.length; ++i) { + if ((results[i] != '.') && (results[i] != '..')) { + var stat = null, p = path.join(reqpath, results[i]); + try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date + if ((stat != null) && (stat != undefined)) { + if (stat.isDirectory() == true) { + response.dir.push({ n: results[i], t: 2, d: stat.mtime }); + } else { + response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime }); + } + } + } + } + } + } + return response; +} + +// Process KVM control channel data +function kvmCtrlData(channel, cmd) { + if (cmd.length > 0 && cmd.charCodeAt(0) != 123) { + // This is upload data + if (this.fileupload != null) { + cmd = Buffer.from(cmd, 'base64'); + var header = cmd.readUInt32BE(0); + if ((header == 0x01000000) || (header == 0x01000001)) { + fs.writeSync(this.fileupload.fp, cmd.slice(4)); + channel.write({ action: 'upload', sub: 'ack', reqid: this.fileupload.reqid }); + if (header == 0x01000001) { fs.closeSync(this.fileupload.fp); this.fileupload = null; } // Close the file + } + } + return; + } + //console.log('KVM Ctrl Data', cmd); + + try { cmd = JSON.parse(cmd); } catch (ex) { console.error('Invalid JSON: ' + cmd); return; } + if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows + switch (cmd.action) { + case 'ping': { + // This is a keep alive + channel.write({ action: 'pong' }); + break; + } + case 'ls': { + /* + // Close the watcher if required + var samepath = ((this.httprequest.watcher != undefined) && (cmd.path == this.httprequest.watcher.path)); + if ((this.httprequest.watcher != undefined) && (samepath == false)) { + //console.log('Closing watcher: ' + this.httprequest.watcher.path); + //this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!! + delete this.httprequest.watcher; + } + */ + + // Send the folder content to the browser + var response = getDirectoryInfo(cmd.path); + if (cmd.reqid != undefined) { response.reqid = cmd.reqid; } + channel.write(response); + + /* + // Start the directory watcher + if ((cmd.path != '') && (samepath == false)) { + var watcher = fs.watch(cmd.path, onFileWatcher); + watcher.tunnel = this.httprequest; + watcher.path = cmd.path; + this.httprequest.watcher = watcher; + //console.log('Starting watcher: ' + this.httprequest.watcher.path); + } + */ + break; + } + case 'mkdir': { + // Create a new empty folder + fs.mkdirSync(cmd.path); + break; + } + case 'rm': { + // Remove many files or folders + for (var i in cmd.delfiles) { + var fullpath = path.join(cmd.path, cmd.delfiles[i]); + try { fs.unlinkSync(fullpath); } catch (e) { console.log(e); } + } + break; + } + case 'rename': { + // Rename a file or folder + var oldfullpath = path.join(cmd.path, cmd.oldname); + var newfullpath = path.join(cmd.path, cmd.newname); + try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); } + break; + } + case 'download': { + // Download a file, to browser + var sendNextBlock = 0; + if (cmd.sub == 'start') { // Setup the download + if (this.filedownload != null) { channel.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; } + this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 } + try { this.filedownload.f = fs.openSync(this.filedownload.path, 'rbN'); } catch (e) { channel.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; } + if (this.filedownload) { channel.write({ action: 'download', sub: 'start', id: cmd.id }); } + } else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands + if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; } + } + // Send the next download block(s) + while (sendNextBlock > 0) { + sendNextBlock--; + var buf = Buffer.alloc(4096); + var len = fs.readSync(this.filedownload.f, buf, 4, 4092, null); + this.filedownload.ptr += len; + if (len < 4092) { buf.writeInt32BE(0x01000001, 0); fs.closeSync(this.filedownload.f); delete this.filedownload; sendNextBlock = 0; } else { buf.writeInt32BE(0x01000000, 0); } + channel.write(buf.slice(0, len + 4).toString('base64')); // Write as Base64 + } + break; + } + case 'upload': { + // Upload a file, from browser + if (cmd.sub == 'start') { // Start the upload + if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); } + if (!cmd.path || !cmd.name) break; + this.fileupload = { reqid: cmd.reqid }; + var filepath = path.join(cmd.path, cmd.name); + try { this.fileupload.fp = fs.openSync(filepath, 'wbN'); } catch (e) { } + if (this.fileupload.fp) { channel.write({ action: 'upload', sub: 'start', reqid: this.fileupload.reqid }); } else { this.fileupload = null; channel.write({ action: 'upload', sub: 'error', reqid: this.fileupload.reqid }); } + } + else if (cmd.sub == 'cancel') { // Stop the upload + if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); this.fileupload = null; } + } + break; + } + case 'copy': { + // Copy a bunch of files from scpath to dspath + for (var i in cmd.names) { + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]); + if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } } + } + break; + } + case 'move': { + // Move a bunch of files from scpath to dspath + for (var i in cmd.names) { + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]); + if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } } + } + break; + } + default: + // Unknown action, ignore it. + break; + } +} + +function webRtcCleanUp() { + if (webRtcDesktop == null) return; + if (webRtcDesktop.rtcchannel) { + try { webRtcDesktop.rtcchannel.close(); } catch (e) { } + try { webRtcDesktop.rtcchannel.removeAllListeners('data'); } catch (e) { } + try { webRtcDesktop.rtcchannel.removeAllListeners('end'); } catch (e) { } + delete webRtcDesktop.rtcchannel; + } + if (webRtcDesktop.webrtc) { + try { webRtcDesktop.webrtc.close(); } catch (e) { } + try { webRtcDesktop.webrtc.removeAllListeners('connected'); } catch (e) { } + try { webRtcDesktop.webrtc.removeAllListeners('disconnected'); } catch (e) { } + try { webRtcDesktop.webrtc.removeAllListeners('dataChannel'); } catch (e) { } + delete webRtcDesktop.webrtc; + } + if (webRtcDesktop.kvm) { + try { webRtcDesktop.kvm.end(); } catch (e) { } + delete webRtcDesktop.kvm; + } + webRtcDesktop = null; +} + +function kvmSetData(x) { + osamtstack.IPS_KVMRedirectionSettingData_DataChannelWrite(Buffer.from(x).toString('base64'), function () { }); +} + +function startLmsWsmanResponse(stack, name, responses, status) { + if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); } + else if (status != 200) { console.log('ERROR: Unable to get object from Intel(R) AMT, status = ' + status + '.'); } + else { + //console.log(JSON.stringify(responses), status); + var amtlogicalelements = responses["CIM_SoftwareIdentity"].responses; + if (amtlogicalelements.length > 0) { + var v = getInstance(amtlogicalelements, "AMT")["VersionString"]; + amtversion = parseInt(v.split('.')[0]); + amtversionmin = parseInt(v.split('.')[1]); + //console.log(amtversion, amtversionmin); + } + } +} + + +// Process commands in the LMS control channel +// Command 9 is add a notification. +function processLmsControlData(data) { + if (data.length < 2) return; + var cmdid = data.readUInt16LE(0); + switch (cmdid) { + case 1: // Request basic Intel AMT information (CMD = 1) + { getAmtInfo(function (meinfo, socket) { meinfo.LoginMode = 2; socket.write(Buffer.concat([Buffer.from('0100', 'hex'), Buffer.from(JSON.stringify(meinfo))])); }, this); break; } + case 2: // Intel AMT MEI Unprovision (CMD = 2) + { if (data.length < 6) break; amtMei.unprovision(data.readUInt32LE(2), function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(2, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; } + case 3: // Intel AMT MEI GetLocalSystemAccount (CMD = 3) + { amtMei.getLocalSystemAccount(function (account, socket) { socket.write(Buffer.concat([Buffer.from('030000000000', 'hex'), account.raw])); }, this); break; } + case 4: // Instruct Intel AMT to start remote configuration (CMD = 4) + { amtMei.startConfiguration(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; } + case 5: // Instruct Intel AMT to stop remote configuration (CMD = 5) + { amtMei.stopConfiguration(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; } + case 6: // Instruct Intel AMT connect CIRA (CMD = 6) + { amtMei.openUserInitiatedConnection(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; } + case 7: // Instruct Intel AMT disconnect CIRA (CMD = 7) + { amtMei.closeUserInitiatedConnection(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; } + case 8: // Get Intel AMT CIRA State (CMD = 8) + { amtMei.getRemoteAccessConnectionStatus(function (state, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(8, 0); data.writeUInt32LE(state.status, 2); socket.write(Buffer.concat([data, state.raw])); }, this); break; } + default: + // Unknown action, ignore it. + break; + } +} + + +// +// MeshCentral TCP port router +// + +function startRouter() { + tcpserver = net.createServer(OnTcpClientConnected); + tcpserver.on('error', function (e) { console.log('ERROR: ' + JSON.stringify(e)); exit(0); return; }); + tcpserver.listen(settings.localPort, function () { + // We started listening. + if (settings.remoteName == null) { + console.log('Redirecting local port ' + settings.localPort + ' to remote port ' + settings.remotePort + '.'); + } else { + console.log('Redirecting local port ' + settings.localPort + ' to ' + settings.remoteName + ':' + settings.remotePort + '.'); + } + console.log('Press ctrl-c to exit.'); + + // If settings has a "cmd", run it now. + //process.exec("notepad.exe"); + }); +} + +// Called when a TCP connect is received on the local port. Launch a tunnel. +function OnTcpClientConnected(c) { + try { + // 'connection' listener + debug(1, 'Client connected'); + c.on('end', function () { disconnectTunnel(this, this.websocket, 'Client closed'); }); + c.pause(); + try { + options = http.parseUri(settings.serverUrl + '?user=' + settings.username + '&pass=' + settings.password + '&nodeid=' + settings.remoteNodeId + '&tcpport=' + settings.remotePort); + } catch (e) { console.log('Unable to parse \"serverUrl\".'); process.exit(1); return; } + options.checkServerIdentity = onVerifyServer; + options.rejectUnauthorized = false; + c.websocket = http.request(options); + c.websocket.tcp = c; + c.websocket.tunneling = false; + c.websocket.upgrade = OnWebSocket; + c.websocket.on('error', function (e) { console.log('ERROR: ' + JSON.stringify(e)); }); + c.websocket.end(); + } catch (e) { debug(2, e); } +} + +// Disconnect both TCP & WebSocket connections and display a message. +function disconnectTunnel(tcp, ws, msg) { + if (ws != null) { try { ws.end(); } catch (e) { debug(2, e); } } + if (tcp != null) { try { tcp.end(); } catch (e) { debug(2, e); } } + debug(1, 'Tunnel disconnected: ' + msg); +} + +// Called when the web socket gets connected +function OnWebSocket(msg, s, head) { + debug(1, 'Websocket connected'); + s.on('data', function (msg) { + if (this.parent.tunneling == false) { + msg = msg.toString(); + if (msg == 'c') { + this.parent.tunneling = true; this.pipe(this.parent.tcp); this.parent.tcp.pipe(this); debug(1, 'Tunnel active'); + } else if ((msg.length > 6) && (msg.substring(0, 6) == 'error:')) { + console.log(msg.substring(6)); + disconnectTunnel(this.tcp, this, msg.substring(6)); + } + } + }); + s.on('error', function (msg) { disconnectTunnel(this.tcp, this, 'Websocket error'); }); + s.on('close', function (msg) { disconnectTunnel(this.tcp, this, 'Websocket closed'); }); + s.parent = this; +} + +// Try to discover the location of the mesh server +function discoverMeshServer() { console.log('Looking for server...'); discoveryInterval = setInterval(discoverMeshServerOnce, 5000); discoverMeshServerOnce(); } + +// Try to discover the location of the mesh server only once +function discoverMeshServerOnce() { + var interfaces = os.networkInterfaces(); + for (var adapter in interfaces) { + if (interfaces.hasOwnProperty(adapter)) { + for (var i = 0; i < interfaces[adapter].length; ++i) { + var addr = interfaces[adapter][i]; + multicastSockets[i] = dgram.createSocket({ type: (addr.family == "IPv4" ? "udp4" : "udp6") }); + multicastSockets[i].bind({ address: addr.address, exclusive: false }); + if (addr.family == "IPv4") { + try { + multicastSockets[i].addMembership(membershipIPv4); + //multicastSockets[i].setMulticastLoopback(true); + multicastSockets[i].once('message', OnMulticastMessage); + multicastSockets[i].send(settings.serverId, 16989, membershipIPv4); + } catch (e) { } + } + } + } + } +} + +// Called when a multicast packet is received +function OnMulticastMessage(msg, rinfo) { + var m = msg.toString().split('|'); + if ((m.length == 3) && (m[0] == 'MeshCentral2') && (m[1] == settings.serverId)) { + settings.serverUrl = m[2].replace('%s', rinfo.address).replace('/agent.ashx', '/meshrelay.ashx'); + console.log('Found server at ' + settings.serverUrl + '.'); + if (discoveryInterval != null) { clearInterval(discoveryInterval); discoveryInterval = null; } + startRouter(); + } +} + + +// +// PUSH MESHCOMMANDER INTO FIRMWARE +// + +function nextStepStorageUpload() { + debug(3, "nextStepStorageUpload"); + getAmtStorage(function (statusCode, data) { + if (statusCode == 200) { + debug(2, "getAmtStorage: " + JSON.stringify(data, null, 2)); + if ((data['content'] != null) && (data['content']['index.htm'] != null)) { nextStepStorageUpload3('index.htm'); } + else if ((data['content'] != null) && (data['content']['logon.htm'] != null)) { nextStepStorageUpload3('logon.htm'); } + else if ((data['content'] != null) && (data['content']['logon.htm'] != null)) { nextStepStorageUpload3('logon.htm'); } + else { nextStepStorageUpload2('index.htm', null); } + } else { + console.log("Unable to read storage state."); + exit(); + return; + } + }); +} + +function nextStepStorageUpload2(uploadName, linkName) { + debug(3, "nextStepStorageUpload2"); + if (settings.webapp == null) { console.log("Done."); exit(); return; } else { + console.log("Uploading MeshCommander..."); + pushToStorage(uploadName, linkName, Buffer.from(settings.webapp, 'base64'), function (statusCode) { + if (statusCode == 500) { console.log("Error, check that computer is powered on."); exit(); return; } + if (statusCode != 200) { + if (uploadName == 'index.htm') { + nextStepStorageUpload2('mesh/commander/console', 'MeshCommander'); + } else { + console.log("Unable to upload MeshCommander, status = " + statusCode + "."); exit(); return; + } + } else { + console.log("Verifying MeshCommander..."); + verifyStorage(uploadName, Buffer.from(settings.webapp, 'base64'), function (verified) { + if (verified == true) { console.log('Done.'); } else { console.log('MeshCommander verification failed.'); } + exit(); return; + }); + } + }); + } +} + +function nextStepStorageUpload3(deleteName) { + console.log("Deleting " + deleteName + " from storage..."); + deleteStorage(deleteName, function (statusCode) { + if (statusCode == 500) { console.log("Error, check that computer is powered on."); exit(); return; } + if (statusCode == 200) { nextStepStorageUpload(); } else { console.log("Unable to delete " + deleteName + "."); exit(); return; } + }); +} + +// Fetch the Intel AMT storage document +function getAmtStorage(func, noretry) { + var req = digest.request({ protocol: settings.protocol, method: "GET", host: settings.hostname, path: "/amt-storage/", port: settings.localport }, + function (response) { + if (response.statusCode != 200) { console.log("Unable to connect to Intel(R) AMT."); func(response.statusCode, null); } + response.on('data', function (chunk) { if (response.acc == null) { response.acc = chunk; } else { response.acc += chunk; } }); + response.on('end', function () { + var data = response.acc.toString(), len, data2, amtstorage = null; + try { + do { len = data.length; data2 = data; data = data2.replace('\x00', ''); } while (data != data2); // Remove all zero's, this is needed because firmware sometimes returns garbage we must fix. + do { len = data.length; data2 = data; data = data2.replace('\x22\x01\x22', '\x22\x22'); } while (data != data2); // "\x01", this is needed because firmware sometimes returns garbage we must fix. + amtstorage = JSON.parse(data); + } catch (e) { console.log("Error: Unable to parse Intel AMT response."); func(null); } + if (func != null) { func(response.statusCode, amtstorage); } + }); + }); + req.on('error', function (e) { console.log("Error occured: " + JSON.stringify(e)); if (noretry == true) { if (func != null) { func(null); } } else { getAmtStorage(func, true); } }); + req.end(); +} + +// Fetch the Intel AMT storage document +function pushToStorage(name, linkname, data, func, ptr) { + if (ptr == null) { ptr = 0; } + var req = digest.request({ protocol: settings.protocol, method: "PUT", host: settings.hostname, path: ("/amt-storage/" + name + ((ptr != 0) ? '?append=' : '')), port: settings.localport }); + req.on('error', function (e) { console.log("Error occured: " + JSON.stringify(e)); if (func != null) { func(null); } }); + req.on('response', function (response) { + debug(1, 'Chunk Done', data.length, ptr); + if ((response.statusCode == 200) && (ptr < data.length)) { pushToStorage(name, linkname, data, func, ptr); } else { if (func != null) { func(response.statusCode); } } + }); + var header = (ptr > 0) ? '' : 'Content-Encoding:gzipContent-Type:text/html' + ((linkname != null) ? ('' + linkname + '') : '') + ''; + var blocklen = ((data.length - ptr) > (7000 - header.length)) ? (7000 - header.length) : (data.length - ptr); + req.write(Buffer.concat([new Buffer(header), data.slice(ptr, ptr + blocklen)])); + ptr += blocklen; + req.end(); +} + +// Fetch the Intel AMT storage document +function verifyStorage(name, data, func) { + var req = digest.request({ protocol: settings.protocol, method: "GET", host: settings.hostname, path: ("/amt-storage/" + name), port: settings.localport }); + req.on('error', function (e) { console.log("Verify error occured: " + JSON.stringify(e)); if (func != null) { func(null); } }); + req.on('response', function (response) { + response.ptr = 0; + response.ok = true; + response.on('data', function (data2) { if (data2.toString('hex') != data.slice(response.ptr, response.ptr + data2.length).toString('hex')) { response.ok = false; console.log('Verifiy failed (' + response.ptr + ', ' + data2.length + ').'); } response.ptr += data2.length; }); + response.on('end', function () { if (func != null) { func(response.ok); } }); + }); + req.end(); +} + +// Fetch the Intel AMT storage document +function deleteStorage(name, func, noretry) { + var req = digest.request({ protocol: settings.protocol, method: "DELETE", host: settings.hostname, path: "/amt-storage/" + name, port: settings.localport }); + req.on('error', function (e) { if ((e == 'Error: Socket was unexpectedly closed') && (noretry != true)) { deleteStorage(name, func, true); } else { if (func != null) { if (e.statusCode) { func(e.statusCode); } else { func(null); } } } }); + req.on('response', function (response) { if (func != null) { func(response.statusCode); } }); + req.end(); +} + +// Parse URL arguments +function parseUrlArguments(url) { + var r = {}, x = url.split('?'); + if (x.length < 2) return r; + x = x[1].split('&'); + for (var i in x) { var j = x[i].indexOf('='); if (j > 0) { r[x[i].substring(0, j).toLowerCase()] = x[i].substring(j + 1); } } + return r; +} + +// Remove a element from a array +function removeItemFromArray(array, element) { + var index = array.indexOf(element); + if (index !== -1) { array.splice(index, 1); } +} + +// Run MeshCmd, but before we do, we need to see if what type of service we are going to be +var serviceName = null; +var serviceOpSpecified = 0; +var serviceInstall = 0; + +for (var i in process.argv) { + if (process.argv[i].toLowerCase() == 'install') { serviceInstall = 1 } else if (process.argv[i].toLowerCase() == 'uninstall') { serviceInstall = -1 } + if ((process.argv[i].toLowerCase() == 'microlms') || (process.argv[i].toLowerCase() == 'amtlms') || (process.argv[i].toLowerCase() == 'lms')) { serviceName = 'MicroLMS'; break; } + if ((process.argv[i].toLowerCase() == 'meshcommander') || (process.argv[i].toLowerCase() == 'commander')) { serviceName = 'MeshCommander'; break; } +} + +if (serviceName == null) { + for (var i in process.argv) { + if ((process.argv[i].toLowerCase() == 'install') || (process.argv[i].toLowerCase() == 'uninstall')) { + console.log('In order to install/uninstall, a service type must be specified.'); + process.exit(); + } + } + if (process.execPath.includes('MicroLMS')) { serviceName = 'MicroLMS'; } + else if (process.execPath.includes('MeshCommander')) { serviceName = 'MeshCommander'; } + else { serviceName = 'not_a_service'; } +} + +if (serviceInstall == 0) { + run(process.argv); +} else { + var serviceHost = require('service-host'); + var meshcmdService = new serviceHost({ name: serviceName, startType: 'AUTO_START' }); + + // Called when the background service is started. + meshcmdService.on('serviceStart', function onStart() { + console.setDestination(console.Destinations.DISABLED); // Disable console.log(). + if (process.execPath.includes('MicroLMS')) { run([process.execPath, 'microlms']); } // + else if (process.execPath.includes('MeshCommander')) { run([process.execPath, 'meshcommander']); } + else { console.log('Aborting Service Start, because unknown binary: ' + process.execPath); process.exit(1); } + }); + + // Called when the background service is stopping + meshcmdService.on('serviceStop', function onStop() { console.log('Stopping service'); process.exit(); }); // The console.log() is for debugging, will be ignored unless "console.setDestination()" is set. + + // Called when the executable is not running as a service, run normally. + meshcmdService.on('normalStart', function onNormalStart() { try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); } }); + meshcmdService.run(); +} diff --git a/agents-new/meshcore-old.js b/agents-new/meshcore-old.js new file mode 100644 index 00000000..e45677dd --- /dev/null +++ b/agents-new/meshcore-old.js @@ -0,0 +1,1761 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +process.on('uncaughtException', function (ex) { + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": "uncaughtException1: " + ex }); +}); + +// NOTE: This seems to cause big problems, don't enable the debugger in the server's meshcore. +//attachDebugger({ webport: 9999, wait: 1 }).then(function (prt) { console.log('Point Browser for Debug to port: ' + prt); }); + +// Mesh Rights +var MESHRIGHT_EDITMESH = 1; +var MESHRIGHT_MANAGEUSERS = 2; +var MESHRIGHT_MANAGECOMPUTERS = 4; +var MESHRIGHT_REMOTECONTROL = 8; +var MESHRIGHT_AGENTCONSOLE = 16; +var MESHRIGHT_SERVERFILES = 32; +var MESHRIGHT_WAKEDEVICE = 64; +var MESHRIGHT_SETNOTES = 128; +var MESHRIGHT_REMOTEVIEW = 256; +var MESHRIGHT_NOTERMINAL = 512; +var MESHRIGHT_NOFILES = 1024; +var MESHRIGHT_NOAMT = 2048; +var MESHRIGHT_LIMITEDINPUT = 4096; + +function createMeshCore(agent) { + var obj = {}; + + /* + function borderController() { + this.container = null; + this.Start = function Start(user) { + if (this.container == null) { + if (process.platform == 'win32') { + try { + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.SessionId }); + } catch (ex) { + this.container = require('ScriptContainer').Create({ processIsolation: 1 }); + } + } else { + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.uid }); + } + this.container.parent = this; + this.container.addModule('monitor-info', getJSModule('monitor-info')); + this.container.addModule('monitor-border', getJSModule('monitor-border')); + this.container.addModule('promise', getJSModule('promise')); + this.container.once('exit', function (code) { sendConsoleText('Border Process Exited with code: ' + code); this.parent.container = this.parent._container = null; }); + 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.exit(); + } + } + } + obj.borderManager = new borderController(); + */ + + // MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent. + var meshCoreObj = { "action": "coreinfo", "value": "MeshCore v6", "caps": 14 }; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript, 32 = Temporary Agent, 64 = Recovery Agent + + // Get the operating system description string + try { require('os').name().then(function (v) { meshCoreObj.osdesc = v; }); } catch (ex) { } + + var meshServerConnectionState = 0; + var tunnels = {}; + var lastMeInfo = 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 amt = null; + var processManager = require('process-manager'); + var wifiScannerLib = null; + var wifiScanner = null; + var networkMonitor = null; + var amtscanner = null; + var nextTunnelIndex = 1; + var amtPolicy = 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) { // if the agent is compiled with KVM support + // Check if this computer supports a desktop + try { if ((process.platform == 'win32') || (process.platform == 'darwin') || (require('monitor-info').kvm_x11_support)) { meshCoreObj.caps |= 1; } } catch (ex) { } + } + } else { + // Running in nodejs + meshCoreObj.value += '-NodeJS'; + meshCoreObj.caps = 8; + mesh = agent.getMeshApi(); + } + + /* + 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 (ex) { amtscanner = null; } + + // Fetch the SMBios Tables + var SMBiosTables = null; + var SMBiosTablesRaw = null; + try { + var SMBiosModule = null; + try { SMBiosModule = require('smbios'); } catch (ex) { } + if (SMBiosModule != null) { + SMBiosModule.get(function (data) { + if (data != null) { + SMBiosTablesRaw = data; + SMBiosTables = require('smbios').parse(data) + if (mesh.isControlChannelConnected) { mesh.SendCommand({ "action": "smbios", "value": SMBiosTablesRaw }); } + + // If SMBios tables say that AMT is present, try to connect MEI + if (SMBiosTables.amtInfo && (SMBiosTables.amtInfo.AMT == true)) { + var amtmodule = require('amt-manage'); + amt = new amtmodule(mesh, db, true); + amt.onStateChange = function (state) { if (state == 2) { sendPeriodicServerUpdate(1); } } + if (amtPolicy != null) { amt.setPolicy(amtPolicy); } + amt.start(); + } + } + }); + } + } catch (ex) { sendConsoleText("ex1: " + ex); } + + // Try to load up the WIFI scanner + try { + var wifiScannerLib = require('wifi-scanner'); + wifiScanner = new wifiScannerLib(); + wifiScanner.on('accessPoint', function (data) { sendConsoleText("wifiScanner: " + data); }); + } catch (ex) { wifiScannerLib = null; wifiScanner = null; } + + // 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.on('error', 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': { + // Return the list of running processes + if (data.sessionid) { + processManager.getProcesses(function (plist) { mesh.SendCommand({ "action": "msg", "type": "ps", "value": JSON.stringify(plist), "sessionid": data.sessionid }); }); + } + break; + } + case 'pskill': { + // Kill a process + if (data.value) { + try { process.kill(data.value); } catch (e) { sendConsoleText("pskill: " + JSON.stringify(e)); } + } + break; + } + case 'openUrl': { + // Open a local web browser and return success/fail + sendConsoleText('OpenURL: ' + data.url); + if (data.url) { mesh.SendCommand({ "action": "msg", "type":"openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); } + break; + } + case 'getclip': { + // Send the load clipboard back to the user + sendConsoleText('getClip: ' + JSON.stringify(data)); + require("clipboard").read().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); }); + break; + } + case 'setclip': { + // Set the load clipboard to a user value + sendConsoleText('setClip: ' + JSON.stringify(data)); + if (typeof data.data == 'string') { + require("clipboard")(data.data); // Set the clipboard + mesh.SendCommand({ "action": "msg", "type": "setclip", "sessionid": data.sessionid, "success": true }); + } + break; + } + default: + // Unknown action, ignore it. + 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; + } + case 'openUrl': { + // Open a local web browser and return success/fail + sendConsoleText('OpenURL: ' + data.url); + if (data.url) { mesh.SendCommand({ "action": "openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); } + break; + } + case 'amtPolicy': { + // Store the latest Intel AMT policy + amtPolicy = data.amtPolicy; + if (data.amtPolicy != null) { db.Put('amtPolicy', JSON.stringify(data.amtPolicy)); } else { db.Put('amtPolicy', null); } + if (amt != null) { amt.setPolicy(amtPolicy); } + break; + } + case 'getScript': { + // Received a configuration script from the server + sendConsoleText('getScript: ' + JSON.stringify(data)); + break; + } + default: + // Unknown action, ignore it. + 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; + + //sendConsoleText('onTunnelUpgrade'); + + 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 = Terminal, 2 = Desktop, 5 = Files + // 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) { + // Check user access rights for terminal + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOTERMINAL) != 0))) { + // Disengage this tunnel, user does not have the rights to do this!! + this.httprequest.protocol = 999999; + this.httprequest.s.end(); + sendConsoleText('Error: No Terminal Control Rights.'); + return; + } + + // Remote terminal using native pipes + if (process.platform == "win32") + { + this.httprequest._term = require('win-terminal').Start(80, 25); + this.httprequest._term.pipe(this, { dataTypeSkip: 1 }); + this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false }); + this.prependListener('end', function () { this.httprequest._term.end(function () { console.log('Terminal was closed'); }); }); + //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.end = function () { + if (process.platform == "win32") { + // Unpipe the web socket + this.unpipe(this.httprequest._term); + this.httprequest._term.unpipe(this); + + // Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends). + if (this.rtcchannel) { + this.rtcchannel.unpipe(this.httprequest._term); + this.httprequest._term.unpipe(this.rtcchannel); + } + + // Clean up + this.httprequest._term.end(); + this.httprequest._term = null; + } else { + // TODO!! + } + }; + + this.removeAllListeners('data'); + this.on('data', onTunnelControlData); + //this.write('MeshCore Terminal Hello'); + if (process.platform == 'linux') { this.httprequest.process.stdin.write("stty erase ^H\nalias ls='ls --color=auto'\nclear\n"); } + } else if (this.httprequest.protocol == 2) + { + // Check user access rights for desktop + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0)) { + // Disengage this tunnel, user does not have the rights to do this!! + this.httprequest.protocol = 999999; + this.httprequest.s.end(); + sendConsoleText('Error: No Desktop Control Rights.'); + return; + } + + // 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; + + // Unpipe the web socket + this.unpipe(this.httprequest.desktop.kvm); + this.httprequest.desktop.kvm.unpipe(this); + + // Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends). + if (this.rtcchannel) { + this.rtcchannel.unpipe(this.httprequest.desktop.kvm); + this.httprequest.desktop.kvm.unpipe(this.rtcchannel); + } + + 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; } + + if ((this.httprequest.rights == 0xFFFFFFFF) || (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) != 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0))) { + // If we have remote control rights, pipe the KVM input + this.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. Pipe the Browser --> KVM input. + } else { + // We need to only pipe non-mouse & non-keyboard inputs. + //sendConsoleText('Warning: No Remote Desktop Input Rights.'); + // TODO!!! + } + + this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. Pipe the KVM --> Browser images. + this.removeAllListeners('data'); + this.on('data', onTunnelControlData); + //this.write('MeshCore KVM Hello!1'); + } else if (this.httprequest.protocol == 5) { + // Check user access rights for files + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOFILES) != 0))) { + // Disengage this tunnel, user does not have the rights to do this!! + this.httprequest.protocol = 999999; + this.httprequest.s.end(); + sendConsoleText('Error: No Files Control Rights.'); + return; + } + + // 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': { + // Delete, possibly recursive delete + for (var i in cmd.delfiles) { + try { deleteFolderRecursive(obj.path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (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; + } + default: + // Unknown action, ignore it. + break; + } + } + //sendConsoleText("Got tunnel #" + this.httprequest.index + " data: " + data, this.httprequest.sessionid); + } + } + + // Delete a directory with a files and directories within it + function deleteFolderRecursive(path, rec) { + if (fs.existsSync(path)) { + if (rec == true) { + fs.readdirSync(obj.path.join(path, '*')).forEach(function (file, index) { + var curPath = obj.path.join(path, file); + if (fs.statSync(curPath).isDirectory()) { // recurse + deleteFolderRecursive(curPath, true); + } else { // delete file + fs.unlinkSync(curPath); + } + }); + } + fs.unlinkSync(path); + } + }; + + // 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; + } + default: + // Unknown action, ignore it. + 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 + if (process.platform == 'win32') + { + ws.httprequest._term.unpipe(ws); + } + else + { + 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. + if (process.platform == 'win32') + { + ws.unpipe(ws.httprequest._term); + ws.rtcchannel.pipe(ws.httprequest._term, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. + } + else + { + 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 + if (process.platform == 'win32') + { + ws.httprequest._term.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. + } + else + { + 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. + if (ws.httprequest.protocol == 1) return; // TODO: Terminal is currently broken with WebRTC. Reject WebRTC upgrade for now. + 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 () { + // The WebRTC channel closed, unpipe the KVM now. This is also done when the web socket closes. + //sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed'); + if (this.websocket.desktop && this.websocket.desktop.kvm) { + this.unpipe(this.websocket.desktop.kvm); + this.websocket.httprequest.desktop.kvm.unpipe(this); + } + }); + 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; } + }; + + // Open a web browser to a specified URL on current user's desktop + function openUserDesktopUrl(url) { + var child = null; + try { + switch (process.platform) { + case 'win32': + //child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe', ["/c", "start", url], { type: childProcess.SpawnTypes.USER, uid: require('user-sessions').Current().Active[0].SessionId }); + child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe', ["/c", "start", url], { type: childProcess.SpawnTypes.USER }); + break; + case 'linux': + child = require('child_process').execFile('/usr/bin/xdg-open', ['xdg-open', url], { uid: require('user-sessions').consoleUid() }); + break; + case 'darwin': + child = require('child_process').execFile('/usr/bin/open', ['open', url], { uid: require('user-sessions').consoleUid() }); + break; + default: + // Unknown platform, ignore this command. + break; + } + } catch (ex) { } + return child; + } + + // 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, osinfo,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, sendcaps, openurl, amtreset, amtccm, amtdeactivate,\r\namtpolicy, getscript, getclip, setclip.'; + break; + } + /* + case 'border': + { + if ((args['_'].length == 1) && (args['_'][0] == 'on')) { + if (meshCoreObj.users.length > 0) { + obj.borderManager.Start(meshCoreObj.users[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 'getclip': { + require("clipboard").read().then(function (str) { sendConsoleText(str, sessionid); }); + break; + } + case 'setclip': { + if (args['_'].length != 1) { response = 'Proper usage: setclip (text)'; } else { require("clipboard")(args['_'][0]); response = 'Setting clipboard to: ' + args['_'][0]; } + break; + } + case 'amtreset': { + if (amt != null) { amt.reset(); response = 'Done.'; } + break; + } + case 'amtlmsreset': { + if (amt != null) { amt.lmsreset(); response = 'Done.'; } + break; + } + case 'amtccm': { + if (amt == null) { response = 'Intel AMT not supported.'; } else { + if (args['_'].length != 1) { response = 'Proper usage: amtccm (adminPassword)'; } // Display usage + else { amt.setPolicy({ type: 0 }); amt.activeToCCM(args['_'][0]); } + } + break; + } + case 'amtdeactivate': { + if (amt == null) { response = 'Intel AMT not supported.'; } else { amt.setPolicy({ type: 0 }); amt.deactivateCCM(); } + break; + } + case 'amtpolicy': { + if (amtPolicy == null) { + response = 'No Intel(R) AMT policy.'; + } else { + response = JSON.stringify(amtPolicy); + } + break; + } + case 'openurl': { + if (args['_'].length != 1) { response = 'Proper usage: openurl (url)'; } // Display usage + else { if (openUserDesktopUrl(args['_'][0]) == null) { response = 'Failed.'; } else { response = 'Success.'; } } + break; + } + case 'users': { + if (meshCoreObj.users == null) { response = 'Active users are unknown.'; } else { response = 'Active Users: ' + meshCoreObj.users.join(', ') + '.'; } + require('user-sessions').enumerateUsers().then(function (u) { for (var i in u) { sendConsoleText(u[i]); } }); + 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 = 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': { + 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) { response = 'SMBios tables not available.'; } else { response = objToString(SMBiosTables, 0, ' ', true); } + break; + } + case 'rawsmbios': { + if (SMBiosTablesRaw == null) { response = 'SMBios tables not available.'; } else { + response = ''; + for (var i in SMBiosTablesRaw) { + var header = false; + for (var j in SMBiosTablesRaw[i]) { + if (SMBiosTablesRaw[i][j].length > 0) { + if (header == false) { response += ('Table type #' + i + ((require('smbios').smTableTypes[i] == null) ? '' : (', ' + require('smbios').smTableTypes[i]))) + '\r\n'; header = true; } + response += (' ' + SMBiosTablesRaw[i][j].toString('hex')) + '\r\n'; + } + } + } + } + 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: ' + meshCoreObj.value + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform: ' + process.platform + '.\r\nCapabilities: ' + meshCoreObj.caps + '.\r\nServer URL: ' + mesh.ServerUrl + '.'; + if (amt != null) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amt.lmsstate] + '.'; } + if (meshCoreObj.osdesc) { response += '\r\nOS: ' + meshCoreObj.osdesc + '.'; } + response += '\r\nModules: ' + addedModules.join(', ') + '.'; + response += '\r\nServer Connection: ' + mesh.isControlChannelConnected + ', State: ' + meshServerConnectionState + '.'; + response += '\r\lastMeInfo: ' + lastMeInfo + '.'; + var oldNodeId = db.Get('OldNodeId'); + if (oldNodeId != null) { response += '\r\nOldNodeID: ' + oldNodeId + '.'; } + if (process.platform != 'win32') { response += '\r\nX11 support: ' + require('monitor-info').kvm_x11_support + '.'; } + break; + } + case 'osinfo': { // Return the operating system information + var i = 1; + if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; } + for (var j = 0; j < i; j++) { + var pr = require('os').name(); + pr.sessionid = sessionid; + pr.then(function (v) { sendConsoleText("OS: " + v, this.sessionid); }); + } + break; + } + case 'sendcaps': { // Send capability flags to the server + if (args['_'].length == 0) { + response = 'Proper usage: sendcaps (number)'; // Display correct command usage + } else { + meshCoreObj.caps = parseInt(args['_'][0]); + mesh.SendCommand(meshCoreObj); + response = JSON.stringify(meshCoreObj); + } + break; + } + case 'sendosdesc': { // Send OS description + if (args['_'].length > 0) { + meshCoreObj.osdesc = args['_'][0]; + mesh.SendCommand(meshCoreObj); + response = JSON.stringify(meshCoreObj); + } else { + response = 'Proper usage: sendosdesc [os description]'; // Display correct command usage + } + 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 = Buffer.alloc(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.on('error', 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 + if (amt != null) { + amt.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; + } + case 'getscript': { + if (args['_'].length != 1) { + response = 'Proper usage: getscript [scriptNumber].'; + } else { + mesh.SendCommand({ "action": "getScript", "type": args['_'][0] }); + } + 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 }); } + + // Update the server with basic info, logged in users and more. + mesh.SendCommand(meshCoreObj); + + // Send SMBios tables if present + if (SMBiosTablesRaw != null) { mesh.SendCommand({ "action": "smbios", "value": SMBiosTablesRaw }); } + + // Update the server on more advanced stuff, like Intel ME and Network Settings + meInfoStr = null; + sendPeriodicServerUpdate(); + //if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes + } + } + + // 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(flags) { + if (meshServerConnectionState == 0) return; // Not connected to server, do nothing. + if (!flags) { flags = 0xFFFFFFFF; } + + if ((flags & 1) && (amt != null)) { + // If we have a connected MEI, get Intel ME information + amt.getAmtInfo(function (meinfo) { + try { + if (meinfo == null) return; + 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) { + var meInfoStr = JSON.stringify(intelamt); + if (meInfoStr != lastMeInfo) { + meshCoreObj.intelamt = intelamt; + mesh.SendCommand(meshCoreObj); + lastMeInfo = meInfoStr; + } + } + } catch (ex) { } + }); + } + + if (flags & 2) { + // Update network information + sendNetworkUpdateNagle(false); + } + } + + + // 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); + + //resetMicroLms(); + + // Setup logged in user monitoring (THIS IS BROKEN IN WIN7) + try { + var userSession = require('user-sessions'); + userSession.on('changed', function onUserSessionChanged() { + userSession.enumerateUsers().then(function (users) { + var u = [], a = users.Active; + for (var i = 0; i < a.length; i++) { + var un = a[i].Domain ? (a[i].Domain + '\\' + a[i].Username) : (a[i].Username); + if (u.indexOf(un) == -1) { u.push(un); } // Only push users in the list once. + } + meshCoreObj.users = u; + mesh.SendCommand(meshCoreObj); + }); + }); + userSession.emit('changed'); + //userSession.on('locked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has LOCKED the desktop'); }); + //userSession.on('unlocked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has UNLOCKED the desktop'); }); + } catch (ex) { } + } + + 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; + } + + return obj; +} + +// +// Module startup +// + +try { + 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); + } +} catch (ex) { + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": "uncaughtException2: " + ex }); +} \ No newline at end of file diff --git a/agents-new/meshcore.js b/agents-new/meshcore.js new file mode 100644 index 00000000..0cdfb3d7 --- /dev/null +++ b/agents-new/meshcore.js @@ -0,0 +1,1776 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +process.on('uncaughtException', function (ex) { + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": "uncaughtException1: " + ex }); +}); + +// NOTE: This seems to cause big problems, don't enable the debugger in the server's meshcore. +//attachDebugger({ webport: 9999, wait: 1 }).then(function (prt) { console.log('Point Browser for Debug to port: ' + prt); }); + +// Mesh Rights +var MESHRIGHT_EDITMESH = 1; +var MESHRIGHT_MANAGEUSERS = 2; +var MESHRIGHT_MANAGECOMPUTERS = 4; +var MESHRIGHT_REMOTECONTROL = 8; +var MESHRIGHT_AGENTCONSOLE = 16; +var MESHRIGHT_SERVERFILES = 32; +var MESHRIGHT_WAKEDEVICE = 64; +var MESHRIGHT_SETNOTES = 128; +var MESHRIGHT_REMOTEVIEW = 256; +var MESHRIGHT_NOTERMINAL = 512; +var MESHRIGHT_NOFILES = 1024; +var MESHRIGHT_NOAMT = 2048; +var MESHRIGHT_LIMITEDINPUT = 4096; + +function createMeshCore(agent) { + var obj = {}; + + /* + function borderController() { + this.container = null; + this.Start = function Start(user) { + if (this.container == null) { + if (process.platform == 'win32') { + try { + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.SessionId }); + } catch (ex) { + this.container = require('ScriptContainer').Create({ processIsolation: 1 }); + } + } else { + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.uid }); + } + this.container.parent = this; + this.container.addModule('monitor-info', getJSModule('monitor-info')); + this.container.addModule('monitor-border', getJSModule('monitor-border')); + this.container.addModule('promise', getJSModule('promise')); + this.container.once('exit', function (code) { sendConsoleText('Border Process Exited with code: ' + code); this.parent.container = this.parent._container = null; }); + 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.exit(); + } + } + } + obj.borderManager = new borderController(); + */ + + // MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent. + var meshCoreObj = { "action": "coreinfo", "value": "MeshCore v6", "caps": 14 }; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript, 32 = Temporary Agent, 64 = Recovery Agent + + // Get the operating system description string + try { require('os').name().then(function (v) { meshCoreObj.osdesc = v; }); } catch (ex) { } + + var meshServerConnectionState = 0; + var tunnels = {}; + var lastMeInfo = 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 amt = null; + var processManager = require('process-manager'); + var wifiScannerLib = null; + var wifiScanner = null; + var networkMonitor = null; + var amtscanner = null; + var nextTunnelIndex = 1; + var amtPolicy = 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) { // if the agent is compiled with KVM support + // Check if this computer supports a desktop + try { if ((process.platform == 'win32') || (process.platform == 'darwin') || (require('monitor-info').kvm_x11_support)) { meshCoreObj.caps |= 1; } } catch (ex) { } + } + } else { + // Running in nodejs + meshCoreObj.value += '-NodeJS'; + meshCoreObj.caps = 8; + mesh = agent.getMeshApi(); + } + + /* + 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 (ex) { amtscanner = null; } + + // Fetch the SMBios Tables + var SMBiosTables = null; + var SMBiosTablesRaw = null; + try { + var SMBiosModule = null; + try { SMBiosModule = require('smbios'); } catch (ex) { } + if (SMBiosModule != null) { + SMBiosModule.get(function (data) { + if (data != null) { + SMBiosTablesRaw = data; + SMBiosTables = require('smbios').parse(data) + if (mesh.isControlChannelConnected) { mesh.SendCommand({ "action": "smbios", "value": SMBiosTablesRaw }); } + + // If SMBios tables say that AMT is present, try to connect MEI + if (SMBiosTables.amtInfo && (SMBiosTables.amtInfo.AMT == true)) { + var amtmodule = require('amt-manage'); + amt = new amtmodule(mesh, db, true); + amt.onStateChange = function (state) { if (state == 2) { sendPeriodicServerUpdate(1); } } + if (amtPolicy != null) { amt.setPolicy(amtPolicy); } + amt.start(); + } + } + }); + } + } catch (ex) { sendConsoleText("ex1: " + ex); } + + // Try to load up the WIFI scanner + try { + var wifiScannerLib = require('wifi-scanner'); + wifiScanner = new wifiScannerLib(); + wifiScanner.on('accessPoint', function (data) { sendConsoleText("wifiScanner: " + data); }); + } catch (ex) { wifiScannerLib = null; wifiScanner = null; } + + // 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.on('error', 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': { + // Return the list of running processes + if (data.sessionid) { + processManager.getProcesses(function (plist) { mesh.SendCommand({ "action": "msg", "type": "ps", "value": JSON.stringify(plist), "sessionid": data.sessionid }); }); + } + break; + } + case 'pskill': { + // Kill a process + if (data.value) { + try { process.kill(data.value); } catch (e) { sendConsoleText("pskill: " + JSON.stringify(e)); } + } + break; + } + case 'openUrl': { + // Open a local web browser and return success/fail + sendConsoleText('OpenURL: ' + data.url); + if (data.url) { mesh.SendCommand({ "action": "msg", "type":"openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); } + break; + } + case 'getclip': { + // Send the load clipboard back to the user + sendConsoleText('getClip: ' + JSON.stringify(data)); + if (require('MeshAgent').isService) + { + require('clipboard').dispatchRead().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); }); + } + else + { + require("clipboard").read().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); }); + } + break; + } + case 'setclip': { + // Set the load clipboard to a user value + sendConsoleText('setClip: ' + JSON.stringify(data)); + if (typeof data.data == 'string') + { + if (require('MeshAgent').isService) + { + require('clipboard').dispatchWrite(data.data); + } + else + { + require("clipboard")(data.data); // Set the clipboard + } + mesh.SendCommand({ "action": "msg", "type": "setclip", "sessionid": data.sessionid, "success": true }); + } + break; + } + default: + // Unknown action, ignore it. + 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; + } + case 'openUrl': { + // Open a local web browser and return success/fail + sendConsoleText('OpenURL: ' + data.url); + if (data.url) { mesh.SendCommand({ "action": "openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); } + break; + } + case 'amtPolicy': { + // Store the latest Intel AMT policy + amtPolicy = data.amtPolicy; + if (data.amtPolicy != null) { db.Put('amtPolicy', JSON.stringify(data.amtPolicy)); } else { db.Put('amtPolicy', null); } + if (amt != null) { amt.setPolicy(amtPolicy); } + break; + } + case 'getScript': { + // Received a configuration script from the server + sendConsoleText('getScript: ' + JSON.stringify(data)); + break; + } + default: + // Unknown action, ignore it. + 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; + + //sendConsoleText('onTunnelUpgrade'); + + 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 = Terminal, 2 = Desktop, 5 = Files + // 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) { + // Check user access rights for terminal + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOTERMINAL) != 0))) { + // Disengage this tunnel, user does not have the rights to do this!! + this.httprequest.protocol = 999999; + this.httprequest.s.end(); + sendConsoleText('Error: No Terminal Control Rights.'); + return; + } + + // Remote terminal using native pipes + if (process.platform == "win32") + { + this.httprequest._term = require('win-terminal').Start(80, 25); + this.httprequest._term.pipe(this, { dataTypeSkip: 1 }); + this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false }); + this.prependListener('end', function () { this.httprequest._term.end(function () { console.log('Terminal was closed'); }); }); + //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.end = function () { + if (process.platform == "win32") { + // Unpipe the web socket + this.unpipe(this.httprequest._term); + this.httprequest._term.unpipe(this); + + // Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends). + if (this.rtcchannel) { + this.rtcchannel.unpipe(this.httprequest._term); + this.httprequest._term.unpipe(this.rtcchannel); + } + + // Clean up + this.httprequest._term.end(); + this.httprequest._term = null; + } else { + // TODO!! + } + }; + + this.removeAllListeners('data'); + this.on('data', onTunnelControlData); + //this.write('MeshCore Terminal Hello'); + if (process.platform == 'linux') { this.httprequest.process.stdin.write("stty erase ^H\nalias ls='ls --color=auto'\nclear\n"); } + } else if (this.httprequest.protocol == 2) + { + // Check user access rights for desktop + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0)) { + // Disengage this tunnel, user does not have the rights to do this!! + this.httprequest.protocol = 999999; + this.httprequest.s.end(); + sendConsoleText('Error: No Desktop Control Rights.'); + return; + } + + // 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; + + // Unpipe the web socket + this.unpipe(this.httprequest.desktop.kvm); + this.httprequest.desktop.kvm.unpipe(this); + + // Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends). + if (this.rtcchannel) { + this.rtcchannel.unpipe(this.httprequest.desktop.kvm); + this.httprequest.desktop.kvm.unpipe(this.rtcchannel); + } + + 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; } + + if ((this.httprequest.rights == 0xFFFFFFFF) || (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) != 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0))) { + // If we have remote control rights, pipe the KVM input + this.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. Pipe the Browser --> KVM input. + } else { + // We need to only pipe non-mouse & non-keyboard inputs. + //sendConsoleText('Warning: No Remote Desktop Input Rights.'); + // TODO!!! + } + + this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. Pipe the KVM --> Browser images. + this.removeAllListeners('data'); + this.on('data', onTunnelControlData); + //this.write('MeshCore KVM Hello!1'); + } else if (this.httprequest.protocol == 5) { + // Check user access rights for files + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOFILES) != 0))) { + // Disengage this tunnel, user does not have the rights to do this!! + this.httprequest.protocol = 999999; + this.httprequest.s.end(); + sendConsoleText('Error: No Files Control Rights.'); + return; + } + + // 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': { + // Delete, possibly recursive delete + for (var i in cmd.delfiles) { + try { deleteFolderRecursive(obj.path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (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; + } + default: + // Unknown action, ignore it. + break; + } + } + //sendConsoleText("Got tunnel #" + this.httprequest.index + " data: " + data, this.httprequest.sessionid); + } + } + + // Delete a directory with a files and directories within it + function deleteFolderRecursive(path, rec) { + if (fs.existsSync(path)) { + if (rec == true) { + fs.readdirSync(obj.path.join(path, '*')).forEach(function (file, index) { + var curPath = obj.path.join(path, file); + if (fs.statSync(curPath).isDirectory()) { // recurse + deleteFolderRecursive(curPath, true); + } else { // delete file + fs.unlinkSync(curPath); + } + }); + } + fs.unlinkSync(path); + } + }; + + // 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; + } + default: + // Unknown action, ignore it. + 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 + if (process.platform == 'win32') + { + ws.httprequest._term.unpipe(ws); + } + else + { + 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. + if (process.platform == 'win32') + { + ws.unpipe(ws.httprequest._term); + ws.rtcchannel.pipe(ws.httprequest._term, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. + } + else + { + 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 + if (process.platform == 'win32') + { + ws.httprequest._term.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. + } + else + { + 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. + if (ws.httprequest.protocol == 1) return; // TODO: Terminal is currently broken with WebRTC. Reject WebRTC upgrade for now. + 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 () { + // The WebRTC channel closed, unpipe the KVM now. This is also done when the web socket closes. + //sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed'); + if (this.websocket.desktop && this.websocket.desktop.kvm) { + this.unpipe(this.websocket.desktop.kvm); + this.websocket.httprequest.desktop.kvm.unpipe(this); + } + }); + 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; } + }; + + // Open a web browser to a specified URL on current user's desktop + function openUserDesktopUrl(url) { + var child = null; + try { + switch (process.platform) { + case 'win32': + //child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe', ["/c", "start", url], { type: childProcess.SpawnTypes.USER, uid: require('user-sessions').Current().Active[0].SessionId }); + child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe', ["/c", "start", url], { type: childProcess.SpawnTypes.USER }); + break; + case 'linux': + child = require('child_process').execFile('/usr/bin/xdg-open', ['xdg-open', url], { uid: require('user-sessions').consoleUid() }); + break; + case 'darwin': + child = require('child_process').execFile('/usr/bin/open', ['open', url], { uid: require('user-sessions').consoleUid() }); + break; + default: + // Unknown platform, ignore this command. + break; + } + } catch (ex) { } + return child; + } + + // 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, osinfo,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, sendcaps, openurl, amtreset, amtccm, amtdeactivate,\r\namtpolicy, getscript, getclip, setclip.'; + break; + } + /* + case 'border': + { + if ((args['_'].length == 1) && (args['_'][0] == 'on')) { + if (meshCoreObj.users.length > 0) { + obj.borderManager.Start(meshCoreObj.users[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 'getclip': { + require("clipboard").read().then(function (str) { sendConsoleText(str, sessionid); }); + break; + } + case 'setclip': { + if (args['_'].length != 1) { response = 'Proper usage: setclip (text)'; } else { require("clipboard")(args['_'][0]); response = 'Setting clipboard to: ' + args['_'][0]; } + break; + } + case 'amtreset': { + if (amt != null) { amt.reset(); response = 'Done.'; } + break; + } + case 'amtlmsreset': { + if (amt != null) { amt.lmsreset(); response = 'Done.'; } + break; + } + case 'amtccm': { + if (amt == null) { response = 'Intel AMT not supported.'; } else { + if (args['_'].length != 1) { response = 'Proper usage: amtccm (adminPassword)'; } // Display usage + else { amt.setPolicy({ type: 0 }); amt.activeToCCM(args['_'][0]); } + } + break; + } + case 'amtdeactivate': { + if (amt == null) { response = 'Intel AMT not supported.'; } else { amt.setPolicy({ type: 0 }); amt.deactivateCCM(); } + break; + } + case 'amtpolicy': { + if (amtPolicy == null) { + response = 'No Intel(R) AMT policy.'; + } else { + response = JSON.stringify(amtPolicy); + } + break; + } + case 'openurl': { + if (args['_'].length != 1) { response = 'Proper usage: openurl (url)'; } // Display usage + else { if (openUserDesktopUrl(args['_'][0]) == null) { response = 'Failed.'; } else { response = 'Success.'; } } + break; + } + case 'users': { + if (meshCoreObj.users == null) { response = 'Active users are unknown.'; } else { response = 'Active Users: ' + meshCoreObj.users.join(', ') + '.'; } + require('user-sessions').enumerateUsers().then(function (u) { for (var i in u) { sendConsoleText(u[i]); } }); + 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 = 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': { + 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) { response = 'SMBios tables not available.'; } else { response = objToString(SMBiosTables, 0, ' ', true); } + break; + } + case 'rawsmbios': { + if (SMBiosTablesRaw == null) { response = 'SMBios tables not available.'; } else { + response = ''; + for (var i in SMBiosTablesRaw) { + var header = false; + for (var j in SMBiosTablesRaw[i]) { + if (SMBiosTablesRaw[i][j].length > 0) { + if (header == false) { response += ('Table type #' + i + ((require('smbios').smTableTypes[i] == null) ? '' : (', ' + require('smbios').smTableTypes[i]))) + '\r\n'; header = true; } + response += (' ' + SMBiosTablesRaw[i][j].toString('hex')) + '\r\n'; + } + } + } + } + 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: ' + meshCoreObj.value + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform: ' + process.platform + '.\r\nCapabilities: ' + meshCoreObj.caps + '.\r\nServer URL: ' + mesh.ServerUrl + '.'; + if (amt != null) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amt.lmsstate] + '.'; } + if (meshCoreObj.osdesc) { response += '\r\nOS: ' + meshCoreObj.osdesc + '.'; } + response += '\r\nModules: ' + addedModules.join(', ') + '.'; + response += '\r\nServer Connection: ' + mesh.isControlChannelConnected + ', State: ' + meshServerConnectionState + '.'; + response += '\r\lastMeInfo: ' + lastMeInfo + '.'; + var oldNodeId = db.Get('OldNodeId'); + if (oldNodeId != null) { response += '\r\nOldNodeID: ' + oldNodeId + '.'; } + if (process.platform != 'win32') { response += '\r\nX11 support: ' + require('monitor-info').kvm_x11_support + '.'; } + break; + } + case 'osinfo': { // Return the operating system information + var i = 1; + if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; } + for (var j = 0; j < i; j++) { + var pr = require('os').name(); + pr.sessionid = sessionid; + pr.then(function (v) { sendConsoleText("OS: " + v, this.sessionid); }); + } + break; + } + case 'sendcaps': { // Send capability flags to the server + if (args['_'].length == 0) { + response = 'Proper usage: sendcaps (number)'; // Display correct command usage + } else { + meshCoreObj.caps = parseInt(args['_'][0]); + mesh.SendCommand(meshCoreObj); + response = JSON.stringify(meshCoreObj); + } + break; + } + case 'sendosdesc': { // Send OS description + if (args['_'].length > 0) { + meshCoreObj.osdesc = args['_'][0]; + mesh.SendCommand(meshCoreObj); + response = JSON.stringify(meshCoreObj); + } else { + response = 'Proper usage: sendosdesc [os description]'; // Display correct command usage + } + 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 = Buffer.alloc(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.on('error', 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 + if (amt != null) { + amt.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; + } + case 'getscript': { + if (args['_'].length != 1) { + response = 'Proper usage: getscript [scriptNumber].'; + } else { + mesh.SendCommand({ "action": "getScript", "type": args['_'][0] }); + } + 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 }); } + + // Update the server with basic info, logged in users and more. + mesh.SendCommand(meshCoreObj); + + // Send SMBios tables if present + if (SMBiosTablesRaw != null) { mesh.SendCommand({ "action": "smbios", "value": SMBiosTablesRaw }); } + + // Update the server on more advanced stuff, like Intel ME and Network Settings + meInfoStr = null; + sendPeriodicServerUpdate(); + //if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes + } + } + + // 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(flags) { + if (meshServerConnectionState == 0) return; // Not connected to server, do nothing. + if (!flags) { flags = 0xFFFFFFFF; } + + if ((flags & 1) && (amt != null)) { + // If we have a connected MEI, get Intel ME information + amt.getAmtInfo(function (meinfo) { + try { + if (meinfo == null) return; + 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) { + var meInfoStr = JSON.stringify(intelamt); + if (meInfoStr != lastMeInfo) { + meshCoreObj.intelamt = intelamt; + mesh.SendCommand(meshCoreObj); + lastMeInfo = meInfoStr; + } + } + } catch (ex) { } + }); + } + + if (flags & 2) { + // Update network information + sendNetworkUpdateNagle(false); + } + } + + + // 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); + + //resetMicroLms(); + + // Setup logged in user monitoring (THIS IS BROKEN IN WIN7) + try { + var userSession = require('user-sessions'); + userSession.on('changed', function onUserSessionChanged() { + userSession.enumerateUsers().then(function (users) { + var u = [], a = users.Active; + for (var i = 0; i < a.length; i++) { + var un = a[i].Domain ? (a[i].Domain + '\\' + a[i].Username) : (a[i].Username); + if (u.indexOf(un) == -1) { u.push(un); } // Only push users in the list once. + } + meshCoreObj.users = u; + mesh.SendCommand(meshCoreObj); + }); + }); + userSession.emit('changed'); + //userSession.on('locked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has LOCKED the desktop'); }); + //userSession.on('unlocked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has UNLOCKED the desktop'); }); + } catch (ex) { } + } + + 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; + } + + return obj; +} + +// +// Module startup +// + +try { + 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); + } +} catch (ex) { + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": "uncaughtException2: " + ex }); +} \ No newline at end of file diff --git a/agents-new/meshinstall-initd.sh b/agents-new/meshinstall-initd.sh new file mode 100644 index 00000000..7dd5dee7 --- /dev/null +++ b/agents-new/meshinstall-initd.sh @@ -0,0 +1,82 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: +# Required-Start: $local_fs $network $named $time $syslog +# Required-Stop: $local_fs $network $named $time $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Description: +### END INIT INFO + +SCRIPT=/usr/local/mesh/meshagent +RUNAS=root + +PIDFILE=/var/run/meshagent.pid +LOGFILE=/var/log/meshagent.log + +start() { + if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") 2>/dev/null; then + echo 'Service already running' >&2 + return 1 + fi + echo 'Starting service…' >&2 + local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!" + su -c "$CMD" $RUNAS > "$PIDFILE" + echo 'Service started' >&2 +} + +stop() { + if [ ! -f "$PIDFILE" ]; then + echo 'Service not running' >&2 + return 1 + else + pid=$( cat "$PIDFILE" ) + if kill -0 $pid 2>/dev/null; then + echo 'Stopping service…' >&2 + kill -16 $pid + echo 'Service stopped' >&2 + else + echo 'Service not running' + fi + rm -f $"PIDFILE" + fi +} +restart(){ + stop + start +} +status(){ + if [ -f "$PIDFILE" ] + then + pid=$( cat "$PIDFILE" ) + if kill -0 $pid 2>/dev/null; then + echo "meshagent start/running, process $pid" + else + echo 'meshagent stop/waiting' + fi + else + echo 'meshagent stop/waiting' + fi + +} + + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + status + ;; + *) + echo "Usage: service meshagent {start|stop|restart|status}" + ;; +esac +exit 0 diff --git a/agents-new/meshinstall-linux.sh b/agents-new/meshinstall-linux.sh new file mode 100644 index 00000000..d18f0797 --- /dev/null +++ b/agents-new/meshinstall-linux.sh @@ -0,0 +1,235 @@ +#!/bin/bash + +CheckStartupType() { + # echo "Checking process autostart system..." + starttype=`ps -p 1 | awk '/1/ {print $4}'` + # Systemd + if [[ $starttype == 'systemd' ]]; then return 1; + elif [[ $starttype == 'init' ]]; + then + # Upstart + if [[ `/sbin/init --version` =~ upstart ]]; then return 2; + # Sysv-init + return 3; + fi + fi + return 0; +} + +# Add "StartupType=(type)" to .msh file +UpdateMshFile() { + # Remove all lines that start with "StartupType=" + sed '/^StartupType=/ d' < /usr/local/mesh/meshagent.msh >> /usr/local/mesh/meshagent2.msh + # Add the startup type to the file + echo "StartupType=$starttype" >> /usr/local/mesh/meshagent2.msh + mv /usr/local/mesh/meshagent2.msh /usr/local/mesh/meshagent.msh +} + +CheckInstallAgent() { + # echo "Checking mesh identifier..." + if [ -e "/usr/local" ] + then + installpath="/usr/local/mesh" + else + installpath="/usr/mesh" + fi + if [ $# -ge 2 ] + then + url=$1 + meshid=$2 + meshidlen=${#meshid} + if [ $meshidlen -eq 64 ] + then + machineid=0 + machinetype=$( uname -m ) + + # If we have 3 arguments... + if [ $# -ge 3 ] + then + # echo "Computer type is specified..." + machineid=$3 + else + # echo "Detecting computer type..." + if [ $machinetype == 'x86_64' ] || [ $machinetype == 'amd64' ] + then + # Linux x86, 64 bit + machineid=6 + fi + if [ $machinetype == 'x86' ] || [ $machinetype == 'i686' ] || [ $machinetype == 'i586' ] + then + # Linux x86, 32 bit + machineid=5 + fi + if [ $machinetype == 'armv6l' ] || [ $machinetype == 'armv7l' ] + then + # RaspberryPi 1 (armv6l) or RaspberryPi 2/3 (armv7l) + machineid=25 + fi + # Add more machine types, detect KVM support... here. + fi + + if [ $machineid -eq 0 ] + then + echo "Unsupported machine type: $machinetype." + else + DownloadAgent $url $meshid $machineid + fi + + else + echo "MeshID is not correct, must be 64 characters long." + fi + else + echo "URI and/or MeshID have not been specified, must be passed in as arguments." + return 0; + fi +} + +DownloadAgent() { + url=$1 + meshid=$2 + machineid=$3 + # Create folder + mkdir -p /usr/local/mesh + cd /usr/local/mesh + echo "Downloading Mesh agent #$machineid..." + wget $url/meshagents?id=$machineid --no-check-certificate {{{noproxy}}}-O /usr/local/mesh/meshagent + + # If it did not work, try again using http + if [ $? != 0 ] + then + url=${url/"https://"/"http://"} + wget $url/meshagents?id=$machineid {{{noproxy}}}-O /usr/local/mesh/meshagent + fi + + if [ $? -eq 0 ] + then + echo "Mesh agent downloaded." + # TODO: We could check the meshagent sha256 hash, but best to authenticate the server. + chmod 755 /usr/local/mesh/meshagent + wget $url/meshsettings?id=$meshid --no-check-certificate {{{noproxy}}}-O /usr/local/mesh/meshagent.msh + + # If it did not work, try again using http + if [ $? -ne 0 ] + then + wget $url/meshsettings?id=$meshid {{{noproxy}}}-O /usr/local/mesh/meshagent.msh + fi + + if [ $? -eq 0 ] + then + UpdateMshFile + if [ $starttype -eq 1 ] + then + # systemd + if [ -d "/lib/systemd/system/" ] + then + echo -e "[Unit]\nDescription=MeshCentral Agent\n[Service]\nExecStart=/usr/local/mesh/meshagent\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=meshagent.service\n" > /lib/systemd/system/meshagent.service + else + # Some distros have the systemd folder at a different place + if [ -d "/usr/lib/systemd/system/" ] + then + echo -e "[Unit]\nDescription=MeshCentral Agent\n[Service]\nExecStart=/usr/local/mesh/meshagent\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=meshagent.service\n" > /usr/lib/systemd/system/meshagent.service + else + echo "Unable to find systemd folder." + fi + fi + systemctl enable meshagent + systemctl start meshagent + echo 'meshagent installed as systemd service.' + echo 'To start service: sudo systemctl start meshagent' + echo 'To stop service: sudo systemctl stop meshagent' + elif [ $starttype -eq 3 ] + then + # initd + wget $url/meshagents?script=2 --no-check-certificate {{{noproxy}}}-O /etc/init.d/meshagent + chmod +x /etc/init.d/meshagent + # creates symlinks for rc.d + update-rc.d meshagent defaults + service meshagent start + echo 'meshagent installed as init.d service.' + echo 'To start service: sudo service meshagent start' + echo 'To stop service: sudo service meshagent stop' + elif [ $starttype -eq 2 ] + then + # upstart + echo -e "start on runlevel [2345]\nstop on runlevel [016]\n\nrespawn\n\nchdir /usr/local/mesh\nexec /usr/local/mesh/meshagent\n\n" > /etc/init/meshagent.conf + service meshagent start + echo 'meshagent installed as upstart/init.d service.' + echo 'To start service: sudo initctl start meshagent' + echo 'To stop service: sudo initctl stop meshagent' + else + # unknown + echo "Unknown Service Platform Type. (ie: init, systemd, etc)" + echo "Unable to install meshagent as service." + fi + echo "Mesh agent started." + else + echo "Unable to download mesh settings at: $url/meshsettings?id=$meshid." + fi + else + echo "Unable to download mesh agent at: $url/meshagents?id=$machineid." + fi +} + +UninstallAgent() { +# Uninstall agent + if [ -e "/usr/local" ] + then + installpath="/usr/local/mesh" + else + installpath="/usr/mesh" + fi + + if [ $starttype -eq 1 ] + then + # systemd + rm -f /sbin/meshcmd /lib/systemd/system/meshagent.service + systemctl disable meshagent + systemctl stop meshagent + else + if [ $starttype -eq 3 ]; then + # initd + service meshagent stop + update-rc.d -f meshagent remove + rm -f /sbin/meshcmd /etc/init.d/meshagent + elif [ $starttype -eq 2 ]; then + # upstart + service meshagent stop + rm -f /sbin/meshcmd + rm -f /etc/init/meshagent.conf + rm -f /etc/rc2.d/S20mesh /etc/rc3.d/S20mesh /etc/rc5.d/S20mesh + fi + fi + + if [ -e $installpath ] + then + rm -rf $installpath/* + rmdir $installpath + fi + echo "Agent uninstalled." +} + + +CheckStartupType +starttype=$? +#echo "Type: $starttype" + +currentuser=$( whoami ) +if [ $currentuser == 'root' ] +then + if [ $# -eq 0 ] + then + echo -e "This script will install or uninstall a mesh agent, usage:\n $0 [serverurl] [meshid] (machineid)\n $0 uninstall" + else + if [ $# -eq 1 ] + then + if [ $1 == 'uninstall' ] || [ $1 == 'UNINSTALL' ] + then + UninstallAgent + fi + else + CheckInstallAgent $1 $2 $3 + fi + fi +else + echo "Must be root to install or uninstall mesh agent." +fi diff --git a/agents-new/modules_meshcmd/amt-lme.js b/agents-new/modules_meshcmd/amt-lme.js new file mode 100644 index 00000000..7049708f --- /dev/null +++ b/agents-new/modules_meshcmd/amt-lme.js @@ -0,0 +1,895 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +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-new/modules_meshcmd/amt-mei.js b/agents-new/modules_meshcmd/amt-mei.js new file mode 100644 index 00000000..e2cec413 --- /dev/null +++ b/agents-new/modules_meshcmd/amt-mei.js @@ -0,0 +1,417 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +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) + { + if(this.Parent._rq.isEmpty()) + { + this.Parent.emit('error', e); // No pending requests, so propagate the error up + } + else + { + // There is a pending request, so fail the pending request + var user = this.Parent._rq.deQueue(); + var params = user.optional; + var callback = user.func; + params.unshift({ Status: -1 }); // Relay an error + callback.apply(this.Parent, params); + + if(!this.Parent._rq.isEmpty()) + { + // There are still more pending requests, so try to re-helpconnect MEI + this.connect(heci.GUIDS.AMT, { noPipeline: 1 }); + } + } + }); + 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 = Buffer.alloc(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.Status == 0 && 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 = Buffer.alloc(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-new/modules_meshcmd/amt-scanner.js b/agents-new/modules_meshcmd/amt-scanner.js new file mode 100644 index 00000000..c455b753 --- /dev/null +++ b/agents-new/modules_meshcmd/amt-scanner.js @@ -0,0 +1,105 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @description 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-new/modules_meshcmd/amt-script.js b/agents-new/modules_meshcmd/amt-script.js new file mode 100644 index 00000000..d00ed101 --- /dev/null +++ b/agents-new/modules_meshcmd/amt-script.js @@ -0,0 +1,401 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @fileoverview Script Compiler / Decompiler / Runner +* @author Ylian Saint-Hilaire +* @version v0.1.0e +*/ + +// Core functions +script_functionTable1 = ['nop', 'jump', 'set', 'print', 'dialog', 'getitem', 'substr', 'indexof', 'split', 'join', 'length', 'jsonparse', 'jsonstr', 'add', 'substract', 'parseint', 'wsbatchenum', 'wsput', 'wscreate', 'wsdelete', 'wsexec', 'scriptspeed', 'wssubscribe', 'wsunsubscribe', 'readchar', 'signwithdummyca']; + +// functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6) +script_functionTable2 = ['encodeuri', 'decodeuri', 'passwordcheck', 'atob', 'btoa', 'hex2str', 'str2hex', 'random', 'md5', 'maketoarray', 'readshort', 'readshortx', 'readint', 'readsint', 'readintx', 'shorttostr', 'shorttostrx', 'inttostr', 'inttostrx']; + +// functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6) +script_functionTableX2 = [encodeURI, decodeURI, passwordcheck, atob, btoa, hex2rstr, rstr2hex, random, rstr_md5, MakeToArray, ReadShort, ReadShortX, ReadInt, ReadSInt, ReadIntX, ShortToStr, ShortToStrX, IntToStr, IntToStrX]; + + +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 ReadShortX(v, p) { return (v[p + 1] << 8) + v[p]; } +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 ReadSInt(v, p) { return (v[p] << 24) + (v[p + 1] << 16) + (v[p + 2] << 8) + v[p + 3]; } +function ReadIntX(v, p) { return (v[p + 3] * 0x1000000) + (v[p + 2] << 16) + (v[p + 1] << 8) + v[p]; } +function ShortToStr(v) { return String.fromCharCode((v >> 8) & 0xFF, v & 0xFF); } +function ShortToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF); } +function IntToStr(v) { return String.fromCharCode((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); } +function IntToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF); } +//function ShortToStr(v) { var b = Buffer.alloc(2); b.writeInt16BE(v); return b; } +//function ShortToStrX(v) { var b = Buffer.alloc(2); b.writeInt16LE(v); return b; } +//function IntToStr(v) { var b = Buffer.alloc(4); b.writeInt32BE(v); return b; } +//function IntToStrX(v) { var b = Buffer.alloc(4); b.writeInt32LE(v); return b; } +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 passwordcheck(p) { if (p.length < 8) return false; var upper = 0, lower = 0, number = 0, nonalpha = 0; for (var i in p) { var c = p.charCodeAt(i); if ((c > 64) && (c < 91)) { upper = 1; } else if ((c > 96) && (c < 123)) { lower = 1; } else if ((c > 47) && (c < 58)) { number = 1; } else { nonalpha = 1; } } return ((upper + lower + number + nonalpha) == 4); } +function hex2rstr(x) { Buffer.from(x, 'hex').toString(); } +function rstr2hex(x) { Buffer.from(x).toString('hex'); } +function random() { return Math.floor(Math.random()*max); } +function rstr_md5(str) { return hex2rstr(hex_md5(str)); } +function getItem(x, y, z) { for (var i in x) { if (x[i][y] == z) return x[i]; } return null; } + +var httpErrorTable = { + 200: 'OK', + 401: 'Authentication Error', + 408: 'Timeout Error', + 601: 'WSMAN Parsing Error', + 602: 'Unable to parse HTTP response header', + 603: 'Unexpected HTTP enum response', + 604: 'Unexpected HTTP pull response', + 998: 'Invalid TLS certificate' +} + +// Setup the script state +module.exports.setup = function(binary, startvars) { + var obj = { startvars: startvars, onCompleted: null }; + if (binary.length < 6) { console.error('Invalid script length'); return null; } // Script must have at least 6 byte header + if (ReadInt(binary, 0) != 0x247D2945) { console.error('Invalid binary script'); return null; } // Check the script magic header + if (ReadShort(binary, 4) > 1) { console.error('Unsupported script version'); return null; } // Check the script version + obj.script = binary.slice(6); + + // Reset the script to the start + obj.reset = function (stepspeed) { + obj.stop(); + obj.ip = 0; + obj.variables = startvars; + obj.state = 1; + } + + // Start the script + obj.start = function (stepspeed) { + obj.stop(); + if (stepspeed == null) { obj.stepspeed = 10; } else { obj.stepspeed = stepspeed; } + if (obj.stepspeed > 0) { obj.timer = setInterval(function () { obj.step() }, obj.stepspeed); } + } + + // Stop the script + obj.stop = function () { + if (obj.timer != null) { clearInterval(obj.timer); } + obj.timer = null; + obj.stepspeed = 0; + } + + // function used to load and store variable values + obj.getVar = function (name) { if (name == undefined) return undefined; return obj.getVarEx(name.split('.'), obj.variables); } + obj.getVarEx = function (name, val) { try { if (name == undefined) return undefined; if (name.length == 0) return val; return obj.getVarEx(name.slice(1), val[name[0]]); } catch (e) { return null; } } + obj.setVar = function (name, val) { obj.setVarEx(name.split('.'), obj.variables, val); } + obj.setVarEx = function (name, vars, val) { if (name.length == 1) { vars[name[0]] = val; } else { obj.setVarEx(name.slice(1), vars[name[0]], val); } } + + // Run the script one step forward + obj.step = function () { + if (obj.state != 1) return; + if (obj.ip < obj.script.length) { + var cmdid = ReadShort(obj.script, obj.ip); + var cmdlen = ReadShort(obj.script, obj.ip + 2); + var argcount = ReadShort(obj.script, obj.ip + 4); + var argptr = obj.ip + 6; + var args = []; + + // Clear all temp variables (This is optional) + for (var i in obj.variables) { if (i.startsWith('__')) { delete obj.variables[i]; } } + + // Loop on each argument, moving forward by the argument length each time + for (var i = 0; i < argcount; i++) { + var arglen = ReadShort(obj.script, argptr); + var argval = obj.script.slice(argptr + 2, argptr + 2 + arglen); + var argtyp = argval[0]; + argval = argval.slice(1); + if (argtyp < 2) { + // Get the value and replace all {var} with variable values + argval = argval.toString(); + while (argval.split("{").length > 1) { var t = argval.split("{").pop().split("}").shift(); argval = argval.replace('{' + t + '}', obj.getVar(t)); } + if (argtyp == 1) { obj.variables['__' + i] = decodeURI(argval); argval = '__' + i; } // If argtyp is 1, this is a literal. Store in temp variable. + args.push(argval); + } + if (argtyp == 2 || argtyp == 3) { + obj.variables['__' + i] = ReadSInt(argval, 0); + args.push('__' + i); + } + argptr += (2 + arglen); + } + + // Move instruction pointer forward by command size + obj.ip += cmdlen; + + // Get all variable values + var argsval = []; + for (var i = 0; i < 10; i++) { argsval.push(obj.getVar(args[i])); } + var storeInArg0; + try { + if (cmdid < 10000) { + // Lets run the actual command + switch (cmdid) { + case 0: // nop + break; + case 1: // jump(label) or jump(label, a, compare, b) + if (argsval[2]) { + if ( + (argsval[2] == '<' && argsval[1] < argsval[3]) || + (argsval[2] == '<=' && argsval[1] <= argsval[3]) || + (argsval[2] == '!=' && argsval[1] != argsval[3]) || + (argsval[2] == '=' && argsval[1] == argsval[3]) || + (argsval[2] == '>=' && argsval[1] >= argsval[3]) || + (argsval[2] == '>' && argsval[1] > argsval[3]) + ) { + obj.ip = argsval[0]; + } + } else { + obj.ip = argsval[0]; // Set the instruction pointer to the new location in the script + } + break; + case 2: // set(variable, value) + if (args[1] == undefined) delete obj.variables[args[0]]; else obj.setVar(args[0], argsval[1]); + break; + case 3: // print(message) + var v = obj.toString(argsval[0]); + if (v.indexOf('INFO: ') == 0) { v = v.substring(6); } + if (v.indexOf('SUCCESS: ') == 0) { v = v.substring(9); } + if (obj.onConsole) { obj.onConsole(v, obj); } else { console.log(v); } + // Q(obj.consoleid).value += () + '\n'); Q(obj.console).scrollTop = Q(obj.console).scrollHeight; + break; + case 4: // dialog(title, content, buttons) + obj.state = 2; + obj.dialog = true; + setDialogMode(11, argsval[0], argsval[2], obj.xxStepDialogOk, argsval[1], obj); + break; + case 5: // getitem(a, b, c) + for (var i in argsval[1]) { if (argsval[1][i][argsval[2]] == argsval[3]) { storeInArg0 = i; } }; + break; + case 6: // substr(variable_dest, variable_src, index, len) + storeInArg0 = argsval[1].substr(argsval[2], argsval[3]); + break; + case 7: // indexOf(variable_dest, variable_src, index, len) + storeInArg0 = argsval[1].indexOf(argsval[2]); + break; + case 8: // split(variable_dest, variable_src, separator) + storeInArg0 = argsval[1].split(argsval[2]); + break; + case 9: // join(variable_dest, variable_src, separator) + storeInArg0 = argsval[1].join(argsval[2]); + break; + case 10: // length(variable_dest, variable_src) + if (argsval[1] == null) { storeInArg0 = 0; } else { storeInArg0 = argsval[1].length; } + break; + case 11: // jsonparse(variable_dest, json) + storeInArg0 = JSON.parse(argsval[1]); + break; + case 12: // jsonstr(variable_dest, variable_src) + storeInArg0 = JSON.stringify(argsval[1]); + break; + case 13: // add(variable_dest, variable_src, value) + storeInArg0 = (argsval[1] + argsval[2]); + break; + case 14: // substract(variable_dest, variable_src, value) + storeInArg0 = (argsval[1] - argsval[2]); + break; + case 15: // parseInt(variable_dest, variable_src) + storeInArg0 = parseInt(argsval[1]); + break; + case 16: // wsbatchenum(name, objectList) + obj.state = 2; + obj.amtstack.BatchEnum(argsval[0], argsval[1], obj.xxWsmanReturn, obj); + break; + case 17: // wsput(name, args) + obj.state = 2; + obj.amtstack.Put(argsval[0], argsval[1], obj.xxWsmanReturn, obj); + break; + case 18: // wscreate(name, args) + obj.state = 2; + obj.amtstack.Create(argsval[0], argsval[1], obj.xxWsmanReturn, obj); + break; + case 19: // wsdelete(name, args) + obj.state = 2; + obj.amtstack.Delete(argsval[0], argsval[1], obj.xxWsmanReturn, obj); + break; + case 20: // wsexec(name, method, args, selectors) + obj.state = 2; + obj.amtstack.Exec(argsval[0], argsval[1], argsval[2], obj.xxWsmanReturn, obj, 0, argsval[3]); + break; + case 21: // Script Speed + obj.stepspeed = argsval[0]; + if (obj.timer != null) { clearInterval(obj.timer); obj.timer = setInterval(function () { obj.step() }, obj.stepspeed); } + break; + case 22: // wssubscribe(name, delivery, url, selectors, opaque, user, pass) + obj.state = 2; + obj.amtstack.Subscribe(argsval[0], argsval[1], argsval[2], obj.xxWsmanReturn, obj, 0, argsval[3], argsval[4], argsval[5], argsval[6]); + break; + case 23: // wsunsubscribe(name, selectors) + obj.state = 2; + obj.amtstack.UnSubscribe(argsval[0], obj.xxWsmanReturn, obj, 0, argsval[1]); + break; + case 24: // readchar(str, pos) + console.log(argsval[1], argsval[2], argsval[1].charCodeAt(argsval[2])); + storeInArg0 = argsval[1].charCodeAt(argsval[2]); + break; + case 25: // signWithDummyCa + // Not supported + break; + default: { + obj.state = 9; + console.error("Script Error, unknown command: " + cmdid); + } + } + } else { + if (cmdid < 20000) { + // functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6) + storeInArg0 = script_functionTableX2[cmdid - 10000](argsval[1], argsval[2], argsval[3], argsval[4], argsval[5], argsval[6]); + } else { + // Optional functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6) + //if (script_functionTableX3 && script_functionTableX3[cmdid - 20000]) { + // storeInArg0 = script_functionTableX3[cmdid - 20000](obj, argsval[1], argsval[2], argsval[3], argsval[4], argsval[5], argsval[6]); // Note that optional calls start with "obj" as first argument. + //} + } + } + if (storeInArg0 != undefined) obj.setVar(args[0], storeInArg0); + } catch (e) { + if (typeof e == 'object') { e = e.message; } + obj.setVar('_exception', e); + } + } + + if (obj.state == 1 && obj.ip >= obj.script.length) { obj.state = 0; obj.stop(); if (obj.onCompleted) { obj.onCompleted(); } } + if (obj.onStep) obj.onStep(obj); + return obj; + } + + obj.xxStepDialogOk = function (button) { + obj.variables['DialogSelect'] = button; + obj.state = 1; + obj.dialog = false; + if (obj.onStep) obj.onStep(obj); + } + + obj.xxWsmanReturn = function (stack, name, responses, status) { + obj.setVar(name, responses); + obj.setVar('wsman_result', status); + obj.setVar('wsman_result_str', ((httpErrorTable[status]) ? (httpErrorTable[status]) : ('Error #' + status))); + obj.state = 1; + if (obj.onStep) obj.onStep(obj); + } + + obj.toString = function (x) { if (typeof x == 'object') return JSON.stringify(x); return x; } + + obj.reset(); + return obj; +} + +// Argument types: 0 = Variable, 1 = String, 2 = Integer, 3 = Label +module.exports.compile = function(script, onmsg) { + var r = '', scriptlines = script.split('\n'), labels = {}, labelswap = [], swaps = []; + // Go thru each script line and encode it + for (var i in scriptlines) { + var scriptline = scriptlines[i]; + if (scriptline.startsWith('##SWAP ')) { var x = scriptline.split(' '); if (x.length == 3) { swaps[x[1]] = x[2]; } } // Add a swap instance + if (scriptline[0] == '#' || scriptline.length == 0) continue; // Skip comments & blank lines + for (var x in swaps) { scriptline = scriptline.split(x).join(swaps[x]); } // Apply all swaps + var keywords = scriptline.match(/"[^"]*"|[^\s"]+/g); + if (keywords.length == 0) continue; // Skip blank lines + if (scriptline[0] == ':') { labels[keywords[0].toUpperCase()] = r.length; continue; } // Mark a label position + var funcIndex = script_functionTable1.indexOf(keywords[0].toLowerCase()); + if (funcIndex == -1) { funcIndex = script_functionTable2.indexOf(keywords[0].toLowerCase()); if (funcIndex >= 0) funcIndex += 10000; } + if (funcIndex == -1) { if (onmsg) { onmsg("Unabled to compile, unknown command: " + keywords[0]); } return ''; } + // Encode CommandId, CmdSize, ArgCount, Arg1Len, Arg1, Arg2Len, Arg2... + var cmd = ShortToStr(keywords.length - 1); + for (var j in keywords) { + if (j == 0) continue; + if (keywords[j][0] == ':') { + labelswap.push([keywords[j], r.length + cmd.length + 7]); // Add a label swap + cmd += ShortToStr(5) + String.fromCharCode(3) + IntToStr(0xFFFFFFFF); // Put an empty label + } else { + var argint = parseInt(keywords[j]); + if (argint == keywords[j]) { + cmd += ShortToStr(5) + String.fromCharCode(2) + IntToStr(argint); + } else { + if (keywords[j][0] == '"' && keywords[j][keywords[j].length - 1] == '"') { + cmd += ShortToStr(keywords[j].length - 1) + String.fromCharCode(1) + keywords[j].substring(1, keywords[j].length - 1); + } else { + cmd += ShortToStr(keywords[j].length + 1) + String.fromCharCode(0) + keywords[j]; + } + } + } + } + cmd = ShortToStr(funcIndex) + ShortToStr(cmd.length + 4) + cmd; + r += cmd; + } + // Perform all the needed label swaps + for (i in labelswap) { + var label = labelswap[i][0].toUpperCase(), position = labelswap[i][1], target = labels[label]; + if (target == undefined) { if (onmsg) { onmsg("Unabled to compile, unknown label: " + label); } return ''; } + r = r.substr(0, position) + IntToStr(target) + r.substr(position + 4); + } + return IntToStr(0x247D2945) + ShortToStr(1) + r; +} + +// Decompile the script, intended for debugging only +module.exports.decompile = function(binary, onecmd) { + var r = '', ptr = 6, labelcount = 0, labels = {}; + if (onecmd >= 0) { + ptr = onecmd; // If we are decompiling just one command, set the ptr to that command. + } else { + if (binary.length < 6) { return '# Invalid script length'; } + var magic = ReadInt(binary, 0); + var version = ReadShort(binary, 4); + if (magic != 0x247D2945) { return '# Invalid binary script: ' + magic; } + if (version != 1) { return '# Invalid script version'; } + } + // Loop on each command, moving forward by the command length each time. + while (ptr < binary.length) { + var cmdid = ReadShort(binary, ptr); + var cmdlen = ReadShort(binary, ptr + 2); + var argcount = ReadShort(binary, ptr + 4); + var argptr = ptr + 6; + var argstr = ''; + if (!(onecmd >= 0)) r += ":label" + (ptr - 6) + "\n"; + // Loop on each argument, moving forward by the argument length each time + for (var i = 0; i < argcount; i++) { + var arglen = ReadShort(binary, argptr); + var argval = binary.substring(argptr + 2, argptr + 2 + arglen); + var argtyp = argval.charCodeAt(0); + if (argtyp == 0) { argstr += ' ' + argval.substring(1); } // Variable + else if (argtyp == 1) { argstr += ' \"' + argval.substring(1) + '\"'; } // String + else if (argtyp == 2) { argstr += ' ' + ReadInt(argval, 1); } // Integer + else if (argtyp == 3) { // Label + var target = ReadInt(argval, 1); + var label = labels[target]; + if (!label) { label = ":label" + target; labels[label] = target; } + argstr += ' ' + label; + } + argptr += (2 + arglen); + } + // Go in the script function table to decode the function + if (cmdid < 10000) { + r += script_functionTable1[cmdid] + argstr + "\n"; + } else { + if ((cmdid >= 10000) && (cmdid < 10000)) { r += script_functionTable2[cmdid - 10000] + argstr + "\n"; } + } + ptr += cmdlen; + if (onecmd >= 0) return r; // If we are decompiling just one command, exit now + } + // Remove all unused labels + var scriptlines = r.split('\n'); + r = ''; + for (var i in scriptlines) { + var line = scriptlines[i]; + if (line[0] != ':') { r += line + '\n'; } else { if (labels[line]) { r += line + '\n'; } } + } + return r; +} diff --git a/agents-new/modules_meshcmd/amt-wsman-duk.js b/agents-new/modules_meshcmd/amt-wsman-duk.js new file mode 100644 index 00000000..4e9bc33a --- /dev/null +++ b/agents-new/modules_meshcmd/amt-wsman-duk.js @@ -0,0 +1,144 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @description 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; + + 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); + //console.log('Request ' + (obj.RequestCount++)); + req.on('error', function (e) { obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); }); + req.on('response', function (response) { + //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 () { 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-new/modules_meshcmd/amt-wsman.js b/agents-new/modules_meshcmd/amt-wsman.js new file mode 100644 index 00000000..6561bd44 --- /dev/null +++ b/agents-new/modules_meshcmd/amt-wsman.js @@ -0,0 +1,211 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @description 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-new/modules_meshcmd/amt-xml.js b/agents-new/modules_meshcmd/amt-xml.js new file mode 100644 index 00000000..5890d742 --- /dev/null +++ b/agents-new/modules_meshcmd/amt-xml.js @@ -0,0 +1,185 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { } + + +// 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.error("Unable to parse XML: " + xml, e); + 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. +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-new/modules_meshcmd/amt.js b/agents-new/modules_meshcmd/amt.js new file mode 100644 index 00000000..2ceb01d5 --- /dev/null +++ b/agents-new/modules_meshcmd/amt.js @@ -0,0 +1,1017 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @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_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, tag) { obj.Exec("AMT_PublicKeyManagementService", "AddCertificate", { "CertificateBlob": CertificateBlob }, callback_func, tag); } + 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, tag) { obj.Exec("AMT_SetupAndConfigurationService", "CommitChanges", { "_method_dummy": _method_dummy }, callback_func, tag); } + 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_TLSCredentialContext_Create = function AMT_TLSCredentialContext_Create(ElementInContext, ElementProvidingContext, callback_func, tag) { obj.Create("AMT_TLSCredentialContext", { "ElementInContext": ElementInContext, "ElementProvidingContext": ElementProvidingContext }, 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 = Buffer.from(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-new/modules_meshcmd/service-host.js b/agents-new/modules_meshcmd/service-host.js new file mode 100644 index 00000000..fabc4e81 --- /dev/null +++ b/agents-new/modules_meshcmd/service-host.js @@ -0,0 +1,389 @@ +/* +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, 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('service-manager'); + +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') + { + this.GM = require('_GenericMarshal'); + this.Advapi = this.GM.CreateNativeProxy('Advapi32.dll'); + this.Advapi.CreateMethod({ method: 'StartServiceCtrlDispatcherA', threadDispatch: 1 }); + this.Advapi.CreateMethod('RegisterServiceCtrlHandlerExA'); + this.Advapi.CreateMethod('SetServiceStatus'); + this.Kernel32 = this.GM.CreateNativeProxy('Kernel32.dll'); + this.Kernel32.CreateMethod('GetLastError'); + + this.Ole32 = this.GM.CreateNativeProxy('Ole32.dll'); + this.Ole32.CreateMethod('CoInitializeEx'); + this.Ole32.CreateMethod('CoUninitialize'); + + this._ServiceName = this.GM.CreateVariable(typeof (serviceName) == 'string' ? serviceName : serviceName.name); + this._ServiceMain = this.GM.GetGenericGlobalCallback(2); + this._ServiceMain.Parent = this; + this._ServiceMain.GM = this.GM; + this._ServiceMain.on('GlobalCallback', function onGlobalCallback(argc, argv) + { + //ToDo: Check to make sure this is for us + + this.Parent._ServiceStatus = this.GM.CreateVariable(28); + //typedef struct _SERVICE_STATUS { + // DWORD dwServiceType; + // DWORD dwCurrentState; + // DWORD dwControlsAccepted; + // DWORD dwWin32ExitCode; + // DWORD dwServiceSpecificExitCode; + // DWORD dwCheckPoint; + // DWORD dwWaitHint; + //} SERVICE_STATUS, *LPSERVICE_STATUS; + + // 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.RegisterServiceCtrlHandlerExA(this.Parent._ServiceName, this.Parent._ServiceControlHandler, this.Parent.GM.StashObject(this.Parent._ServiceControlHandler)); + if(this.Parent._ServiceStatusHandle.Val == 0) + { + process.exit(1); + } + + // Service is starting + this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.SERVICE_START_PENDING, 4); + this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus); + + // Service running + this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.RUNNING, 4); + 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() + { + var GM = require('_GenericMarshal'); + var Advapi = GM.CreateNativeProxy('Advapi32.dll'); + Advapi.CreateMethod('SetServiceStatus'); + + Kernel32 = this.GM.CreateNativeProxy('Kernel32.dll'); + Kernel32.CreateMethod('GetLastError'); + + var status = GM.CreateVariable(28); + + // Service was stopped + status.toBuffer().writeUInt32LE(SERVICE_WIN32); + status.toBuffer().writeUInt32LE(0x00000001, 4); + status.toBuffer().writeUInt32LE(0, 8); + + Advapi.SetServiceStatus(this._ServiceStatusHandle, status); + + this.Ole32.CoUninitialize(); + }); + + this.Parent.emit('serviceStart'); + }); + this._ServiceControlHandler = this.GM.GetGenericGlobalCallback(4); + this._ServiceControlHandler.Parent = this; + this._ServiceControlHandler.GM = this.GM; + 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); + } + }); + } + + if (serviceName) { this._ServiceOptions = typeof (serviceName) == 'object' ? serviceName : { name: serviceName }; } + else + { + throw ('Must specify either ServiceName or Options'); + } + if (!this._ServiceOptions.servicePath) + { + this._ServiceOptions.servicePath = process.execPath; + } + + this.run = function run() + { + var serviceOperation = 0; + + for(var i = 0; iStandardOutPath\n' + options.stdout + '') : ''); + var autoStart = (options.startType == 'AUTO_START' ? '' : ''); + var params = ' ProgramArguments\n'; + params += ' \n'; + params += (' /usr/local/mesh_services/' + options.name + '/' + options.name + '\n'); + if(options.parameters) + { + for(var itm in options.parameters) + { + params += (' ' + options.parameters[itm] + '\n'); + } + } + params += ' \n'; + + var plist = '\n'; + plist += '\n'; + plist += '\n'; + plist += ' \n'; + plist += ' Label\n'; + plist += (' ' + options.name + '\n'); + plist += (params + '\n'); + plist += ' WorkingDirectory\n'; + plist += (' /usr/local/mesh_services/' + options.name + '\n'); + plist += (stdoutpath + '\n'); + plist += ' RunAtLoad\n'; + plist += (autoStart + '\n'); + plist += ' \n'; + plist += ''; + + if (!require('fs').existsSync('/usr/local/mesh_services')) { require('fs').mkdirSync('/usr/local/mesh_services'); } + if (!require('fs').existsSync('/Library/LaunchDaemons/' + options.name + '.plist')) + { + if (!require('fs').existsSync('/usr/local/mesh_services/' + options.name)) { require('fs').mkdirSync('/usr/local/mesh_services/' + options.name); } + if (options.binary) + { + require('fs').writeFileSync('/usr/local/mesh_services/' + options.name + '/' + options.name, options.binary); + } + else + { + require('fs').copyFileSync(options.servicePath, '/usr/local/mesh_services/' + options.name + '/' + options.name); + } + require('fs').writeFileSync('/Library/LaunchDaemons/' + options.name + '.plist', plist); + var m = require('fs').statSync('/usr/local/mesh_services/' + options.name + '/' + options.name).mode; + m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP); + require('fs').chmodSync('/usr/local/mesh_services/' + options.name + '/' + options.name, m); + } + else + { + throw ('Service: ' + options.name + ' already exists'); + } + } + } + this.uninstallService = function uninstallService(name) + { + if (!this.isAdmin()) { throw ('Uninstalling a service, requires admin'); } + + if (typeof (name) == 'object') { name = name.name; } + if (process.platform == 'win32') + { + var service = this.getService(name); + if (service.status.state == undefined || service.status.state == 'STOPPED') + { + if (this.proxy.DeleteService(service._service) == 0) + { + throw ('Uninstall Service for: ' + name + ', failed with error: ' + this.proxy2.GetLastError()); + } + else + { + try + { + require('fs').unlinkSync(this.getServiceFolder() + '\\' + name + '.exe'); + } + catch(e) + { + } + } + } + else + { + throw ('Cannot uninstall service: ' + name + ', because it is: ' + service.status.state); + } + } + else if(process.platform == 'linux') + { + switch (this.getServiceType()) + { + case 'init': + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); + this._update.stdout.on('data', function (chunk) { }); + this._update.stdin.write('service ' + name + ' stop\n'); + this._update.stdin.write('update-rc.d -f ' + name + ' remove\n'); + this._update.stdin.write('exit\n'); + this._update.waitExit(); + try + { + require('fs').unlinkSync('/etc/init.d/' + name); + console.log(name + ' uninstalled'); + + } + catch (e) + { + console.log(name + ' could not be uninstalled', e) + } + break; + case 'systemd': + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); + this._update.stdout.on('data', function (chunk) { }); + this._update.stdin.write('systemctl stop ' + name + '.service\n'); + this._update.stdin.write('systemctl disable ' + name + '.service\n'); + this._update.stdin.write('exit\n'); + this._update.waitExit(); + try + { + require('fs').unlinkSync('/usr/local/mesh/' + name); + require('fs').unlinkSync('/lib/systemd/system/' + name + '.service'); + console.log(name + ' uninstalled'); + } + catch (e) + { + console.log(name + ' could not be uninstalled', e) + } + break; + default: // unknown platform service type + break; + } + } + else if(process.platform == 'darwin') + { + if (require('fs').existsSync('/Library/LaunchDaemons/' + name + '.plist')) + { + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.on('data', function (chunk) { }); + child.stdin.write('launchctl stop ' + name + '\n'); + child.stdin.write('launchctl unload /Library/LaunchDaemons/' + name + '.plist\n'); + child.stdin.write('exit\n'); + child.waitExit(); + + try + { + require('fs').unlinkSync('/usr/local/mesh_services/' + name + '/' + name); + require('fs').unlinkSync('/Library/LaunchDaemons/' + name + '.plist'); + } + catch(e) + { + throw ('Error uninstalling service: ' + name + ' => ' + e); + } + + try + { + require('fs').rmdirSync('/usr/local/mesh_services/' + name); + } + catch(e) + {} + } + else + { + throw ('Service: ' + name + ' does not exist'); + } + } + } + if(process.platform == 'linux') + { + this.getServiceType = function getServiceType() + { + return (require('process-manager').getProcessInfo(1).Name); + }; + } +} + +module.exports = serviceManager; \ No newline at end of file diff --git a/agents-new/modules_meshcmd/smbios.js b/agents-new/modules_meshcmd/smbios.js new file mode 100644 index 00000000..91944371 --- /dev/null +++ b/agents-new/modules_meshcmd/smbios.js @@ -0,0 +1,343 @@ +/* +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']; + +// 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; +} + +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 && i <= SMData.length) + { + var strstart = i; + + // Start of String, find end of string + while (SMData[i++] != 0 && i <= SMData.length); + try + { + ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim()); + } + catch (ee) + { + console.log('oops'); + } + } + 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) { + //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; + } + if (callback) { callback.apply(this, [null]); return; } else { return (null); } + }; + this.parse = function parse(data) { + var r = {}; + try + { + r.processorInfo = this.processorInfo(data); + } + catch(e) + { + } + try + { + r.memoryInfo = this.memoryInfo(data); + } + catch(e) + { + } + try + { + r.systemInfo = this.systemInfo(data); + } + catch(e) + { + } + try + { + r.systemSlots = this.systemInfo(data); + } + catch(e) + { + } + try + { + r.amtInfo = this.amtInfo(data); + } + catch(e) + { + } + 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(); + var uuid = si.slice(4, 20); + + retVal.uuid = [zeroLeftPad(uuid.readUInt32LE(0).toString(16), 8), + zeroLeftPad(uuid.readUInt16LE(4).toString(16), 4), + zeroLeftPad(uuid.readUInt16LE(6).toString(16), 4), + zeroLeftPad(uuid.readUInt16BE(8).toString(16), 4), + zeroLeftPad(uuid.slice(10).toString('hex').toLowerCase(), 12)].join('-'); + + 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-new/modules_meshcmd/user-sessions.js b/agents-new/modules_meshcmd/user-sessions.js new file mode 100644 index 00000000..1e245dfd --- /dev/null +++ b/agents-new/modules_meshcmd/user-sessions.js @@ -0,0 +1,750 @@ +/* +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 NOTIFY_FOR_THIS_SESSION = 0; +var NOTIFY_FOR_ALL_SESSIONS = 1; +var WM_WTSSESSION_CHANGE = 0x02B1; +var WM_POWERBROADCAST = 0x218; +var PBT_POWERSETTINGCHANGE = 0x8013; +var PBT_APMSUSPEND = 0x4; +var PBT_APMRESUMESUSPEND = 0x7; +var PBT_APMRESUMEAUTOMATIC = 0x12; +var PBT_APMPOWERSTATUSCHANGE = 0xA; + +var WTS_CONSOLE_CONNECT = (0x1); +var WTS_CONSOLE_DISCONNECT = (0x2); +var WTS_REMOTE_CONNECT = (0x3); +var WTS_REMOTE_DISCONNECT = (0x4); +var WTS_SESSION_LOGON = (0x5); +var WTS_SESSION_LOGOFF = (0x6); +var WTS_SESSION_LOCK = (0x7); +var WTS_SESSION_UNLOCK = (0x8); +var WTS_SESSION_REMOTE_CONTROL = (0x9); +var WTS_SESSION_CREATE = (0xA); +var WTS_SESSION_TERMINATE = (0xB); + +var GUID_ACDC_POWER_SOURCE; +var GUID_BATTERY_PERCENTAGE_REMAINING; +var GUID_CONSOLE_DISPLAY_STATE; + +function UserSessions() +{ + this._ObjectID = 'user-sessions'; + require('events').EventEmitter.call(this, true) + .createEvent('changed') + .createEvent('locked') + .createEvent('unlocked'); + + 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); + }; + try + { + this.Current(p.__handler); + } + catch(e) + { + p.__rejector(e); + } + p.parent = this; + return (p); + } + + if (process.platform == 'win32') + { + this._serviceHooked = false; + this._marshal = require('_GenericMarshal'); + this._kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll'); + this._kernel32.CreateMethod('GetLastError'); + + try + { + this._wts = this._marshal.CreateNativeProxy('Wtsapi32.dll'); + this._wts.CreateMethod('WTSEnumerateSessionsA'); + this._wts.CreateMethod('WTSQuerySessionInformationA'); + this._wts.CreateMethod('WTSRegisterSessionNotification'); + this._wts.CreateMethod('WTSUnRegisterSessionNotification'); + this._wts.CreateMethod('WTSFreeMemory'); + } + catch(exc) + { + } + + this._advapi = this._marshal.CreateNativeProxy('Advapi32.dll'); + this._advapi.CreateMethod('AllocateAndInitializeSid'); + this._advapi.CreateMethod('CheckTokenMembership'); + this._advapi.CreateMethod('FreeSid'); + + this._user32 = this._marshal.CreateNativeProxy('user32.dll'); + this._user32.CreateMethod({ method: 'RegisterPowerSettingNotification', threadDispatch: 1}); + this._user32.CreateMethod('UnregisterPowerSettingNotification'); + this._rpcrt = this._marshal.CreateNativeProxy('Rpcrt4.dll'); + this._rpcrt.CreateMethod('UuidFromStringA'); + this._rpcrt.StringToUUID = function StringToUUID(guid) + { + var retVal = StringToUUID.us._marshal.CreateVariable(16); + if(StringToUUID.us._rpcrt.UuidFromStringA(StringToUUID.us._marshal.CreateVariable(guid), retVal).Val == 0) + { + return (retVal); + } + else + { + throw ('Could not convert string to UUID'); + } + } + this._rpcrt.StringToUUID.us = this; + + GUID_ACDC_POWER_SOURCE = this._rpcrt.StringToUUID('5d3e9a59-e9D5-4b00-a6bd-ff34ff516548'); + GUID_BATTERY_PERCENTAGE_REMAINING = this._rpcrt.StringToUUID('a7ad8041-b45a-4cae-87a3-eecbb468a9e1'); + GUID_CONSOLE_DISPLAY_STATE = this._rpcrt.StringToUUID('6fe69556-704a-47a0-8f24-c28d936fda47'); + + 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.isRoot = function isRoot() + { + var NTAuthority = this._marshal.CreateVariable(6); + NTAuthority.toBuffer().writeInt8(5, 5); + + var AdministratorsGroup = this._marshal.CreatePointer(); + var admin = false; + + if (this._advapi.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0) + { + var member = this._marshal.CreateInteger(); + if (this._advapi.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0) + { + if (member.toBuffer().readUInt32LE() != 0) { admin = true; } + } + this._advapi.FreeSid(AdministratorsGroup.Deref()); + } + return admin; + } + + 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(cb) + { + 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, 'Active', { value: showActiveOnly(retVal) }); + if (cb) { cb(retVal); } + return (retVal); + }; + + + // We need to spin up a message pump, and fetch a window handle + var message_pump = require('win-message-pump'); + this._messagepump = new message_pump({ filter: WM_WTSSESSION_CHANGE }); this._messagepump.parent = this; + this._messagepump.on('exit', function (code) { this.parent._wts.WTSUnRegisterSessionNotification(this.parent.hwnd); }); + this._messagepump.on('hwnd', function (h) + { + this.parent.hwnd = h; + + // We need to yield, and do this in the next event loop pass, becuase we don't want to call 'RegisterPowerSettingNotification' + // from the messagepump 'thread', because we are actually on the microstack thread, such that the message pump thread, is holding + // on a semaphore for us to return. If we call now, we may deadlock on Windows 7, becuase it will try to notify immediately + this.immediate = setImmediate(function (self) + { + // Now that we have a window handle, we can register it to receive Windows Messages + if (self.parent._wts) { self.parent._wts.WTSRegisterSessionNotification(self.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS); } + self.parent._user32.ACDC_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0); + self.parent._user32.BATT_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0); + self.parent._user32.DISP_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0); + //console.log(self.parent._user32.ACDC_H.Val, self.parent._user32.BATT_H.Val, self.parent._user32.DISP_H.Val); + }, this); + }); + this._messagepump.on('message', function (msg) + { + switch(msg.message) + { + case WM_WTSSESSION_CHANGE: + switch(msg.wparam) + { + case WTS_SESSION_LOCK: + this.parent.enumerateUsers().then(function (users) + { + if (users[msg.lparam]) { this.parent.emit('locked', users[msg.lparam]); } + }); + break; + case WTS_SESSION_UNLOCK: + this.parent.enumerateUsers().then(function (users) + { + if (users[msg.lparam]) { this.parent.emit('unlocked', users[msg.lparam]); } + }); + break; + case WTS_SESSION_LOGON: + case WTS_SESSION_LOGOFF: + this.parent.emit('changed'); + break; + } + break; + case WM_POWERBROADCAST: + switch(msg.wparam) + { + default: + console.log('WM_POWERBROADCAST [UNKNOWN wparam]: ' + msg.wparam); + break; + case PBT_APMSUSPEND: + require('power-monitor').emit('sx', 'SLEEP'); + break; + case PBT_APMRESUMEAUTOMATIC: + require('power-monitor').emit('sx', 'RESUME_NON_INTERACTIVE'); + break; + case PBT_APMRESUMESUSPEND: + require('power-monitor').emit('sx', 'RESUME_INTERACTIVE'); + break; + case PBT_APMPOWERSTATUSCHANGE: + require('power-monitor').emit('changed'); + break; + case PBT_POWERSETTINGCHANGE: + var lparam = this.parent._marshal.CreatePointer(Buffer.from(msg.lparam_hex, 'hex')); + var data = lparam.Deref(20, lparam.Deref(16, 4).toBuffer().readUInt32LE(0)).toBuffer(); + switch(lparam.Deref(0, 16).toBuffer().toString('hex')) + { + case GUID_ACDC_POWER_SOURCE.Deref(0, 16).toBuffer().toString('hex'): + switch(data.readUInt32LE(0)) + { + case 0: + require('power-monitor').emit('acdc', 'AC'); + break; + case 1: + require('power-monitor').emit('acdc', 'BATTERY'); + break; + case 2: + require('power-monitor').emit('acdc', 'HOT'); + break; + } + break; + case GUID_BATTERY_PERCENTAGE_REMAINING.Deref(0, 16).toBuffer().toString('hex'): + require('power-monitor').emit('batteryLevel', data.readUInt32LE(0)); + break; + case GUID_CONSOLE_DISPLAY_STATE.Deref(0, 16).toBuffer().toString('hex'): + switch(data.readUInt32LE(0)) + { + case 0: + require('power-monitor').emit('display', 'OFF'); + break; + case 1: + require('power-monitor').emit('display', 'ON'); + break; + case 2: + require('power-monitor').emit('display', 'DIMMED'); + break; + } + break; + } + break; + } + break; + default: + break; + } + }); + } + else if(process.platform == 'linux') + { + var dbus = require('linux-dbus'); + this._linuxWatcher = require('fs').watch('/var/run/utmp'); + this._linuxWatcher.user_session = this; + this._linuxWatcher.on('change', function (a, b) + { + this.user_session.emit('changed'); + }); + this._users = function _users() + { + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('awk -F: \'($3 >= 0) {printf "%s:%s\\n", $1, $3}\' /etc/passwd\nexit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + var ret = {}, tokens; + for (var ln in lines) + { + tokens = lines[ln].split(':'); + if (tokens[0]) { ret[tokens[0]] = tokens[1]; } + } + return (ret); + } + this._uids = function _uids() { + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('awk -F: \'($3 >= 0) {printf "%s:%s\\n", $1, $3}\' /etc/passwd\nexit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + var ret = {}, tokens; + for (var ln in lines) { + tokens = lines[ln].split(':'); + if (tokens[0]) { ret[tokens[1]] = tokens[0]; } + } + return (ret); + } + 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 = {}; + 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.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]) + { + 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(); + + + 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(); }); + + return (retVal); + } + this._recheckLoggedInUsers = function _recheckLoggedInUsers() + { + this.enumerateUsers().then(function (u) + { + + if (u.Active.length > 0) + { + // There is already a user logged in, so we can monitor DBUS for lock/unlock + if (this.parent._linux_lock_watcher != null && this.parent._linux_lock_watcher.uid != u.Active[0].uid) + { + delete this.parent._linux_lock_watcher; + } + this.parent._linux_lock_watcher = new dbus(process.env['XDG_CURRENT_DESKTOP'] == 'Unity' ? 'com.ubuntu.Upstart0_6' : 'org.gnome.ScreenSaver', u.Active[0].uid); + this.parent._linux_lock_watcher.user_session = this.parent; + this.parent._linux_lock_watcher.on('signal', function (s) + { + var p = this.user_session.enumerateUsers(); + p.signalData = s.data[0]; + p.then(function (u) + { + switch (this.signalData) + { + case true: + case 'desktop-lock': + this.parent.emit('locked', u.Active[0]); + break; + case false: + case 'desktop-unlock': + this.parent.emit('unlocked', u.Active[0]); + break; + } + }); + }); + } + else if (this.parent._linux_lock_watcher != null) + { + delete this.parent._linux_lock_watcher; + } + }); + + }; + this.on('changed', this._recheckLoggedInUsers); // For linux Lock/Unlock monitoring, we need to watch for LogOn/LogOff, and keep track of the UID. + + + // First step, is to see if there is a user logged in: + this._recheckLoggedInUsers(); + } + else if(process.platform == 'darwin') + { + this._users = function () + { + var child = require('child_process').execFile('/usr/bin/dscl', ['dscl', '.', 'list', '/Users', 'UniqueID']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('exit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + var tokens, i; + var users = {}; + + for (i = 0; i < lines.length; ++i) { + tokens = lines[i].split(' '); + if (tokens[0]) { users[tokens[0]] = tokens[tokens.length - 1]; } + } + + return (users); + } + this._uids = function () { + var child = require('child_process').execFile('/usr/bin/dscl', ['dscl', '.', 'list', '/Users', 'UniqueID']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('exit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + var tokens, i; + var users = {}; + + for (i = 0; i < lines.length; ++i) { + tokens = lines[i].split(' '); + if (tokens[0]) { users[tokens[tokens.length - 1]] = tokens[0]; } + } + + return (users); + } + this._idTable = function() + { + var table = {}; + var child = require('child_process').execFile('/usr/bin/id', ['id']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.waitExit(); + + var lines = child.stdout.str.split('\n')[0].split(' '); + for (var i = 0; i < lines.length; ++i) { + var types = lines[i].split('='); + var tokens = types[1].split(','); + table[types[0]] = {}; + + for (var j in tokens) { + var idarr = tokens[j].split('('); + var id = idarr[0]; + var name = idarr[1].substring(0, idarr[1].length - 1).trim(); + table[types[0]][name] = id; + table[types[0]][id] = name; + } + } + return (table); + } + this.Current = function (cb) + { + var users = {}; + var table = this._idTable(); + var child = require('child_process').execFile('/usr/bin/last', ['last']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + for (var i = 0; i < lines.length && lines[i].length > 0; ++i) + { + if (!users[lines[i].split(' ')[0]]) + { + try + { + users[lines[i].split(' ')[0]] = { Username: lines[i].split(' ')[0], State: lines[i].split('still logged in').length > 1 ? 'Active' : 'Inactive', uid: table.uid[lines[i].split(' ')[0]] }; + } + catch(e) + {} + } + else + { + if(users[lines[i].split(' ')[0]].State != 'Active' && lines[i].split('still logged in').length > 1) + { + users[lines[i].split(' ')[0]].State = 'Active'; + } + } + } + + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) }); + if (cb) { cb.call(this, users); } + } + } + + if(process.platform == 'linux' || process.platform == 'darwin') + { + this._self = function _self() + { + var child = require('child_process').execFile('/usr/bin/id', ['id', '-u']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.waitExit(); + return (parseInt(child.stdout.str)); + } + this.isRoot = function isRoot() + { + return (this._self() == 0); + } + this.consoleUid = function consoleUid() + { + var checkstr = process.platform == 'darwin' ? 'console' : ((process.env['DISPLAY'])?process.env['DISPLAY']:':0') + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('who\nexit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + var tokens, i, j; + for (i in lines) + { + tokens = lines[i].split(' '); + for (j = 1; j < tokens.length; ++j) + { + if (tokens[j].length > 0) + { + return (parseInt(this._users()[tokens[0]])); + } + } + } + + throw ('nobody logged into console'); + } + } + + +} +function showActiveOnly(source) +{ + var retVal = []; + var unique = {}; + var usernames = []; + var tmp; + + for (var i in source) + { + if (source[i].State == 'Active') + { + retVal.push(source[i]); + tmp = (source[i].Domain ? (source[i].Domain + '\\') : '') + source[i].Username; + if (!unique[tmp]) { unique[tmp] = tmp;} + } + } + + for (var i in unique) + { + usernames.push(i); + } + + Object.defineProperty(retVal, 'usernames', { value: usernames }); + 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, (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); +} + +module.exports = new UserSessions(); \ No newline at end of file diff --git a/agents-new/modules_meshcmd/x/process-manager.js b/agents-new/modules_meshcmd/x/process-manager.js new file mode 100644 index 00000000..d9dbfe05 --- /dev/null +++ b/agents-new/modules_meshcmd/x/process-manager.js @@ -0,0 +1,163 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +var GM = require('_GenericMarshal'); + +// Used on Windows and Linux to get information about running processes +function processManager() { + this._ObjectID = 'process-manager'; // Used for debugging, allows you to get the object type at runtime. + + // Setup the platform specific calls. + 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': + case 'darwin': + this._childProcess = require('child_process'); + break; + default: + throw (process.platform + ' not supported'); + break; + } + this.enumerateProcesses = function enumerateProcesses() + { + var promise = require('promise'); + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + this.getProcesses(function (ps, prom) { prom._res(ps); }, ret); + return (ret); + } + // Return a object of: pid -> process information. + this.getProcesses = function getProcesses(callback) + { + switch(process.platform) + { + default: + throw ('Enumerating processes on ' + process.platform + ' not supported'); + break; + case 'win32': // Windows processes + 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)] = { pid: 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': // Linux processes + 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) { + if (tokenList[key.PID]) { retVal[tokenList[key.PID]] = { pid: 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; + case 'darwin': + var promise = require('promise'); + var p = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + p.pm = this; + p.callback = callback; + p.args = []; + for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); } + p.child = this._childProcess.execFile("/bin/ps", ["ps", "-xa"]); + p.child.promise = p; + p.child.stdout.ps = ''; + p.child.stdout.on('data', function (chunk) { this.ps += chunk.toString(); }); + p.child.on('exit', function () + { + var lines = this.stdout.ps.split('\n'); + var pidX = lines[0].split('PID')[0].length + 3; + var cmdX = lines[0].split('CMD')[0].length; + var ret = {}; + for (var i = 1; i < lines.length; ++i) + { + if (lines[i].length > 0) + { + ret[lines[i].substring(0, pidX).trim()] = { pid: lines[i].substring(0, pidX).trim(), cmd: lines[i].substring(cmdX) }; + } + } + this.promise._res(ret); + }); + p.then(function (ps) + { + this.args.unshift(ps); + this.callback.apply(this.pm, this.args); + }); + break; + } + }; + + // Get information about a specific process on Linux + 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'); + 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; + } + }; +} + +module.exports = new processManager(); \ No newline at end of file diff --git a/agents-new/modules_meshcore/amt-lme.js b/agents-new/modules_meshcore/amt-lme.js new file mode 100644 index 00000000..3c84eb48 --- /dev/null +++ b/agents-new/modules_meshcore/amt-lme.js @@ -0,0 +1,898 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +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; + + try { + 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 + } + } catch (ex) { console.log('Binding error, LMS port ' + (port + lme_port_offset) + ': ' + ex) } // TODO: We can't bind + 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-new/modules_meshcore/amt-manage.js b/agents-new/modules_meshcore/amt-manage.js new file mode 100644 index 00000000..b0e9b786 --- /dev/null +++ b/agents-new/modules_meshcore/amt-manage.js @@ -0,0 +1,649 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @fileoverview Intel(r) AMT Management +* @author Ylian Saint-Hilaire +* @version v0.1.0 +*/ + +/** + * Construct a AmtStackCreateService object, this ia the main Intel AMT communication stack. + * @constructor + */ +function AmtManager(agent, db, isdebug) { + var sendConsole = function (msg) { agent.SendCommand({ "action": "msg", "type": "console", "value": msg }); } + var debug = function (msg) { if (isdebug) { sendConsole('amt-manager: ' + msg + '
'); } } + var amtMei = null, amtMeiState = 0; + var amtLms = null, amtLmsState = 0; + var amtGetVersionResult = null; + var oswsstack = null; + var osamtstack = null; + var amtpolicy = null; + var obj = this; + obj.state = 0; + obj.lmsstate = 0; + obj.onStateChange = null; + obj.setDebug = function (x) { isdebug = x; } + + // Set current Intel AMT activation policy + obj.setPolicy = function (policy) { + if (JSON.stringify(amtpolicy) != JSON.stringify(policy)) { + amtpolicy = policy; + if (applyPolicyTimer == null) { obj.applyPolicy(); } + } + } + + // Try to load up the MEI module + var rebindToMeiRetrys = 0; + obj.reset = function () { + ++rebindToMeiRetrys; + amtMei = null, amtMeiState = 0, amtLms = null, amtLmsState = 0, obj.state = 0, obj.lmsstate = 0; + //debug('Binding to MEI'); + try { + var amtMeiLib = require('amt-mei'); + amtMei = new amtMeiLib(); + amtMei.on('error', function (e) { debug('MEI error'); amtMei = null; amtMeiState = -1; obj.state = -1; obj.onStateChange(amtMeiState); }); + amtMei.getVersion(function (result) { + if (result == null) { + amtMeiState = -1; + obj.state = -1; + if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); } + if (rebindToMeiRetrys < 10) { setTimeout(obj.reset, 10000); } + } else { + amtGetVersionResult = result; + amtMeiState = 2; + obj.state = 2; + rebindToMeiRetrys = 0; + if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); } + //debug('MEI binded'); + obj.lmsreset(); + } + }); + } catch (ex) { debug('MEI exception: ' + ex); amtMei = null; amtMeiState = -1; obj.state = -1; } + } + + // Get Intel AMT information using MEI + var amtMeiTmpState = null; + obj.getAmtInfo = function(func) { + if ((amtMei == null) || (amtMeiState < 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 (result) { if (result) { amtMeiTmpState.Versions = {}; for (var version in result.Versions) { amtMeiTmpState.Versions[result.Versions[version].Description] = result.Versions[version].Version; } } }); + amtMei.getProvisioningMode(function (result) { if (result) { amtMeiTmpState.ProvisioningMode = result.mode; } }); + amtMei.getProvisioningState(function (result) { if (result) { amtMeiTmpState.ProvisioningState = result.state; } }); + amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } }); + amtMei.getControlMode(function (result) { if (result != null) { if (result.controlMode == 1) { amtMeiTmpState.Flags += 2; } if (result.controlMode == 2) { amtMeiTmpState.Flags += 4; } } }); // Flag 2 = CCM, 4 = ACM + //amtMei.getMACAddresses(function (result) { if (result) { amtMeiTmpState.mac = result; } }); + amtMei.getLanInterfaceSettings(0, function (result) { if (result) { amtMeiTmpState.net0 = result; } }); + amtMei.getLanInterfaceSettings(1, function (result) { if (result) { amtMeiTmpState.net1 = result; } }); + amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { amtMeiTmpState.UUID = result.uuid; } }); + 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 + var handleAmtNotification = function(notifyMsg) { + if ((notifyMsg == null) || (notifyMsg.Body == null) || (notifyMsg.Body.MessageID == null) || (notifyMsg.Body.MessageArguments == null)) return null; + var amtMessage = notifyMsg.Body.MessageID, amtMessageArg = notifyMsg.Body.MessageArguments[0], notify = null; + + switch (amtMessage) { + case 'iAMT0050': { if (amtMessageArg == '48') { notify = 'Intel® AMT Serial-over-LAN connected'; } else if (amtMessageArg == '49') { notify = 'Intel® AMT Serial-over-LAN disconnected'; } break; } // SOL + case 'iAMT0052': { if (amtMessageArg == '1') { notify = 'Intel® AMT KVM connected'; } else if (amtMessageArg == '2') { notify = 'Intel® AMT KVM disconnected'; } break; } // KVM + default: { break; } + } + + // Sent to the entire group, no sessionid or userid specified. + if (notify != null) { agent.SendCommand({ "action": "msg", "type": "notify", "value": notify, "tag": "general" }); } + } + + // Launch LMS + obj.lmsreset = function () { + //debug('Binding to LMS'); + var amtLms = null, amtLmsState = 0; + obj.lmsstate = 0; + try { + var lme_heci = require('amt-lme'); + amtLmsState = 1; + obj.lmsstate = 1; + amtLms = new lme_heci(); + amtLms.on('error', function (e) { amtLmsState = 0; obj.lmsstate = 0; amtLms = null; debug('LMS error'); setupMeiOsAdmin(1); }); + amtLms.on('connect', function () { amtLmsState = 2; obj.lmsstate = 2; debug('LMS connected'); setupMeiOsAdmin(2); }); + //amtLms.on('bind', function (map) { }); + amtLms.on('notify', function (data, options, str, code) { + //debug('LMS notify'); + if (code == 'iAMT0052-3') { + kvmGetData(); + } else { + //if (str != null) { debug('Intel AMT LMS: ' + str); } + handleAmtNotification(data); + } + }); + } catch (e) { amtLmsState = -1; obj.lmsstate = -1; amtLms = null; } + } + + + // + // KVM Data Channel + // + + var setupMeiOsAdmin = function (state) { + //debug('Setup MEI OS Admin'); + if ((amtMei == null) || (amtMeiState < 2) || (amtGetVersionResult == null)) { return; } // If there is no MEI, don't bother with obj. + amtMei.getLocalSystemAccount(function (x) { + if (x == null) return; + //debug('getLocalSystemAccount ' + JSON.stringify(x)); + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + oswsstack = new wsman(transport, '127.0.0.1', 16992, x.user, x.pass, false); + osamtstack = new amt(oswsstack); + //if (func) { func(state); } + + // We got the $$OsAdmin account setup. + amtMeiState = 3; + obj.state = 3; + if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); } + if (applyPolicyTimer == null) { obj.applyPolicy(); } + + //var AllWsman = "CIM_SoftwareIdentity,IPS_SecIOService,IPS_ScreenSettingData,IPS_ProvisioningRecordLog,IPS_HostBasedSetupService,IPS_HostIPSettings,IPS_IPv6PortSettings".split(','); + //osamtstack.BatchEnum(null, AllWsman, startLmsWsmanResponse, null, true); + //************************************* + // Setup KVM data channel if this is Intel AMT 12 or above + var amtver = null; + try { for (var i in amtGetVersionResult.Versions) { if (amtGetVersionResult.Versions[i].Description == 'AMT') amtver = parseInt(amtGetVersionResult.Versions[i].Version.split('.')[0]); } } catch (e) { } + if ((amtver != null) && (amtver >= 12)) { + debug('KVM data channel setup'); + kvmGetData('skip'); // Clear any previous data, this is a dummy read to about handling old data. + obj.kvmTempTimer = setInterval(function () { kvmGetData(); }, 2000); // Start polling for KVM data. + kvmSetData(JSON.stringify({ action: 'restart', ver: 1 })); // Send a restart command to advise the console if present that MicroLMS just started. + } + }); + } + + var kvmGetData = function (tag) { + osamtstack.IPS_KVMRedirectionSettingData_DataChannelRead(obj.kvmDataGetResponse, tag); + } + + var 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; + var kvmProcessData = function (realms, messageId, val) { + var data = null; + try { data = JSON.parse(val) } catch (e) { } + if ((data != null) && (data.action)) { + if (data.action == 'present') { kvmSetData(JSON.stringify({ action: 'present', ver: 1, platform: process.platform })); } + if (data.action == 'offer') { + webRtcDesktop = {}; + var rtc = require('ILibWebRTC'); + webRtcDesktop.webrtc = rtc.createConnection(); + webRtcDesktop.webrtc.on('connected', function () { }); + webRtcDesktop.webrtc.on('disconnected', function () { obj.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 () { debug('WebRTC DataChannel closed2'); obj.webRtcCleanUp(); }); + //webRtcDesktop.rtcchannel.on('data', function (data) { debug('WebRTC data: ' + data); }); + }); + kvmSetData(JSON.stringify({ action: 'answer', ver: 1, sdp: webRtcDesktop.webrtc.setOffer(data.sdp) })); + } + } + } + + // Process KVM control channel data + var kvmCtrlData = function (channel, cmd) { + if (cmd.length > 0 && cmd.charCodeAt(0) != 123) { + // This is upload data + if (obj.fileupload != null) { + cmd = Buffer.from(cmd, 'base64'); + var header = cmd.readUInt32BE(0); + if ((header == 0x01000000) || (header == 0x01000001)) { + fs.writeSync(obj.fileupload.fp, cmd.slice(4)); + channel.write({ action: 'upload', sub: 'ack', reqid: obj.fileupload.reqid }); + if (header == 0x01000001) { fs.closeSync(obj.fileupload.fp); obj.fileupload = null; } // Close the file + } + } + return; + } + debug('KVM Ctrl Data: ' + cmd); + //sendConsoleText('KVM Ctrl Data: ' + cmd); + + try { cmd = JSON.parse(cmd); } catch (ex) { debug('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 = ((obj.httprequest.watcher != undefined) && (cmd.path == obj.httprequest.watcher.path)); + if ((obj.httprequest.watcher != undefined) && (samepath == false)) { + //console.log('Closing watcher: ' + obj.httprequest.watcher.path); + //obj.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!! + delete obj.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 = obj.httprequest; + watcher.path = cmd.path; + obj.httprequest.watcher = watcher; + //console.log('Starting watcher: ' + obj.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) { debug(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) { debug(e); } + break; + } + case 'download': { + // Download a file, to browser + var sendNextBlock = 0; + if (cmd.sub == 'start') { // Setup the download + if (obj.filedownload != null) { channel.write({ action: 'download', sub: 'cancel', id: obj.filedownload.id }); delete obj.filedownload; } + obj.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 } + try { obj.filedownload.f = fs.openSync(obj.filedownload.path, 'rbN'); } catch (e) { channel.write({ action: 'download', sub: 'cancel', id: obj.filedownload.id }); delete obj.filedownload; } + if (obj.filedownload) { channel.write({ action: 'download', sub: 'start', id: cmd.id }); } + } else if ((obj.filedownload != null) && (cmd.id == obj.filedownload.id)) { // Download commands + if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete obj.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; } + } + // Send the next download block(s) + while (sendNextBlock > 0) { + sendNextBlock--; + var buf = Buffer.alloc(4096); + var len = fs.readSync(obj.filedownload.f, buf, 4, 4092, null); + obj.filedownload.ptr += len; + if (len < 4092) { buf.writeInt32BE(0x01000001, 0); fs.closeSync(obj.filedownload.f); delete obj.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 (obj.fileupload != null) { fs.closeSync(obj.fileupload.fp); } + if (!cmd.path || !cmd.name) break; + obj.fileupload = { reqid: cmd.reqid }; + var filepath = path.join(cmd.path, cmd.name); + try { obj.fileupload.fp = fs.openSync(filepath, 'wbN'); } catch (e) { } + if (obj.fileupload.fp) { channel.write({ action: 'upload', sub: 'start', reqid: obj.fileupload.reqid }); } else { obj.fileupload = null; channel.write({ action: 'upload', sub: 'error', reqid: obj.fileupload.reqid }); } + } + else if (cmd.sub == 'cancel') { // Stop the upload + if (obj.fileupload != null) { fs.closeSync(obj.fileupload.fp); obj.fileupload = null; } + } + break; + } + case 'copy': { + // Copy a bunch of files from scpath to dspath + for (var i in cmd.names) { + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]); + if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } } + } + break; + } + case 'move': { + // Move a bunch of files from scpath to dspath + for (var i in cmd.names) { + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]); + if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } } + } + break; + } + default: { + debug('Invalid KVM command: ' + cmd); + break; + } + } + } + + var webRtcCleanUp = function () { + debug('webRtcCleanUp'); + if (webRtcDesktop == null) return; + if (webRtcDesktop.rtcchannel) { + try { webRtcDesktop.rtcchannel.close(); } catch (e) { } + try { webRtcDesktop.rtcchannel.removeAllListeners('data'); } catch (e) { } + try { webRtcDesktop.rtcchannel.removeAllListeners('end'); } catch (e) { } + delete webRtcDesktop.rtcchannel; + } + if (webRtcDesktop.webrtc) { + try { webRtcDesktop.webrtc.close(); } catch (e) { } + try { webRtcDesktop.webrtc.removeAllListeners('connected'); } catch (e) { } + try { webRtcDesktop.webrtc.removeAllListeners('disconnected'); } catch (e) { } + try { webRtcDesktop.webrtc.removeAllListeners('dataChannel'); } catch (e) { } + delete webRtcDesktop.webrtc; + } + if (webRtcDesktop.kvm) { + try { webRtcDesktop.kvm.end(); } catch (e) { } + delete webRtcDesktop.kvm; + } + webRtcDesktop = null; + } + + var kvmSetData = function (x) { + osamtstack.IPS_KVMRedirectionSettingData_DataChannelWrite(Buffer.from(x).toString('base64'), function () { }); + } + + // Delete a directory with a files and directories within it + var deleteFolderRecursive = function(path, rec) { + if (fs.existsSync(path)) { + if (rec == true) { + fs.readdirSync(obj.path.join(path, '*')).forEach(function (file, index) { + var curPath = obj.path.join(path, file); + if (fs.statSync(curPath).isDirectory()) { // recurse + deleteFolderRecursive(curPath, true); + } else { // delete file + fs.unlinkSync(curPath); + } + }); + } + fs.unlinkSync(path); + } + }; + + // 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('/'); + } + }; + + function md5hex(str) { return require('MD5Stream').create().syncHash(str).toString('hex'); } + + // + // Deactivate Intel AMT CCM + // + + // When called, this will use MEI to deactivate Intel AMT when it's in CCM mode. Simply calls "unprovision" on MEI and checks the return code. + obj.deactivateCCM = function() { + amtMei.unprovision(1, function (status) { + if (status == 0) { + debug('Success deactivating Intel AMT CCM.'); + agent.SendCommand({ "action": "coreinfo", "intelamt": { "state": 0, "flags": 0 } }); + applyPolicyTimer = setTimeout(obj.applyPolicy, 8000); + } else { + debug('Intel AMT CCM deactivation error: ' + status); + } + }); + } + + // + // Activate Intel AMT to CCM + // + + function makePass(length) { + var text = "", possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for (var i = 0; i < length; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); } + return text; + } + + obj.activeToCCM = function (adminpass) { + if ((adminpass == null) || (adminpass == '')) { adminpass = 'P@0s' + makePass(23); } + intelAmtAdminPass = adminpass; + //debug('Trying to get local account info...'); + amtMei.getLocalSystemAccount(function (x) { + if ((x != null) && x.user && x.pass) { + //debug('Intel AMT local account info: User=' + x.user + ', Pass=' + x.pass + '.'); + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + oswsstack = new wsman(transport, '127.0.0.1', 16992, x.user, x.pass, false); + osamtstack = new amt(oswsstack); + //debug('Trying to get Intel AMT activation information...'); + osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], activeToCCMEx2, adminpass); + } else { + debug('Unable to get $$OsAdmin password.'); + } + }); + } + + var activeToCCMEx2 = function(stack, name, responses, status, adminpass) { + if (status != 200) { debug('Failed to fetch activation information, status ' + status); } + else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { debug('Client control mode activation not allowed'); } + else { stack.IPS_HostBasedSetupService_Setup(2, md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + adminpass).substring(0, 32), null, null, null, null, activeToCCMEx3); } + } + + var activeToCCMEx3 = function(stack, name, responses, status) { + if (status != 200) { debug('Failed to activate, status ' + status); } + else if (responses.Body.ReturnValue != 0) { debug('Client control mode activation failed: ' + responses.Body.ReturnValueStr); } + else { + debug('Intel AMT CCM activation success.'); + db.Put('amtCCMPass', intelAmtAdminPass); + agent.SendCommand({ "action": "coreinfo", "intelamt": { "state": 2, "flags": 2, "user": "admin", "pass": intelAmtAdminPass } }); + } + applyPolicyTimer = setTimeout(obj.applyPolicy, 8000); + } + + obj.start = function () { + // Try to load Intel AMT policy + var amtPolicy = null; + try { amtPolicy = JSON.parse(db.Get('amtPolicy')); } catch (ex) { debug('Exception loading amtPolicy'); } + //if (amtPolicy == null) { debug('no amtPolicy'); } else { debug('Loaded amtPolicy: ' + JSON.stringify(amtPolicy)); } + try { intelAmtAdminPass = db.Get('amtCCMPass'); } catch (ex) { } + if (typeof intelAmtAdminPass != 'string') { intelAmtAdminPass = null; } + obj.reset(); + } + + // Apply Intel AMT policy + var intelAmtAdminPass, wsstack, amtstack, applyPolicyTimer, policyWsmanRetry = 0; + obj.applyPolicy = function () { + applyPolicyTimer = null; + if ((amtMeiState != 3) || (typeof amtpolicy != 'object') || (typeof amtpolicy.type != 'number') || (amtpolicy.type == 0)) return; + if ((amtpolicy.password != null) && (amtpolicy.password != '')) { intelAmtAdminPass = amtpolicy.password; } + obj.getAmtInfo(function (meinfo) { + if ((amtpolicy.type == 1) && (meinfo.ProvisioningState == 2) && ((meinfo.Flags & 2) != 0)) { + // CCM Deactivation Policy. + wsstack = null; + amtstack = null; + obj.deactivateCCM(); + } else if ((amtpolicy.type == 2) && (meinfo.ProvisioningState == 0)) { + // CCM Activation Policy + wsstack = null; + amtstack = null; + if ((amtpolicy.password == null) || (amtpolicy.password == '')) { intelAmtAdminPass = null; } + obj.activeToCCM(intelAmtAdminPass); + } else if ((amtpolicy.type == 2) && (meinfo.ProvisioningState == 2) && (intelAmtAdminPass != null) && ((meinfo.Flags & 2) != 0)) { + // Perform password test + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, '127.0.0.1', 16992, 'admin', intelAmtAdminPass, false); + amtstack = new amt(wsstack); + var wsmanQuery = ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService', '*AMT_RedirectionService', '*CIM_KVMRedirectionSAP', 'AMT_PublicKeyCertificate', '*AMT_EnvironmentDetectionSettingData']; + if (amtpolicy.cirasetup == 2) { wsmanQuery.push("AMT_ManagementPresenceRemoteSAP", "AMT_RemoteAccessCredentialContext", "AMT_RemoteAccessPolicyAppliesToMPS", "AMT_RemoteAccessPolicyRule", "*AMT_UserInitiatedConnectionService", "AMT_MPSUsernamePassword"); } + try { amtstack.BatchEnum(null, wsmanQuery, wsmanPassTestResponse); } catch (ex) { debug(ex); } + } else { + // Other possible cases... + } + }); + } + + function wsmanPassTestResponse(stack, name, responses, status) { + if (status != 200) { + if (status == 401) { + if (amtpolicy.badpass == 1) { obj.deactivateCCM(); } // Incorrect password, reactivate + } else { + if (++policyWsmanRetry < 20) { + if (policyWsmanRetry == 10) { debug('WSMAN fault, MEI Reset'); obj.reset(); } + var wsmanQuery = ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService', '*AMT_RedirectionService', '*CIM_KVMRedirectionSAP', 'AMT_PublicKeyCertificate', '*AMT_EnvironmentDetectionSettingData']; + if (amtpolicy.cirasetup == 2) { wsmanQuery.push("AMT_ManagementPresenceRemoteSAP", "AMT_RemoteAccessCredentialContext", "AMT_RemoteAccessPolicyAppliesToMPS", "AMT_RemoteAccessPolicyRule", "*AMT_UserInitiatedConnectionService", "AMT_MPSUsernamePassword"); } + try { amtstack.BatchEnum(null, wsmanQuery, wsmanPassTestResponse); } catch (ex) { debug(ex); } + } else { + debug('WSMAN fault, status=' + status); + policyWsmanRetry = 0; + } + } + } else { + policyWsmanRetry = 0; + var s = {}; + s.redir = (responses['AMT_RedirectionService'].response["ListenerEnabled"] == true); + s.sol = ((responses['AMT_RedirectionService'].response["EnabledState"] & 2) != 0); + s.ider = ((responses['AMT_RedirectionService'].response["EnabledState"] & 1) != 0); + s.kvm = (responses['CIM_KVMRedirectionSAP'] != null) && ((responses['CIM_KVMRedirectionSAP'].response["EnabledState"] == 6 && responses['CIM_KVMRedirectionSAP'].response["RequestedState"] == 2) || responses['CIM_KVMRedirectionSAP'].response["EnabledState"] == 2 || responses['CIM_KVMRedirectionSAP'].response["EnabledState"] == 6); + + // Enable Ping and RMCP if disabled + if ((responses['AMT_GeneralSettings'].response['PingResponseEnabled'] != true) || (responses['AMT_GeneralSettings'].response['RmcpPingResponseEnabled'] != true)) { + responses['AMT_GeneralSettings'].response['PingResponseEnabled'] = true; + responses['AMT_GeneralSettings'].response['RmcpPingResponseEnabled'] = true; + amtstack.Put('AMT_GeneralSettings', responses['AMT_GeneralSettings'].response, function (stack, name, response, status) { if (status != 200) { debug("Enable PING PUT Error " + status); } }, 0, 1) + } + + // Enable redirection port, SOL and IDER if needed + if ((s.redir == false) || (s.sol == false) || (s.ider == false)) { + var r = responses['AMT_RedirectionService'].response; + r["ListenerEnabled"] = true; // Turn on the redirection port + r["EnabledState"] = 32768 + 1 + 2; // Turn on IDER (1) and SOL (2) + amtstack.AMT_RedirectionService_RequestStateChange(r["EnabledState"], function (stack, name, response, status) { if (status != 200) { debug("Enable Redirection EXEC Error " + status); } }); + } + + // Enable KVM if needed + if ((responses['CIM_KVMRedirectionSAP'] != null) && (s.kvm == false)) { + amtstack.CIM_KVMRedirectionSAP_RequestStateChange(2, 0, + function (stack, name, response, status) { + if (status != 200) { messagebox("Error", "KVMRedirectionSAP, RequestStateChange Error " + status); return; } + amtstack.Put("AMT_RedirectionService", r, function (stack, name, response, status) { if (status != 200) { debug("Enable KVM PUT Error " + status); } }, 0, 1) + } + ); + } + + // Check if the MeshCentral root certificate is present + if (typeof amtpolicy.rootcert == 'string') { + var rootFound = false, xxCertificates = responses["AMT_PublicKeyCertificate"].responses; + for (var i in xxCertificates) { if ((xxCertificates[i]["X509Certificate"] == amtpolicy.rootcert) && (xxCertificates[i]["TrustedRootCertficate"] == true)) { rootFound = true; } } + if (rootFound == false) { amtstack.AMT_PublicKeyManagementService_AddTrustedRootCertificate(amtpolicy.rootcert, function (stack, name, response, status) { if (status != 200) { debug("Add root cert EXEC Error " + status); } }); } + } + + // If CIRA needs to be setup + if ((amtpolicy.cirasetup == 2) && (amtpolicy.ciraserver != null)) { + var serverFound = false, xxCiraServers = responses["AMT_ManagementPresenceRemoteSAP"].responses; + for (var i in xxCiraServers) { if ((xxCiraServers[i].AccessInfo == amtpolicy.ciraserver.name) && (xxCiraServers[i].Port == amtpolicy.ciraserver.port)) { serverFound = xxCiraServers[i].Name; } } + if (serverFound == false) { + // TODO: Remove all CIRA activation policies. + // amtstack.Delete('AMT_RemoteAccessPolicyRule', { 'PolicyRuleName': name }, editMpsPolicyOk2); + // TODO: Remove all other MPS servers. + + // Add our MPS server + amtstack.AMT_RemoteAccessService_AddMpServer(amtpolicy.ciraserver.name, 201, amtpolicy.ciraserver.port, 2, null, amtpolicy.ciraserver.user, amtpolicy.ciraserver.pass, null, function (stack, name, response, status) { + if (status != 200) { + debug("Add MPS server EXEC Error " + status); + } else { + serverFound = false; + var x = response.Body.MpServer.ReferenceParameters.SelectorSet.Selector; + for (var i in x) { if (x[i]['@Name'] == 'Name') { serverFound = x[i]['Value']; } } + if (serverFound != false) { checkCiraTriggerPolicy(responses, serverFound); } + } + }); + } else { + checkCiraTriggerPolicy(responses, serverFound); + } + } else if (amtpolicy.cirasetup == 1) { + // This call will clear environement detection if needed. + checkEnvironmentDetection(responses); + } + } + } + + function checkCiraTriggerPolicy(responses, serverInstanceName) { + // Check CIRA activation policy + var server1 = '
http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
http://intel.com/wbem/wscim/1/amt-schema/1/AMT_ManagementPresenceRemoteSAP' + serverInstanceName + ''; + amtstack.AMT_RemoteAccessService_AddRemoteAccessPolicyRule(2, 0, 'AAAAAAAAAAo=', [server1], null, function (stack, name, response, status) { + if (status != 200) { + debug("Add AddRemoteAccessPolicyRule Error " + status); + } else { + //debug('AMT_RemoteAccessService_AddRemoteAccessPolicyRule Response:' + JSON.stringify(response)); + checkEnvironmentDetection(responses); + } + }); + } + + // Check environement detection. This will set or clear the environement detection strings as needed. + function checkEnvironmentDetection(responses) { + var t2 = []; + if ((amtpolicy.ciraserver != null) && (amtpolicy.ciraserver.home != null)) { t2 = amtpolicy.ciraserver.home; } + var t = responses["AMT_EnvironmentDetectionSettingData"].response; + t['DetectionStrings'] = MakeToArray(t['DetectionStrings']); + if (CompareStrArrays(t['DetectionStrings'], t2) == false) { + t['DetectionStrings'] = t2; + amtstack.Put('AMT_EnvironmentDetectionSettingData', t, function (stack, name, response, status) { if (status != 200) { debug("Put AMT_EnvironmentDetectionSettingData Error " + status); } }, 0, 1); + } + } + + // Imperfect compare of two string arrays. + function CompareStrArrays(arr1, arr2) { + if (arr1 == arr2) return true; + if (arr1 == null) { arr1 = []; } + if (arr2 == null) { arr2 = []; } + if (arr1.length != arr2.length) return false; + for (var i in arr1) { if (arr2.indexOf(arr1[i]) == -1) return false; } + return true; + } + + function MakeToArray(v) { if (!v || v == null || typeof v == "object") return v; return [v]; }; + +} + +module.exports = AmtManager; diff --git a/agents-new/modules_meshcore/amt-mei.js b/agents-new/modules_meshcore/amt-mei.js new file mode 100644 index 00000000..00e6714a --- /dev/null +++ b/agents-new/modules_meshcore/amt-mei.js @@ -0,0 +1,418 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +var Q = require('queue'); +function amt_heci() { + var emitterUtils = require('events').inherits(this); + emitterUtils.createEvent('error'); + + var heci = require('heci'); + var sendConsole = function (msg) { require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": msg }); } + + 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) + { + if(this.Parent._rq.isEmpty()) + { + this.Parent.emit('error', e); // No pending requests, so propagate the error up + } + else + { + // There is a pending request, so fail the pending request + var user = this.Parent._rq.deQueue(); + var params = user.optional; + var callback = user.func; + params.unshift({ Status: -1 }); // Relay an error + callback.apply(this.Parent, params); + + if(!this.Parent._rq.isEmpty()) + { + // There are still more pending requests, so try to re-helpconnect MEI + this.connect(heci.GUIDS.AMT, { noPipeline: 1 }); + } + } + }); + 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 = Buffer.alloc(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.Status == 0 && 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 = Buffer.alloc(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-new/modules_meshcore/amt-scanner.js b/agents-new/modules_meshcore/amt-scanner.js new file mode 100644 index 00000000..c455b753 --- /dev/null +++ b/agents-new/modules_meshcore/amt-scanner.js @@ -0,0 +1,105 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @description 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-new/modules_meshcore/amt-wsman-duk.js b/agents-new/modules_meshcore/amt-wsman-duk.js new file mode 100644 index 00000000..86377bdf --- /dev/null +++ b/agents-new/modules_meshcore/amt-wsman-duk.js @@ -0,0 +1,147 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @description 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; + + 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); + //console.log('Request ' + (obj.RequestCount++)); + + req.on('error', function (e) { obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); }); + req.on('response', function (response) { + //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 () { 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-new/modules_meshcore/amt-wsman.js b/agents-new/modules_meshcore/amt-wsman.js new file mode 100644 index 00000000..6561bd44 --- /dev/null +++ b/agents-new/modules_meshcore/amt-wsman.js @@ -0,0 +1,211 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @description 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-new/modules_meshcore/amt-xml.js b/agents-new/modules_meshcore/amt-xml.js new file mode 100644 index 00000000..5890d742 --- /dev/null +++ b/agents-new/modules_meshcore/amt-xml.js @@ -0,0 +1,185 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { } + + +// 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.error("Unable to parse XML: " + xml, e); + 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. +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-new/modules_meshcore/amt.js b/agents-new/modules_meshcore/amt.js new file mode 100644 index 00000000..7026c76d --- /dev/null +++ b/agents-new/modules_meshcore/amt.js @@ -0,0 +1,1017 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @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_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, tag) { obj.Exec("AMT_PublicKeyManagementService", "AddCertificate", { "CertificateBlob": CertificateBlob }, callback_func, tag); } + 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, InternalMpServer, callback_func) { obj.Exec("AMT_RemoteAccessService", "AddRemoteAccessPolicyRule", { "Trigger": Trigger, "TunnelLifeTime": TunnelLifeTime, "ExtendedData": ExtendedData, "MpServer": MpServer, "InternalMpServer": InternalMpServer }, 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, tag) { obj.Exec("AMT_SetupAndConfigurationService", "CommitChanges", { "_method_dummy": _method_dummy }, callback_func, tag); } + 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_TLSCredentialContext_Create = function AMT_TLSCredentialContext_Create(ElementInContext, ElementProvidingContext, callback_func, tag) { obj.Create("AMT_TLSCredentialContext", { "ElementInContext": ElementInContext, "ElementProvidingContext": ElementProvidingContext }, 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 = Buffer.from(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-new/modules_meshcore/linux-dbus.js b/agents-new/modules_meshcore/linux-dbus.js new file mode 100644 index 00000000..59d41bf1 --- /dev/null +++ b/agents-new/modules_meshcore/linux-dbus.js @@ -0,0 +1,128 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { } + + + +function dbus(address, uid) +{ + this._ObjectID = 'linux-dbus'; + require('events').EventEmitter.call(this, true) + .createEvent('signal'); + Object.defineProperty(this, "uid", { value: uid }); + this._child = require('child_process').execFile("/bin/sh", ["sh"], { type: require('child_process').SpawnTypes.TERM, uid: uid == null ? -1 : uid }); + this._child.stdin.write('dbus-monitor --session "type=\'signal\', interface=\'' + address + '\'" | ( while read X; do echo "$X"; done )\n'); + this._child.stdout.dbus = this; + this._child.stdout.on('data', function (chunk) + { + // Parse DBUS Data + if (!this.ready) { this.ready = true; return; } + + var lines = []; + var tokens = chunk.toString().split('\r\n'); + for (var i in tokens) + { + if (tokens[i] == '') + { + // End of record + this.dbus.preParseRecords(lines); + lines = []; + } + else + { + lines.push(tokens[i]); + } + } + }); + this.preParseRecords = function (lines) + { + var record = []; + for (var i in lines) + { + if(lines[i].startsWith('signal ')) + { + if(record.length>0) + { + this.parseRecords(record); + } + record = []; + } + record.push(lines[i]); + } + if (record.length > 0) + { + this.parseRecords(record); + } + } + this.parseRecords = function (lines) + { + if (lines[0].startsWith('signal ')) + { + var signal = {}; + var sigtokens = lines[0].split(' '); + sigtokens.shift(); + + for (var i in sigtokens) { + var sigitems = sigtokens[i].split('='); + if (sigitems.length == 2) { + signal[sigitems[0]] = sigitems[1]; + } + } + + lines.shift(); + signal.data = lines; + + this.parseSignal(signal); + } + } + this.parseSignal = function(signal) + { + var data = signal.data; + signal.data = []; + + for(var i=0; i 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']; + +// 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; +} + +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 && i <= SMData.length) + { + var strstart = i; + + // Start of String, find end of string + while (SMData[i++] != 0 && i <= SMData.length); + try + { + ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim()); + } + catch (ee) + { + console.log('oops'); + } + } + 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) { + //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; + } + if (callback) { callback.apply(this, [null]); return; } else { return (null); } + }; + this.parse = function parse(data) { + var r = {}; + try + { + r.processorInfo = this.processorInfo(data); + } + catch(e) + { + } + try + { + r.memoryInfo = this.memoryInfo(data); + } + catch(e) + { + } + try + { + r.systemInfo = this.systemInfo(data); + } + catch(e) + { + } + try + { + r.systemSlots = this.systemInfo(data); + } + catch(e) + { + } + try + { + r.amtInfo = this.amtInfo(data); + } + catch(e) + { + } + 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(); + var uuid = si.slice(4, 20); + + retVal.uuid = [zeroLeftPad(uuid.readUInt32LE(0).toString(16), 8), + zeroLeftPad(uuid.readUInt16LE(4).toString(16), 4), + zeroLeftPad(uuid.readUInt16LE(6).toString(16), 4), + zeroLeftPad(uuid.readUInt16BE(8).toString(16), 4), + zeroLeftPad(uuid.slice(10).toString('hex').toLowerCase(), 12)].join('-'); + + 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-new/modules_meshcore/toaster.js b/agents-new/modules_meshcore/toaster.js new file mode 100644 index 00000000..4053ad4c --- /dev/null +++ b/agents-new/modules_meshcore/toaster.js @@ -0,0 +1,125 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +var toasters = {}; + +function Toaster() +{ + this._ObjectID = 'toaster'; + this.Toast = function Toast(title, caption) + { + var retVal = {}; + var emitter = require('events').inherits(retVal); + emitter.createEvent('Dismissed'); + + retVal.title = title; + retVal.caption = caption; + + if (process.platform == 'win32') + { + emitter.createEvent('Clicked'); + + 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.Active[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-message-pump', getJSModule('win-message-pump')); + + 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); + } + else + { + if(!require('fs').existsSync('/usr/bin/notify-send')) + { + throw ('Toast not supported on this platform'); + } + Object.defineProperty(retVal, '_sessions', { + value: require('user-sessions').Current(function onCurrentSession(sessions) + { + this._cchild = require('child_process').execFile('/usr/bin/whoami', ['whoami'], { type: require('child_process').SpawnTypes.TERM }); + this._cchild.stdout.on('data', function (chunk) + { + if (chunk.toString().split('\r\n')[0] == 'root') + { + if (sessions[':0'].State != 'Connected' && sessions[':0'].State != 'Active') + { + // No logged in user owns the display + this.parent.parent.Parent.emit('Dismissed'); + return; + } + + // We root, so we need to direct to DISPLAY=:0 + this.parent.parent._notify = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); + this.parent.parent._notify.stdin.write('su - ' + sessions[':0'].Username + ' -c "DISPLAY=:0 notify-send \'' + this.parent.parent.Parent.title + '\' \'' + this.parent.parent.Parent.caption + '\'"\n'); + this.parent.parent._notify.stdin.write('exit\n'); + this.parent.parent._notify.stdout.on('data', function (chunk) { }); + } + else + { + // We ain't root, so that means we can just call send-notify directly + this.parent.parent._notify = require('child_process').execFile('/usr/bin/notify-send', ['notify-send', this.parent.parent.Parent.title, this.parent.parent.Parent.caption], { type: require('child_process').SpawnTypes.TERM }); + this.parent.parent._notify.stdout.on('data', function (chunk) { }); + } + + // NOTIFY-SEND has a bug where timeouts don't work, so the default is 10 seconds + this.parent.parent.Parent._timeout = setTimeout(function onFakeDismissed(obj) + { + obj.emit('Dismissed'); + }, 10000, this.parent.parent.Parent); + }); + this._cchild.parent = this; + }) + }); + retVal._sessions.Parent = retVal; + + toasters[retVal._hashCode()] = retVal; + retVal.on('Dismissed', function () { delete toasters[this._hashCode()]; }); + + return (retVal); + } + }; +} + +module.exports = new Toaster(); \ No newline at end of file diff --git a/agents-new/modules_meshcore/wifi-scanner-windows.js b/agents-new/modules_meshcore/wifi-scanner-windows.js new file mode 100644 index 00000000..d3c405cb --- /dev/null +++ b/agents-new/modules_meshcore/wifi-scanner-windows.js @@ -0,0 +1,170 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +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-new/modules_meshcore/wifi-scanner.js b/agents-new/modules_meshcore/wifi-scanner.js new file mode 100644 index 00000000..c0f63ff1 --- /dev/null +++ b/agents-new/modules_meshcore/wifi-scanner.js @@ -0,0 +1,127 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +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-new/modules_meshcore/win-console.js b/agents-new/modules_meshcore/win-console.js new file mode 100644 index 00000000..89e3c275 --- /dev/null +++ b/agents-new/modules_meshcore/win-console.js @@ -0,0 +1,164 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +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 = 'win-console'; + 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-message-pump'); + 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-new/modules_meshcore/win-terminal.js b/agents-new/modules_meshcore/win-terminal.js new file mode 100644 index 00000000..6a63b782 --- /dev/null +++ b/agents-new/modules_meshcore/win-terminal.js @@ -0,0 +1,507 @@ +/* +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 promise = require('promise'); +var duplex = require('stream').Duplex; + +var SW_HIDE = 0; +var SW_MINIMIZE = 6; +var STARTF_USESHOWWINDOW = 0x1; +var STD_INPUT_HANDLE = -10; +var STD_OUTPUT_HANDLE = -11; +var EVENT_CONSOLE_CARET = 0x4001; +var EVENT_CONSOLE_END_APPLICATION = 0x4007; +var WINEVENT_OUTOFCONTEXT = 0x000; +var WINEVENT_SKIPOWNPROCESS = 0x0002; +var CREATE_NEW_PROCESS_GROUP = 0x200; +var EVENT_CONSOLE_UPDATE_REGION = 0x4002; +var EVENT_CONSOLE_UPDATE_SIMPLE = 0x4003; +var EVENT_CONSOLE_UPDATE_SCROLL = 0x4004; +var EVENT_CONSOLE_LAYOUT = 0x4005; +var EVENT_CONSOLE_START_APPLICATION = 0x4006; +var KEY_EVENT = 0x1; +var MAPVK_VK_TO_VSC = 0; +var WM_QUIT = 0x12; + +var GM = require('_GenericMarshal'); +var si = GM.CreateVariable(GM.PointerSize == 4 ? 68 : 104); +var pi = GM.CreateVariable(GM.PointerSize == 4 ? 16 : 24); + +si.Deref(0, 4).toBuffer().writeUInt32LE(GM.PointerSize == 4 ? 68 : 104); // si.cb +si.Deref(GM.PointerSize == 4 ? 48 : 64, 2).toBuffer().writeUInt16LE(SW_HIDE | SW_MINIMIZE); // si.wShowWindow +si.Deref(GM.PointerSize == 4 ? 44 : 60, 4).toBuffer().writeUInt32LE(STARTF_USESHOWWINDOW); // si.dwFlags; + +var MSG = GM.CreateVariable(GM.PointerSize == 4 ? 28 : 48); + +function windows_terminal() { + this._ObjectID = 'windows_terminal'; + this._user32 = GM.CreateNativeProxy('User32.dll'); + this._user32.CreateMethod('DispatchMessageA'); + this._user32.CreateMethod('GetMessageA'); + this._user32.CreateMethod('MapVirtualKeyA'); + this._user32.CreateMethod('PostThreadMessageA'); + this._user32.CreateMethod('SetWinEventHook'); + this._user32.CreateMethod('ShowWindow'); + this._user32.CreateMethod('TranslateMessage'); + this._user32.CreateMethod('UnhookWinEvent'); + this._user32.CreateMethod('VkKeyScanA'); + this._user32.terminal = this; + + this._kernel32 = GM.CreateNativeProxy('Kernel32.dll'); + this._kernel32.CreateMethod('AllocConsole'); + this._kernel32.CreateMethod('CreateProcessA'); + this._kernel32.CreateMethod('CloseHandle'); + this._kernel32.CreateMethod('FillConsoleOutputAttribute'); + this._kernel32.CreateMethod('FillConsoleOutputCharacterA'); + this._kernel32.CreateMethod('GetConsoleScreenBufferInfo'); + this._kernel32.CreateMethod('GetConsoleWindow'); + this._kernel32.CreateMethod('GetLastError'); + this._kernel32.CreateMethod('GetStdHandle'); + this._kernel32.CreateMethod('GetThreadId'); + this._kernel32.CreateMethod('ReadConsoleOutputA'); + this._kernel32.CreateMethod('SetConsoleCursorPosition'); + this._kernel32.CreateMethod('SetConsoleScreenBufferSize'); + this._kernel32.CreateMethod('SetConsoleWindowInfo'); + this._kernel32.CreateMethod('TerminateProcess'); + this._kernel32.CreateMethod('WaitForSingleObject'); + this._kernel32.CreateMethod('WriteConsoleInputA'); + + var currentX = 0; + var currentY = 0; + + this._scrx = 0; + this._scry = 0; + + this.SendCursorUpdate = function () { + var newCsbi = GM.CreateVariable(22); + + if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, newCsbi).Val == 0) { return; } + if (newCsbi.Deref(4, 2).toBuffer().readUInt16LE() != this.currentX || newCsbi.Deref(6, 2).toBuffer().readUInt16LE() != this.currentY) { + //wchar_t mywbuf[512]; + //swprintf(mywbuf, 512, TEXT("csbi.dwCursorPosition.X = %d, csbi.dwCursorPosition.Y = %d, newCsbi.dwCursorPosition.X = %d, newCsbi.dwCursorPosition.Y = %d\r\n"), csbi.dwCursorPosition.X, csbi.dwCursorPosition.Y, newCsbi.dwCursorPosition.X, newCsbi.dwCursorPosition.Y); + //OutputDebugString(mywbuf); + + //m_viewOffset = newCsbi.srWindow.Top; + //WriteMoveCursor((SerialAgent *)this->sa, (char)(newCsbi.dwCursorPosition.Y - m_viewOffset), (char)(newCsbi.dwCursorPosition.X - m_viewOffset)); + //LowStackSendData((SerialAgent *)(this->sa), "", 0); + + this.currentX = newCsbi.Deref(4, 2).toBuffer().readUInt16LE(); + this.currentY = newCsbi.Deref(6, 2).toBuffer().readUInt16LE(); + } + } + + this.ClearScreen = function () { + var CONSOLE_SCREEN_BUFFER_INFO = GM.CreateVariable(22); + if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, CONSOLE_SCREEN_BUFFER_INFO).Val == 0) { return; } + + var coordScreen = GM.CreateVariable(4); + var dwConSize = CONSOLE_SCREEN_BUFFER_INFO.Deref(0, 2).toBuffer().readUInt16LE(0) * CONSOLE_SCREEN_BUFFER_INFO.Deref(2, 2).toBuffer().readUInt16LE(0); + var cCharsWritten = GM.CreateVariable(4); + + // Fill the entire screen with blanks. + if (this._kernel32.FillConsoleOutputCharacterA(this._stdoutput, 32, dwConSize, coordScreen.Deref(0, 4).toBuffer().readUInt32LE(), cCharsWritten).Val == 0) { return; } + + // Get the current text attribute. + if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, CONSOLE_SCREEN_BUFFER_INFO).Val == 0) { return; } + + // Set the buffer's attributes accordingly. + if (this._kernel32.FillConsoleOutputAttribute(this._stdoutput, CONSOLE_SCREEN_BUFFER_INFO.Deref(8, 2).toBuffer().readUInt16LE(0), dwConSize, coordScreen.Deref(0, 4).toBuffer().readUInt32LE(), cCharsWritten).Val == 0) { return; } + + // Put the cursor at its home coordinates. + this._kernel32.SetConsoleCursorPosition(this._stdoutput, coordScreen.Deref(0, 4).toBuffer().readUInt32LE()); + + // Put the window to top-left. + var rect = GM.CreateVariable(8); + var srWindow = CONSOLE_SCREEN_BUFFER_INFO.Deref(10, 8).toBuffer(); + rect.Deref(4, 2).toBuffer().writeUInt16LE(srWindow.readUInt16LE(4) - srWindow.readUInt16LE(0)); + rect.Deref(6, 2).toBuffer().writeUInt16LE(srWindow.readUInt16LE(6) - srWindow.readUInt16LE(2)); + + this._kernel32.SetConsoleWindowInfo(this._stdoutput, 1, rect); + } + + this.Start = function Start(CONSOLE_SCREEN_WIDTH, CONSOLE_SCREEN_HEIGHT) + { + this.stopping = null; + if (this._kernel32.GetConsoleWindow().Val == 0) { + if (this._kernel32.AllocConsole().Val == 0) { + throw ('AllocConsole failed with: ' + this._kernel32.GetLastError().Val); + } + } + + this._stdinput = this._kernel32.GetStdHandle(STD_INPUT_HANDLE); + this._stdoutput = this._kernel32.GetStdHandle(STD_OUTPUT_HANDLE); + this._connected = false; + var coordScreen = GM.CreateVariable(4); + coordScreen.Deref(0, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_WIDTH); + coordScreen.Deref(2, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_HEIGHT); + + var rect = GM.CreateVariable(8); + rect.Deref(4, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_WIDTH - 1); + rect.Deref(6, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_HEIGHT - 1); + + if (this._kernel32.SetConsoleWindowInfo(this._stdoutput, 1, rect).Val == 0) { + throw ('Failed to set Console Screen Size'); + } + if (this._kernel32.SetConsoleScreenBufferSize(this._stdoutput, coordScreen.Deref(0, 4).toBuffer().readUInt32LE()).Val == 0) { + throw ('Failed to set Console Buffer Size'); + } + + // Hide the console window + this._user32.ShowWindow(this._kernel32.GetConsoleWindow().Val, SW_HIDE); + + this.ClearScreen(); + this._hookThread().then(function () { + // Hook Ready + this.terminal.StartCommand(); + }, console.log); + this._stream = new duplex({ + 'write': function (chunk, flush) { + if (!this.terminal.connected) { + //console.log('_write: ' + chunk); + if (!this._promise.chunk) { + this._promise.chunk = []; + } + if (typeof (chunk) == 'string') { + this._promise.chunk.push(chunk); + } else { + this._promise.chunk.push(Buffer.alloc(chunk.length)); + chunk.copy(this._promise.chunk.peek()); + } + this._promise.chunk.peek().flush = flush; + this._promise.then(function () { + var buf; + while (this.chunk.length > 0) { + buf = this.chunk.shift(); + this.terminal._WriteBuffer(buf); + buf.flush(); + } + }); + } + else { + //console.log('writeNOW: ' + chunk); + this.terminal._WriteBuffer(chunk); + flush(); + } + return (true); + }, + 'final': function (flush) { + var p = this.terminal._stop(); + p.__flush = flush; + p.then(function () { this.__flush(); }); + } + }); + this._stream.terminal = this; + this._stream._promise = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + this._stream._promise.terminal = this; + return (this._stream); + }; + this._stop = function () { + if (this.stopping) { return (this.stopping); } + //console.log('Stopping Terminal...'); + this._ConsoleWinEventProc.removeAllListeners('GlobalCallback'); + this.stopping = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + + var threadID = this._kernel32.GetThreadId(this._user32.SetWinEventHook.async.thread()).Val; + this._user32.PostThreadMessageA(threadID, WM_QUIT, 0, 0); + this._stream.emit('end'); + return (this.stopping); + } + + this._hookThread = function () { + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + ret.terminal = this; + this._ConsoleWinEventProc = GM.GetGenericGlobalCallback(7); + this._ConsoleWinEventProc.terminal = this; + var p = this._user32.SetWinEventHook.async(EVENT_CONSOLE_CARET, EVENT_CONSOLE_END_APPLICATION, 0, this._ConsoleWinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); + p.ready = ret; + p.terminal = this; + p.then(function (hwinEventHook) { + if (hwinEventHook.Val == 0) { + this.ready._rej('Error calling SetWinEventHook'); + } else { + this.terminal.hwinEventHook = hwinEventHook; + this.ready._res(); + this.terminal._GetMessage(); + } + }); + + this._ConsoleWinEventProc.on('GlobalCallback', function (hhook, dwEvent, hwnd, idObject, idChild, idEventThread, swmsEventTime) { + if (!this.terminal.hwinEventHook || this.terminal.hwinEventHook.Val != hhook.Val) { return; } + var buffer = null; + + switch (dwEvent.Val) { + case EVENT_CONSOLE_CARET: + break; + case EVENT_CONSOLE_UPDATE_REGION: + if (!this.terminal.connected) { + this.terminal.connected = true; + this.terminal._stream._promise._res(); + } + if (this.terminal._scrollTimer == null) { + buffer = this.terminal._GetScreenBuffer(LOWORD(idObject.Val), HIWORD(idObject.Val), LOWORD(idChild.Val), HIWORD(idChild.Val)); + //console.log('UPDATE REGION: [Left: ' + LOWORD(idObject.Val) + ' Top: ' + HIWORD(idObject.Val) + ' Right: ' + LOWORD(idChild.Val) + ' Bottom: ' + HIWORD(idChild.Val) + ']'); + this.terminal._SendDataBuffer(buffer); + } + break; + case EVENT_CONSOLE_UPDATE_SIMPLE: + //console.log('UPDATE SIMPLE: [X: ' + LOWORD(idObject.Val) + ' Y: ' + HIWORD(idObject.Val) + ' Char: ' + LOWORD(idChild.Val) + ' Attr: ' + HIWORD(idChild.Val) + ']'); + var simplebuffer = { data: [ Buffer.alloc(1, LOWORD(idChild.Val)) ], attributes: [ HIWORD(idChild.Val) ], width: 1, height: 1, x: LOWORD(idObject.Val), y: HIWORD(idObject.Val) }; + this.terminal._SendDataBuffer(simplebuffer); + break; + case EVENT_CONSOLE_UPDATE_SCROLL: + //console.log('UPDATE SCROLL: [dx: ' + idObject.Val + ' dy: ' + idChild.Val + ']'); + this.terminal._SendScroll(idObject.Val, idChild.Val); + break; + case EVENT_CONSOLE_LAYOUT: + //console.log('CONSOLE_LAYOUT'); + //snprintf( Buf, 512, "Event Console LAYOUT!\r\n"); + //SendLayout(); + break; + case EVENT_CONSOLE_START_APPLICATION: + //console.log('START APPLICATION: [PID: ' + idObject.Val + ' CID: ' + idChild.Val + ']'); + //snprintf( Buf, 512, "Event Console START APPLICATION!\r\nProcess ID: %d - Child ID: %d\r\n\r\n", (int)idObject, (int)idChild); + //SendConsoleEvent(dwEvent, idObject, idChild); + break; + case EVENT_CONSOLE_END_APPLICATION: + if (idObject.Val == this.terminal._hProcessID) + { + //console.log('END APPLICATION: [PID: ' + idObject.Val + ' CID: ' + idChild.Val + ']'); + this.terminal._hProcess = null; + this.terminal._stop().then(function () { console.log('STOPPED'); }); + } + break; + default: + //snprintf(Buf, 512, "unknown console event.\r\n"); + console.log('Unknown event: ' + dwEvent.Val); + break; + } + + //mbstowcs_s(&l, wBuf, Buf, 512); + //OutputDebugString(wBuf); + + }); + return (ret); + } + + this._GetMessage = function () { + if (this._user32.abort) { console.log('aborting loop'); return; } + this._user32.GetMessageA.async(this._user32.SetWinEventHook.async, MSG, 0, 0, 0).then(function (ret) { + //console.log('GetMessage Response'); + if (ret.Val != 0) { + if (ret.Val == -1) { + // handle the error and possibly exit + } else { + //console.log('TranslateMessage'); + this.nativeProxy._user32.TranslateMessage.async(this.nativeProxy.user32.SetWinEventHook.async, MSG).then(function () { + //console.log('DispatchMessage'); + this.nativeProxy._user32.DispatchMessageA.async(this.nativeProxy.user32.SetWinEventHook.async, MSG).then(function () { + this.nativeProxy.terminal._GetMessage(); + }, console.log); + }, console.log); + } + } else + { + this.nativeProxy.UnhookWinEvent.async(this.nativeProxy.terminal._user32.SetWinEventHook.async, this.nativeProxy.terminal.hwinEventHook) + .then(function () + { + if (this.nativeProxy.terminal._hProcess == null) { return; } + + this.nativeProxy.terminal.stopping._res(); + if (this.nativeProxy.terminal._kernel32.TerminateProcess(this.nativeProxy.terminal._hProcess, 1067).Val == 0) { + var e = this.nativeProxy.terminal._kernel32.GetLastError().Val; + console.log('Unable to kill Terminal Process, error: ' + e); + } + this.nativeProxy.terminal.stopping = null; + }, function (err) + { + console.log('REJECTED_UnhookWinEvent: ' + err); + }); + } + }, function (err) { + // Get Message Failed + console.log('REJECTED_GETMessage: ' + err); + }); + } + this._WriteBuffer = function (buf) { + for (var i = 0; i < buf.length; ++i) { + if (typeof (buf) == 'string') { + this._WriteCharacter(buf.charCodeAt(i), false); + } else { + this._WriteCharacter(buf[i], false); + } + } + } + this._WriteCharacter = function (key, bControlKey) { + var rec = GM.CreateVariable(20); + rec.Deref(0, 2).toBuffer().writeUInt16LE(KEY_EVENT); // rec.EventType + rec.Deref(4, 4).toBuffer().writeUInt16LE(1); // rec.Event.KeyEvent.bKeyDown + rec.Deref(16, 4).toBuffer().writeUInt32LE(bControlKey); // rec.Event.KeyEvent.dwControlKeyState + rec.Deref(14, 1).toBuffer()[0] = key; // rec.Event.KeyEvent.uChar.AsciiChar + rec.Deref(8, 2).toBuffer().writeUInt16LE(1); // rec.Event.KeyEvent.wRepeatCount + rec.Deref(10, 2).toBuffer().writeUInt16LE(this._user32.VkKeyScanA(key).Val); // rec.Event.KeyEvent.wVirtualKeyCode + rec.Deref(12, 2).toBuffer().writeUInt16LE(this._user32.MapVirtualKeyA(this._user32.VkKeyScanA(key).Val, MAPVK_VK_TO_VSC).Val); + + var dwWritten = GM.CreateVariable(4); + if (this._kernel32.WriteConsoleInputA(this._stdinput, rec, 1, dwWritten).Val == 0) { return (false); } + + rec.Deref(4, 4).toBuffer().writeUInt16LE(0); // rec.Event.KeyEvent.bKeyDown + return (this._kernel32.WriteConsoleInputA(this._stdinput, rec, 1, dwWritten).Val != 0); + } + + // Get the current visible screen buffer + this._GetScreenBuffer = function (sx, sy, ex, ey) { + var info = GM.CreateVariable(22); + if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, info).Val == 0) { throw ('Error getting screen buffer info'); } + + var nWidth = info.Deref(14, 2).toBuffer().readUInt16LE() - info.Deref(10, 2).toBuffer().readUInt16LE() + 1; + var nHeight = info.Deref(16, 2).toBuffer().readUInt16LE() - info.Deref(12, 2).toBuffer().readUInt16LE() + 1; + + if (arguments[3] == null) { + // Use Default Parameters + sx = 0; + sy = 0; + ex = nWidth - 1; + ey = nHeight - 1; + } else { + if (this._scrx != 0) { sx += this._scrx; ex += this._scrx; } + if (this._scry != 0) { sy += this._scry; ey += this._scry; } + this._scrx = this._scry = 0; + } + + var nBuffer = GM.CreateVariable((ex - sx + 1) * (ey - sy + 1) * 4); + var size = GM.CreateVariable(4); + size.Deref(0, 2).toBuffer().writeUInt16LE(ex - sx + 1, 0); + size.Deref(2, 2).toBuffer().writeUInt16LE(ey - sy + 1, 0); + + var startCoord = GM.CreateVariable(4); + startCoord.Deref(0, 2).toBuffer().writeUInt16LE(0, 0); + startCoord.Deref(2, 2).toBuffer().writeUInt16LE(0, 0); + + var region = GM.CreateVariable(8); + region.buffer = region.toBuffer(); + region.buffer.writeUInt16LE(sx, 0); + region.buffer.writeUInt16LE(sy, 2); + region.buffer.writeUInt16LE(ex, 4); + region.buffer.writeUInt16LE(ey, 6); + + if (this._kernel32.ReadConsoleOutputA(this._stdoutput, nBuffer, size.Deref(0, 4).toBuffer().readUInt32LE(), startCoord.Deref(0, 4).toBuffer().readUInt32LE(), region).Val == 0) { + throw ('Unable to read Console Output'); + } + + // Lets convert the buffer into something simpler + //var retVal = { data: Buffer.alloc((dw - dx + 1) * (dh - dy + 1)), attributes: Buffer.alloc((dw - dx + 1) * (dh - dy + 1)), width: dw - dx + 1, height: dh - dy + 1, x: dx, y: dy }; + + var retVal = { data: [], attributes: [], width: ex - sx + 1, height: ey - sy + 1, x: sx, y: sy }; + var x, y, line, ifo, tmp, lineWidth = ex - sx + 1; + + for (y = 0; y <= (ey - sy) ; ++y) { + retVal.data.push(Buffer.alloc(lineWidth)); + retVal.attributes.push(Buffer.alloc(lineWidth)); + + line = nBuffer.Deref(y * lineWidth * 4, lineWidth * 4).toBuffer(); + for (x = 0; x < lineWidth; ++x) { + retVal.data.peek()[x] = line[x * 4]; + retVal.attributes.peek()[x] = line[2 + (x * 4)]; + } + } + + return (retVal); + } + + this._SendDataBuffer = function (data) { + // { data, attributes, width, height, x, y } + + var dy, line, attr; + for (dy = 0; dy < data.height; ++dy) { + line = data.data[dy]; + attr = data.attributes[dy]; + line.s = line.toString(); + + //line = data.data.slice(data.width * dy, (data.width * dy) + data.width); + //attr = data.attributes.slice(data.width * dy, (data.width * dy) + data.width); + this._stream.push(TranslateLine(data.x + 1, data.y + dy + 1, line, attr)); + } + } + + this._SendScroll = function _SendScroll(dx, dy) { + if (this._scrollTimer) { return; } + + var info = GM.CreateVariable(22); + if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, info).Val == 0) { throw ('Error getting screen buffer info'); } + + var nWidth = info.Deref(14, 2).toBuffer().readUInt16LE() - info.Deref(10, 2).toBuffer().readUInt16LE() + 1; + var nHeight = info.Deref(16, 2).toBuffer().readUInt16LE() - info.Deref(12, 2).toBuffer().readUInt16LE() + 1; + + this._stream.push(GetEsc('H', [nHeight - 1, 0])); + for (var i = 0; i > nHeight; ++i) { this._stream.push(Buffer.from('\r\n')); } + + var buffer = this._GetScreenBuffer(0, 0, nWidth - 1, nHeight - 1); + this._SendDataBuffer(buffer); + + this._scrollTimer = setTimeout(function (self, nw, nh) { + var buffer = self._GetScreenBuffer(0, 0, nw - 1, nh - 1); + self._SendDataBuffer(buffer); + self._scrollTimer = null; + }, 250, this, nWidth, nHeight); + } + + this.StartCommand = function StartCommand() { + if (this._kernel32.CreateProcessA(GM.CreateVariable(process.env['windir'] + '\\system32\\cmd.exe'), 0, 0, 0, 1, CREATE_NEW_PROCESS_GROUP, 0, 0, si, pi).Val == 0) { + console.log('Error Spawning CMD'); + return; + } + + this._kernel32.CloseHandle(pi.Deref(GM.PointerSize, GM.PointerSize).Deref()); // pi.hThread + this._hProcess = pi.Deref(0, GM.PointerSize).Deref(); // pi.hProcess + this._hProcessID = pi.Deref(GM.PointerSize == 4 ? 8 : 16, 4).toBuffer().readUInt32LE(); // pi.dwProcessId + //console.log('Ready => hProcess: ' + this._hProcess._ptr + ' PID: ' + this._hProcessID); + } +} + +function LOWORD(val) { return (val & 0xFFFF); } +function HIWORD(val) { return ((val >> 16) & 0xFFFF); } +function GetEsc(op, args) { return (Buffer.from('\x1B[' + args.join(';') + op)); } +function MeshConsole(msg) { require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": JSON.stringify(msg) }); } +function TranslateLine(x, y, data, attributes) { + var i, fcolor, bcolor, rcolor, fbright, bbright, lastAttr, fc, bc, rc, fb, bb, esc = [], output = [GetEsc('H', [y, x])]; + if (typeof attributes == 'number') { attributes = [ attributes ]; } // If we get a single attribute, turn it into an array. + + for (i = 0; i < data.length; i++) { + if (lastAttr != attributes[i]) { // To boost performance, if the attribute is the same as the last one, skip this entire part. + fc = (attributes[i] & 0x0007); + fc = ((fc & 0x0001) << 2) + (fc & 0x0002) + ((fc & 0x0004) >> 2); // Foreground color + bc = (attributes[i] & 0x0070) >> 4; + bc = ((bc & 0x0001) << 2) + (bc & 0x0002) + ((bc & 0x0004) >> 2); // Background color + rc = (attributes[i] & 0x4000); // Reverse color set + fb = (attributes[i] & 0x0008) >> 3; // Bright foreground set + bb = (attributes[i] & 0x0080); // Bright background set + + if (rc != rcolor) { if (rc != 0) { esc.push(7); } else { esc.push(0); fcolor = 7; bcolor = 0; fbright = 0; bbright = 0; } rcolor = rc; } // Reverse Color + if (fc != fcolor) { esc.push(fc + 30); fcolor = fc; } // Set the foreground color if needed + if (bc != bcolor) { esc.push(bc + 40); bcolor = bc; } // Set the background color if needed + if (fb != fbright) { esc.push(2 - fb); fbright = fb; } // Set the bright foreground color if needed + if (bb != bbright) { if (bb == 0) { esc.push(bcolor + 40); } else { esc.push(bcolor + 100); bbright = bb; } } // Set bright Background color if needed + + if (esc.length > 0) { output.push(GetEsc('m', esc)); esc = []; } + lastAttr = attributes[i]; + } + output.push(Buffer.from(String.fromCharCode(data[i]))); + } + + return Buffer.concat(output); +} + +module.exports = new windows_terminal(); \ No newline at end of file diff --git a/agents-new/modules_meshcore/x/clipboard.js b/agents-new/modules_meshcore/x/clipboard.js new file mode 100644 index 00000000..341d0da5 --- /dev/null +++ b/agents-new/modules_meshcore/x/clipboard.js @@ -0,0 +1,178 @@ +/* +Copyright 2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +var promise = require('promise'); + +function nativeAddModule(name) +{ + var value = getJSModule(name); + var ret = "duk_peval_string_noresult(ctx, \"addModule('" + name + "', Buffer.from('" + Buffer.from(value).toString('base64') + "', 'base64').toString());\");"; + module.exports(ret); +} + +function lin_readtext() +{ + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + try + { + require('monitor-info') + } + catch(exc) + { + ret._rej(exc); + return (ret); + } + + var X11 = require('monitor-info')._X11; + if (!X11) + { + ret._rej('X11 required for Clipboard Manipulation'); + } + else + { + var SelectionNotify = 31; + var AnyPropertyType = 0; + var GM = require('monitor-info')._gm; + + ret._getInfoPromise = require('monitor-info').getInfo(); + ret._getInfoPromise._masterPromise = ret; + ret._getInfoPromise.then(function (mon) + { + if (mon.length > 0) + { + var white = X11.XWhitePixel(mon[0].display, mon[0].screenId).Val; + + this._masterPromise.CLIPID = X11.XInternAtom(mon[0].display, GM.CreateVariable('CLIPBOARD'), 0); + this._masterPromise.FMTID = X11.XInternAtom(mon[0].display, GM.CreateVariable('UTF8_STRING'), 0); + this._masterPromise.PROPID = X11.XInternAtom(mon[0].display, GM.CreateVariable('XSEL_DATA'), 0); + this._masterPromise.INCRID = X11.XInternAtom(mon[0].display, GM.CreateVariable('INCR'), 0); + this._masterPromise.ROOTWIN = X11.XRootWindow(mon[0].display, mon[0].screenId); + this._masterPromise.FAKEWIN = X11.XCreateSimpleWindow(mon[0].display, this._masterPromise.ROOTWIN, 0, 0, mon[0].right, 5, 0, white, white); + + X11.XSync(mon[0].display, 0); + X11.XConvertSelection(mon[0].display, this._masterPromise.CLIPID, this._masterPromise.FMTID, this._masterPromise.PROPID, this._masterPromise.FAKEWIN, 0); + X11.XSync(mon[0].display, 0); + + this._masterPromise.DescriptorEvent = require('DescriptorEvents').addDescriptor(X11.XConnectionNumber(mon[0].display).Val, { readset: true }); + this._masterPromise.DescriptorEvent._masterPromise = this._masterPromise; + this._masterPromise.DescriptorEvent._display = mon[0].display; + this._masterPromise.DescriptorEvent.on('readset', function (fd) + { + var XE = GM.CreateVariable(1024); + while (X11.XPending(this._display).Val) + { + X11.XNextEventSync(this._display, XE); + if(XE.Deref(0, 4).toBuffer().readUInt32LE() == SelectionNotify) + { + var id = GM.CreatePointer(); + var bits = GM.CreatePointer(); + var sz = GM.CreatePointer(); + var tail = GM.CreatePointer(); + var result = GM.CreatePointer(); + + X11.XGetWindowProperty(this._display, this._masterPromise.FAKEWIN, this._masterPromise.PROPID, 0, 65535, 0, AnyPropertyType, id, bits, sz, tail, result); + this._masterPromise._res(result.Deref().String); + X11.XFree(result.Deref()); + X11.XDestroyWindow(this._display, this._masterPromise.FAKEWIN); + + this.removeDescriptor(fd); + break; + } + } + }); + } + }); + } + return (ret); +} +function lin_copytext() +{ +} + +function win_readtext() +{ + var ret = ''; + var CF_TEXT = 1; + var GM = require('_GenericMarshal'); + var user32 = GM.CreateNativeProxy('user32.dll'); + var kernel32 = GM.CreateNativeProxy('kernel32.dll'); + kernel32.CreateMethod('GlobalAlloc'); + kernel32.CreateMethod('GlobalLock'); + kernel32.CreateMethod('GlobalUnlock'); + user32.CreateMethod('OpenClipboard'); + user32.CreateMethod('CloseClipboard'); + user32.CreateMethod('GetClipboardData'); + + user32.OpenClipboard(0); + var h = user32.GetClipboardData(CF_TEXT); + if(h.Val!=0) + { + var hbuffer = kernel32.GlobalLock(h); + ret = hbuffer.String; + kernel32.GlobalUnlock(h); + } + user32.CloseClipboard(); + + var p = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + p._res(ret); + return (p); +} + +function win_copytext(txt) +{ + var GMEM_MOVEABLE = 0x0002; + var CF_TEXT = 1; + + var GM = require('_GenericMarshal'); + var user32 = GM.CreateNativeProxy('user32.dll'); + var kernel32 = GM.CreateNativeProxy('kernel32.dll'); + kernel32.CreateMethod('GlobalAlloc'); + kernel32.CreateMethod('GlobalLock'); + kernel32.CreateMethod('GlobalUnlock'); + user32.CreateMethod('OpenClipboard'); + user32.CreateMethod('EmptyClipboard'); + user32.CreateMethod('CloseClipboard'); + user32.CreateMethod('SetClipboardData'); + + var h = kernel32.GlobalAlloc(GMEM_MOVEABLE, txt.length + 2); + h.autoFree(false); + var hbuffer = kernel32.GlobalLock(h); + hbuffer.autoFree(false); + var tmp = Buffer.alloc(txt.length + 1); + Buffer.from(txt).copy(tmp); + tmp.copy(hbuffer.Deref(0, txt.length + 1).toBuffer()); + kernel32.GlobalUnlock(h); + + user32.OpenClipboard(0); + user32.EmptyClipboard(); + user32.SetClipboardData(CF_TEXT, h); + user32.CloseClipboard(); +} + +switch(process.platform) +{ + case 'win32': + module.exports = win_copytext; + module.exports.read = win_readtext; + break; + case 'linux': + module.exports = lin_copytext; + module.exports.read = lin_readtext; + break; + case 'darwin': + break; +} +module.exports.nativeAddModule = nativeAddModule; \ No newline at end of file diff --git a/agents-new/modules_meshcore/x/monitor-info.js b/agents-new/modules_meshcore/x/monitor-info.js new file mode 100644 index 00000000..fe4c7454 --- /dev/null +++ b/agents-new/modules_meshcore/x/monitor-info.js @@ -0,0 +1,313 @@ +/* +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 promise = require('promise'); +var PPosition = 4; +var PSize = 8; +var _NET_WM_STATE_REMOVE = 0; // remove/unset property +var _NET_WM_STATE_ADD = 1; // add/set property +var _NET_WM_STATE_TOGGLE = 2; // toggle property +var SubstructureRedirectMask = (1 << 20); +var SubstructureNotifyMask = (1 << 19); + +function getLibInfo(libname) +{ + if (process.platform != 'linux') { throw ('Only supported on linux'); } + + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write("ldconfig -p | grep '" + libname + ".so.'\nexit\n"); + child.waitExit(); + + var v = []; + var lines = child.stdout.str.split('\n'); + for (var i in lines) { + if (lines[i]) { + var info = lines[i].split('=>'); + var pth = info[1].trim(); + var libinfo = info[0].trim().split(' '); + var lib = libinfo[0]; + var plat = libinfo[1].substring(1, libinfo[1].length - 1).split(','); + + if (lib.startsWith(libname + '.so.')) { + v.push({ lib: lib, path: pth, info: plat }); + } + } + } + return (v); +} + +function monitorinfo() +{ + this._ObjectID = 'monitor-info'; + this._gm = require('_GenericMarshal'); + + if (process.platform == 'win32') + { + this._user32 = this._gm.CreateNativeProxy('user32.dll'); + this._user32.CreateMethod('EnumDisplayMonitors'); + this._kernel32 = this._gm.CreateNativeProxy('kernel32.dll'); + this._kernel32.CreateMethod('GetLastError'); + + this.getInfo = function getInfo() + { + var info = this; + return (new promise(function (resolver, rejector) { + this._monitorinfo = { resolver: resolver, rejector: rejector, self: info, callback: info._gm.GetGenericGlobalCallback(4) }; + this._monitorinfo.callback.info = this._monitorinfo; + this._monitorinfo.dwData = info._gm.ObjectToPtr(this._monitorinfo); + + this._monitorinfo.callback.results = []; + this._monitorinfo.callback.on('GlobalCallback', function OnMonitorInfo(hmon, hdc, r, user) { + if (this.ObjectToPtr_Verify(this.info, user)) { + var rb = r.Deref(0, 16).toBuffer(); + this.results.push({ left: rb.readInt32LE(0), top: rb.readInt32LE(4), right: rb.readInt32LE(8), bottom: rb.readInt32LE(12) }); + + var r = this.info.self._gm.CreateInteger(); + r.Val = 1; + return (r); + } + }); + + if (info._user32.EnumDisplayMonitors(0, 0, this._monitorinfo.callback, this._monitorinfo.dwData).Val == 0) { + rejector('LastError=' + info._kernel32.GetLastError().Val); + return; + } + else { + resolver(this._monitorinfo.callback.results); + } + + })); + } + } + else if(process.platform == 'linux') + { + // First thing we need to do, is determine where the X11 libraries are + var askOS = false; + try + { + if (require('user-sessions').isRoot()) { askOS = true; } + } + catch (e) + { } + + if (askOS) + { + // Sufficient access rights to use ldconfig + var x11info = getLibInfo('libX11'); + var xtstinfo = getLibInfo('libXtst'); + var xextinfo = getLibInfo('libXext'); + var ix; + + for(ix in x11info) + { + try + { + this._gm.CreateNativeProxy(x11info[ix].path); + Object.defineProperty(this, 'Location_X11LIB', { value: x11info[ix].path }); + break; + } + catch(ex) + { + } + } + for (ix in xtstinfo) + { + try + { + this._gm.CreateNativeProxy(xtstinfo[ix].path); + Object.defineProperty(this, 'Location_X11TST', { value: xtstinfo[ix].path }); + break; + } + catch (ex) + { + } + } + for (ix in xextinfo) + { + try + { + this._gm.CreateNativeProxy(xextinfo[ix].path); + Object.defineProperty(this, 'Location_X11EXT', { value: xextinfo[ix].path }); + break; + } + catch (ex) + { + } + } + } + else + { + // Not enough access rights to use ldconfig, so manually search + var fs = require('fs'); + var files = fs.readdirSync('/usr/lib'); + var files2; + + for (var i in files) { + try { + if (files[i].split('libX11.so.').length > 1 && files[i].split('.').length == 3) { + Object.defineProperty(this, 'Location_X11LIB', { value: '/usr/lib/' + files[i] }); + } + if (files[i].split('libXtst.so.').length > 1 && files[i].split('.').length == 3) { + Object.defineProperty(this, 'Location_X11TST', { value: '/usr/lib/' + files[i] }); + } + if (files[i].split('libXext.so.').length > 1 && files[i].split('.').length == 3) { + Object.defineProperty(this, 'Location_X11EXT', { value: '/usr/lib/' + files[i] }); + } + + if (files[i].split('-linux-').length > 1) { + files2 = fs.readdirSync('/usr/lib/' + files[i]); + for (j in files2) { + if (files2[j].split('libX11.so.').length > 1 && files2[j].split('.').length == 3) { + Object.defineProperty(this, 'Location_X11LIB', { value: '/usr/lib/' + files[i] + '/' + files2[j] }); + } + if (files2[j].split('libXtst.so.').length > 1 && files2[j].split('.').length == 3) { + Object.defineProperty(this, 'Location_X11TST', { value: '/usr/lib/' + files[i] + '/' + files2[j] }); + } + if (files2[j].split('libXext.so.').length > 1 && files2[j].split('.').length == 3) { + Object.defineProperty(this, 'Location_X11EXT', { value: '/usr/lib/' + files[i] + '/' + files2[j] }); + } + } + } + } catch (ex) { } + } + } + Object.defineProperty(this, 'kvm_x11_support', { value: (this.Location_X11LIB && this.Location_X11TST && this.Location_X11EXT)?true:false }); + + if (this.Location_X11LIB) + { + this._X11 = this._gm.CreateNativeProxy(this.Location_X11LIB); + this._X11.CreateMethod('XChangeProperty'); + this._X11.CreateMethod('XCloseDisplay'); + this._X11.CreateMethod('XConnectionNumber'); + this._X11.CreateMethod('XConvertSelection'); + this._X11.CreateMethod('XCreateGC'); + this._X11.CreateMethod('XCreateWindow'); + this._X11.CreateMethod('XCreateSimpleWindow'); + this._X11.CreateMethod('XDefaultColormap'); + this._X11.CreateMethod('XDefaultScreen'); + this._X11.CreateMethod('XDestroyWindow'); + this._X11.CreateMethod('XDrawLine'); + this._X11.CreateMethod('XDisplayHeight'); + this._X11.CreateMethod('XDisplayWidth'); + this._X11.CreateMethod('XFetchName'); + this._X11.CreateMethod('XFlush'); + this._X11.CreateMethod('XFree'); + this._X11.CreateMethod('XCreateGC'); + this._X11.CreateMethod('XGetWindowProperty'); + this._X11.CreateMethod('XInternAtom'); + this._X11.CreateMethod('XMapWindow'); + this._X11.CreateMethod({ method: 'XNextEvent', threadDispatch: true }); + this._X11.CreateMethod({ method: 'XNextEvent', newName: 'XNextEventSync' }); + this._X11.CreateMethod('XOpenDisplay'); + this._X11.CreateMethod('XPending'); + this._X11.CreateMethod('XRootWindow'); + this._X11.CreateMethod('XSelectInput'); + this._X11.CreateMethod('XScreenCount'); + this._X11.CreateMethod('XScreenOfDisplay'); + this._X11.CreateMethod('XSelectInput'); + this._X11.CreateMethod('XSendEvent'); + this._X11.CreateMethod('XSetForeground'); + this._X11.CreateMethod('XSetFunction'); + this._X11.CreateMethod('XSetLineAttributes'); + this._X11.CreateMethod('XSetNormalHints'); + this._X11.CreateMethod('XSetSubwindowMode'); + this._X11.CreateMethod('XSync'); + this._X11.CreateMethod('XBlackPixel'); + this._X11.CreateMethod('XWhitePixel'); + } + + this.isUnity = function isUnity() + { + return (process.env['XDG_CURRENT_DESKTOP'] == 'Unity'); + } + + this.unDecorateWindow = function unDecorateWindow(display, window) + { + var MwmHints = this._gm.CreateVariable(40); + var mwmHintsProperty = this._X11.XInternAtom(display, this._gm.CreateVariable('_MOTIF_WM_HINTS'), 0); + MwmHints.Deref(0, 4).toBuffer().writeUInt32LE(1 << 1); + this._X11.XChangeProperty(display, window, mwmHintsProperty, mwmHintsProperty, 32, 0, MwmHints, 5); + } + this.setWindowSizeHints = function setWindowSizeHints(display, window, x, y, width, height) + { + var sizeHints = this._gm.CreateVariable(80); + sizeHints.Deref(0, 4).toBuffer().writeUInt32LE(PPosition | PSize); + sizeHints.Deref(8, 4).toBuffer().writeUInt32LE(x); + sizeHints.Deref(12, 4).toBuffer().writeUInt32LE(y); + sizeHints.Deref(16, 4).toBuffer().writeUInt32LE(width); + sizeHints.Deref(20, 4).toBuffer().writeUInt32LE(height); + this._X11.XSetNormalHints(display, window, sizeHints); + } + this.setAlwaysOnTop = function setAlwaysOnTop(display, rootWindow, window) + { + var wmNetWmState = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE'), 1); + var wmStateAbove = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE_ABOVE'), 1); + + var xclient = this._gm.CreateVariable(96); + xclient.Deref(0, 4).toBuffer().writeUInt32LE(33); // ClientMessage type + xclient.Deref(48, 4).toBuffer().writeUInt32LE(32); // Format 32 + wmNetWmState.pointerBuffer().copy(xclient.Deref(40, 8).toBuffer()); // message_type + xclient.Deref(56, 8).toBuffer().writeUInt32LE(_NET_WM_STATE_ADD); // data.l[0] + wmStateAbove.pointerBuffer().copy(xclient.Deref(64, 8).toBuffer()); // data.l[1] + + window.pointerBuffer().copy(xclient.Deref(32, 8).toBuffer()); // window + this._X11.XSendEvent(display, rootWindow, 0, SubstructureRedirectMask | SubstructureNotifyMask, xclient); + } + this.hideWindowIcon = function hideWindowIcon(display, rootWindow, window) + { + var wmNetWmState = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE'), 1); + var wmStateSkip = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE_SKIP_TASKBAR'), 1); + + var xclient = this._gm.CreateVariable(96); + xclient.Deref(0, 4).toBuffer().writeUInt32LE(33); // ClientMessage type + xclient.Deref(48, 4).toBuffer().writeUInt32LE(32); // Format 32 + wmNetWmState.pointerBuffer().copy(xclient.Deref(40, 8).toBuffer()); // message_type + xclient.Deref(56, 8).toBuffer().writeUInt32LE(_NET_WM_STATE_ADD); // data.l[0] + wmStateSkip.pointerBuffer().copy(xclient.Deref(64, 8).toBuffer()); // data.l[1] + + window.pointerBuffer().copy(xclient.Deref(32, 8).toBuffer()); // window + this._X11.XSendEvent(display, rootWindow, 0, SubstructureRedirectMask | SubstructureNotifyMask, xclient); + } + + this.getInfo = function getInfo() + { + var info = this; + return (new promise(function (resolver, rejector) + { + var display = info._X11.XOpenDisplay(info._gm.CreateVariable(':0')); + var screenCount = info._X11.XScreenCount(display).Val; + var ret = []; + for(var i=0;i process information. + this.getProcesses = function getProcesses(callback) + { + switch(process.platform) + { + default: + throw ('Enumerating processes on ' + process.platform + ' not supported'); + break; + case 'win32': // Windows processes + 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)] = { pid: 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': // Linux processes + 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) { + if (tokenList[key.PID]) { retVal[tokenList[key.PID]] = { pid: 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; + case 'darwin': + var promise = require('promise'); + var p = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + p.pm = this; + p.callback = callback; + p.args = []; + for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); } + p.child = this._childProcess.execFile("/bin/ps", ["ps", "-xa"]); + p.child.promise = p; + p.child.stdout.ps = ''; + p.child.stdout.on('data', function (chunk) { this.ps += chunk.toString(); }); + p.child.on('exit', function () + { + var lines = this.stdout.ps.split('\n'); + var pidX = lines[0].split('PID')[0].length + 3; + var cmdX = lines[0].split('CMD')[0].length; + var ret = {}; + for (var i = 1; i < lines.length; ++i) + { + if (lines[i].length > 0) + { + ret[lines[i].substring(0, pidX).trim()] = { pid: lines[i].substring(0, pidX).trim(), cmd: lines[i].substring(cmdX) }; + } + } + this.promise._res(ret); + }); + p.then(function (ps) + { + this.args.unshift(ps); + this.callback.apply(this.pm, this.args); + }); + break; + } + }; + + // Get information about a specific process on Linux + 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'); + 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; + } + }; +} + +module.exports = new processManager(); \ No newline at end of file diff --git a/agents-new/modules_meshcore/x/service-manager.js b/agents-new/modules_meshcore/x/service-manager.js new file mode 100644 index 00000000..168fc96e --- /dev/null +++ b/agents-new/modules_meshcore/x/service-manager.js @@ -0,0 +1,497 @@ +/* +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 parseServiceStatus(token) +{ + var j = {}; + var serviceType = token.Deref(0, 4).IntVal; + j.isFileSystemDriver = ((serviceType & 0x00000002) == 0x00000002); + j.isKernelDriver = ((serviceType & 0x00000001) == 0x00000001); + j.isSharedProcess = ((serviceType & 0x00000020) == 0x00000020); + j.isOwnProcess = ((serviceType & 0x00000010) == 0x00000010); + j.isInteractive = ((serviceType & 0x00000100) == 0x00000100); + switch (token.Deref((1 * 4), 4).toBuffer().readUInt32LE()) + { + case 0x00000005: + j.state = 'CONTINUE_PENDING'; + break; + case 0x00000006: + j.state = 'PAUSE_PENDING'; + break; + case 0x00000007: + j.state = 'PAUSED'; + break; + case 0x00000004: + j.state = 'RUNNING'; + break; + case 0x00000002: + j.state = 'START_PENDING'; + break; + case 0x00000003: + j.state = 'STOP_PENDING'; + break; + case 0x00000001: + j.state = 'STOPPED'; + break; + } + var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE(); + j.controlsAccepted = []; + if ((controlsAccepted & 0x00000010) == 0x00000010) + { + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDADD'); + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDREMOVE'); + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDENABLE'); + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDDISABLE'); + } + if ((controlsAccepted & 0x00000008) == 0x00000008) { j.controlsAccepted.push('SERVICE_CONTROL_PARAMCHANGE'); } + if ((controlsAccepted & 0x00000002) == 0x00000002) { j.controlsAccepted.push('SERVICE_CONTROL_PAUSE'); j.controlsAccepted.push('SERVICE_CONTROL_CONTINUE'); } + if ((controlsAccepted & 0x00000100) == 0x00000100) { j.controlsAccepted.push('SERVICE_CONTROL_PRESHUTDOWN'); } + if ((controlsAccepted & 0x00000004) == 0x00000004) { j.controlsAccepted.push('SERVICE_CONTROL_SHUTDOWN'); } + if ((controlsAccepted & 0x00000001) == 0x00000001) { j.controlsAccepted.push('SERVICE_CONTROL_STOP'); } + if ((controlsAccepted & 0x00000020) == 0x00000020) { j.controlsAccepted.push('SERVICE_CONTROL_HARDWAREPROFILECHANGE'); } + if ((controlsAccepted & 0x00000040) == 0x00000040) { j.controlsAccepted.push('SERVICE_CONTROL_POWEREVENT'); } + if ((controlsAccepted & 0x00000080) == 0x00000080) { j.controlsAccepted.push('SERVICE_CONTROL_SESSIONCHANGE'); } + j.pid = token.Deref((7 * 4), 4).toBuffer().readUInt32LE(); + return (j); +} + +function serviceManager() +{ + this._ObjectID = 'service-manager'; + if (process.platform == 'win32') + { + this.GM = require('_GenericMarshal'); + this.proxy = this.GM.CreateNativeProxy('Advapi32.dll'); + this.proxy.CreateMethod('OpenSCManagerA'); + this.proxy.CreateMethod('EnumServicesStatusExA'); + this.proxy.CreateMethod('OpenServiceA'); + this.proxy.CreateMethod('QueryServiceStatusEx'); + this.proxy.CreateMethod('ControlService'); + this.proxy.CreateMethod('StartServiceA'); + this.proxy.CreateMethod('CloseServiceHandle'); + this.proxy.CreateMethod('CreateServiceA'); + this.proxy.CreateMethod('ChangeServiceConfig2A'); + this.proxy.CreateMethod('DeleteService'); + this.proxy.CreateMethod('AllocateAndInitializeSid'); + this.proxy.CreateMethod('CheckTokenMembership'); + this.proxy.CreateMethod('FreeSid'); + + this.proxy2 = this.GM.CreateNativeProxy('Kernel32.dll'); + this.proxy2.CreateMethod('GetLastError'); + + this.isAdmin = function isAdmin() { + var NTAuthority = this.GM.CreateVariable(6); + NTAuthority.toBuffer().writeInt8(5, 5); + var AdministratorsGroup = this.GM.CreatePointer(); + var admin = false; + + if (this.proxy.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0) + { + var member = this.GM.CreateInteger(); + if (this.proxy.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0) + { + if (member.toBuffer().readUInt32LE() != 0) { admin = true; } + } + this.proxy.FreeSid(AdministratorsGroup.Deref()); + } + return admin; + }; + this.getProgramFolder = function getProgramFolder() + { + if (require('os').arch() == 'x64') + { + // 64 bit Windows + if (this.GM.PointerSize == 4) + { + return process.env['ProgramFiles(x86)']; // 32 Bit App + } + return process.env['ProgramFiles']; // 64 bit App + } + + // 32 bit Windows + return process.env['ProgramFiles']; + }; + this.getServiceFolder = function getServiceFolder() { return this.getProgramFolder() + '\\mesh'; }; + + this.enumerateService = function () { + var machineName = this.GM.CreatePointer(); + var dbName = this.GM.CreatePointer(); + var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0001 | 0x0004); + + var bytesNeeded = this.GM.CreatePointer(); + var servicesReturned = this.GM.CreatePointer(); + var resumeHandle = this.GM.CreatePointer(); + //var services = this.proxy.CreateVariable(262144); + var success = this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, 0x00, 0x00, bytesNeeded, servicesReturned, resumeHandle, 0x00); + if (bytesNeeded.IntVal <= 0) { + throw ('error enumerating services'); + } + var sz = bytesNeeded.IntVal; + var services = this.GM.CreateVariable(sz); + this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, services, sz, bytesNeeded, servicesReturned, resumeHandle, 0x00); + console.log("servicesReturned", servicesReturned.IntVal); + + var ptrSize = dbName._size; + var blockSize = 36 + (2 * ptrSize); + blockSize += ((ptrSize - (blockSize % ptrSize)) % ptrSize); + var retVal = []; + for (var i = 0; i < servicesReturned.IntVal; ++i) { + var token = services.Deref(i * blockSize, blockSize); + var j = {}; + j.name = token.Deref(0, ptrSize).Deref().String; + j.displayName = token.Deref(ptrSize, ptrSize).Deref().String; + j.status = parseServiceStatus(token.Deref(2 * ptrSize, 36)); + retVal.push(j); + } + this.proxy.CloseServiceHandle(handle); + return (retVal); + } + this.getService = function (name) { + var serviceName = this.GM.CreateVariable(name); + var ptr = this.GM.CreatePointer(); + var bytesNeeded = this.GM.CreateVariable(ptr._size); + var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0001 | 0x0004 | 0x0020 | 0x0010); + if (handle.Val == 0) { throw ('could not open ServiceManager'); } + var h = this.proxy.OpenServiceA(handle, serviceName, 0x0004 | 0x0020 | 0x0010 | 0x00010000); + if (h.Val != 0) { + var success = this.proxy.QueryServiceStatusEx(h, 0, 0, 0, bytesNeeded); + var status = this.GM.CreateVariable(bytesNeeded.toBuffer().readUInt32LE()); + success = this.proxy.QueryServiceStatusEx(h, 0, status, status._size, bytesNeeded); + if (success != 0) { + retVal = {}; + retVal.status = parseServiceStatus(status); + retVal._scm = handle; + retVal._service = h; + retVal._GM = this.GM; + retVal._proxy = this.proxy; + require('events').inherits(retVal); + retVal.on('~', function () { this._proxy.CloseServiceHandle(this); this._proxy.CloseServiceHandle(this._scm); }); + retVal.name = name; + retVal.stop = function () { + if (this.status.state == 'RUNNING') { + var newstate = this._GM.CreateVariable(36); + var success = this._proxy.ControlService(this._service, 0x00000001, newstate); + if (success == 0) { + throw (this.name + '.stop() failed'); + } + } + else { + throw ('cannot call ' + this.name + '.stop(), when current state is: ' + this.status.state); + } + } + retVal.start = function () { + if (this.status.state == 'STOPPED') { + var success = this._proxy.StartServiceA(this._service, 0, 0); + if (success == 0) { + throw (this.name + '.start() failed'); + } + } + else { + throw ('cannot call ' + this.name + '.start(), when current state is: ' + this.status.state); + } + } + return (retVal); + } + else { + + } + } + + this.proxy.CloseServiceHandle(handle); + throw ('could not find service: ' + name); + } + } + else + { + this.isAdmin = function isAdmin() + { + return (require('user-sessions').isRoot()); + } + } + this.installService = function installService(options) + { + if (process.platform == 'win32') + { + if (!this.isAdmin()) { throw ('Installing as Service, requires admin'); } + + // Before we start, we need to copy the binary to the right place + var folder = this.getServiceFolder(); + if (!require('fs').existsSync(folder)) { require('fs').mkdirSync(folder); } + require('fs').copyFileSync(options.servicePath, folder + '\\' + options.name + '.exe'); + options.servicePath = folder + '\\' + options.name + '.exe'; + + var servicePath = this.GM.CreateVariable('"' + options.servicePath + '"'); + var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0002); + if (handle.Val == 0) { throw ('error opening SCManager'); } + var serviceName = this.GM.CreateVariable(options.name); + var displayName = this.GM.CreateVariable(options.name); + var allAccess = 0x000F01FF; + var serviceType; + + + switch (options.startType) { + case 'BOOT_START': + serviceType = 0x00; + break; + case 'SYSTEM_START': + serviceType = 0x01; + break; + case 'AUTO_START': + serviceType = 0x02; + break; + case 'DEMAND_START': + serviceType = 0x03; + break; + default: + serviceType = 0x04; // Disabled + break; + } + + var h = this.proxy.CreateServiceA(handle, serviceName, displayName, allAccess, 0x10 | 0x100, serviceType, 0, servicePath, 0, 0, 0, 0, 0); + if (h.Val == 0) { this.proxy.CloseServiceHandle(handle); throw ('Error Creating Service: ' + this.proxy2.GetLastError().Val); } + if (options.description) { + console.log(options.description); + + var dscPtr = this.GM.CreatePointer(); + dscPtr.Val = this.GM.CreateVariable(options.description); + + if (this.proxy.ChangeServiceConfig2A(h, 1, dscPtr) == 0) { + this.proxy.CloseServiceHandle(h); + this.proxy.CloseServiceHandle(handle); + throw ('Unable to set description'); + } + } + this.proxy.CloseServiceHandle(h); + this.proxy.CloseServiceHandle(handle); + return (this.getService(options.name)); + } + if(process.platform == 'linux') + { + if (!this.isAdmin()) { throw ('Installing as Service, requires root'); } + + switch (this.getServiceType()) + { + case 'init': + require('fs').copyFileSync(options.servicePath, '/etc/init.d/' + options.name); + console.log('copying ' + options.servicePath); + var m = require('fs').statSync('/etc/init.d/' + options.name).mode; + m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP); + require('fs').chmodSync('/etc/init.d/' + options.name, m); + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); + this._update._moduleName = options.name; + this._update.stdout.on('data', function (chunk) { }); + this._update.stdin.write('update-rc.d ' + options.name + ' defaults\n'); + this._update.stdin.write('exit\n'); + //update-rc.d meshagent defaults # creates symlinks for rc.d + //service meshagent start + + this._update.waitExit(); + + break; + case 'systemd': + var serviceDescription = options.description ? options.description : 'MeshCentral Agent'; + if (!require('fs').existsSync('/usr/local/mesh')) { require('fs').mkdirSync('/usr/local/mesh'); } + require('fs').copyFileSync(options.servicePath, '/usr/local/mesh/' + options.name); + var m = require('fs').statSync('/usr/local/mesh/' + options.name).mode; + m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP); + require('fs').chmodSync('/usr/local/mesh/' + options.name, m); + require('fs').writeFileSync('/lib/systemd/system/' + options.name + '.service', '[Unit]\nDescription=' + serviceDescription + '\n[Service]\nExecStart=/usr/local/mesh/' + options.name + '\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=' + options.name + '.service\n', { flags: 'w' }); + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); + this._update._moduleName = options.name; + this._update.stdout.on('data', function (chunk) { }); + this._update.stdin.write('systemctl enable ' + options.name + '.service\n'); + this._update.stdin.write('exit\n'); + this._update.waitExit(); + break; + default: // unknown platform service type + break; + } + } + if(process.platform == 'darwin') + { + if (!this.isAdmin()) { throw ('Installing as Service, requires root'); } + + // Mac OS + var stdoutpath = (options.stdout ? ('StandardOutPath\n' + options.stdout + '') : ''); + var autoStart = (options.startType == 'AUTO_START' ? '' : ''); + var params = ' ProgramArguments\n'; + params += ' \n'; + params += (' /usr/local/mesh_services/' + options.name + '/' + options.name + '\n'); + if(options.parameters) + { + for(var itm in options.parameters) + { + params += (' ' + options.parameters[itm] + '\n'); + } + } + params += ' \n'; + + var plist = '\n'; + plist += '\n'; + plist += '\n'; + plist += ' \n'; + plist += ' Label\n'; + plist += (' ' + options.name + '\n'); + plist += (params + '\n'); + plist += ' WorkingDirectory\n'; + plist += (' /usr/local/mesh_services/' + options.name + '\n'); + plist += (stdoutpath + '\n'); + plist += ' RunAtLoad\n'; + plist += (autoStart + '\n'); + plist += ' \n'; + plist += ''; + + if (!require('fs').existsSync('/usr/local/mesh_services')) { require('fs').mkdirSync('/usr/local/mesh_services'); } + if (!require('fs').existsSync('/Library/LaunchDaemons/' + options.name + '.plist')) + { + if (!require('fs').existsSync('/usr/local/mesh_services/' + options.name)) { require('fs').mkdirSync('/usr/local/mesh_services/' + options.name); } + if (options.binary) + { + require('fs').writeFileSync('/usr/local/mesh_services/' + options.name + '/' + options.name, options.binary); + } + else + { + require('fs').copyFileSync(options.servicePath, '/usr/local/mesh_services/' + options.name + '/' + options.name); + } + require('fs').writeFileSync('/Library/LaunchDaemons/' + options.name + '.plist', plist); + var m = require('fs').statSync('/usr/local/mesh_services/' + options.name + '/' + options.name).mode; + m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP); + require('fs').chmodSync('/usr/local/mesh_services/' + options.name + '/' + options.name, m); + } + else + { + throw ('Service: ' + options.name + ' already exists'); + } + } + } + this.uninstallService = function uninstallService(name) + { + if (!this.isAdmin()) { throw ('Uninstalling a service, requires admin'); } + + if (typeof (name) == 'object') { name = name.name; } + if (process.platform == 'win32') + { + var service = this.getService(name); + if (service.status.state == undefined || service.status.state == 'STOPPED') + { + if (this.proxy.DeleteService(service._service) == 0) + { + throw ('Uninstall Service for: ' + name + ', failed with error: ' + this.proxy2.GetLastError()); + } + else + { + try + { + require('fs').unlinkSync(this.getServiceFolder() + '\\' + name + '.exe'); + } + catch(e) + { + } + } + } + else + { + throw ('Cannot uninstall service: ' + name + ', because it is: ' + service.status.state); + } + } + else if(process.platform == 'linux') + { + switch (this.getServiceType()) + { + case 'init': + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); + this._update.stdout.on('data', function (chunk) { }); + this._update.stdin.write('service ' + name + ' stop\n'); + this._update.stdin.write('update-rc.d -f ' + name + ' remove\n'); + this._update.stdin.write('exit\n'); + this._update.waitExit(); + try + { + require('fs').unlinkSync('/etc/init.d/' + name); + console.log(name + ' uninstalled'); + + } + catch (e) + { + console.log(name + ' could not be uninstalled', e) + } + break; + case 'systemd': + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); + this._update.stdout.on('data', function (chunk) { }); + this._update.stdin.write('systemctl stop ' + name + '.service\n'); + this._update.stdin.write('systemctl disable ' + name + '.service\n'); + this._update.stdin.write('exit\n'); + this._update.waitExit(); + try + { + require('fs').unlinkSync('/usr/local/mesh/' + name); + require('fs').unlinkSync('/lib/systemd/system/' + name + '.service'); + console.log(name + ' uninstalled'); + } + catch (e) + { + console.log(name + ' could not be uninstalled', e) + } + break; + default: // unknown platform service type + break; + } + } + else if(process.platform == 'darwin') + { + if (require('fs').existsSync('/Library/LaunchDaemons/' + name + '.plist')) + { + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.on('data', function (chunk) { }); + child.stdin.write('launchctl stop ' + name + '\n'); + child.stdin.write('launchctl unload /Library/LaunchDaemons/' + name + '.plist\n'); + child.stdin.write('exit\n'); + child.waitExit(); + + try + { + require('fs').unlinkSync('/usr/local/mesh_services/' + name + '/' + name); + require('fs').unlinkSync('/Library/LaunchDaemons/' + name + '.plist'); + } + catch(e) + { + throw ('Error uninstalling service: ' + name + ' => ' + e); + } + + try + { + require('fs').rmdirSync('/usr/local/mesh_services/' + name); + } + catch(e) + {} + } + else + { + throw ('Service: ' + name + ' does not exist'); + } + } + } + if(process.platform == 'linux') + { + this.getServiceType = function getServiceType() + { + return (require('process-manager').getProcessInfo(1).Name); + }; + } +} + +module.exports = serviceManager; \ No newline at end of file diff --git a/agents-new/modules_meshcore/x/user-sessions.js b/agents-new/modules_meshcore/x/user-sessions.js new file mode 100644 index 00000000..1e245dfd --- /dev/null +++ b/agents-new/modules_meshcore/x/user-sessions.js @@ -0,0 +1,750 @@ +/* +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 NOTIFY_FOR_THIS_SESSION = 0; +var NOTIFY_FOR_ALL_SESSIONS = 1; +var WM_WTSSESSION_CHANGE = 0x02B1; +var WM_POWERBROADCAST = 0x218; +var PBT_POWERSETTINGCHANGE = 0x8013; +var PBT_APMSUSPEND = 0x4; +var PBT_APMRESUMESUSPEND = 0x7; +var PBT_APMRESUMEAUTOMATIC = 0x12; +var PBT_APMPOWERSTATUSCHANGE = 0xA; + +var WTS_CONSOLE_CONNECT = (0x1); +var WTS_CONSOLE_DISCONNECT = (0x2); +var WTS_REMOTE_CONNECT = (0x3); +var WTS_REMOTE_DISCONNECT = (0x4); +var WTS_SESSION_LOGON = (0x5); +var WTS_SESSION_LOGOFF = (0x6); +var WTS_SESSION_LOCK = (0x7); +var WTS_SESSION_UNLOCK = (0x8); +var WTS_SESSION_REMOTE_CONTROL = (0x9); +var WTS_SESSION_CREATE = (0xA); +var WTS_SESSION_TERMINATE = (0xB); + +var GUID_ACDC_POWER_SOURCE; +var GUID_BATTERY_PERCENTAGE_REMAINING; +var GUID_CONSOLE_DISPLAY_STATE; + +function UserSessions() +{ + this._ObjectID = 'user-sessions'; + require('events').EventEmitter.call(this, true) + .createEvent('changed') + .createEvent('locked') + .createEvent('unlocked'); + + 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); + }; + try + { + this.Current(p.__handler); + } + catch(e) + { + p.__rejector(e); + } + p.parent = this; + return (p); + } + + if (process.platform == 'win32') + { + this._serviceHooked = false; + this._marshal = require('_GenericMarshal'); + this._kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll'); + this._kernel32.CreateMethod('GetLastError'); + + try + { + this._wts = this._marshal.CreateNativeProxy('Wtsapi32.dll'); + this._wts.CreateMethod('WTSEnumerateSessionsA'); + this._wts.CreateMethod('WTSQuerySessionInformationA'); + this._wts.CreateMethod('WTSRegisterSessionNotification'); + this._wts.CreateMethod('WTSUnRegisterSessionNotification'); + this._wts.CreateMethod('WTSFreeMemory'); + } + catch(exc) + { + } + + this._advapi = this._marshal.CreateNativeProxy('Advapi32.dll'); + this._advapi.CreateMethod('AllocateAndInitializeSid'); + this._advapi.CreateMethod('CheckTokenMembership'); + this._advapi.CreateMethod('FreeSid'); + + this._user32 = this._marshal.CreateNativeProxy('user32.dll'); + this._user32.CreateMethod({ method: 'RegisterPowerSettingNotification', threadDispatch: 1}); + this._user32.CreateMethod('UnregisterPowerSettingNotification'); + this._rpcrt = this._marshal.CreateNativeProxy('Rpcrt4.dll'); + this._rpcrt.CreateMethod('UuidFromStringA'); + this._rpcrt.StringToUUID = function StringToUUID(guid) + { + var retVal = StringToUUID.us._marshal.CreateVariable(16); + if(StringToUUID.us._rpcrt.UuidFromStringA(StringToUUID.us._marshal.CreateVariable(guid), retVal).Val == 0) + { + return (retVal); + } + else + { + throw ('Could not convert string to UUID'); + } + } + this._rpcrt.StringToUUID.us = this; + + GUID_ACDC_POWER_SOURCE = this._rpcrt.StringToUUID('5d3e9a59-e9D5-4b00-a6bd-ff34ff516548'); + GUID_BATTERY_PERCENTAGE_REMAINING = this._rpcrt.StringToUUID('a7ad8041-b45a-4cae-87a3-eecbb468a9e1'); + GUID_CONSOLE_DISPLAY_STATE = this._rpcrt.StringToUUID('6fe69556-704a-47a0-8f24-c28d936fda47'); + + 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.isRoot = function isRoot() + { + var NTAuthority = this._marshal.CreateVariable(6); + NTAuthority.toBuffer().writeInt8(5, 5); + + var AdministratorsGroup = this._marshal.CreatePointer(); + var admin = false; + + if (this._advapi.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0) + { + var member = this._marshal.CreateInteger(); + if (this._advapi.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0) + { + if (member.toBuffer().readUInt32LE() != 0) { admin = true; } + } + this._advapi.FreeSid(AdministratorsGroup.Deref()); + } + return admin; + } + + 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(cb) + { + 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, 'Active', { value: showActiveOnly(retVal) }); + if (cb) { cb(retVal); } + return (retVal); + }; + + + // We need to spin up a message pump, and fetch a window handle + var message_pump = require('win-message-pump'); + this._messagepump = new message_pump({ filter: WM_WTSSESSION_CHANGE }); this._messagepump.parent = this; + this._messagepump.on('exit', function (code) { this.parent._wts.WTSUnRegisterSessionNotification(this.parent.hwnd); }); + this._messagepump.on('hwnd', function (h) + { + this.parent.hwnd = h; + + // We need to yield, and do this in the next event loop pass, becuase we don't want to call 'RegisterPowerSettingNotification' + // from the messagepump 'thread', because we are actually on the microstack thread, such that the message pump thread, is holding + // on a semaphore for us to return. If we call now, we may deadlock on Windows 7, becuase it will try to notify immediately + this.immediate = setImmediate(function (self) + { + // Now that we have a window handle, we can register it to receive Windows Messages + if (self.parent._wts) { self.parent._wts.WTSRegisterSessionNotification(self.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS); } + self.parent._user32.ACDC_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0); + self.parent._user32.BATT_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0); + self.parent._user32.DISP_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0); + //console.log(self.parent._user32.ACDC_H.Val, self.parent._user32.BATT_H.Val, self.parent._user32.DISP_H.Val); + }, this); + }); + this._messagepump.on('message', function (msg) + { + switch(msg.message) + { + case WM_WTSSESSION_CHANGE: + switch(msg.wparam) + { + case WTS_SESSION_LOCK: + this.parent.enumerateUsers().then(function (users) + { + if (users[msg.lparam]) { this.parent.emit('locked', users[msg.lparam]); } + }); + break; + case WTS_SESSION_UNLOCK: + this.parent.enumerateUsers().then(function (users) + { + if (users[msg.lparam]) { this.parent.emit('unlocked', users[msg.lparam]); } + }); + break; + case WTS_SESSION_LOGON: + case WTS_SESSION_LOGOFF: + this.parent.emit('changed'); + break; + } + break; + case WM_POWERBROADCAST: + switch(msg.wparam) + { + default: + console.log('WM_POWERBROADCAST [UNKNOWN wparam]: ' + msg.wparam); + break; + case PBT_APMSUSPEND: + require('power-monitor').emit('sx', 'SLEEP'); + break; + case PBT_APMRESUMEAUTOMATIC: + require('power-monitor').emit('sx', 'RESUME_NON_INTERACTIVE'); + break; + case PBT_APMRESUMESUSPEND: + require('power-monitor').emit('sx', 'RESUME_INTERACTIVE'); + break; + case PBT_APMPOWERSTATUSCHANGE: + require('power-monitor').emit('changed'); + break; + case PBT_POWERSETTINGCHANGE: + var lparam = this.parent._marshal.CreatePointer(Buffer.from(msg.lparam_hex, 'hex')); + var data = lparam.Deref(20, lparam.Deref(16, 4).toBuffer().readUInt32LE(0)).toBuffer(); + switch(lparam.Deref(0, 16).toBuffer().toString('hex')) + { + case GUID_ACDC_POWER_SOURCE.Deref(0, 16).toBuffer().toString('hex'): + switch(data.readUInt32LE(0)) + { + case 0: + require('power-monitor').emit('acdc', 'AC'); + break; + case 1: + require('power-monitor').emit('acdc', 'BATTERY'); + break; + case 2: + require('power-monitor').emit('acdc', 'HOT'); + break; + } + break; + case GUID_BATTERY_PERCENTAGE_REMAINING.Deref(0, 16).toBuffer().toString('hex'): + require('power-monitor').emit('batteryLevel', data.readUInt32LE(0)); + break; + case GUID_CONSOLE_DISPLAY_STATE.Deref(0, 16).toBuffer().toString('hex'): + switch(data.readUInt32LE(0)) + { + case 0: + require('power-monitor').emit('display', 'OFF'); + break; + case 1: + require('power-monitor').emit('display', 'ON'); + break; + case 2: + require('power-monitor').emit('display', 'DIMMED'); + break; + } + break; + } + break; + } + break; + default: + break; + } + }); + } + else if(process.platform == 'linux') + { + var dbus = require('linux-dbus'); + this._linuxWatcher = require('fs').watch('/var/run/utmp'); + this._linuxWatcher.user_session = this; + this._linuxWatcher.on('change', function (a, b) + { + this.user_session.emit('changed'); + }); + this._users = function _users() + { + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('awk -F: \'($3 >= 0) {printf "%s:%s\\n", $1, $3}\' /etc/passwd\nexit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + var ret = {}, tokens; + for (var ln in lines) + { + tokens = lines[ln].split(':'); + if (tokens[0]) { ret[tokens[0]] = tokens[1]; } + } + return (ret); + } + this._uids = function _uids() { + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('awk -F: \'($3 >= 0) {printf "%s:%s\\n", $1, $3}\' /etc/passwd\nexit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + var ret = {}, tokens; + for (var ln in lines) { + tokens = lines[ln].split(':'); + if (tokens[0]) { ret[tokens[1]] = tokens[0]; } + } + return (ret); + } + 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 = {}; + 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.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]) + { + 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(); + + + 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(); }); + + return (retVal); + } + this._recheckLoggedInUsers = function _recheckLoggedInUsers() + { + this.enumerateUsers().then(function (u) + { + + if (u.Active.length > 0) + { + // There is already a user logged in, so we can monitor DBUS for lock/unlock + if (this.parent._linux_lock_watcher != null && this.parent._linux_lock_watcher.uid != u.Active[0].uid) + { + delete this.parent._linux_lock_watcher; + } + this.parent._linux_lock_watcher = new dbus(process.env['XDG_CURRENT_DESKTOP'] == 'Unity' ? 'com.ubuntu.Upstart0_6' : 'org.gnome.ScreenSaver', u.Active[0].uid); + this.parent._linux_lock_watcher.user_session = this.parent; + this.parent._linux_lock_watcher.on('signal', function (s) + { + var p = this.user_session.enumerateUsers(); + p.signalData = s.data[0]; + p.then(function (u) + { + switch (this.signalData) + { + case true: + case 'desktop-lock': + this.parent.emit('locked', u.Active[0]); + break; + case false: + case 'desktop-unlock': + this.parent.emit('unlocked', u.Active[0]); + break; + } + }); + }); + } + else if (this.parent._linux_lock_watcher != null) + { + delete this.parent._linux_lock_watcher; + } + }); + + }; + this.on('changed', this._recheckLoggedInUsers); // For linux Lock/Unlock monitoring, we need to watch for LogOn/LogOff, and keep track of the UID. + + + // First step, is to see if there is a user logged in: + this._recheckLoggedInUsers(); + } + else if(process.platform == 'darwin') + { + this._users = function () + { + var child = require('child_process').execFile('/usr/bin/dscl', ['dscl', '.', 'list', '/Users', 'UniqueID']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('exit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + var tokens, i; + var users = {}; + + for (i = 0; i < lines.length; ++i) { + tokens = lines[i].split(' '); + if (tokens[0]) { users[tokens[0]] = tokens[tokens.length - 1]; } + } + + return (users); + } + this._uids = function () { + var child = require('child_process').execFile('/usr/bin/dscl', ['dscl', '.', 'list', '/Users', 'UniqueID']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('exit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + var tokens, i; + var users = {}; + + for (i = 0; i < lines.length; ++i) { + tokens = lines[i].split(' '); + if (tokens[0]) { users[tokens[tokens.length - 1]] = tokens[0]; } + } + + return (users); + } + this._idTable = function() + { + var table = {}; + var child = require('child_process').execFile('/usr/bin/id', ['id']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.waitExit(); + + var lines = child.stdout.str.split('\n')[0].split(' '); + for (var i = 0; i < lines.length; ++i) { + var types = lines[i].split('='); + var tokens = types[1].split(','); + table[types[0]] = {}; + + for (var j in tokens) { + var idarr = tokens[j].split('('); + var id = idarr[0]; + var name = idarr[1].substring(0, idarr[1].length - 1).trim(); + table[types[0]][name] = id; + table[types[0]][id] = name; + } + } + return (table); + } + this.Current = function (cb) + { + var users = {}; + var table = this._idTable(); + var child = require('child_process').execFile('/usr/bin/last', ['last']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + for (var i = 0; i < lines.length && lines[i].length > 0; ++i) + { + if (!users[lines[i].split(' ')[0]]) + { + try + { + users[lines[i].split(' ')[0]] = { Username: lines[i].split(' ')[0], State: lines[i].split('still logged in').length > 1 ? 'Active' : 'Inactive', uid: table.uid[lines[i].split(' ')[0]] }; + } + catch(e) + {} + } + else + { + if(users[lines[i].split(' ')[0]].State != 'Active' && lines[i].split('still logged in').length > 1) + { + users[lines[i].split(' ')[0]].State = 'Active'; + } + } + } + + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) }); + if (cb) { cb.call(this, users); } + } + } + + if(process.platform == 'linux' || process.platform == 'darwin') + { + this._self = function _self() + { + var child = require('child_process').execFile('/usr/bin/id', ['id', '-u']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.waitExit(); + return (parseInt(child.stdout.str)); + } + this.isRoot = function isRoot() + { + return (this._self() == 0); + } + this.consoleUid = function consoleUid() + { + var checkstr = process.platform == 'darwin' ? 'console' : ((process.env['DISPLAY'])?process.env['DISPLAY']:':0') + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('who\nexit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + var tokens, i, j; + for (i in lines) + { + tokens = lines[i].split(' '); + for (j = 1; j < tokens.length; ++j) + { + if (tokens[j].length > 0) + { + return (parseInt(this._users()[tokens[0]])); + } + } + } + + throw ('nobody logged into console'); + } + } + + +} +function showActiveOnly(source) +{ + var retVal = []; + var unique = {}; + var usernames = []; + var tmp; + + for (var i in source) + { + if (source[i].State == 'Active') + { + retVal.push(source[i]); + tmp = (source[i].Domain ? (source[i].Domain + '\\') : '') + source[i].Username; + if (!unique[tmp]) { unique[tmp] = tmp;} + } + } + + for (var i in unique) + { + usernames.push(i); + } + + Object.defineProperty(retVal, 'usernames', { value: usernames }); + 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, (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); +} + +module.exports = new UserSessions(); \ No newline at end of file diff --git a/agents-new/modules_meshcore/x/win-message-pump.js b/agents-new/modules_meshcore/x/win-message-pump.js new file mode 100644 index 00000000..93047af8 --- /dev/null +++ b/agents-new/modules_meshcore/x/win-message-pump.js @@ -0,0 +1,124 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +var WH_CALLWNDPROC = 4; +var WM_QUIT = 0x0012; + +var GM = require('_GenericMarshal'); + +function WindowsMessagePump(options) +{ + this._ObjectID = 'win-message-pump'; + this._options = options; + var emitterUtils = require('events').inherits(this); + emitterUtils.createEvent('hwnd'); + emitterUtils.createEvent('error'); + emitterUtils.createEvent('message'); + emitterUtils.createEvent('exit'); + + this._msg = GM.CreateVariable(GM.PointerSize == 4 ? 28 : 48); + this._kernel32 = GM.CreateNativeProxy('Kernel32.dll'); + this._kernel32.mp = this; + this._kernel32.CreateMethod('GetLastError'); + this._kernel32.CreateMethod('GetModuleHandleA'); + + this._user32 = GM.CreateNativeProxy('User32.dll'); + this._user32.mp = this; + this._user32.CreateMethod('GetMessageA'); + this._user32.CreateMethod('CreateWindowExA'); + this._user32.CreateMethod('TranslateMessage'); + this._user32.CreateMethod('DispatchMessageA'); + this._user32.CreateMethod('RegisterClassExA'); + this._user32.CreateMethod('DefWindowProcA'); + this._user32.CreateMethod('PostMessageA'); + + + this.wndclass = GM.CreateVariable(GM.PointerSize == 4 ? 48 : 80); + this.wndclass.mp = this; + this.wndclass.hinstance = this._kernel32.GetModuleHandleA(0); + this.wndclass.cname = GM.CreateVariable('MainWWWClass'); + this.wndclass.wndproc = GM.GetGenericGlobalCallback(4); + this.wndclass.wndproc.mp = this; + this.wndclass.toBuffer().writeUInt32LE(this.wndclass._size); + this.wndclass.cname.pointerBuffer().copy(this.wndclass.Deref(GM.PointerSize == 4 ? 40 : 64, GM.PointerSize).toBuffer()); + this.wndclass.wndproc.pointerBuffer().copy(this.wndclass.Deref(8, GM.PointerSize).toBuffer()); + this.wndclass.hinstance.pointerBuffer().copy(this.wndclass.Deref(GM.PointerSize == 4 ? 20 : 24, GM.PointerSize).toBuffer()); + this.wndclass.wndproc.on('GlobalCallback', function onWndProc(xhwnd, xmsg, wparam, lparam) + { + if (this.mp._hwnd != null && this.mp._hwnd.Val == xhwnd.Val) + { + // This is for us + this.mp.emit('message', { message: xmsg.Val, wparam: wparam.Val, lparam: lparam.Val, lparam_hex: lparam.pointerBuffer().toString('hex') }); + return (this.mp._user32.DefWindowProcA(xhwnd, xmsg, wparam, lparam)); + } + else if(this.mp._hwnd == null && this.CallingThread() == this.mp._user32.RegisterClassExA.async.threadId()) + { + // This message was generated from our CreateWindowExA method + return (this.mp._user32.DefWindowProcA(xhwnd, xmsg, wparam, lparam)); + } + }); + + this._user32.RegisterClassExA.async(this.wndclass).then(function () + { + this.nativeProxy.CreateWindowExA.async(this.nativeProxy.RegisterClassExA.async, 0x00000088, this.nativeProxy.mp.wndclass.cname, 0, 0x00800000, 0, 0, 100, 100, 0, 0, 0, 0) + .then(function(h) + { + if (h.Val == 0) + { + // Error creating hidden window + this.nativeProxy.mp.emit('error', 'Error creating hidden window'); + } + else + { + this.nativeProxy.mp._hwnd = h; + this.nativeProxy.mp.emit('hwnd', h); + this.nativeProxy.mp._startPump(); + } + }); + }); + this._startPump = function _startPump() + { + this._user32.GetMessageA.async(this._user32.RegisterClassExA.async, this._msg, this._hwnd, 0, 0).then(function (r) + { + if(r.Val > 0) + { + this.nativeProxy.TranslateMessage.async(this.nativeProxy.RegisterClassExA.async, this.nativeProxy.mp._msg).then(function () + { + this.nativeProxy.DispatchMessageA.async(this.nativeProxy.RegisterClassExA.async, this.nativeProxy.mp._msg).then(function () + { + this.nativeProxy.mp._startPump(); + }); + }); + } + else + { + // We got a 'QUIT' message + delete this.nativeProxy.mp._hwnd; + this.nativeProxy.mp.emit('exit', 0); + } + }, function (err) { this.nativeProxy.mp.stop(); }); + } + + this.stop = function stop() + { + if (this._hwnd) + { + this._user32.PostMessageA(this._hwnd, WM_QUIT, 0, 0); + } + }; +} + +module.exports = WindowsMessagePump; diff --git a/agents-new/modules_meshcore/x/win-registry.js b/agents-new/modules_meshcore/x/win-registry.js new file mode 100644 index 00000000..88dde0c3 --- /dev/null +++ b/agents-new/modules_meshcore/x/win-registry.js @@ -0,0 +1,218 @@ +/* +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_ENUMERATE_SUB_KEYS = 0x0008; +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 = 'win-registry'; + this._marshal = require('_GenericMarshal'); + this._AdvApi = this._marshal.CreateNativeProxy('Advapi32.dll'); + this._AdvApi.CreateMethod('RegCreateKeyExA'); + this._AdvApi.CreateMethod('RegEnumKeyExA'); + this._AdvApi.CreateMethod('RegEnumValueA'); + this._AdvApi.CreateMethod('RegOpenKeyExA'); + this._AdvApi.CreateMethod('RegQueryInfoKeyA'); + 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 err; + var h = this._marshal.CreatePointer(); + var len = this._marshal.CreateVariable(4); + var valType = this._marshal.CreateVariable(4); + var HK = this._marshal.CreatePointer(hkey); + var retVal = null; + if (key) { key = this._marshal.CreateVariable(key); } + if (!path) { path = ''; } + + + if ((err = this._AdvApi.RegOpenKeyExA(HK, this._marshal.CreateVariable(path), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, h).Val) != 0) + { + throw ('Opening Registry Key: ' + path + ' => Returned Error: ' + err); + } + + if ((path == '' && !key) || !key) + { + var result = { subkeys: [], values: [] }; + + // Enumerate keys + var achClass = this._marshal.CreateVariable(1024); + var achKey = this._marshal.CreateVariable(1024); + var achValue = this._marshal.CreateVariable(32768); + var achValueSize = this._marshal.CreateVariable(4); + var nameSize = this._marshal.CreateVariable(4); + var achClassSize = this._marshal.CreateVariable(4); achClassSize.toBuffer().writeUInt32LE(1024); + var numSubKeys = this._marshal.CreateVariable(4); + var numValues = this._marshal.CreateVariable(4); + var longestSubkeySize = this._marshal.CreateVariable(4); + var longestClassString = this._marshal.CreateVariable(4); + var longestValueName = this._marshal.CreateVariable(4); + var longestValueData = this._marshal.CreateVariable(4); + var securityDescriptor = this._marshal.CreateVariable(4); + var lastWriteTime = this._marshal.CreateVariable(8); + + retVal = this._AdvApi.RegQueryInfoKeyA(h.Deref(), achClass, achClassSize, 0, + numSubKeys, longestSubkeySize, longestClassString, numValues, + longestValueName, longestValueData, securityDescriptor, lastWriteTime); + if (retVal.Val != 0) { throw ('RegQueryInfoKeyA() returned error: ' + retVal.Val); } + for(var i = 0; i < numSubKeys.toBuffer().readUInt32LE(); ++i) + { + nameSize.toBuffer().writeUInt32LE(1024); + retVal = this._AdvApi.RegEnumKeyExA(h.Deref(), i, achKey, nameSize, 0, 0, 0, lastWriteTime); + if(retVal.Val == 0) + { + result.subkeys.push(achKey.String); + } + } + for (var i = 0; i < numValues.toBuffer().readUInt32LE() ; ++i) + { + achValueSize.toBuffer().writeUInt32LE(32768); + if(this._AdvApi.RegEnumValueA(h.Deref(), i, achValue, achValueSize, 0, 0, 0, 0).Val == 0) + { + result.values.push(achValue.String); + } + } + return (result); + } + + 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/agents-new/recoverycore.js b/agents-new/recoverycore.js new file mode 100644 index 00000000..762fa91f --- /dev/null +++ b/agents-new/recoverycore.js @@ -0,0 +1,466 @@ + +var http = require('http'); +var childProcess = require('child_process'); +var meshCoreObj = { "action": "coreinfo", "value": "MeshCore Recovery", "caps": 14 }; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript +var nextTunnelIndex = 1; +var tunnels = {}; +var fs = require('fs'); + +//attachDebugger({ webport: 9994, wait: 1 }).then(function (p) { console.log('Debug on port: ' + p); }); + +function sendConsoleText(msg) +{ + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": msg }); +} +// Return p number of spaces +function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ret; } return r; } + +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('/'); + } + }; +// 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) + '}'; +} + +// 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 = require('MeshAgent').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; +} + +require('MeshAgent').on('Connected', function () +{ + require('os').name().then(function (v) + { + sendConsoleText("Mesh Agent Receovery Console, OS: " + v); + require('MeshAgent').SendCommand(meshCoreObj); + }); +}); + +// Tunnel callback operations +function onTunnelUpgrade(response, s, head) { + this.s = s; + s.httprequest = this; + s.end = onTunnelClosed; + s.tunnel = this; + + //sendConsoleText('onTunnelUpgrade'); + + 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; + } +} + +require('MeshAgent').AddCommandHandler(function (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.on('upgrade', function (response, s, head) + { + this.s = s; + s.httprequest = this; + s.tunnel = this; + s.on('end', function () + { + if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls. + + // 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; } + + + //sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid); + delete tunnels[this.httprequest.index]; + + // Clean up WebSocket + this.removeAllListeners('data'); + }); + s.on('data', function (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.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) + { + // 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._term = require('win-terminal').Start(80, 25); + this.httprequest._term.pipe(this, { dataTypeSkip: 1 }); + this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false }); + this.prependListener('end', function () { this.httprequest._term.end(function () { sendConsoleText('Terminal was closed'); }); }); + } + 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.on('end', function () { + if (process.platform == "win32") + { + // Unpipe the web socket + this.unpipe(this.httprequest._term); + this.httprequest._term.unpipe(this); + + // Clean up + this.httprequest._term.end(); + this.httprequest._term = null; + } + }); + } + } + 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))) { return; } // If this is control data, handle it now. + if (cmd.action == undefined) { return; } + console.log('action: ', cmd.action); + + //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': + // 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))); + break; + case 'mkdir': { + // Create a new empty folder + fs.mkdirSync(cmd.path); + break; + } + case 'rm': { + // Delete, possibly recursive delete + for (var i in cmd.delfiles) + { + try { deleteFolderRecursive(path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (e) { } + } + break; + } + case 'rename': { + // Rename a file or folder + var oldfullpath = path.join(cmd.path, cmd.oldname); + var newfullpath = path.join(cmd.path, cmd.newname); + try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); } + break; + } + case '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 ? 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 = 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; + } + } + } + } + }); + }); + 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; + } + + default: + // Unknown action, ignore it. + break; + } + break; + } + default: + // Unknown action, ignore it. + break; + } + } +}); + +function processConsoleCommand(cmd, args, rights, sessionid) +{ + try + { + var response = null; + switch (cmd) + { + case 'help': + response = 'Available commands are: osinfo, dbkeys, dbget, dbset, dbcompact, netinfo.'; + break; + + case 'osinfo': { // Return the operating system information + var i = 1; + if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; } + for (var j = 0; j < i; j++) { + var pr = require('os').name(); + pr.sessionid = sessionid; + pr.then(function (v) { sendConsoleText("OS: " + v, this.sessionid); }); + } + 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 '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 'netinfo': { // Show network interface information + //response = objToString(mesh.NetInfo, 0, ' '); + var interfaces = require('os').networkInterfaces(); + response = objToString(interfaces, 0, ' ', true); + 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); } +} + +// 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 = 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 = 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; +} +// Delete a directory with a files and directories within it +function deleteFolderRecursive(path, rec) { + if (fs.existsSync(path)) { + if (rec == true) { + fs.readdirSync(path.join(path, '*')).forEach(function (file, index) { + var curPath = path.join(path, file); + if (fs.statSync(curPath).isDirectory()) { // recurse + deleteFolderRecursive(curPath, true); + } else { // delete file + fs.unlinkSync(curPath); + } + }); + } + fs.unlinkSync(path); + } +}; diff --git a/agents-new/testsuite.js b/agents-new/testsuite.js new file mode 100644 index 00000000..bcb9055d --- /dev/null +++ b/agents-new/testsuite.js @@ -0,0 +1,157 @@ +/* +Copyright 2017-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +// 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; + }; +} + +// 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, 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) { r += (addPad(p + 2, ret) + i + ': ' + objToString(x[i], p + 2, ret) + (ret ? '\r\n' : ' ')); } + return r + addPad(p, ret) + '}'; +} + +// Return p number of spaces +function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += 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; +} + +// Parge a URL string into an options object +function parseUrl(url) { + var x = url.split('/'); + if (x.length < 4) return null; + var y = x[2].split(':'); + var options = {}; + var options = { protocol: x[0], hostname: y[0], path: '/' + x.splice(3).join('/') }; + if (y.length == 1) { options.port = ((x[0] == 'https:') || (x[0] == 'wss:')) ? 443 : 80; } else { options.port = parseInt(y[1]); } + if (isNaN(options.port) == true) return null; + return options; +} + +//console.log(objToString(db2, 2, ' ')); + +{ + // TODO: Fix this to use the event emitor + // TODO: Add SHA256 sync + console.log('--- Test 1: SHA256 hashing ---'); + var sha256 = require('SHA256Stream'); + sha256.hashString = function (x) { if (x == '81B637D8FCD2C6DA6359E6963113A1170DE795E4B725B84D1E0B4CFD9EC58CE9') { console.log('Test 1 - OK: ' + x); } else { console.log('Test 1 - FAIL: ' + x); } }; + sha256.write('bob'); + sha256.end(); +} +{ + // FAIL!!!!!!!!! + var sha256x = require('SHA256Stream'); + sha256x.hashString = function (x) { if (x == '81B637D8FCD2C6DA6359E6963113A1170DE795E4B725B84D1E0B4CFD9EC58CE9') { console.log('Test 1 - OK: ' + x); } else { console.log('Test 1 - FAIL: ' + x); } }; + sha256x.write('bob'); + sha256x.end(); +} + +/* +{ + console.log('--- Test 2: Database ---'); + var db = require('SimpleDataStore').Create('TestSuite.db'); + var sha256 = require('SHA256Stream'); + + // Write a pile of hashes to the DB + sha256.hashString = function (x) { db.Put(x.substring(0, 16), x.substring(16)); console.log('ADD: ' + x.substring(0, 16) + ': ' + x.substring(16)); }; + for (var i = 0; i < 10; i++) { console.log(i); sha256.write('A' + i); sha256.end(); } + + // Compact plenty of times + for (var i = 0; i < 10; i++) { console.log(i); db.Compact(); } + + // Check all the hashes + sha256.hashString = function (x) { + var r = db.Get(x.substring(0, 16)); + console.log('GET: ' + x.substring(0, 16) + ': ' + r); + if (r != x.substring(16)) { console.log('FAILED ' + x.substring(0, 16) + ': ' + x.substring(16) + ' != ' + r); } + //db.Put(x.substring(0, 16), ''); + }; + for (var i = 0; i < 10; i++) { console.log(i); sha256.write('A' + i); sha256.end(); } + console.log('Test 2 - Completed.'); +} +*/ + +{ + console.log('--- Test 3: Files ---'); + var r, fs = require('fs'); + //console.log(objToString(fs, 2, ' ')); + r = fs.mkdirSync('TestSuite-123'); + r = fs.renameSync('TestSuite-123', 'TestSuite-1234'); + console.log(r); + r = fs.unlinkSync('TestSuite-1234'); +} + +console.log('--- Tests Completed ---'); +process.exit(2); \ No newline at end of file diff --git a/agents-new/tinycore.js b/agents-new/tinycore.js new file mode 100644 index 00000000..4bbf7d2e --- /dev/null +++ b/agents-new/tinycore.js @@ -0,0 +1,67 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +function createMeshCore(agent) { + var obj = {}; + + // MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent. + obj.meshCoreInfo = "TinyCore v1"; + + if (agent == null) { + // If we are running in Duktape, agent will be null + var mesh = require('MeshAgent'); + } else { + // Running in nodejs + var mesh = agent.getMeshApi(); + } + + // Handle a mesh agent command + function handleServerCommand(data) { + if ((typeof data == 'object') && (data.action == 'msg') && (data.type == 'console') && data.value && data.sessionid) { + mesh.SendCommand({ "action": "msg", "type": "console", "value": "Tiny core: " + data.value, "sessionid": data.sessionid }); + } + } + + // Called when the server connection state changes + function handleServerConnection(state) { + if (state == 1) { mesh.SendCommand({ "action": "coreinfo", "value": obj.meshCoreInfo }); } // Server connected, send mesh core information + } + + obj.start = function() { + // Hook up mesh agent events + mesh.AddCommandHandler(handleServerCommand); + mesh.AddConnectHandler(handleServerConnection); + mesh.SendCommand({ "action": "coreinfo", "value": obj.meshCoreInfo }); // TODO: Check if connected before sending + } + + obj.stop = function() { + mesh.AddCommandHandler(null); + mesh.AddConnectHandler(null); + } + + return obj; +} + +var xexports = 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 + createMeshCore().start(null); +} diff --git a/meshagent.js b/meshagent.js index e1119005..c76e1edd 100644 --- a/meshagent.js +++ b/meshagent.js @@ -1094,6 +1094,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if ((command.caps != null) && (device.agent.core != command.value)) { if ((command.value == null) && (device.agent.core != null)) { delete device.agent.core; } else { device.agent.core = command.value; } change = 1; } // Don't save this as an event to the db. if ((command.caps != null) && ((device.agent.caps & 0xFFFFFFE7) != (command.caps & 0xFFFFFFE7))) { device.agent.caps = ((device.agent.caps & 24) + (command.caps & 0xFFFFFFE7)); change = 1; } // Allow Javascript on the agent to change all capabilities except console and javascript support, Don't save this as an event to the db. if ((command.osdesc != null) && (device.osdesc != command.osdesc)) { device.osdesc = command.osdesc; change = 1; changes.push('os desc'); } // Don't save this as an event to the db. + if (device.ip != obj.remoteaddr) { device.ip = obj.remoteaddr; change = 1; } if (command.intelamt) { if (!device.intelamt) { device.intelamt = {}; } if ((command.intelamt.ver != null) && (device.intelamt.ver != command.intelamt.ver)) { changes.push('AMT version'); device.intelamt.ver = command.intelamt.ver; change = 1; log = 1; } diff --git a/package.json b/package.json index ae4fef7a..33283555 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.3.0-i", + "version": "0.3.0-k", "keywords": [ "Remote Management", "Intel AMT", diff --git a/views/default-min.handlebars b/views/default-min.handlebars index f277bdf1..98c1f378 100644 --- a/views/default-min.handlebars +++ b/views/default-min.handlebars @@ -1 +1 @@ - MeshCentral
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file + MeshCentral
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file diff --git a/views/default.handlebars b/views/default.handlebars index bb6b3f3f..78e5e173 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -922,7 +922,7 @@ QV('p13AutoConnect', debugmode); // Files QV('autoconnectbutton2', debugmode); // Terminal QV('autoconnectbutton1', debugmode); // Desktop - QV('DeskClip', debugmode); // Clipboard feature, not completed so show in in debug mode only. + //QV('DeskClip', debugmode); // Clipboard feature, not completed so show in in debug mode only. toggleFullScreen(); @@ -2050,34 +2050,42 @@ var deviceBoxWidth = Math.floor(totalDeviceViewWidth / 301); deviceBoxWidth = 301 + Math.floor((totalDeviceViewWidth - (deviceBoxWidth * 301)) / deviceBoxWidth); + if (view == 2) { + r += ''; } if (r != '') { r += '
UserAddressConnectivity'; //State'; + } + // Go thru the list of nodes and display them for (var i in nodes) { - if (nodes[i].v == false) continue; - var mesh2 = meshes[nodes[i].meshid], meshlinks = mesh2.links['user/' + domain + '/' + userinfo.name.toLowerCase()]; + var node = nodes[i]; + if (node.v == false) continue; + var mesh2 = meshes[node.meshid], meshlinks = mesh2.links['user/' + domain + '/' + userinfo.name.toLowerCase()]; if (meshlinks == null) continue; var meshrights = meshlinks.rights; if ((view == 3) && (mesh2.mtype == 1)) continue; if (sort == 0) { // Mesh header - if (nodes[i].meshid != current) { + if (node.meshid != current) { deviceHeaderSet(); var extra = ''; - if (meshes[nodes[i].meshid].mtype == 1) { extra = ', Intel® AMT only'; } + if (view == 2) { r += '
'; } + if (meshes[node.meshid].mtype == 1) { extra = ', Intel® AMT only'; } if ((view == 1) && (current != null)) { if (c == 2) { r += '
'; } } + if (view == 2) { r += '
'; } r += '
'; r += getMeshActions(mesh2, meshrights); - r += '' + EscapeHtml(meshes[nodes[i].meshid].name) + '' + extra + '
'; - current = nodes[i].meshid; + r += '' + EscapeHtml(meshes[node.meshid].name) + '' + extra + '
'; + if (view == 2) { r += ''; } + current = node.meshid; displayedMeshes[current] = 1; c = 0; } } else if (sort == 1) { // Power header - var pwr = nodes[i].pwr?nodes[i].pwr:0; + var pwr = node.pwr?node.pwr:0; if (pwr !== current) { deviceHeaderSet(); if ((view == 1) && (current !== null)) { if (c == 2) { r += '
'; } if (r != '') { r += ''; } } - r += '
' + PowerStateStr2(nodes[i].pwr) + '
'; + r += '
' + PowerStateStr2(node.pwr) + '
'; current = pwr; c = 0; } @@ -2087,41 +2095,52 @@ } count++; - var title = EscapeHtml(nodes[i].name); + var title = EscapeHtml(node.name); if (title.length == 0) { title = 'None'; } - if ((nodes[i].rname != null) && (nodes[i].rname.length > 0)) { title += " / " + EscapeHtml(nodes[i].rname); } - var name = EscapeHtml(nodes[i].name); - if (showRealNames == true && nodes[i].rname != null) name = EscapeHtml(nodes[i].rname); + if ((node.rname != null) && (node.rname.length > 0)) { title += " / " + EscapeHtml(node.rname); } + var name = EscapeHtml(node.name); + if (showRealNames == true && node.rname != null) name = EscapeHtml(node.rname); if (name.length == 0) { name = 'None'; } // Node - var icon = nodes[i].icon; - var nodestate = NodeStateStr(nodes[i]); - if ((!nodes[i].conn) || (nodes[i].conn == 0)) { icon += ' gray'; } + var icon = node.icon; + if ((!node.conn) || (node.conn == 0)) { icon += ' gray'; } if (view == 1) { - r += '
' + name + '
' + nodestate + '
'; + r += '
' + name + '
' + NodeStateStr(node) + '
'; } else if (view == 2) { + var states = []; + if (node.conn) { + if ((node.conn & 1) != 0) { states.push('Agent'); } + if ((node.conn & 2) != 0) { states.push('CIRA'); } + else if ((node.conn & 4) != 0) { states.push('AMT'); } + if ((node.conn & 8) != 0) { states.push('Relay'); } + } r += '
'; - r += '
'; - r += '
'; + r += '
'; + r += '
'; r += '
'; - r += '
' + nodestate + '' + name + '
'; - } else if ((view == 3) && (nodes[i].conn & 1) && (((meshrights & 8) || (meshrights & 256)) != 0) && ((nodes[i].agent.caps & 1) != 0)) { // Check if we have rights and agent is capable of KVM. - if ((multiDesktopFilter.length == 0) || (multiDesktopFilter.indexOf('devid_' + nodes[i]._id) >= 0)) { - r += '
'; - //r += ''; + r += '
' + name + '
'; + r += '' + getUserShortStr(node); + r += '' + (node.ip != null ? node.ip : ''); + r += '' + states.join(' + '); + //r += '' + (node.pwr != null ? powerStateStrings[node.pwr] : ''); + r += ''; + } else if ((view == 3) && (node.conn & 1) && (((meshrights & 8) || (meshrights & 256)) != 0) && ((node.agent.caps & 1) != 0)) { // Check if we have rights and agent is capable of KVM. + if ((multiDesktopFilter.length == 0) || (multiDesktopFilter.indexOf('devid_' + node._id) >= 0)) { + r += '
'; + //r += ''; r += '
 ' + name + '
'; - r += '
Disconnected
'; + r += '
Disconnected
'; r += '
'; - kvmDivs.push(nodes[i]._id); + kvmDivs.push(node._id); } } // If we are displaying devices by group, put the device in the right group. if ((sort == 3) && (r != '')) { - if (nodes[i].tags) { - for (var j in nodes[i].tags) { - var tag = nodes[i].tags[j]; + if (node.tags) { + for (var j in node.tags) { + var tag = node.tags[j]; if (groups[tag] == null) { groups[tag] = r; groupCount[tag] = 1; } else { groups[tag] += r; groupCount[tag] += 1; } if (view == 3) break; } @@ -2130,7 +2149,7 @@ } deviceHeaderTotal++; - if (typeof deviceHeaderCount[nodes[i].state] == 'undefined') { deviceHeaderCount[nodes[i].state] = 1; } else { deviceHeaderCount[nodes[i].state]++; } + if (typeof deviceHeaderCount[node.state] == 'undefined') { deviceHeaderCount[node.state] = 1; } else { deviceHeaderCount[node.state]++; } } // If displaying devices by groups, sort the group names and display the devices. @@ -2278,6 +2297,16 @@ } } + function getUserShortStr(node) { + if (node == null || node.users == null || node.users.length == 0) return ''; + if (node.users.length > 1) { return '' + node.users.length + ' users'; } + var u = node.users[0], su = u, i = u.indexOf('\\'); + if (i > 0) { su = u.substring(i + 1); } + su = EscapeHtml(su); + if (su.length > 15) { su = su.substring(0, 14) + '…'; } + return '' + su + ''; + } + function autoConnectDesktops() { if (Q('autoConnectDesktopCheckbox').checked == true) { connectAllKvmFunction(); } } function connectAllKvmFunction() { for (var i in nodes) { if (multiDesktop[nodes[i]._id] == null) { toggleKvmDevice(nodes[i]._id); } } } function disconnectAllKvmFunction() { for (var nodeid in multiDesktop) { multiDesktop[nodeid].Stop(); } multiDesktop = {}; } @@ -2728,9 +2757,30 @@ function onSearchInputChanged() { var x = Q('SearchInput').value.toLowerCase().trim(); putstore("search", x); + var userSearch = null, ipSearch = null, groupSearch = null; + if (x.startsWith('user:')) { userSearch = x.substring(5); } + else if (x.startsWith('u:')) { userSearch = x.substring(2); } + else if (x.startsWith('ip:')) { ipSearch = x.substring(3); } + else if (x.startsWith('group:')) { groupSearch = x.substring(6); } + else if (x.startsWith('g:')) { groupSearch = x.substring(2); } + if (x == '') { + // No search for (var d in nodes) { nodes[d].v = true; } + } else if (ipSearch != null) { + // IP address search + for (var d in nodes) { nodes[d].v = ((nodes[d].ip != null) && (nodes[d].ip.indexOf(ipSearch) >= 0)); } + } else if (groupSearch != null) { + // Group filter + for (var d in nodes) { nodes[d].v = (meshes[nodes[d].meshid].name.toLowerCase().indexOf(groupSearch) >= 0); } + } else if (userSearch != null) { + // User search + for (var d in nodes) { + nodes[d].v = false; + if (nodes[d].users && nodes[d].users.length > 0) { for (var i in nodes[d].users) { if (nodes[d].users[i].toLowerCase().indexOf(userSearch) >= 0) { nodes[d].v = true; } } } + } } else { + // Device name search try { var rs = x.split(/\s+/).join('|'), rx = new RegExp(rs); // In some cases (like +), this can throw an exception. for (var d in nodes) { @@ -4124,8 +4174,8 @@ QV('deskFocusBtn', (desktop != null) && (desktop.contype == 2) && (deskState != 0) && (desktopsettings.showfocus)); QV('DeskCAD', inputAllowed); QE('DeskCAD', deskState == 3); - //QV('DeskClip', (desktop != null) && (desktop.contype == 1)); - QE('DeskClip', deskState == 3); + //QV('DeskClip', (desktop == null) || (desktop.contype != 2)); + //QE('DeskClip', deskState == 3); QV('DeskWD', (currentNode.agent) && (currentNode.agent.id < 5) && inputAllowed); QE('DeskWD', deskState == 3); QV('deskkeys', (currentNode.agent) && (currentNode.agent.id < 5) && inputAllowed); @@ -6404,17 +6454,24 @@ // Get search var userSearch = Q('UserSearchInput').value.toLowerCase(); + var emailSearch = userSearch; + if (userSearch.startsWith('email:')) { userSearch = null; emailSearch = emailSearch.substring(6); } + else if (userSearch.startsWith('name:')) { emailSearch = null; userSearch = userSearch.substring(5); } + else if (userSearch.startsWith('e:')) { userSearch = null; emailSearch = emailSearch.substring(2); } + else if (userSearch.startsWith('n:')) { emailSearch = null; userSearch = userSearch.substring(2); } // Display the users using the sorted list var x = '', addHeader = true; - x += '
NameGroupsLast AccessPermissions'; // Online users for (var i in sortedUserIds) { var user = users[sortedUserIds[i]], sessions = null; if (wssessions != null) { sessions = wssessions[user._id]; } - if ((sessions != null) && (user.name.toLowerCase().indexOf(userSearch) >= 0)) { + if ((sessions != null) && + ((userSearch != null) && ((userSearch == '') || (user.name.toLowerCase().indexOf(userSearch) >= 0)) || + ((emailSearch != null) && ((user.email != null) && (user.email.toLowerCase().indexOf(emailSearch) >= 0)))) + ) { if (maxUsers > 0) { if (addHeader) { x += '
Online Users'; addHeader = false; } x += addUserHtml(user, sessions); @@ -6429,7 +6486,10 @@ for (var i in sortedUserIds) { var user = users[sortedUserIds[i]], sessions = null; if (wssessions != null) { sessions = wssessions[user._id]; } - if ((sessions == null) && (user.name.toLowerCase().indexOf(userSearch) >= 0)) { + if ((sessions == null) && + ((userSearch != null) && ((userSearch == '') || (user.name.toLowerCase().indexOf(userSearch) >= 0)) || + ((emailSearch != null) && ((user.email != null) && (user.email.toLowerCase().indexOf(emailSearch) >= 0)))) + ) { if (maxUsers > 0) { if (addHeader) { x += '
Offline Users'; addHeader = false; } x += addUserHtml(user, sessions);