Improved server list view and search box.

Ylian Saint-Hilaire committed Mar 15, 2019 at 12:30 UTC 0aedf985fe3a08de7cfe24ff681af1d55bd74e57
72 files changed +20049 -37
agents-new/MeshAgentOSXPackager.zip
Binary files /dev/null and b/agents-new/MeshAgentOSXPackager.zip differ
agents-new/MeshCmd-signed.exe
Binary files /dev/null and b/agents-new/MeshCmd-signed.exe differ
agents-new/MeshCmd64-signed.exe
Binary files /dev/null and b/agents-new/MeshCmd64-signed.exe differ
agents-new/MeshCommander-Small.gz
Binary files /dev/null and b/agents-new/MeshCommander-Small.gz differ
agents-new/MeshService-signed.exe
Binary files /dev/null and b/agents-new/MeshService-signed.exe differ
agents-new/MeshService.exe
Binary files /dev/null and b/agents-new/MeshService.exe differ
agents-new/MeshService64-signed.exe
Binary files /dev/null and b/agents-new/MeshService64-signed.exe differ
agents-new/MeshService64.exe
Binary files /dev/null and b/agents-new/MeshService64.exe differ
agents-new/agentrecoverycore.js new
+466
@@ -0,0 +1,466 @@
1 +
2 +var http = require('http');
3 +var childProcess = require('child_process');
4 +var meshCoreObj = { "action": "coreinfo", "value": "MeshCore Recovery", "caps": 14 }; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript
5 +var nextTunnelIndex = 1;
6 +var tunnels = {};
7 +var fs = require('fs');
8 +
9 +//attachDebugger({ webport: 9994, wait: 1 }).then(function (p) { console.log('Debug on port: ' + p); });
10 +
11 +function sendConsoleText(msg)
12 +{
13 + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": msg });
14 +}
15 +// Return p number of spaces
16 +function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ret; } return r; }
17 +
18 +var path =
19 + {
20 + join: function ()
21 + {
22 + var x = [];
23 + for (var i in arguments)
24 + {
25 + var w = arguments[i];
26 + if (w != null)
27 + {
28 + while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
29 + if (i != 0)
30 + {
31 + while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); }
32 + }
33 + x.push(w);
34 + }
35 + }
36 + if (x.length == 0) return '/';
37 + return x.join('/');
38 + }
39 + };
40 +// Convert an object to string with all functions
41 +function objToString(x, p, pad, ret) {
42 + if (ret == undefined) ret = '';
43 + if (p == undefined) p = 0;
44 + if (x == null) { return '[null]'; }
45 + if (p > 8) { return '[...]'; }
46 + if (x == undefined) { return '[undefined]'; }
47 + if (typeof x == 'string') { if (p == 0) return x; return '"' + x + '"'; }
48 + if (typeof x == 'buffer') { return '[buffer]'; }
49 + if (typeof x != 'object') { return x; }
50 + var r = '{' + (ret ? '\r\n' : ' ');
51 + for (var i in x) { if (i != '_ObjectID') { r += (addPad(p + 2, pad) + i + ': ' + objToString(x[i], p + 2, pad, ret) + (ret ? '\r\n' : ' ')); } }
52 + return r + addPad(p, pad) + '}';
53 +}
54 +
55 +// Split a string taking into account the quoats. Used for command line parsing
56 +function splitArgs(str)
57 +{
58 + var myArray = [], myRegexp = /[^\s"]+|"([^"]*)"/gi;
59 + do { var match = myRegexp.exec(str); if (match != null) { myArray.push(match[1] ? match[1] : match[0]); } } while (match != null);
60 + return myArray;
61 +}
62 +
63 +// Parse arguments string array into an object
64 +function parseArgs(argv)
65 +{
66 + var results = { '_': [] }, current = null;
67 + for (var i = 1, len = argv.length; i < len; i++) {
68 + var x = argv[i];
69 + if (x.length > 2 && x[0] == '-' && x[1] == '-') {
70 + if (current != null) { results[current] = true; }
71 + current = x.substring(2);
72 + } else {
73 + if (current != null) { results[current] = toNumberIfNumber(x); current = null; } else { results['_'].push(toNumberIfNumber(x)); }
74 + }
75 + }
76 + if (current != null) { results[current] = true; }
77 + return results;
78 +}
79 +// Get server target url with a custom path
80 +function getServerTargetUrl(path)
81 +{
82 + var x = require('MeshAgent').ServerUrl;
83 + //sendConsoleText("mesh.ServerUrl: " + mesh.ServerUrl);
84 + if (x == null) { return null; }
85 + if (path == null) { path = ''; }
86 + x = http.parseUri(x);
87 + if (x == null) return null;
88 + return x.protocol + '//' + x.host + ':' + x.port + '/' + path;
89 +}
90 +
91 +// Get server url. If the url starts with "*/..." change it, it not use the url as is.
92 +function getServerTargetUrlEx(url)
93 +{
94 + if (url.substring(0, 2) == '*/') { return getServerTargetUrl(url.substring(2)); }
95 + return url;
96 +}
97 +
98 +require('MeshAgent').on('Connected', function ()
99 +{
100 + require('os').name().then(function (v)
101 + {
102 + sendConsoleText("Mesh Agent Receovery Console, OS: " + v);
103 + require('MeshAgent').SendCommand(meshCoreObj);
104 + });
105 +});
106 +
107 +// Tunnel callback operations
108 +function onTunnelUpgrade(response, s, head) {
109 + this.s = s;
110 + s.httprequest = this;
111 + s.end = onTunnelClosed;
112 + s.tunnel = this;
113 +
114 + //sendConsoleText('onTunnelUpgrade');
115 +
116 + if (this.tcpport != null) {
117 + // This is a TCP relay connection, pause now and try to connect to the target.
118 + s.pause();
119 + s.data = onTcpRelayServerTunnelData;
120 + var connectionOptions = { port: parseInt(this.tcpport) };
121 + if (this.tcpaddr != null) { connectionOptions.host = this.tcpaddr; } else { connectionOptions.host = '127.0.0.1'; }
122 + s.tcprelay = net.createConnection(connectionOptions, onTcpRelayTargetTunnelConnect);
123 + s.tcprelay.peerindex = this.index;
124 + } else {
125 + // This is a normal connect for KVM/Terminal/Files
126 + s.data = onTunnelData;
127 + }
128 +}
129 +
130 +require('MeshAgent').AddCommandHandler(function (data)
131 +{
132 + if (typeof data == 'object')
133 + {
134 + // If this is a console command, parse it and call the console handler
135 + switch (data.action)
136 + {
137 + case 'msg':
138 + {
139 + switch (data.type)
140 + {
141 + case 'console': { // Process a console command
142 + if (data.value && data.sessionid)
143 + {
144 + var args = splitArgs(data.value);
145 + processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid);
146 + }
147 + break;
148 + }
149 + case 'tunnel':
150 + {
151 + if (data.value != null) { // Process a new tunnel connection request
152 + // Create a new tunnel object
153 + var xurl = getServerTargetUrlEx(data.value);
154 + if (xurl != null) {
155 + var woptions = http.parseUri(xurl);
156 + woptions.rejectUnauthorized = 0;
157 + //sendConsoleText(JSON.stringify(woptions));
158 + var tunnel = http.request(woptions);
159 + tunnel.on('upgrade', function (response, s, head)
160 + {
161 + this.s = s;
162 + s.httprequest = this;
163 + s.tunnel = this;
164 + s.on('end', function ()
165 + {
166 + if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls.
167 +
168 + // If there is a upload or download active on this connection, close the file
169 + if (this.httprequest.uploadFile) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
170 + if (this.httprequest.downloadFile) { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; }
171 +
172 +
173 + //sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid);
174 + delete tunnels[this.httprequest.index];
175 +
176 + // Clean up WebSocket
177 + this.removeAllListeners('data');
178 + });
179 + s.on('data', function (data)
180 + {
181 + // If this is upload data, save it to file
182 + if (this.httprequest.uploadFile)
183 + {
184 + 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.
185 + this.write(new Buffer(JSON.stringify({ action: 'uploadack', reqid: this.httprequest.uploadFileid }))); // Ask for more data
186 + return;
187 + }
188 +
189 + if (this.httprequest.state == 0) {
190 + // Check if this is a relay connection
191 + if (data == 'c') { this.httprequest.state = 1; sendConsoleText("Tunnel #" + this.httprequest.index + " now active", this.httprequest.sessionid); }
192 + } else {
193 + // Handle tunnel data
194 + if (this.httprequest.protocol == 0)
195 + {
196 + // Take a look at the protocol
197 + this.httprequest.protocol = parseInt(data);
198 + if (typeof this.httprequest.protocol != 'number') { this.httprequest.protocol = 0; }
199 + if (this.httprequest.protocol == 1)
200 + {
201 + // Remote terminal using native pipes
202 + if (process.platform == "win32")
203 + {
204 + this.httprequest._term = require('win-terminal').Start(80, 25);
205 + this.httprequest._term.pipe(this, { dataTypeSkip: 1 });
206 + this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false });
207 + this.prependListener('end', function () { this.httprequest._term.end(function () { sendConsoleText('Terminal was closed'); }); });
208 + }
209 + else
210 + {
211 + this.httprequest.process = childProcess.execFile("/bin/sh", ["sh"], { type: childProcess.SpawnTypes.TERM });
212 + this.httprequest.process.tunnel = this;
213 + this.httprequest.process.on('exit', function (ecode, sig) { this.tunnel.end(); });
214 + this.httprequest.process.stderr.on('data', function (chunk) { this.parent.tunnel.write(chunk); });
215 + this.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
216 + this.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
217 + this.prependListener('end', function () { this.httprequest.process.kill(); });
218 + }
219 +
220 + this.on('end', function () {
221 + if (process.platform == "win32")
222 + {
223 + // Unpipe the web socket
224 + this.unpipe(this.httprequest._term);
225 + this.httprequest._term.unpipe(this);
226 +
227 + // Clean up
228 + this.httprequest._term.end();
229 + this.httprequest._term = null;
230 + }
231 + });
232 + }
233 + }
234 + else if (this.httprequest.protocol == 5)
235 + {
236 + // Process files commands
237 + var cmd = null;
238 + try { cmd = JSON.parse(data); } catch (e) { };
239 + if (cmd == null) { return; }
240 + if ((cmd.ctrlChannel == '102938') || ((cmd.type == 'offer') && (cmd.sdp != null))) { return; } // If this is control data, handle it now.
241 + if (cmd.action == undefined) { return; }
242 + console.log('action: ', cmd.action);
243 +
244 + //sendConsoleText('CMD: ' + JSON.stringify(cmd));
245 +
246 + if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
247 + //console.log(objToString(cmd, 0, ' '));
248 + switch (cmd.action)
249 + {
250 + case 'ls':
251 + // Send the folder content to the browser
252 + var response = getDirectoryInfo(cmd.path);
253 + if (cmd.reqid != undefined) { response.reqid = cmd.reqid; }
254 + this.write(new Buffer(JSON.stringify(response)));
255 + break;
256 + case 'mkdir': {
257 + // Create a new empty folder
258 + fs.mkdirSync(cmd.path);
259 + break;
260 + }
261 + case 'rm': {
262 + // Delete, possibly recursive delete
263 + for (var i in cmd.delfiles)
264 + {
265 + try { deleteFolderRecursive(path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (e) { }
266 + }
267 + break;
268 + }
269 + case 'rename': {
270 + // Rename a file or folder
271 + var oldfullpath = path.join(cmd.path, cmd.oldname);
272 + var newfullpath = path.join(cmd.path, cmd.newname);
273 + try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); }
274 + break;
275 + }
276 + case 'upload': {
277 + // Upload a file, browser to agent
278 + if (this.httprequest.uploadFile != undefined) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
279 + if (cmd.path == undefined) break;
280 + var filepath = cmd.name ? path.join(cmd.path, cmd.name) : cmd.path;
281 + try { this.httprequest.uploadFile = fs.openSync(filepath, 'wbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror', reqid: cmd.reqid }))); break; }
282 + this.httprequest.uploadFileid = cmd.reqid;
283 + if (this.httprequest.uploadFile) { this.write(new Buffer(JSON.stringify({ action: 'uploadstart', reqid: this.httprequest.uploadFileid }))); }
284 + break;
285 + }
286 + case 'copy': {
287 + // Copy a bunch of files from scpath to dspath
288 + for (var i in cmd.names) {
289 + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
290 + if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
291 + }
292 + break;
293 + }
294 + case 'move': {
295 + // Move a bunch of files from scpath to dspath
296 + for (var i in cmd.names) {
297 + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
298 + if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
299 + }
300 + break;
301 + }
302 + }
303 + }
304 + }
305 + });
306 + });
307 + tunnel.onerror = function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); }
308 + tunnel.sessionid = data.sessionid;
309 + tunnel.rights = data.rights;
310 + tunnel.state = 0;
311 + tunnel.url = xurl;
312 + tunnel.protocol = 0;
313 + tunnel.tcpaddr = data.tcpaddr;
314 + tunnel.tcpport = data.tcpport;
315 + tunnel.end();
316 + // Put the tunnel in the tunnels list
317 + var index = nextTunnelIndex++;
318 + tunnel.index = index;
319 + tunnels[index] = tunnel;
320 +
321 + //sendConsoleText('New tunnel connection #' + index + ': ' + tunnel.url + ', rights: ' + tunnel.rights, data.sessionid);
322 + }
323 + }
324 + break;
325 + }
326 +
327 + default:
328 + // Unknown action, ignore it.
329 + break;
330 + }
331 + break;
332 + }
333 + default:
334 + // Unknown action, ignore it.
335 + break;
336 + }
337 + }
338 +});
339 +
340 +function processConsoleCommand(cmd, args, rights, sessionid)
341 +{
342 + try
343 + {
344 + var response = null;
345 + switch (cmd)
346 + {
347 + case 'help':
348 + response = 'Available commands are: osinfo, dbkeys, dbget, dbset, dbcompact, netinfo.';
349 + break;
350 +
351 + case 'osinfo': { // Return the operating system information
352 + var i = 1;
353 + if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; }
354 + for (var j = 0; j < i; j++) {
355 + var pr = require('os').name();
356 + pr.sessionid = sessionid;
357 + pr.then(function (v) { sendConsoleText("OS: " + v, this.sessionid); });
358 + }
359 + break;
360 + }
361 + case 'dbkeys': { // Return all data store keys
362 + response = JSON.stringify(db.Keys);
363 + break;
364 + }
365 + case 'dbget': { // Return the data store value for a given key
366 + if (db == null) { response = 'Database not accessible.'; break; }
367 + if (args['_'].length != 1) {
368 + response = 'Proper usage: dbget (key)'; // Display the value for a given database key
369 + } else {
370 + response = db.Get(args['_'][0]);
371 + }
372 + break;
373 + }
374 + case 'dbset': { // Set a data store key and value pair
375 + if (db == null) { response = 'Database not accessible.'; break; }
376 + if (args['_'].length != 2) {
377 + response = 'Proper usage: dbset (key) (value)'; // Set a database key
378 + } else {
379 + var r = db.Put(args['_'][0], args['_'][1]);
380 + response = 'Key set: ' + r;
381 + }
382 + break;
383 + }
384 + case 'dbcompact': { // Compact the data store
385 + if (db == null) { response = 'Database not accessible.'; break; }
386 + var r = db.Compact();
387 + response = 'Database compacted: ' + r;
388 + break;
389 + }
390 + case 'tunnels': { // Show the list of current tunnels
391 + response = '';
392 + for (var i in tunnels) { response += 'Tunnel #' + i + ', ' + tunnels[i].url + '\r\n'; }
393 + if (response == '') { response = 'No websocket sessions.'; }
394 + break;
395 + }
396 + case 'netinfo': { // Show network interface information
397 + //response = objToString(mesh.NetInfo, 0, ' ');
398 + var interfaces = require('os').networkInterfaces();
399 + response = objToString(interfaces, 0, ' ', true);
400 + break;
401 + }
402 + default: { // This is an unknown command, return an error message
403 + response = 'Unknown command \"' + cmd + '\", type \"help\" for list of avaialble commands.';
404 + break;
405 + }
406 + }
407 + } catch (e) { response = 'Command returned an exception error: ' + e; console.log(e); }
408 + if (response != null) { sendConsoleText(response, sessionid); }
409 +}
410 +
411 +// Get a formated response for a given directory path
412 +function getDirectoryInfo(reqpath)
413 +{
414 + var response = { path: reqpath, dir: [] };
415 + if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) {
416 + // List all the drives in the root, or the root itself
417 + var results = null;
418 + try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
419 + if (results != null) {
420 + for (var i = 0; i < results.length; ++i) {
421 + var drive = { n: results[i].name, t: 1 };
422 + if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons.
423 + response.dir.push(drive);
424 + }
425 + }
426 + } else {
427 + // List all the files and folders in this path
428 + if (reqpath == '') { reqpath = '/'; }
429 + var results = null, xpath = path.join(reqpath, '*');
430 + //if (process.platform == "win32") { xpath = xpath.split('/').join('\\'); }
431 + try { results = fs.readdirSync(xpath); } catch (e) { }
432 + if (results != null) {
433 + for (var i = 0; i < results.length; ++i) {
434 + if ((results[i] != '.') && (results[i] != '..')) {
435 + var stat = null, p = path.join(reqpath, results[i]);
436 + //if (process.platform == "win32") { p = p.split('/').join('\\'); }
437 + try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date
438 + if ((stat != null) && (stat != undefined)) {
439 + if (stat.isDirectory() == true) {
440 + response.dir.push({ n: results[i], t: 2, d: stat.mtime });
441 + } else {
442 + response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime });
443 + }
444 + }
445 + }
446 + }
447 + }
448 + }
449 + return response;
450 +}
451 +// Delete a directory with a files and directories within it
452 +function deleteFolderRecursive(path, rec) {
453 + if (fs.existsSync(path)) {
454 + if (rec == true) {
455 + fs.readdirSync(path.join(path, '*')).forEach(function (file, index) {
456 + var curPath = path.join(path, file);
457 + if (fs.statSync(curPath).isDirectory()) { // recurse
458 + deleteFolderRecursive(curPath, true);
459 + } else { // delete file
460 + fs.unlinkSync(curPath);
461 + }
462 + });
463 + }
464 + fs.unlinkSync(path);
465 + }
466 +};
agents-new/compressModules.bat new
+7
@@ -0,0 +1,7 @@
1 +@ECHO OFF
2 +MD modules_meshcmd_min
3 +MD modules_meshcore_min
4 +"..\..\WebSiteCompiler\bin\Debug\WebSiteCompiler.exe" compressalljs "modules_meshcore" "modules_meshcore_min"
5 +"..\..\WebSiteCompiler\bin\Debug\WebSiteCompiler.exe" compressalljs "modules_meshcmd" "modules_meshcmd_min"
6 +"..\..\WebSiteCompiler\bin\Debug\WebSiteCompiler.exe" meshcore.js
7 +"..\..\WebSiteCompiler\bin\Debug\WebSiteCompiler.exe" meshcmd.js
agents-new/compressRemove.bat new
+7
@@ -0,0 +1,7 @@
1 +@ECHO OFF
2 +DEL meshcmd.min.js
3 +DEL meshcore.min.js
4 +DEL modules_meshcmd_min\*.min.js
5 +DEL modules_meshcore_min\*.min.js
6 +RD modules_meshcmd_min
7 +RD modules_meshcore_min
\ No newline at end of file
agents-new/meshagent_arm
Binary files /dev/null and b/agents-new/meshagent_arm differ
agents-new/meshagent_arm-linaro
Binary files /dev/null and b/agents-new/meshagent_arm-linaro differ
agents-new/meshagent_armhf
Binary files /dev/null and b/agents-new/meshagent_armhf differ
agents-new/meshagent_mips
Binary files /dev/null and b/agents-new/meshagent_mips differ
agents-new/meshagent_osx-x86-64
Binary files /dev/null and b/agents-new/meshagent_osx-x86-64 differ
agents-new/meshagent_pogo
Binary files /dev/null and b/agents-new/meshagent_pogo differ
agents-new/meshagent_poky
Binary files /dev/null and b/agents-new/meshagent_poky differ
agents-new/meshagent_poky64
Binary files /dev/null and b/agents-new/meshagent_poky64 differ
agents-new/meshagent_x86
Binary files /dev/null and b/agents-new/meshagent_x86 differ
agents-new/meshagent_x86-64
Binary files /dev/null and b/agents-new/meshagent_x86-64 differ
agents-new/meshagent_x86-64_nokvm
Binary files /dev/null and b/agents-new/meshagent_x86-64_nokvm differ
agents-new/meshagent_x86_nokvm
Binary files /dev/null and b/agents-new/meshagent_x86_nokvm differ
agents-new/meshcmd.js new
+1604
@@ -0,0 +1,1604 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +/**
18 +* @description MeshCmd, command line tool for Intel AMT and MeshCentral.
19 +* @author Ylian Saint-Hilaire
20 +* @version v0.2.0
21 +*/
22 +
23 +// Debug Stuff
24 +//console.displayFinalizerMessages = 1; // Display objects that have event listeners that are disposed.
25 +//console.displayStreamPipeMessages = 1; // Display stream pipe and un-pipes
26 +//var __gc = setInterval(function () { console.log('GC'); _debugGC() }, 2000); //
27 +
28 +
29 +var fs = require('fs');
30 +var os = require('os');
31 +var net = require('net');
32 +var http = require('http');
33 +var dgram = require('dgram');
34 +var httpHeaders = require('http-headers');
35 +var tcpserver = null;
36 +var broadcastSockets = {};
37 +var multicastSockets = {};
38 +var discoveryInterval = null;
39 +var membershipIPv4 = '239.255.255.235';
40 +var membershipIPv6 = 'FF02:0:0:0:0:0:0:FE';
41 +var settings = null;
42 +var meshCmdVersion = '***Mesh*Cmd*Version***'; // Dynamically replaced with MeshCentral version
43 +var amtLms = null, amtMei = null, amtMeiState = null;
44 +var wsstack = null, amtstack = null;
45 +var oswsstack = null, osamtstack = null;
46 +var amtMeiTmpState = null;
47 +var SMBiosTables = null;
48 +
49 +// MeshCommander for Firmware (GZIP'ed, Base64) v0.7.4
50 +var Large_IntelAmtWebApp = "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";
51 +var Medium_IntelAmtWebApp = "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";
52 +var Small_IntelAmtWebApp = "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";
53 +
54 +// Check the server certificate fingerprint
55 +function onVerifyServer(clientName, certs) {
56 + if (certs == null) { certs = clientName; } // Temporary thing until we fix duktape
57 + try { for (var i in certs) { if (certs[i].fingerprint.replace(/:/g, '') == settings.serverHttpsHash) { return; } } } catch (e) { }
58 + if (serverhash != null) { console.log('Error: Failed to verify server certificate.'); throw 'Invalid server certificate'; }
59 +}
60 +
61 +// Various utility functions
62 +function debug(level, message) { if ((settings.debugLevel != null) && (settings.debugLevel >= level)) { console.log(message); } }
63 +function exit(status) { if (status == null) { status = 0; } try { process.exit(status); } catch (e) { } }
64 +function getInstance(x, y) { for (var i in x) { if (x[i]["InstanceID"] == y) return x[i]; } return null; }
65 +function md5hex(str) { return require('MD5Stream').create().syncHash(str).toString('hex'); }
66 +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); }
67 +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; }
68 +
69 +// Convert an object to string with all functions
70 +function objToString(x, p, ret) {
71 + if (ret == undefined) ret = '';
72 + if (p == undefined) p = 0;
73 + if (x == null) { return '[null]'; }
74 + if (p > 8) { return '[...]'; }
75 + if (x == undefined) { return '[undefined]'; }
76 + if (typeof x == 'string') { if (p == 0) return x; return '"' + (x.split('\0')[0]) + '"'; }
77 + if (typeof x == 'buffer') { return '[buffer]'; }
78 + if (typeof x != 'object') { return x; }
79 + var r = '{' + (ret ? '\r\n' : ' ');
80 + for (var i in x) {
81 + if (i != '_ObjectID') { r += (addPad(p + 2, ret) + i + ': ' + objToString(x[i], p + 2, ret) + (ret ? '\r\n' : ' ')); }
82 + }
83 + return r + addPad(p, ret) + '}';
84 +}
85 +
86 +// Return p number of spaces
87 +function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ' '; } return r; }
88 +
89 +// Parse the incoming arguments
90 +function run(argv) {
91 + if (meshCmdVersion[0] == '*') { meshCmdVersion = ''; } else { meshCmdVersion = ' v' + meshCmdVersion; }
92 + var args = parceArguments(argv);
93 + //console.log(JSON.stringify(argv));
94 + //console.log('addedModules = ' + JSON.stringify(addedModules));
95 + var actionpath = 'meshaction.txt';
96 + if (args.actionfile != null) { actionpath = args.actionfile; }
97 + var actions = ['HELP', 'ROUTE', 'MICROLMS', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTINFODEBUG', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG', 'AMTPRESENCE'];
98 +
99 + // Load the action file
100 + var actionfile = null;
101 + try { actionfile = fs.readFileSync(actionpath); } catch (e) { }
102 + 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; }
103 + 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] } } }
104 + if (settings == null) { settings = {}; }
105 +
106 + // Set the arguments
107 + if ((typeof args.action) == 'string') { settings.action = args.action; }
108 + if ((typeof args.localport) == 'string') { settings.localport = parseInt(args.localport); }
109 + if ((typeof args.remotenodeid) == 'string') { settings.remoteNodeId = args.remotenodeid; }
110 + if ((typeof args.username) == 'string') { settings.username = args.username; }
111 + if ((typeof args.password) == 'string') { settings.password = args.password; }
112 + if ((typeof args.user) == 'string') { settings.username = args.user; }
113 + if ((typeof args.pass) == 'string') { settings.password = args.pass; }
114 + if ((typeof args.host) == 'string') { settings.hostname = args.host; }
115 + if ((typeof args.hostname) == 'string') { settings.hostname = args.hostname; }
116 + if ((typeof args.serverid) == 'string') { settings.serverId = args.serverid; }
117 + if ((typeof args.serverhttpshash) == 'string') { settings.serverHttpsHash = args.serverhttpshash; }
118 + if ((typeof args.remoteport) == 'string') { settings.remotePort = parseInt(args.remoteport); }
119 + if ((typeof args.out) == 'string') { settings.output = args.out; }
120 + if ((typeof args.output) == 'string') { settings.output = args.output; }
121 + if ((typeof args.debug) == 'string') { settings.debugLevel = parseInt(args.debug); }
122 + if ((typeof args.script) == 'string') { settings.script = args.script; }
123 + if ((typeof args.agent) == 'string') { settings.agent = args.agent; }
124 + if (args.debug) { try { waitForDebugger(); } catch (e) { } }
125 + if (args.noconsole) { settings.noconsole = true; }
126 + if (args.nocommander) { settings.noconsole = true; }
127 + if (args.lmsdebug) { settings.lmsdebug = true; }
128 + if (args.tls) { settings.tls = true; }
129 + if ((argv.length > 1) && (actions.indexOf(argv[1].toUpperCase()) >= 0)) { settings.action = argv[1]; }
130 +
131 + // Validate meshaction.txt
132 + if (settings.action == null) {
133 + console.log('MeshCentral Command (MeshCmd) ' + meshCmdVersion);
134 + console.log('No action specified, use MeshCmd like this:\r\n');
135 + console.log(' meshcmd [action] [arguments...]\r\n');
136 + console.log('Valid MeshCentral actions:');
137 + console.log(' Route - Map a local TCP port to a remote computer.');
138 + console.log('\r\nValid local actions:');
139 + console.log(' SMBios - Display System Management BIOS tables for this computer.');
140 + console.log(' RawSMBios - Display RAW System Management BIOS tables for this computer.');
141 + console.log(' MicroLMS - Run MicroLMS, allowing local access to Intel AMT.');
142 + console.log(' AmtInfo - Show Intel AMT version and activation state.');
143 + console.log(' AmtVersions - Show all Intel ME version information.');
144 + console.log(' AmtHashes - Show all Intel AMT trusted activation hashes.');
145 + console.log(' AmtCCM - Activate Intel AMT into Client Control Mode.');
146 + console.log(' AmtDeactivate - Deactivate Intel AMT if activated in Client Control mode.');
147 + console.log('\r\nValid local or remote actions:');
148 + console.log(' MeshCommander - Launch a local MeshCommander web server.');
149 + console.log(' AmtUUID - Show Intel AMT unique identifier.');
150 + console.log(' AmtAuditLog - Show the Intel AMT audit log.');
151 + console.log(' AmtLoadWebApp - Load MeshCommander in Intel AMT 11.6+ firmware.');
152 + console.log(' AmtClearWebApp - Clear everything from Intel AMT web storage.');
153 + console.log(' AmtStorageState - Show contents of the Intel AMT web storage.');
154 + console.log(' AmtSaveState - Save all Intel AMT WSMAN object to file.');
155 + console.log(' AmtPresence - Heartbeat a local Intel AMT watchdog agent.');
156 + console.log(' AmtScript - Run .mescript on Intel AMT.');
157 + console.log('\r\nHelp on a specific action using:\r\n');
158 + console.log(' meshcmd help [action]');
159 + exit(1); return;
160 + }
161 + if (settings.action == 'help') {
162 + if (argv.length <= 2) {
163 + actions.shift();
164 + console.log('Help usage:\r\n\r\n MeshCmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.');
165 + exit(1); return;
166 + }
167 + var action = argv[2].toLowerCase();
168 + if (action == 'route') {
169 + 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");
170 + } else if (action == 'smbios') {
171 + 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");
172 + console.log('\r\Optional arguments:\r\n');
173 + console.log(' --output [filename] Optional filename to write the results to.');
174 + } else if (action == 'rawsmbios') {
175 + 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");
176 + console.log('\r\Optional arguments:\r\n');
177 + console.log(' --output [filename] Optional filename to write the results to.');
178 + } else if (action == 'amtinfo') {
179 + 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');
180 + } else if ((action == 'amtversion') || (action == 'amtversions')) {
181 + 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');
182 + } else if (action == 'amthashes') {
183 + 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');
184 + } else if ((action == 'microlms') || (action == 'lms') || (action == 'amtlms')) {
185 + 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');
186 + console.log('\r\nPossible arguments:\r\n');
187 + console.log(' --noconsole MeshCommander for LMS will no be available on port 16994.');
188 + console.log('\r\nRun as a background service:\r\n');
189 + console.log(' microlms install/uninstall/start/stop.');
190 + } else if (action == 'amtccm') {
191 + 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');
192 + } else if (action == 'amtdeactivate') {
193 + 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');
194 + } else if (action == 'amtuuid') {
195 + 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');
196 + console.log('\r\nPossible arguments:\r\n');
197 + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
198 + console.log(' --user [username] The Intel AMT login username, admin is default.');
199 + console.log(' --pass [password] The Intel AMT login password.');
200 + console.log(' --tls Specifies that TLS must be used.');
201 + } else if ((action == 'amtloadwebapp') || (action == 'amtloadsmallwebapp') || (action == 'amtloadlargewebapp') || (action == 'amtclearwebapp') || (action == 'amtstoragestate')) {
202 + 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');
203 + console.log('\r\nPossible arguments:\r\n');
204 + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
205 + console.log(' --user [username] The Intel AMT login username, admin is default.');
206 + console.log(' --pass [password] The Intel AMT login password.');
207 + console.log(' --tls Specifies that TLS must be used.');
208 + } else if (action == 'amtclearwebstorage') {
209 + 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');
210 + console.log('\r\nPossible arguments:\r\n');
211 + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
212 + console.log(' --user [username] The Intel AMT login username, admin is default.');
213 + console.log(' --pass [password] The Intel AMT login password.');
214 + console.log(' --tls Specifies that TLS must be used.');
215 + } else if (action == 'amtstoragestate') {
216 + 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');
217 + console.log('\r\nPossible arguments:\r\n');
218 + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
219 + console.log(' --user [username] The Intel AMT login username, admin is default.');
220 + console.log(' --pass [password] The Intel AMT login password.');
221 + console.log(' --tls Specifies that TLS must be used.');
222 + } else if (action == 'amtsavestate') {
223 + 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');
224 + console.log('\r\nPossible arguments:\r\n');
225 + console.log(' --output [filename] The output file for the Intel AMT state in JSON format.');
226 + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
227 + console.log(' --user [username] The Intel AMT login username, admin is default.');
228 + console.log(' --pass [password] The Intel AMT login password.');
229 + console.log(' --tls Specifies that TLS must be used.');
230 + } else if (action == 'amtpresence') {
231 + 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');
232 + console.log('\r\nPossible arguments:\r\n');
233 + console.log(' --user [username] The Intel AMT login username, admin is default.');
234 + console.log(' --pass [password] The Intel AMT login password.');
235 + console.log(' --agent [uuid] The unique identifier of the watchdog agent.');
236 + } else if (action == 'amtscript') {
237 + 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');
238 + console.log('\r\nPossible arguments:\r\n');
239 + console.log(' --script [filename] The script file to run on Intel AMT.');
240 + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
241 + console.log(' --user [username] The Intel AMT login username, admin is default.');
242 + console.log(' --pass [password] The Intel AMT login password.');
243 + console.log(' --tls Specifies that TLS must be used.');
244 + } else if (action == 'meshcommander') {
245 + console.log('This action launched a local web server that hosts MeshCommander, a Intel AMT management console.');
246 + console.log('\r\nPossible arguments:\r\n');
247 + console.log(' --localport [port] Local port used for the web server, 3000 is default.');
248 + console.log('\r\nRun as a background service:\r\n');
249 + console.log(' meshcommander install/uninstall/start/stop.');
250 + } else if (action == 'amtauditlog') {
251 + 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');
252 + console.log('\r\nPossible arguments:\r\n');
253 + console.log(' --output [filename] The output file for the Intel AMT state in JSON format.');
254 + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
255 + console.log(' --user [username] The Intel AMT login username, admin is default.');
256 + console.log(' --pass [password] The Intel AMT login password.');
257 + console.log(' --tls Specifies that TLS must be used.');
258 + } else {
259 + actions.shift();
260 + console.log('Invalid action, usage:\r\n\r\n meshcmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.');
261 + }
262 + exit(1); return;
263 + }
264 + settings.action = settings.action.toLowerCase();
265 + debug(1, "Settings: " + JSON.stringify(settings));
266 + if (settings.action == 'smbios') {
267 + // Display SM BIOS tables in raw form
268 + SMBiosTables = require('smbios');
269 + SMBiosTables.get(function (data) {
270 + var r = SMBiosTables.parse(data);
271 + var out = objToString(r, 0, '\r\n');
272 + 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); }
273 + exit(1);
274 + });
275 + } else if (settings.action == 'rawsmbios') {
276 + // Display SM BIOS tables in raw form
277 + SMBiosTables = require('smbios');
278 + SMBiosTables.get(function (data) {
279 + var out = '';
280 + 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'; } } }
281 + 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); }
282 + exit(1);
283 + });
284 + } else if (settings.action == 'route') {
285 + // MeshCentral Router, port map local TCP port to a remote computer
286 + 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; }
287 + if ((settings.remoteNodeId == null) || (typeof settings.remoteNodeId != 'string')) { console.log('No or invalid \"remoteNodeId\" specified.'); exit(1); return; }
288 + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { console.log('No or invalid \"username\" specified, use --username [username].'); exit(1); return; }
289 + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
290 + if ((settings.serverId == null) || (typeof settings.serverId != 'string') || (settings.serverId.length != 96)) { console.log('No or invalid \"serverId\" specified.'); exit(1); return; }
291 + if ((settings.serverHttpsHash == null) || (typeof settings.serverHttpsHash != 'string') || (settings.serverHttpsHash.length != 96)) { console.log('No or invalid \"serverHttpsHash\" specified.'); exit(1); return; }
292 + 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; }
293 + if (settings.serverUrl != null) { startRouter(); } else { discoverMeshServer(); } // Start MeshCentral Router
294 + } else if ((settings.action == 'amtloadwebapp') || (settings.action == 'amtloadsmallwebapp') || (settings.action == 'amtloadlargewebapp') || (settings.action == 'amtclearwebapp') || (settings.action == 'amtstoragestate')) { // Intel AMT Web Application Actions
295 + // Intel AMT 11.6+ Load MeshCommander into firmware
296 + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
297 + if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; }
298 + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
299 + settings.protocol = 'http:';
300 + settings.localport = 16992;
301 + debug(1, "Settings: " + JSON.stringify(settings));
302 + digest = require('http-digest').create(settings.username, settings.password);
303 + digest.http = require('http');
304 + if (settings.action == 'amtstoragestate') {
305 + 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; } });
306 + } else {
307 + if (settings.action == 'amtloadwebapp') { settings.webapp = Medium_IntelAmtWebApp; }
308 + else if (settings.action == 'amtloadsmallwebapp') { settings.webapp = Small_IntelAmtWebApp; }
309 + else if (settings.action == 'amtloadlargewebapp') { settings.webapp = Large_IntelAmtWebApp; }
310 + else if (settings.action == 'amtclearwebapp') { settings.webapp = null; }
311 + nextStepStorageUpload();
312 + }
313 + } else if ((settings.action == 'amtversion') || (settings.action == 'amtversions') || (settings.action == 'amtver')) {
314 + // Display Intel AMT versions
315 + var amtMeiModule, amtMei;
316 + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
317 + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
318 + amtMei.getVersion(function (val) {
319 + console.log("MEI Version = " + val.BiosVersion.toString());
320 + for (var version in val.Versions) { console.log(val.Versions[version].Description + " = " + val.Versions[version].Version); }
321 + exit(1); return;
322 + });
323 + } else if (settings.action == 'amthashes') {
324 + // Display Intel AMT list of trusted hashes
325 + var amtMeiModule, amtMei;
326 + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
327 + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
328 + amtMei.getHashHandles(function (handles) {
329 + exitOnCount = handles.length;
330 + for (var i = 0; i < handles.length; ++i) {
331 + this.getCertHashEntry(handles[i], function (result) {
332 + console.log(result.name + ', (' + (result.isDefault ? 'Default' : '') + (result.isActive ? ', Active' : ', Disabled') + ')\r\n ' + result.hashAlgorithmStr + ': ' + result.certificateHash);
333 + if (--exitOnCount == 0) { exit(1); }
334 + });
335 + }
336 + });
337 + } else if (settings.action == 'amtinfo') {
338 + // Display Intel AMT version and activation state
339 + mestate = {};
340 + var amtMeiModule, amtMei;
341 + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
342 + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
343 + amtMei.getVersion(function (result) { if (result) { for (var version in result.Versions) { if (result.Versions[version].Description == 'AMT') { mestate.ver = result.Versions[version].Version; } } } });
344 + amtMei.getProvisioningState(function (result) { if (result) { mestate.ProvisioningState = result; } });
345 + amtMei.getProvisioningMode(function (result) { if (result) { mestate.ProvisioningMode = result; } });
346 + amtMei.getEHBCState(function (result) { if (result) { mestate.ehbc = result; } });
347 + amtMei.getControlMode(function (result) { if (result) { mestate.controlmode = result; } });
348 + amtMei.getMACAddresses(function (result) { if (result) { mestate.mac = result; } });
349 + amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } });
350 + amtMei.getLanInterfaceSettings(1, function (result) { if (result) { mestate.net1 = result; } });
351 + amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } });
352 + amtMei.getDnsSuffix(function (result) {
353 + if (result) { mestate.dns = result; }
354 + if (mestate.ver && mestate.ProvisioningState && mestate.ProvisioningMode) {
355 + var str = 'Intel AMT v' + mestate.ver;
356 + if (mestate.ProvisioningState.stateStr == 'PRE') { str += ', pre-provisioning state'; }
357 + else if (mestate.ProvisioningState.stateStr == 'IN') { str += ', in-provisioning state'; }
358 + else if (mestate.ProvisioningState.stateStr == 'POST') {
359 + if (mestate.ProvisioningMode) {
360 + if (mestate.controlmode) {
361 + 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; }
362 + } else {
363 + str += ', activated in ' + mestate.ProvisioningMode.modeStr;
364 + }
365 + }
366 + }
367 + if ((mestate.ehbc) && (mestate.ehbc.EHBC == true)) { str += ', EHBC enabled'; }
368 + str += '.';
369 + 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)); }
370 + 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)); }
371 + console.log(str + '.');
372 + } else {
373 + console.log('Intel(R) AMT not supported.');
374 + }
375 + exit(1);
376 + });
377 + } else if (settings.action == 'amtinfodebug') {
378 + // Display Intel AMT version and activation state
379 + mestate = {};
380 + var amtMeiModule, amtMei;
381 + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
382 + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
383 + amtMei.getVersion(function (result) { console.log('getVersion: ' + JSON.stringify(result)); });
384 + amtMei.getProvisioningState(function (result) { console.log('getProvisioningState: ' + JSON.stringify(result)); });
385 + amtMei.getProvisioningMode(function (result) { console.log('getProvisioningMode: ' + JSON.stringify(result)); });
386 + amtMei.getEHBCState(function (result) { if (result) { console.log('getEHBCState: ' + JSON.stringify(result)); } });
387 + amtMei.getControlMode(function (result) { if (result) { console.log('getControlMode: ' + JSON.stringify(result)); } });
388 + amtMei.getMACAddresses(function (result) { if (result) { console.log('getMACAddresses: ' + JSON.stringify(result)); } });
389 + amtMei.getLanInterfaceSettings(0, function (result) { console.log('getLanInterfaceSettings0: ' + JSON.stringify(result)); });
390 + amtMei.getLanInterfaceSettings(1, function (result) { console.log('getLanInterfaceSettings1: ' + JSON.stringify(result)); });
391 + amtMei.getUuid(function (result) { console.log('getUuid: ' + JSON.stringify(result)); });
392 + amtMei.getDnsSuffix(function (result) { console.log('getDnsSuffix: ' + JSON.stringify(result)); });
393 + } else if (settings.action == 'amtsavestate') {
394 + // Save the entire state of Intel AMT info a JSON file
395 + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
396 + if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; }
397 + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
398 + if ((settings.output == null) || (typeof settings.output != 'string') || (settings.output == '')) { console.log('No or invalid \"output\" file specified, use --output [filename].'); exit(1); return; }
399 + settings.protocol = 'http:';
400 + settings.localport = 16992;
401 + debug(1, "Settings: " + JSON.stringify(settings));
402 + saveEntireAmtState();
403 + } else if ((settings.action == 'microlms') || (settings.action == 'amtlms') || (settings.action == 'lms')) {
404 + // Start Intel AMT MicroLMS
405 + startLms(function (state) {
406 + 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); }
407 + });
408 + } else if (settings.action == 'amtpresence') {
409 + // Heartbeat a Intel AMT watchdog
410 + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
411 + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
412 + if ((settings.agent == null) || (typeof settings.agent != 'string') || (settings.agent == '')) { console.log('No or invalid \"agent\" specified, use --agent [agent].'); exit(1); return; }
413 + performAmtAgentPresence();
414 + } else if (settings.action == 'amtscript') {
415 + // Start running a MEScript
416 + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
417 + if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; }
418 + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
419 + 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; } }
420 + startMeScript();
421 + } else if (settings.action == 'amtuuid') {
422 + // Start running
423 + if (settings.hostname != null) {
424 + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
425 + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
426 + }
427 + settings.protocol = 'http:';
428 + settings.localport = 16992;
429 + debug(1, "Settings: " + JSON.stringify(settings));
430 + getAmtUuid();
431 + } else if (settings.action == 'amtccm') {
432 + // Start activation to CCM
433 + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
434 + settings.protocol = 'http:';
435 + settings.localport = 16992;
436 + debug(1, "Settings: " + JSON.stringify(settings));
437 + activeToCCM();
438 + } else if (settings.action == 'amtdeactivate') {
439 + // Deactivate CCM
440 + debug(1, "Settings: " + JSON.stringify(settings));
441 + deactivateCCM();
442 + } else if (settings.action == 'meshcommander') { // Start MeshCommander
443 + startMeshCommander();
444 + } else if (settings.action == 'amtauditlog') { // Read the Intel AMT audit log
445 + if (settings.hostname != null) {
446 + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
447 + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
448 + } else { settings.hostname = '127.0.0.1'; }
449 + readAmtAuditLog();
450 + } else {
451 + console.log('Invalid \"action\" specified.'); exit(1); return;
452 + }
453 +}
454 +
455 +//
456 +// Intel AMT Agent Presence
457 +//
458 +
459 +function performAmtAgentPresence() { startLms(function () { tempWatchdogTimer = setTimeout(performAmtAgentPresenceRegister, 3000); }); }
460 +
461 +function performAmtAgentPresenceRegister() {
462 + // Setup the Intel AMT WSMAN stack
463 + tempWatchdogTimer = null;
464 + var transport = require('amt-wsman-duk');
465 + var wsman = require('amt-wsman');
466 + var amt = require('amt');
467 + wsstack = new wsman(transport, '127.0.0.1', settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
468 + amtstack = new amt(wsstack);
469 +
470 + // Register the watchdog
471 + watchdog = { DeviceID: Buffer.from(guidToStr(settings.agent.split('-').join('')).split('-').join(''), 'hex').toString('base64'), Retry: 0 };
472 + amtstack.AMT_AgentPresenceWatchdog_RegisterAgent(performAmtAgentPresenceRegisterRetry, watchdog, watchdog.Seq, { 'DeviceID': watchdog.DeviceID });
473 +}
474 +
475 +// Called after the agent is registered
476 +function performAmtAgentPresenceRegisterRetry(stack, name, response, status, watchdog) {
477 + if ((status == 200) && (response.Body.SessionSequenceNumber) && (response.Body.TimeoutInterval)) {
478 + console.log('Asserting presence of the watchdog...');
479 + watchdog.Seq = response.Body.SessionSequenceNumber;
480 + watchdog.Interval = response.Body.TimeoutInterval * 800;
481 + watchdog.Retry = 0;
482 + tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval);
483 + } else {
484 + debug(1, 'Failed to register, status = ' + status);
485 + watchdog.Retry++;
486 + if (watchdog.Retry < 5) {
487 + tempWatchdogTimer = setTimeout(function () { amtstack.AMT_AgentPresenceWatchdog_RegisterAgent(performAmtAgentPresenceRegisterRetry, watchdog, watchdog.Seq, { 'DeviceID': watchdog.DeviceID }); }, 1000);
488 + } else {
489 + console.log('Failed to register this watchdog.');
490 + process.exit(0);
491 + }
492 + }
493 +}
494 +
495 +// Start a new agent assert
496 +function performAmtAgentPresenceAssert() {
497 + watchdog.Seq++;
498 + amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceAssertRetry, watchdog, 0, { 'DeviceID': watchdog.DeviceID });
499 +}
500 +
501 +// Called after the agent is asserted
502 +function performAmtAgentPresenceAssertRetry(stack, name, response, status, watchdog) {
503 + if (status == 200) {
504 + debug(1, 'Succesful assert, sequence = ' + watchdog.Seq);
505 + watchdog.Retry = 0;
506 + tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval);
507 + } else {
508 + debug(1, 'Failed to assert, status = ' + status);
509 + watchdog.Retry++;
510 + if (watchdog.Retry < 5) {
511 + amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceAssertRetry, watchdog, 0, { 'DeviceID': watchdog.DeviceID });
512 + } else {
513 + console.log('Failed to assert presence on this watchdog.');
514 + process.exit(0);
515 + }
516 + }
517 +}
518 +
519 +function performAmtAgentPresenceEx5(stack, name, response, status, watchdog) {
520 + console.log('b', status, watchdog);
521 + if (status == 200) {
522 + watchdog.Retry = 0;
523 + } else {
524 + watchdog.Retry++;
525 + if (watchdog.Retry < 5) {
526 + amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceEx4, watchdog, 0, { 'DeviceID': watchdog.DeviceID });
527 + } else {
528 + console.log('Failed to assert presence on this watchdog.');
529 + process.exit(0);
530 + }
531 + }
532 +}
533 +
534 +//
535 +// Intel AMT Audit Log
536 +//
537 +
538 +function readAmtAuditLog() {
539 + // See if MicroLMS needs to be started
540 + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) {
541 + settings.noconsole = true; startLms(readAmtAuditLogEx);
542 + } else {
543 + readAmtAuditLogEx(9999);
544 + }
545 +}
546 +
547 +function readAmtAuditLogEx(x) {
548 + if (x == 9999) {
549 + var transport = require('amt-wsman-duk');
550 + var wsman = require('amt-wsman');
551 + var amt = require('amt');
552 + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
553 + amtstack = new amt(wsstack);
554 + amtstack.GetAuditLog(readAmtAuditLogEx2);
555 + } else {
556 + osamtstack.GetAuditLog(readAmtAuditLogEx2);
557 + }
558 +}
559 +
560 +function readAmtAuditLogEx2(stack, response, status) {
561 + if (status != 200) {
562 + console.log('Unable to get audit log, status = ' + status + '.');
563 + } else {
564 + var out = '';
565 + for (var i in response) {
566 + var name = ((response[i].Initiator != '') ? (response[i].Initiator + ': ') : '')
567 + out += (response[i].Time + ' - ' + name + response[i].Event + '\r\n');
568 + }
569 + 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); }
570 + }
571 + exit(1);
572 +}
573 +
574 +
575 +//
576 +// MeshCommander local web server
577 +//
578 +
579 +function startMeshCommander() {
580 + // MeshCommander Local v0.7.4
581 + var _IntelAmtLocalWebApp_etag = "LlnBXeX//SEsHV5KjuEC";
582 + var _IntelAmtLocalWebApp = "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";
583 +
584 + if (settings.localport == null) { settings.localport = 3000; }
585 +
586 + // Start the web server
587 + var http = require('http');
588 + webServer = http.createServer();
589 + webServer.listen(settings.localport);
590 + webServer.wsList = {};
591 + webServer.wsListIndex = 0;
592 + webServer.on('upgrade', function (req, socket, head) {
593 + //console.log("WebSocket for " + req.url.split('?')[0]);
594 + switch (req.url.split('?')[0]) {
595 + case '/webrelay.ashx': // MeshCommander relay channel
596 + var ws = socket.upgradeWebSocket();
597 + socket.ws = ws;
598 + ws.wsIndex = ++webServer.wsListIndex;
599 + webServer.wsList[ws.wsIndex] = ws; // Keep a reference so the websocket and forwarder don't get disposed.
600 + ws.pause();
601 +
602 + // We got a new web socket connection, initiate a TCP connection to the target Intel AMT host/port.
603 + var webargs = parseUrlArguments(req.url);
604 + if (webargs.p) { webargs.p = parseInt(webargs.p); }
605 + if (webargs.tls) { webargs.tls = parseInt(webargs.tls); }
606 + if (webargs.tls1only) { webargs.tls1only = parseInt(webargs.tls1only); }
607 + if (webargs.port) { webargs.port = parseInt(webargs.port); }
608 + //console.log('Opening web socket connection to ' + webargs.host + ':' + webargs.port + '.');
609 + if (webargs.tls == 0) {
610 + // If this is TCP (without TLS) set a normal TCP socket
611 + var net = require('net');
612 + ws.forwardclient = net.connect({ host: webargs.host, port: webargs.port })
613 + ws.forwardclient.on('connect', function () { this.pipe(this.ws, { end: false }); this.ws.pipe(this, { end: false }); });
614 + ws.forwardclient.ws = ws;
615 + } else {
616 + // If TLS is going to be used, setup a TLS socket
617 + var tls = require('tls');
618 + var tlsoptions = { host: webargs.host, port: webargs.port, secureProtocol: ((webargs.tls1only == 1) ? 'TLSv1_method' : 'SSLv23_method'), rejectUnauthorized: false };
619 + ws.forwardclient = tls.connect(tlsoptions, function () { this.pipe(this.ws, { end: false }); this.ws.pipe(this, { end: false }); });
620 + ws.forwardclient.ws = ws;
621 + }
622 +
623 + // Handle pipe closure
624 + ws.on('end', function () { try { this.forwardclient.end(); } catch (e) { } delete webServer.wsList[this.wsIndex]; });
625 + ws.forwardclient.on('end', function () { try { this.ws.end(); } catch (e) { } });
626 +
627 + break;
628 + default:
629 + socket.end();
630 + break;
631 + }
632 + });
633 + webServer.on('request', function (req, rsp) {
634 + //console.log("WebRequest for " + req.url.split('?')[0]);
635 + switch (req.url.split('?')[0]) {
636 + case '/': // Serve MeshCommander Web Application
637 + var meshcommander = null;
638 + try { meshcommander = fs.readFileSync('meshcommander.htm'); } catch (e) { }
639 + if (meshcommander != null) {
640 + rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Transfer-Encoding': 'chunked' });
641 + rsp.end(meshcommander);
642 + } else {
643 + 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 });
644 + rsp.end(Buffer.from(_IntelAmtLocalWebApp, 'base64'));
645 + }
646 + break;
647 + default: // Unknown request
648 + rsp.statusCode = 404;
649 + rsp.statusMessage = "Not Found";
650 + rsp.end();
651 + break;
652 + }
653 + });
654 + console.log('MeshCommander running on HTTP port ' + settings.localport + '.');
655 + console.log('Press ctrl-c to exit.');
656 +}
657 +
658 +
659 +//
660 +// Deactivate Intel AMT CCM
661 +//
662 +
663 +// 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.
664 +function deactivateCCM() {
665 + var amtMeiModule, amtMei;
666 + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
667 + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
668 + amtMei.unprovision(1, function (status) { if (status == 0) { console.log('Success'); } else { console.log('Error ' + status); } exit(1); });
669 +}
670 +
671 +
672 +//
673 +// Activate Intel AMT to CCM
674 +//
675 +
676 +function activeToCCM() {
677 + // See if MicroLMS needs to be started and setup the $$OsAdmin wsman stack
678 + settings.noconsole = true;
679 + startLms(activeToCCMEx); // TODO: Fix this so that it works even if LMS already running.
680 +}
681 +
682 +function activeToCCMEx(state) {
683 + osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], activeToCCMEx2);
684 +}
685 +
686 +function activeToCCMEx2(stack, name, responses, status) {
687 + if (status != 200) { console.log('Failed to fetch activation status, status ' + status); exit(1); }
688 + else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { console.log('Client control mode activation not allowed'); exit(1); }
689 + else { osamtstack.IPS_HostBasedSetupService_Setup(2, md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + settings.password).substring(0, 32), null, null, null, null, activeToCCMEx3); }
690 +}
691 +
692 +function activeToCCMEx3(stack, name, responses, status) {
693 + if (status != 200) { console.log('Failed to activate, status ' + status); }
694 + else if (responses.Body.ReturnValue != 0) { console.log('Client control mode activation failed: ' + responses.Body.ReturnValueStr); }
695 + else { console.log('Success'); exit(0); }
696 + exit(1);
697 +}
698 +
699 +
700 +//
701 +// Get AMT UUID
702 +//
703 +
704 +// Called to get the UUID of Intel AMT, start by setting up MicroLMS if we are doing the operation on the local computer
705 +function getAmtUuid() {
706 + if (settings.hostname == null) {
707 + var amtMeiModule, amtMei;
708 + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
709 + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
710 + amtMei.getUuid(function (result) { if ((result == null) || (result.uuid == null)) { console.log('Failed.'); } else { console.log(result.uuid); } exit(1); });
711 + } else {
712 + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { settings.noconsole = true; startLms(getAmtUuidEx); return; } else { getAmtUuidEx(); }
713 + }
714 +}
715 +
716 +// Fetch the computer's UUID by fetching the CIM_ComputerSystemPackage WSMAN object.
717 +function getAmtUuidEx() {
718 + var transport = require('amt-wsman-duk');
719 + var wsman = require('amt-wsman');
720 + var amt = require('amt');
721 + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
722 + amtstack = new amt(wsstack);
723 + amtstack.Get("CIM_ComputerSystemPackage", function (obj, name, response, xstatus, tag) {
724 + if (xstatus == 200) { console.log("GUID: " + guidToStr(response.Body.PlatformGUID.toLowerCase())); } else { console.log("Intel AMT is not available or not activated."); } exit(1);
725 + });
726 +}
727 +
728 +
729 +//
730 +// Run MESCRIPT
731 +//
732 +
733 +// Run a .mescript targeting local or remote Intel AMT.
734 +function startMeScript() {
735 + // See if MicroLMS needs to be started
736 + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { settings.noconsole = true; startLms(startMeScriptEx); return; } else { startMeScriptEx(); }
737 +}
738 +
739 +function startMeScriptEx() {
740 + //console.log('Running script...');
741 + var transport = require('amt-wsman-duk');
742 + var wsman = require('amt-wsman');
743 + var amt = require('amt');
744 + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
745 + amtstack = new amt(wsstack);
746 + //IntelAmtEntireStateProgress = 101;
747 + //amtstack.onProcessChanged = onWsmanProcessChanged;
748 +
749 + var scriptData = null;
750 + if (settings.script != null) {
751 + try { scriptData = fs.readFileSync(settings.script); } catch (e) { console.log('Unable to read script file (1): ' + settings.script + '.'); exit(1); return; }
752 + } else {
753 + scriptData = settings.scriptJSON;
754 + }
755 + if (scriptData == null) { console.log('Unable to read script file (2): ' + settings.script + '.'); exit(1); return; }
756 + try { scriptData = JSON.parse(scriptData); } catch (e) { console.log('Unable to read script file (3): ' + settings.script + '.'); exit(1); return; }
757 + if (scriptData.mescript == null) { console.log('Unable to read script file (4): ' + settings.script + '.'); exit(1); return; }
758 + var scriptData = Buffer.from(scriptData.mescript, 'base64');
759 +
760 + var scriptModule = require('amt-script');
761 + var script = scriptModule.setup(scriptData, {})
762 + script.amtstack = amtstack;
763 + script.start();
764 + script.onCompleted = function () { exit(1); }
765 +}
766 +
767 +
768 +//
769 +// FETCH ALL INTEL AMT STATE
770 +//
771 +
772 +
773 +function saveEntireAmtState2()
774 +{
775 + console.log('Fetching all Intel AMT state, this may take a few minutes...');
776 + var transport = require('amt-wsman-duk');
777 + var wsman = require('amt-wsman');
778 + var amt = require('amt');
779 + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
780 + amtstack = new amt(wsstack);
781 + amtstack.onProcessChanged = onWsmanProcessChanged;
782 + //var AllWsman = "AMT_GeneralSystemDefenseCapabilities".split(',');
783 + 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(',');
784 + IntelAmtEntireStateProgress = 101;
785 + IntelAmtEntireStateCalls = 3;
786 + IntelAmtEntireState = { 'localtime': Date(), 'utctime': new Date().toUTCString(), 'isotime': new Date().toISOString() };
787 + amtstack.BatchEnum(null, AllWsman, saveEntireAmtStateOk2, null, true);
788 + amtstack.GetAuditLog(saveEntireAmtStateOk3);
789 + amtstack.GetMessageLog(saveEntireAmtStateOk4);
790 +
791 +}
792 +
793 +// Save the entire Intel AMT state
794 +function saveEntireAmtState()
795 +{
796 + // See if MicroLMS needs to be started
797 + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost'))
798 + {
799 + settings.noconsole = true;
800 + startLms().then(saveEntireAmtState2);
801 + }
802 + else
803 + {
804 + saveEntireAmtState2();
805 + }
806 +}
807 +
808 +function onWsmanProcessChanged(a, b) { var x = Math.floor((a * 100) / b); if (x < IntelAmtEntireStateProgress) { IntelAmtEntireStateProgress = x; console.log((100 - x) + '%'); } }
809 +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(); }
810 +function saveEntireAmtStateOk3(stack, messages, status) { if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); exit(2); } IntelAmtEntireState['auditlog'] = messages; saveEntireAmtStateDone(); }
811 +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(); }
812 +
813 +// Called when the entire state of Intel AMT is fetched.
814 +function saveEntireAmtStateDone() {
815 + if (--IntelAmtEntireStateCalls != 0) return;
816 + var out = fs.openSync(settings.output, 'w');
817 + fs.writeSync(out, Buffer.from(JSON.stringify(IntelAmtEntireState)));
818 + fs.closeSync(out);
819 + console.log('Done, results written to ' + settings.output + '.');
820 + exit(1);
821 +}
822 +
823 +
824 +//
825 +// FETCH ALL INTEL AMT MEI STATE
826 +//
827 +
828 +// Get Intel AMT information using MEI
829 +// TODO: If this call is called many time at once, it's going to cause issues.
830 +var getAmtInfoFetching = null;
831 +var getAmtInfoFetchingTimer = null;
832 +function getAmtInfo(func, tag) {
833 + if (amtMei == null) { if (func != null) { func(null, tag); } return; }
834 + if (getAmtInfoFetching != null) { getAmtInfoFetching.push({ f: func, t: tag }); return; }
835 + getAmtInfoFetching = [{ f: func, t: tag }];
836 + amtMeiTmpState = { Flags: 0, TrustedHashes: [] }; // Flags: 1=EHBC, 2=CCM, 4=ACM
837 + getAmtInfoFetchingTimer = setTimeout(function () {
838 + // MEI failed to respond, break out and reset everthing.
839 + for (var i in getAmtInfoFetching) { if (getAmtInfoFetching[i].f != null) { getAmtInfoFetching[i].f(amtMeiTmpState, getAmtInfoFetching[i].t); } }
840 + getAmtInfoFetching = null;
841 + getAmtInfoFetchingTimer = null;
842 + var amtMeiModule, amtMei;
843 + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
844 + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
845 + }, 3000);
846 + amtMei.getProtocolVersion(function (result) { if (result != null) { amtMeiTmpState.MeiVersion = result; } });
847 + amtMei.getVersion(function (val) {
848 + amtMeiTmpState.Versions = {};
849 + if (val != null) {
850 + for (var version in val.Versions) { amtMeiTmpState.Versions[val.Versions[version].Description] = val.Versions[version].Version; }
851 + amtMei.getProvisioningMode(function (result) { if (result != null) { amtMeiTmpState.ProvisioningMode = result.mode; } });
852 + amtMei.getProvisioningState(function (result) { if (result != null) { amtMeiTmpState.ProvisioningState = result.state; } });
853 + amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } });
854 + amtMei.getControlMode(function (result) { if (result != null) { if (result.controlMode == 1) { amtMeiTmpState.Flags += 2; } if (result.controlMode == 2) { amtMeiTmpState.Flags += 4; } } });
855 + //amtMei.getMACAddresses(function (result) { if (result != null) { amtMeiTmpState.mac = result; } });
856 + amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } });
857 + amtMei.getHashHandles(function (handles) {
858 + exitOnCount = handles.length;
859 + for (var i = 0; i < handles.length; ++i) {
860 + amtMei.getCertHashEntry(handles[i], function (result) {
861 + amtMeiTmpState.TrustedHashes.push({ Active: result.isActive, Default: result.isDefault, HashAlgorithm: result.hashAlgorithm, Name: result.name, Hash: result.certificateHash });
862 + if (--exitOnCount == 0) {
863 + amtMeiTmpState.Notifications = lmsNotifications; amtMeiState = amtMeiTmpState;
864 + for (var i in getAmtInfoFetching) { if (getAmtInfoFetching[i].f != null) { getAmtInfoFetching[i].f(amtMeiTmpState, getAmtInfoFetching[i].t); } }
865 + getAmtInfoFetching = null;
866 + clearTimeout(getAmtInfoFetchingTimer);
867 + getAmtInfoFetchingTimer = null;
868 + }
869 + });
870 + }
871 + });
872 + } else {
873 + amtMeiState = amtMeiTmpState;
874 + amtMeiState.ProvisioningMode = -858993460;
875 + amtMeiState.TrustedHashes = {};
876 + amtMeiState.Notifications = lmsNotifications;
877 + //console.log('getAmtInfo3', JSON.stringify(amtMeiState));
878 + if (func != null) { func(amtMeiState, tag); }
879 + }
880 + });
881 +}
882 +
883 +
884 +//
885 +// MicroLMS
886 +//
887 +
888 +var lmsControlSockets = {};
889 +var lmsControlSocketsNextId = 1;
890 +var lmsNotifications = [];
891 +var amtLms = null;
892 +var promise = require('promise');
893 +
894 +function startLms(func)
895 +{
896 + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
897 + var lme_heci = null
898 + try { lme_heci = require('amt-lme'); } catch (ex) { }
899 + if (lme_heci == null) { if (func != null) { func(func, 0); } this.promise._res(); return; }
900 +
901 + //var amtLms = null;
902 + var http = require('http');
903 +
904 + // MeshCommander LMS v0.7.4
905 + var _IntelAmtWebApp_etag = "W7PrsMdzMZVycLmuKL5r";
906 + var _IntelAmtWebApp = "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";
907 +
908 + console.log('Setting up MEI...');
909 + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; }
910 + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
911 + //console.log("PTHI Connected.");
912 +
913 + console.log('Setting up LME...');
914 + amtLms = new lme_heci({ debug: settings.lmsdebug });
915 + amtLms.promise = ret;
916 + amtLms.on('error', function (e) {
917 + console.log('LME connection failed', e);
918 + setupMeiOsAdmin(func, amtLms.connected == false ? 0 : 3);
919 + this.promise._res();
920 + });
921 + amtLms.on('notify', function (data, options, str, code) {
922 + if (code == 'iAMT0052-3') {
923 + kvmGetData();
924 + } else if (str != null) {
925 + var notify = { date: Date.now(), str: str, code: code };
926 + lmsNotifications.push(notify);
927 + while (lmsNotifications.length > 100) { lmsNotifications.shift(); }
928 + var notifyBuf = Buffer.concat([Buffer.from('0900', 'hex'), Buffer.from(JSON.stringify(notify))]) // Add a notification
929 + for (var i in lmsControlSockets) { lmsControlSockets[i].write(notifyBuf); }
930 + }
931 + });
932 + //console.log('LME Connecting...');
933 + amtLms.on('bind', function (mapping) {
934 + if (mapping[16992]) { this.removeAllListeners('bind'); } else { return; }
935 + //console.log('LMS Bounded');
936 + amtLms.connected = true;
937 + this.promise._res();
938 +
939 + //console.log("LME Connected.");
940 + if (settings.noconsole !== true) {
941 + amtLms.meshCommander = http.createServer();
942 + amtLms.meshCommander.listen(16994);
943 + amtLms.meshCommander.on('upgrade', function (req, socket, head) {
944 + //console.log("WebSocket for " + req.url.split('?')[0]);
945 + switch (req.url.split('?')[0]) {
946 + case '/lms.ashx': // MeshCommander control channel (PTHI)
947 + socket.ws = socket.upgradeWebSocket();
948 + socket.ws.on('data', processLmsControlData);
949 + socket.ws.on('end', function () { if (lmsControlSockets[this.id]) { delete lmsControlSockets[this.id]; /*console.log('removeControl', JSON.stringify(lmsControlSockets));*/ } });
950 + var id = lmsControlSocketsNextId++;
951 + lmsControlSockets[id] = socket.ws;
952 + socket.ws.id = id;
953 + //socket.ws.write(Buffer.concat([Buffer.from('0900', 'hex'), Buffer.from(JSON.stringify(lmsNotifications))])); // Send out full list of notifications
954 + //console.log('addControl', JSON.stringify(lmsControlSockets));
955 + break;
956 + case '/webrelay.ashx': // MeshCommander data channel (LME)
957 + socket.ws = socket.upgradeWebSocket();
958 + amtLms.bindDuplexStream(socket.ws, 'IPv4', 16992);
959 + break;
960 + default:
961 + socket.end();
962 + break;
963 + }
964 + });
965 + amtLms.meshCommander.on('request', function (req, rsp) {
966 + //console.log("WebRequest for " + req.url.split('?')[0]);
967 + switch (req.url.split('?')[0]) {
968 + case '/': // Serve MeshCommander Web Application for LMS
969 + var lmscommander = null;
970 + try { lmscommander = fs.readFileSync('lmscommander.htm'); } catch (e) { }
971 + if (lmscommander != null) {
972 + rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Transfer-Encoding': 'chunked' });
973 + rsp.end(lmscommander);
974 + } else {
975 + 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 });
976 + rsp.end(Buffer.from(_IntelAmtWebApp, 'base64'));
977 + }
978 + break;
979 + default: // Unknown request
980 + rsp.statusCode = 404;
981 + rsp.statusMessage = "Not Found";
982 + rsp.end();
983 + break;
984 + }
985 +
986 + });
987 + //console.log("LMS started, MeshCommander on HTTP/16994.");
988 + tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 2); }, 100);
989 + //console.logReferenceCount(tempTimer);
990 + } else {
991 + //console.log("LMS started.");
992 + tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 1); }, 100);
993 + //console.logReferenceCount(tempTimer);
994 + }
995 +
996 + });
997 + return (ret);
998 +}
999 +
1000 +function setupMeiOsAdmin(func, state) {
1001 + if (amtMei == null) {
1002 + if (func) { func(state); }
1003 + } else {
1004 + amtMei.getLocalSystemAccount(function (x) {
1005 + var transport = require('amt-wsman-duk');
1006 + var wsman = require('amt-wsman');
1007 + var amt = require('amt');
1008 + oswsstack = new wsman(transport, '127.0.0.1', 16992, x.user, x.pass, false);
1009 + osamtstack = new amt(oswsstack);
1010 + if (func) { func(state); }
1011 + //var AllWsman = "CIM_SoftwareIdentity,IPS_SecIOService,IPS_ScreenSettingData,IPS_ProvisioningRecordLog,IPS_HostBasedSetupService,IPS_HostIPSettings,IPS_IPv6PortSettings".split(',');
1012 + //osamtstack.BatchEnum(null, AllWsman, startLmsWsmanResponse, null, true);
1013 + //*************************************
1014 +
1015 + // Setup KVM data channel if this is Intel AMT 12 or above
1016 + amtMei.getVersion(function (x) {
1017 + var amtver = null;
1018 + try { for (var i in x.Versions) { if (x.Versions[i].Description == 'AMT') amtver = parseInt(x.Versions[i].Version.split('.')[0]); } } catch (e) { }
1019 + if ((amtver != null) && (amtver >= 12)) {
1020 + kvmGetData('skip'); // Clear any previous data, this is a dummy read to about handling old data.
1021 + tempTimer = setInterval(function () { kvmGetData(); }, 2000); // Start polling for KVM data.
1022 + kvmSetData(JSON.stringify({ action: 'restart', ver: 1 })); // Send a restart command to advise the console if present that MicroLMS just started.
1023 + }
1024 + });
1025 + });
1026 + }
1027 +}
1028 +
1029 +function kvmGetData(tag) {
1030 + osamtstack.IPS_KVMRedirectionSettingData_DataChannelRead(kvmDataGetResponse, tag);
1031 +}
1032 +
1033 +function kvmDataGetResponse(stack, name, response, status, tag) {
1034 + if ((tag != 'skip') && (status == 200) && (response.Body.ReturnValue == 0)) {
1035 + var val = null;
1036 + try { val = Buffer.from(response.Body.DataMessage, 'base64').toString(); } catch (e) { return }
1037 + if (val != null) { kvmProcessData(response.Body.RealmsBitmap, response.Body.MessageId, val); }
1038 + }
1039 +}
1040 +
1041 +var webRtcDesktop = null;
1042 +function kvmProcessData(realms, messageId, val) {
1043 + var data = null;
1044 + try { data = JSON.parse(val) } catch (e) { }
1045 + if ((data != null) && (data.action)) {
1046 + if (data.action == 'present') { kvmSetData(JSON.stringify({ action: 'present', ver: 1, platform: process.platform })); }
1047 + if (data.action == 'offer') {
1048 + webRtcDesktop = {};
1049 + var rtc = require('ILibWebRTC');
1050 + webRtcDesktop.webrtc = rtc.createConnection();
1051 + webRtcDesktop.webrtc.on('connected', function () { });
1052 + webRtcDesktop.webrtc.on('disconnected', function () { webRtcCleanUp(); });
1053 + webRtcDesktop.webrtc.on('dataChannel', function (rtcchannel) {
1054 + webRtcDesktop.rtcchannel = rtcchannel;
1055 + var kvmmodule = require('meshDesktop');
1056 + webRtcDesktop.kvm = kvmmodule.getRemoteDesktopStream();
1057 + webRtcDesktop.kvm.pipe(webRtcDesktop.rtcchannel, { dataTypeSkip: 1, end: false });
1058 + webRtcDesktop.rtcchannel.on('end', function () { webRtcCleanUp(); });
1059 + webRtcDesktop.rtcchannel.on('data', function (x) { kvmCtrlData(this, x); });
1060 + webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm, { dataTypeSkip: 1, end: false });
1061 + //webRtcDesktop.kvm.on('end', function () { console.log('WebRTC DataChannel closed2'); webRtcCleanUp(); });
1062 + //webRtcDesktop.rtcchannel.on('data', function (data) { console.log('WebRTC data: ' + data); });
1063 + });
1064 + kvmSetData(JSON.stringify({ action: 'answer', ver: 1, sdp: webRtcDesktop.webrtc.setOffer(data.sdp) }));
1065 + }
1066 + }
1067 +}
1068 +
1069 +// Polyfill path.join
1070 +var path = {
1071 + join: function () {
1072 + var x = [];
1073 + for (var i in arguments) {
1074 + var w = arguments[i];
1075 + if (w != null) {
1076 + while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
1077 + if (i != 0) {
1078 + while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); }
1079 + }
1080 + x.push(w);
1081 + }
1082 + }
1083 + if (x.length == 0) return '/';
1084 + return x.join('/');
1085 + }
1086 +};
1087 +
1088 +// Get a formated response for a given directory path
1089 +function getDirectoryInfo(reqpath) {
1090 + var response = { path: reqpath, dir: [] };
1091 + if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) {
1092 + // List all the drives in the root, or the root itself
1093 + var results = null;
1094 + try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
1095 + //console.log('a', objToString(results, 0, ' '));
1096 + if (results != null) {
1097 + for (var i = 0; i < results.length; ++i) {
1098 + var drive = { n: results[i].name, t: 1 };
1099 + if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons.
1100 + response.dir.push(drive);
1101 + }
1102 + }
1103 + } else {
1104 + // List all the files and folders in this path
1105 + if (reqpath == '') { reqpath = '/'; }
1106 + var xpath = path.join(reqpath, '*');
1107 + var results = null;
1108 +
1109 + try { results = fs.readdirSync(xpath); } catch (e) { }
1110 + if (results != null) {
1111 + for (var i = 0; i < results.length; ++i) {
1112 + if ((results[i] != '.') && (results[i] != '..')) {
1113 + var stat = null, p = path.join(reqpath, results[i]);
1114 + try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date
1115 + if ((stat != null) && (stat != undefined)) {
1116 + if (stat.isDirectory() == true) {
1117 + response.dir.push({ n: results[i], t: 2, d: stat.mtime });
1118 + } else {
1119 + response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime });
1120 + }
1121 + }
1122 + }
1123 + }
1124 + }
1125 + }
1126 + return response;
1127 +}
1128 +
1129 +// Process KVM control channel data
1130 +function kvmCtrlData(channel, cmd) {
1131 + if (cmd.length > 0 && cmd.charCodeAt(0) != 123) {
1132 + // This is upload data
1133 + if (this.fileupload != null) {
1134 + cmd = Buffer.from(cmd, 'base64');
1135 + var header = cmd.readUInt32BE(0);
1136 + if ((header == 0x01000000) || (header == 0x01000001)) {
1137 + fs.writeSync(this.fileupload.fp, cmd.slice(4));
1138 + channel.write({ action: 'upload', sub: 'ack', reqid: this.fileupload.reqid });
1139 + if (header == 0x01000001) { fs.closeSync(this.fileupload.fp); this.fileupload = null; } // Close the file
1140 + }
1141 + }
1142 + return;
1143 + }
1144 + //console.log('KVM Ctrl Data', cmd);
1145 +
1146 + try { cmd = JSON.parse(cmd); } catch (ex) { console.error('Invalid JSON: ' + cmd); return; }
1147 + if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
1148 + switch (cmd.action) {
1149 + case 'ping': {
1150 + // This is a keep alive
1151 + channel.write({ action: 'pong' });
1152 + break;
1153 + }
1154 + case 'ls': {
1155 + /*
1156 + // Close the watcher if required
1157 + var samepath = ((this.httprequest.watcher != undefined) && (cmd.path == this.httprequest.watcher.path));
1158 + if ((this.httprequest.watcher != undefined) && (samepath == false)) {
1159 + //console.log('Closing watcher: ' + this.httprequest.watcher.path);
1160 + //this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!!
1161 + delete this.httprequest.watcher;
1162 + }
1163 + */
1164 +
1165 + // Send the folder content to the browser
1166 + var response = getDirectoryInfo(cmd.path);
1167 + if (cmd.reqid != undefined) { response.reqid = cmd.reqid; }
1168 + channel.write(response);
1169 +
1170 + /*
1171 + // Start the directory watcher
1172 + if ((cmd.path != '') && (samepath == false)) {
1173 + var watcher = fs.watch(cmd.path, onFileWatcher);
1174 + watcher.tunnel = this.httprequest;
1175 + watcher.path = cmd.path;
1176 + this.httprequest.watcher = watcher;
1177 + //console.log('Starting watcher: ' + this.httprequest.watcher.path);
1178 + }
1179 + */
1180 + break;
1181 + }
1182 + case 'mkdir': {
1183 + // Create a new empty folder
1184 + fs.mkdirSync(cmd.path);
1185 + break;
1186 + }
1187 + case 'rm': {
1188 + // Remove many files or folders
1189 + for (var i in cmd.delfiles) {
1190 + var fullpath = path.join(cmd.path, cmd.delfiles[i]);
1191 + try { fs.unlinkSync(fullpath); } catch (e) { console.log(e); }
1192 + }
1193 + break;
1194 + }
1195 + case 'rename': {
1196 + // Rename a file or folder
1197 + var oldfullpath = path.join(cmd.path, cmd.oldname);
1198 + var newfullpath = path.join(cmd.path, cmd.newname);
1199 + try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); }
1200 + break;
1201 + }
1202 + case 'download': {
1203 + // Download a file, to browser
1204 + var sendNextBlock = 0;
1205 + if (cmd.sub == 'start') { // Setup the download
1206 + if (this.filedownload != null) { channel.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
1207 + this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
1208 + 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; }
1209 + if (this.filedownload) { channel.write({ action: 'download', sub: 'start', id: cmd.id }); }
1210 + } else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands
1211 + if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; }
1212 + }
1213 + // Send the next download block(s)
1214 + while (sendNextBlock > 0) {
1215 + sendNextBlock--;
1216 + var buf = Buffer.alloc(4096);
1217 + var len = fs.readSync(this.filedownload.f, buf, 4, 4092, null);
1218 + this.filedownload.ptr += len;
1219 + if (len < 4092) { buf.writeInt32BE(0x01000001, 0); fs.closeSync(this.filedownload.f); delete this.filedownload; sendNextBlock = 0; } else { buf.writeInt32BE(0x01000000, 0); }
1220 + channel.write(buf.slice(0, len + 4).toString('base64')); // Write as Base64
1221 + }
1222 + break;
1223 + }
1224 + case 'upload': {
1225 + // Upload a file, from browser
1226 + if (cmd.sub == 'start') { // Start the upload
1227 + if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); }
1228 + if (!cmd.path || !cmd.name) break;
1229 + this.fileupload = { reqid: cmd.reqid };
1230 + var filepath = path.join(cmd.path, cmd.name);
1231 + try { this.fileupload.fp = fs.openSync(filepath, 'wbN'); } catch (e) { }
1232 + 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 }); }
1233 + }
1234 + else if (cmd.sub == 'cancel') { // Stop the upload
1235 + if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); this.fileupload = null; }
1236 + }
1237 + break;
1238 + }
1239 + case 'copy': {
1240 + // Copy a bunch of files from scpath to dspath
1241 + for (var i in cmd.names) {
1242 + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
1243 + if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
1244 + }
1245 + break;
1246 + }
1247 + case 'move': {
1248 + // Move a bunch of files from scpath to dspath
1249 + for (var i in cmd.names) {
1250 + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
1251 + if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
1252 + }
1253 + break;
1254 + }
1255 + default:
1256 + // Unknown action, ignore it.
1257 + break;
1258 + }
1259 +}
1260 +
1261 +function webRtcCleanUp() {
1262 + if (webRtcDesktop == null) return;
1263 + if (webRtcDesktop.rtcchannel) {
1264 + try { webRtcDesktop.rtcchannel.close(); } catch (e) { }
1265 + try { webRtcDesktop.rtcchannel.removeAllListeners('data'); } catch (e) { }
1266 + try { webRtcDesktop.rtcchannel.removeAllListeners('end'); } catch (e) { }
1267 + delete webRtcDesktop.rtcchannel;
1268 + }
1269 + if (webRtcDesktop.webrtc) {
1270 + try { webRtcDesktop.webrtc.close(); } catch (e) { }
1271 + try { webRtcDesktop.webrtc.removeAllListeners('connected'); } catch (e) { }
1272 + try { webRtcDesktop.webrtc.removeAllListeners('disconnected'); } catch (e) { }
1273 + try { webRtcDesktop.webrtc.removeAllListeners('dataChannel'); } catch (e) { }
1274 + delete webRtcDesktop.webrtc;
1275 + }
1276 + if (webRtcDesktop.kvm) {
1277 + try { webRtcDesktop.kvm.end(); } catch (e) { }
1278 + delete webRtcDesktop.kvm;
1279 + }
1280 + webRtcDesktop = null;
1281 +}
1282 +
1283 +function kvmSetData(x) {
1284 + osamtstack.IPS_KVMRedirectionSettingData_DataChannelWrite(Buffer.from(x).toString('base64'), function () { });
1285 +}
1286 +
1287 +function startLmsWsmanResponse(stack, name, responses, status) {
1288 + if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); }
1289 + else if (status != 200) { console.log('ERROR: Unable to get object from Intel(R) AMT, status = ' + status + '.'); }
1290 + else {
1291 + //console.log(JSON.stringify(responses), status);
1292 + var amtlogicalelements = responses["CIM_SoftwareIdentity"].responses;
1293 + if (amtlogicalelements.length > 0) {
1294 + var v = getInstance(amtlogicalelements, "AMT")["VersionString"];
1295 + amtversion = parseInt(v.split('.')[0]);
1296 + amtversionmin = parseInt(v.split('.')[1]);
1297 + //console.log(amtversion, amtversionmin);
1298 + }
1299 + }
1300 +}
1301 +
1302 +
1303 +// Process commands in the LMS control channel
1304 +// Command 9 is add a notification.
1305 +function processLmsControlData(data) {
1306 + if (data.length < 2) return;
1307 + var cmdid = data.readUInt16LE(0);
1308 + switch (cmdid) {
1309 + case 1: // Request basic Intel AMT information (CMD = 1)
1310 + { getAmtInfo(function (meinfo, socket) { meinfo.LoginMode = 2; socket.write(Buffer.concat([Buffer.from('0100', 'hex'), Buffer.from(JSON.stringify(meinfo))])); }, this); break; }
1311 + case 2: // Intel AMT MEI Unprovision (CMD = 2)
1312 + { 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; }
1313 + case 3: // Intel AMT MEI GetLocalSystemAccount (CMD = 3)
1314 + { amtMei.getLocalSystemAccount(function (account, socket) { socket.write(Buffer.concat([Buffer.from('030000000000', 'hex'), account.raw])); }, this); break; }
1315 + case 4: // Instruct Intel AMT to start remote configuration (CMD = 4)
1316 + { amtMei.startConfiguration(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
1317 + case 5: // Instruct Intel AMT to stop remote configuration (CMD = 5)
1318 + { amtMei.stopConfiguration(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
1319 + case 6: // Instruct Intel AMT connect CIRA (CMD = 6)
1320 + { amtMei.openUserInitiatedConnection(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
1321 + case 7: // Instruct Intel AMT disconnect CIRA (CMD = 7)
1322 + { amtMei.closeUserInitiatedConnection(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; }
1323 + case 8: // Get Intel AMT CIRA State (CMD = 8)
1324 + { 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; }
1325 + default:
1326 + // Unknown action, ignore it.
1327 + break;
1328 + }
1329 +}
1330 +
1331 +
1332 +//
1333 +// MeshCentral TCP port router
1334 +//
1335 +
1336 +function startRouter() {
1337 + tcpserver = net.createServer(OnTcpClientConnected);
1338 + tcpserver.on('error', function (e) { console.log('ERROR: ' + JSON.stringify(e)); exit(0); return; });
1339 + tcpserver.listen(settings.localPort, function () {
1340 + // We started listening.
1341 + if (settings.remoteName == null) {
1342 + console.log('Redirecting local port ' + settings.localPort + ' to remote port ' + settings.remotePort + '.');
1343 + } else {
1344 + console.log('Redirecting local port ' + settings.localPort + ' to ' + settings.remoteName + ':' + settings.remotePort + '.');
1345 + }
1346 + console.log('Press ctrl-c to exit.');
1347 +
1348 + // If settings has a "cmd", run it now.
1349 + //process.exec("notepad.exe");
1350 + });
1351 +}
1352 +
1353 +// Called when a TCP connect is received on the local port. Launch a tunnel.
1354 +function OnTcpClientConnected(c) {
1355 + try {
1356 + // 'connection' listener
1357 + debug(1, 'Client connected');
1358 + c.on('end', function () { disconnectTunnel(this, this.websocket, 'Client closed'); });
1359 + c.pause();
1360 + try {
1361 + options = http.parseUri(settings.serverUrl + '?user=' + settings.username + '&pass=' + settings.password + '&nodeid=' + settings.remoteNodeId + '&tcpport=' + settings.remotePort);
1362 + } catch (e) { console.log('Unable to parse \"serverUrl\".'); process.exit(1); return; }
1363 + options.checkServerIdentity = onVerifyServer;
1364 + options.rejectUnauthorized = false;
1365 + c.websocket = http.request(options);
1366 + c.websocket.tcp = c;
1367 + c.websocket.tunneling = false;
1368 + c.websocket.upgrade = OnWebSocket;
1369 + c.websocket.on('error', function (e) { console.log('ERROR: ' + JSON.stringify(e)); });
1370 + c.websocket.end();
1371 + } catch (e) { debug(2, e); }
1372 +}
1373 +
1374 +// Disconnect both TCP & WebSocket connections and display a message.
1375 +function disconnectTunnel(tcp, ws, msg) {
1376 + if (ws != null) { try { ws.end(); } catch (e) { debug(2, e); } }
1377 + if (tcp != null) { try { tcp.end(); } catch (e) { debug(2, e); } }
1378 + debug(1, 'Tunnel disconnected: ' + msg);
1379 +}
1380 +
1381 +// Called when the web socket gets connected
1382 +function OnWebSocket(msg, s, head) {
1383 + debug(1, 'Websocket connected');
1384 + s.on('data', function (msg) {
1385 + if (this.parent.tunneling == false) {
1386 + msg = msg.toString();
1387 + if (msg == 'c') {
1388 + this.parent.tunneling = true; this.pipe(this.parent.tcp); this.parent.tcp.pipe(this); debug(1, 'Tunnel active');
1389 + } else if ((msg.length > 6) && (msg.substring(0, 6) == 'error:')) {
1390 + console.log(msg.substring(6));
1391 + disconnectTunnel(this.tcp, this, msg.substring(6));
1392 + }
1393 + }
1394 + });
1395 + s.on('error', function (msg) { disconnectTunnel(this.tcp, this, 'Websocket error'); });
1396 + s.on('close', function (msg) { disconnectTunnel(this.tcp, this, 'Websocket closed'); });
1397 + s.parent = this;
1398 +}
1399 +
1400 +// Try to discover the location of the mesh server
1401 +function discoverMeshServer() { console.log('Looking for server...'); discoveryInterval = setInterval(discoverMeshServerOnce, 5000); discoverMeshServerOnce(); }
1402 +
1403 +// Try to discover the location of the mesh server only once
1404 +function discoverMeshServerOnce() {
1405 + var interfaces = os.networkInterfaces();
1406 + for (var adapter in interfaces) {
1407 + if (interfaces.hasOwnProperty(adapter)) {
1408 + for (var i = 0; i < interfaces[adapter].length; ++i) {
1409 + var addr = interfaces[adapter][i];
1410 + multicastSockets[i] = dgram.createSocket({ type: (addr.family == "IPv4" ? "udp4" : "udp6") });
1411 + multicastSockets[i].bind({ address: addr.address, exclusive: false });
1412 + if (addr.family == "IPv4") {
1413 + try {
1414 + multicastSockets[i].addMembership(membershipIPv4);
1415 + //multicastSockets[i].setMulticastLoopback(true);
1416 + multicastSockets[i].once('message', OnMulticastMessage);
1417 + multicastSockets[i].send(settings.serverId, 16989, membershipIPv4);
1418 + } catch (e) { }
1419 + }
1420 + }
1421 + }
1422 + }
1423 +}
1424 +
1425 +// Called when a multicast packet is received
1426 +function OnMulticastMessage(msg, rinfo) {
1427 + var m = msg.toString().split('|');
1428 + if ((m.length == 3) && (m[0] == 'MeshCentral2') && (m[1] == settings.serverId)) {
1429 + settings.serverUrl = m[2].replace('%s', rinfo.address).replace('/agent.ashx', '/meshrelay.ashx');
1430 + console.log('Found server at ' + settings.serverUrl + '.');
1431 + if (discoveryInterval != null) { clearInterval(discoveryInterval); discoveryInterval = null; }
1432 + startRouter();
1433 + }
1434 +}
1435 +
1436 +
1437 +//
1438 +// PUSH MESHCOMMANDER INTO FIRMWARE
1439 +//
1440 +
1441 +function nextStepStorageUpload() {
1442 + debug(3, "nextStepStorageUpload");
1443 + getAmtStorage(function (statusCode, data) {
1444 + if (statusCode == 200) {
1445 + debug(2, "getAmtStorage: " + JSON.stringify(data, null, 2));
1446 + if ((data['content'] != null) && (data['content']['index.htm'] != null)) { nextStepStorageUpload3('index.htm'); }
1447 + else if ((data['content'] != null) && (data['content']['logon.htm'] != null)) { nextStepStorageUpload3('logon.htm'); }
1448 + else if ((data['content'] != null) && (data['content']['logon.htm'] != null)) { nextStepStorageUpload3('logon.htm'); }
1449 + else { nextStepStorageUpload2('index.htm', null); }
1450 + } else {
1451 + console.log("Unable to read storage state.");
1452 + exit();
1453 + return;
1454 + }
1455 + });
1456 +}
1457 +
1458 +function nextStepStorageUpload2(uploadName, linkName) {
1459 + debug(3, "nextStepStorageUpload2");
1460 + if (settings.webapp == null) { console.log("Done."); exit(); return; } else {
1461 + console.log("Uploading MeshCommander...");
1462 + pushToStorage(uploadName, linkName, Buffer.from(settings.webapp, 'base64'), function (statusCode) {
1463 + if (statusCode == 500) { console.log("Error, check that computer is powered on."); exit(); return; }
1464 + if (statusCode != 200) {
1465 + if (uploadName == 'index.htm') {
1466 + nextStepStorageUpload2('mesh/commander/console', 'MeshCommander');
1467 + } else {
1468 + console.log("Unable to upload MeshCommander, status = " + statusCode + "."); exit(); return;
1469 + }
1470 + } else {
1471 + console.log("Verifying MeshCommander...");
1472 + verifyStorage(uploadName, Buffer.from(settings.webapp, 'base64'), function (verified) {
1473 + if (verified == true) { console.log('Done.'); } else { console.log('MeshCommander verification failed.'); }
1474 + exit(); return;
1475 + });
1476 + }
1477 + });
1478 + }
1479 +}
1480 +
1481 +function nextStepStorageUpload3(deleteName) {
1482 + console.log("Deleting " + deleteName + " from storage...");
1483 + deleteStorage(deleteName, function (statusCode) {
1484 + if (statusCode == 500) { console.log("Error, check that computer is powered on."); exit(); return; }
1485 + if (statusCode == 200) { nextStepStorageUpload(); } else { console.log("Unable to delete " + deleteName + "."); exit(); return; }
1486 + });
1487 +}
1488 +
1489 +// Fetch the Intel AMT storage document
1490 +function getAmtStorage(func, noretry) {
1491 + var req = digest.request({ protocol: settings.protocol, method: "GET", host: settings.hostname, path: "/amt-storage/", port: settings.localport },
1492 + function (response) {
1493 + if (response.statusCode != 200) { console.log("Unable to connect to Intel(R) AMT."); func(response.statusCode, null); }
1494 + response.on('data', function (chunk) { if (response.acc == null) { response.acc = chunk; } else { response.acc += chunk; } });
1495 + response.on('end', function () {
1496 + var data = response.acc.toString(), len, data2, amtstorage = null;
1497 + try {
1498 + 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.
1499 + 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.
1500 + amtstorage = JSON.parse(data);
1501 + } catch (e) { console.log("Error: Unable to parse Intel AMT response."); func(null); }
1502 + if (func != null) { func(response.statusCode, amtstorage); }
1503 + });
1504 + });
1505 + req.on('error', function (e) { console.log("Error occured: " + JSON.stringify(e)); if (noretry == true) { if (func != null) { func(null); } } else { getAmtStorage(func, true); } });
1506 + req.end();
1507 +}
1508 +
1509 +// Fetch the Intel AMT storage document
1510 +function pushToStorage(name, linkname, data, func, ptr) {
1511 + if (ptr == null) { ptr = 0; }
1512 + var req = digest.request({ protocol: settings.protocol, method: "PUT", host: settings.hostname, path: ("/amt-storage/" + name + ((ptr != 0) ? '?append=' : '')), port: settings.localport });
1513 + req.on('error', function (e) { console.log("Error occured: " + JSON.stringify(e)); if (func != null) { func(null); } });
1514 + req.on('response', function (response) {
1515 + debug(1, 'Chunk Done', data.length, ptr);
1516 + if ((response.statusCode == 200) && (ptr < data.length)) { pushToStorage(name, linkname, data, func, ptr); } else { if (func != null) { func(response.statusCode); } }
1517 + });
1518 + var header = (ptr > 0) ? '<metadata></metadata>' : '<metadata><headers><h>Content-Encoding:gzip</h><h>Content-Type:text/html</h></headers>' + ((linkname != null) ? ('<link>' + linkname + '</link>') : '') + '</metadata>';
1519 + var blocklen = ((data.length - ptr) > (7000 - header.length)) ? (7000 - header.length) : (data.length - ptr);
1520 + req.write(Buffer.concat([new Buffer(header), data.slice(ptr, ptr + blocklen)]));
1521 + ptr += blocklen;
1522 + req.end();
1523 +}
1524 +
1525 +// Fetch the Intel AMT storage document
1526 +function verifyStorage(name, data, func) {
1527 + var req = digest.request({ protocol: settings.protocol, method: "GET", host: settings.hostname, path: ("/amt-storage/" + name), port: settings.localport });
1528 + req.on('error', function (e) { console.log("Verify error occured: " + JSON.stringify(e)); if (func != null) { func(null); } });
1529 + req.on('response', function (response) {
1530 + response.ptr = 0;
1531 + response.ok = true;
1532 + 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; });
1533 + response.on('end', function () { if (func != null) { func(response.ok); } });
1534 + });
1535 + req.end();
1536 +}
1537 +
1538 +// Fetch the Intel AMT storage document
1539 +function deleteStorage(name, func, noretry) {
1540 + var req = digest.request({ protocol: settings.protocol, method: "DELETE", host: settings.hostname, path: "/amt-storage/" + name, port: settings.localport });
1541 + 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); } } } });
1542 + req.on('response', function (response) { if (func != null) { func(response.statusCode); } });
1543 + req.end();
1544 +}
1545 +
1546 +// Parse URL arguments
1547 +function parseUrlArguments(url) {
1548 + var r = {}, x = url.split('?');
1549 + if (x.length < 2) return r;
1550 + x = x[1].split('&');
1551 + 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); } }
1552 + return r;
1553 +}
1554 +
1555 +// Remove a element from a array
1556 +function removeItemFromArray(array, element) {
1557 + var index = array.indexOf(element);
1558 + if (index !== -1) { array.splice(index, 1); }
1559 +}
1560 +
1561 +// Run MeshCmd, but before we do, we need to see if what type of service we are going to be
1562 +var serviceName = null;
1563 +var serviceOpSpecified = 0;
1564 +var serviceInstall = 0;
1565 +
1566 +for (var i in process.argv) {
1567 + if (process.argv[i].toLowerCase() == 'install') { serviceInstall = 1 } else if (process.argv[i].toLowerCase() == 'uninstall') { serviceInstall = -1 }
1568 + if ((process.argv[i].toLowerCase() == 'microlms') || (process.argv[i].toLowerCase() == 'amtlms') || (process.argv[i].toLowerCase() == 'lms')) { serviceName = 'MicroLMS'; break; }
1569 + if ((process.argv[i].toLowerCase() == 'meshcommander') || (process.argv[i].toLowerCase() == 'commander')) { serviceName = 'MeshCommander'; break; }
1570 +}
1571 +
1572 +if (serviceName == null) {
1573 + for (var i in process.argv) {
1574 + if ((process.argv[i].toLowerCase() == 'install') || (process.argv[i].toLowerCase() == 'uninstall')) {
1575 + console.log('In order to install/uninstall, a service type must be specified.');
1576 + process.exit();
1577 + }
1578 + }
1579 + if (process.execPath.includes('MicroLMS')) { serviceName = 'MicroLMS'; }
1580 + else if (process.execPath.includes('MeshCommander')) { serviceName = 'MeshCommander'; }
1581 + else { serviceName = 'not_a_service'; }
1582 +}
1583 +
1584 +if (serviceInstall == 0) {
1585 + run(process.argv);
1586 +} else {
1587 + var serviceHost = require('service-host');
1588 + var meshcmdService = new serviceHost({ name: serviceName, startType: 'AUTO_START' });
1589 +
1590 + // Called when the background service is started.
1591 + meshcmdService.on('serviceStart', function onStart() {
1592 + console.setDestination(console.Destinations.DISABLED); // Disable console.log().
1593 + if (process.execPath.includes('MicroLMS')) { run([process.execPath, 'microlms']); } //
1594 + else if (process.execPath.includes('MeshCommander')) { run([process.execPath, 'meshcommander']); }
1595 + else { console.log('Aborting Service Start, because unknown binary: ' + process.execPath); process.exit(1); }
1596 + });
1597 +
1598 + // Called when the background service is stopping
1599 + 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.
1600 +
1601 + // Called when the executable is not running as a service, run normally.
1602 + meshcmdService.on('normalStart', function onNormalStart() { try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); } });
1603 + meshcmdService.run();
1604 +}
agents-new/meshcore-old.js new
+1761
@@ -0,0 +1,1761 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +process.on('uncaughtException', function (ex) {
18 + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": "uncaughtException1: " + ex });
19 +});
20 +
21 +// NOTE: This seems to cause big problems, don't enable the debugger in the server's meshcore.
22 +//attachDebugger({ webport: 9999, wait: 1 }).then(function (prt) { console.log('Point Browser for Debug to port: ' + prt); });
23 +
24 +// Mesh Rights
25 +var MESHRIGHT_EDITMESH = 1;
26 +var MESHRIGHT_MANAGEUSERS = 2;
27 +var MESHRIGHT_MANAGECOMPUTERS = 4;
28 +var MESHRIGHT_REMOTECONTROL = 8;
29 +var MESHRIGHT_AGENTCONSOLE = 16;
30 +var MESHRIGHT_SERVERFILES = 32;
31 +var MESHRIGHT_WAKEDEVICE = 64;
32 +var MESHRIGHT_SETNOTES = 128;
33 +var MESHRIGHT_REMOTEVIEW = 256;
34 +var MESHRIGHT_NOTERMINAL = 512;
35 +var MESHRIGHT_NOFILES = 1024;
36 +var MESHRIGHT_NOAMT = 2048;
37 +var MESHRIGHT_LIMITEDINPUT = 4096;
38 +
39 +function createMeshCore(agent) {
40 + var obj = {};
41 +
42 + /*
43 + function borderController() {
44 + this.container = null;
45 + this.Start = function Start(user) {
46 + if (this.container == null) {
47 + if (process.platform == 'win32') {
48 + try {
49 + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.SessionId });
50 + } catch (ex) {
51 + this.container = require('ScriptContainer').Create({ processIsolation: 1 });
52 + }
53 + } else {
54 + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.uid });
55 + }
56 + this.container.parent = this;
57 + this.container.addModule('monitor-info', getJSModule('monitor-info'));
58 + this.container.addModule('monitor-border', getJSModule('monitor-border'));
59 + this.container.addModule('promise', getJSModule('promise'));
60 + this.container.once('exit', function (code) { sendConsoleText('Border Process Exited with code: ' + code); this.parent.container = this.parent._container = null; });
61 + this.container.ExecuteString("var border = require('monitor-border'); border.Start();");
62 + }
63 + }
64 + this.Stop = function Stop() {
65 + if (this.container != null) {
66 + this._container = this.container;
67 + this._container.parent = this;
68 + this.container = null;
69 + this._container.exit();
70 + }
71 + }
72 + }
73 + obj.borderManager = new borderController();
74 + */
75 +
76 + // MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent.
77 + 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
78 +
79 + // Get the operating system description string
80 + try { require('os').name().then(function (v) { meshCoreObj.osdesc = v; }); } catch (ex) { }
81 +
82 + var meshServerConnectionState = 0;
83 + var tunnels = {};
84 + var lastMeInfo = null;
85 + var lastNetworkInfo = null;
86 + var lastPublicLocationInfo = null;
87 + var selfInfoUpdateTimer = null;
88 + var http = require('http');
89 + var net = require('net');
90 + var fs = require('fs');
91 + var rtc = require('ILibWebRTC');
92 + var amt = null;
93 + var processManager = require('process-manager');
94 + var wifiScannerLib = null;
95 + var wifiScanner = null;
96 + var networkMonitor = null;
97 + var amtscanner = null;
98 + var nextTunnelIndex = 1;
99 + var amtPolicy = null;
100 +
101 + // If we are running in Duktape, agent will be null
102 + if (agent == null) {
103 + // Running in native agent, Import libraries
104 + db = require('SimpleDataStore').Shared();
105 + sha = require('SHA256Stream');
106 + mesh = require('MeshAgent');
107 + childProcess = require('child_process');
108 + if (mesh.hasKVM == 1) { // if the agent is compiled with KVM support
109 + // Check if this computer supports a desktop
110 + try { if ((process.platform == 'win32') || (process.platform == 'darwin') || (require('monitor-info').kvm_x11_support)) { meshCoreObj.caps |= 1; } } catch (ex) { }
111 + }
112 + } else {
113 + // Running in nodejs
114 + meshCoreObj.value += '-NodeJS';
115 + meshCoreObj.caps = 8;
116 + mesh = agent.getMeshApi();
117 + }
118 +
119 + /*
120 + var AMTScanner = require("AMTScanner");
121 + var scan = new AMTScanner();
122 +
123 + scan.on("found", function (data) {
124 + if (typeof data === 'string') {
125 + console.log(data);
126 + } else {
127 + console.log(JSON.stringify(data, null, " "));
128 + }
129 + });
130 + scan.scan("10.2.55.140", 1000);
131 + scan.scan("10.2.55.139-10.2.55.145", 1000);
132 + scan.scan("10.2.55.128/25", 2000);
133 + */
134 +
135 + /*
136 + // Try to load up the network monitor
137 + try {
138 + networkMonitor = require('NetworkMonitor');
139 + networkMonitor.on('change', function () { sendNetworkUpdateNagle(); });
140 + networkMonitor.on('add', function (addr) { sendNetworkUpdateNagle(); });
141 + networkMonitor.on('remove', function (addr) { sendNetworkUpdateNagle(); });
142 + } catch (e) { networkMonitor = null; }
143 + */
144 +
145 + // Try to load up the Intel AMT scanner
146 + try {
147 + var AMTScannerModule = require('amt-scanner');
148 + amtscanner = new AMTScannerModule();
149 + //amtscanner.on('found', function (data) { if (typeof data != 'string') { data = JSON.stringify(data, null, " "); } sendConsoleText(data); });
150 + } catch (ex) { amtscanner = null; }
151 +
152 + // Fetch the SMBios Tables
153 + var SMBiosTables = null;
154 + var SMBiosTablesRaw = null;
155 + try {
156 + var SMBiosModule = null;
157 + try { SMBiosModule = require('smbios'); } catch (ex) { }
158 + if (SMBiosModule != null) {
159 + SMBiosModule.get(function (data) {
160 + if (data != null) {
161 + SMBiosTablesRaw = data;
162 + SMBiosTables = require('smbios').parse(data)
163 + if (mesh.isControlChannelConnected) { mesh.SendCommand({ "action": "smbios", "value": SMBiosTablesRaw }); }
164 +
165 + // If SMBios tables say that AMT is present, try to connect MEI
166 + if (SMBiosTables.amtInfo && (SMBiosTables.amtInfo.AMT == true)) {
167 + var amtmodule = require('amt-manage');
168 + amt = new amtmodule(mesh, db, true);
169 + amt.onStateChange = function (state) { if (state == 2) { sendPeriodicServerUpdate(1); } }
170 + if (amtPolicy != null) { amt.setPolicy(amtPolicy); }
171 + amt.start();
172 + }
173 + }
174 + });
175 + }
176 + } catch (ex) { sendConsoleText("ex1: " + ex); }
177 +
178 + // Try to load up the WIFI scanner
179 + try {
180 + var wifiScannerLib = require('wifi-scanner');
181 + wifiScanner = new wifiScannerLib();
182 + wifiScanner.on('accessPoint', function (data) { sendConsoleText("wifiScanner: " + data); });
183 + } catch (ex) { wifiScannerLib = null; wifiScanner = null; }
184 +
185 + // Get our location (lat/long) using our public IP address
186 + var getIpLocationDataExInProgress = false;
187 + var getIpLocationDataExCounts = [0, 0];
188 + function getIpLocationDataEx(func) {
189 + if (getIpLocationDataExInProgress == true) { return false; }
190 + try {
191 + getIpLocationDataExInProgress = true;
192 + getIpLocationDataExCounts[0]++;
193 + var options = http.parseUri("http://ipinfo.io/json");
194 + options.method = 'GET';
195 + http.request(options, function (resp) {
196 + if (resp.statusCode == 200) {
197 + var geoData = '';
198 + resp.data = function (geoipdata) { geoData += geoipdata; };
199 + resp.end = function () {
200 + var location = null;
201 + try {
202 + if (typeof geoData == 'string') {
203 + var result = JSON.parse(geoData);
204 + if (result.ip && result.loc) { location = result; }
205 + }
206 + } catch (e) { }
207 + if (func) { getIpLocationDataExCounts[1]++; func(location); }
208 + }
209 + } else { func(null); }
210 + getIpLocationDataExInProgress = false;
211 + }).end();
212 + return true;
213 + }
214 + catch (e) { return false; }
215 + }
216 +
217 + // Remove all Gateway MAC addresses for interface list. This is useful because the gateway MAC is not always populated reliably.
218 + function clearGatewayMac(str) {
219 + if (str == null) return null;
220 + var x = JSON.parse(str);
221 + for (var i in x.netif) { if (x.netif[i].gatewaymac) { delete x.netif[i].gatewaymac } }
222 + return JSON.stringify(x);
223 + }
224 +
225 + function getIpLocationData(func) {
226 + // Get the location information for the cache if possible
227 + var publicLocationInfo = db.Get('publicLocationInfo');
228 + if (publicLocationInfo != null) { publicLocationInfo = JSON.parse(publicLocationInfo); }
229 + if (publicLocationInfo == null) {
230 + // Nothing in the cache, fetch the data
231 + getIpLocationDataEx(function (locationData) {
232 + if (locationData != null) {
233 + publicLocationInfo = {};
234 + publicLocationInfo.netInfoStr = lastNetworkInfo;
235 + publicLocationInfo.locationData = locationData;
236 + var x = db.Put('publicLocationInfo', JSON.stringify(publicLocationInfo)); // Save to database
237 + if (func) func(locationData); // Report the new location
238 + } else {
239 + if (func) func(null); // Report no location
240 + }
241 + });
242 + } else {
243 + // Check the cache
244 + if (clearGatewayMac(publicLocationInfo.netInfoStr) == clearGatewayMac(lastNetworkInfo)) {
245 + // Cache match
246 + if (func) func(publicLocationInfo.locationData);
247 + } else {
248 + // Cache mismatch
249 + getIpLocationDataEx(function (locationData) {
250 + if (locationData != null) {
251 + publicLocationInfo = {};
252 + publicLocationInfo.netInfoStr = lastNetworkInfo;
253 + publicLocationInfo.locationData = locationData;
254 + var x = db.Put('publicLocationInfo', JSON.stringify(publicLocationInfo)); // Save to database
255 + if (func) func(locationData); // Report the new location
256 + } else {
257 + if (func) func(publicLocationInfo.locationData); // Can't get new location, report the old location
258 + }
259 + });
260 + }
261 + }
262 + }
263 +
264 + // Polyfill String.endsWith
265 + if (!String.prototype.endsWith) {
266 + String.prototype.endsWith = function (searchString, position) {
267 + var subjectString = this.toString();
268 + if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { position = subjectString.length; }
269 + position -= searchString.length;
270 + var lastIndex = subjectString.lastIndexOf(searchString, position);
271 + return lastIndex !== -1 && lastIndex === position;
272 + };
273 + }
274 +
275 + // Polyfill path.join
276 + obj.path = {
277 + join: function () {
278 + var x = [];
279 + for (var i in arguments) {
280 + var w = arguments[i];
281 + if (w != null) {
282 + while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
283 + if (i != 0) {
284 + while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); }
285 + }
286 + x.push(w);
287 + }
288 + }
289 + if (x.length == 0) return '/';
290 + return x.join('/');
291 + }
292 + };
293 +
294 + // Replace a string with a number if the string is an exact number
295 + function toNumberIfNumber(x) { if ((typeof x == 'string') && (+parseInt(x) === x)) { x = parseInt(x); } return x; }
296 +
297 + // Convert decimal to hex
298 + function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); }
299 +
300 + // Convert a raw string to a hex string
301 + function rstr2hex(input) { var r = '', i; for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); } return r; }
302 +
303 + // Convert a buffer into a string
304 + function buf2rstr(buf) { var r = ''; for (var i = 0; i < buf.length; i++) { r += String.fromCharCode(buf[i]); } return r; }
305 +
306 + // Convert a hex string to a raw string // TODO: Do this using Buffer(), will be MUCH faster
307 + function hex2rstr(d) {
308 + if (typeof d != "string" || d.length == 0) return '';
309 + var r = '', m = ('' + d).match(/../g), t;
310 + while (t = m.shift()) r += String.fromCharCode('0x' + t);
311 + return r
312 + }
313 +
314 + // Convert an object to string with all functions
315 + function objToString(x, p, pad, ret) {
316 + if (ret == undefined) ret = '';
317 + if (p == undefined) p = 0;
318 + if (x == null) { return '[null]'; }
319 + if (p > 8) { return '[...]'; }
320 + if (x == undefined) { return '[undefined]'; }
321 + if (typeof x == 'string') { if (p == 0) return x; return '"' + x + '"'; }
322 + if (typeof x == 'buffer') { return '[buffer]'; }
323 + if (typeof x != 'object') { return x; }
324 + var r = '{' + (ret ? '\r\n' : ' ');
325 + for (var i in x) { if (i != '_ObjectID') { r += (addPad(p + 2, pad) + i + ': ' + objToString(x[i], p + 2, pad, ret) + (ret ? '\r\n' : ' ')); } }
326 + return r + addPad(p, pad) + '}';
327 + }
328 +
329 + // Return p number of spaces
330 + function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ret; } return r; }
331 +
332 + // Split a string taking into account the quoats. Used for command line parsing
333 + function splitArgs(str) {
334 + var myArray = [], myRegexp = /[^\s"]+|"([^"]*)"/gi;
335 + do { var match = myRegexp.exec(str); if (match != null) { myArray.push(match[1] ? match[1] : match[0]); } } while (match != null);
336 + return myArray;
337 + }
338 +
339 + // Parse arguments string array into an object
340 + function parseArgs(argv) {
341 + var results = { '_': [] }, current = null;
342 + for (var i = 1, len = argv.length; i < len; i++) {
343 + var x = argv[i];
344 + if (x.length > 2 && x[0] == '-' && x[1] == '-') {
345 + if (current != null) { results[current] = true; }
346 + current = x.substring(2);
347 + } else {
348 + if (current != null) { results[current] = toNumberIfNumber(x); current = null; } else { results['_'].push(toNumberIfNumber(x)); }
349 + }
350 + }
351 + if (current != null) { results[current] = true; }
352 + return results;
353 + }
354 +
355 + // Get server target url with a custom path
356 + function getServerTargetUrl(path) {
357 + var x = mesh.ServerUrl;
358 + //sendConsoleText("mesh.ServerUrl: " + mesh.ServerUrl);
359 + if (x == null) { return null; }
360 + if (path == null) { path = ''; }
361 + x = http.parseUri(x);
362 + if (x == null) return null;
363 + return x.protocol + '//' + x.host + ':' + x.port + '/' + path;
364 + }
365 +
366 + // Get server url. If the url starts with "*/..." change it, it not use the url as is.
367 + function getServerTargetUrlEx(url) {
368 + if (url.substring(0, 2) == '*/') { return getServerTargetUrl(url.substring(2)); }
369 + return url;
370 + }
371 +
372 + // Send a wake-on-lan packet
373 + function sendWakeOnLan(hexMac) {
374 + var count = 0;
375 + try {
376 + var interfaces = require('os').networkInterfaces();
377 + var magic = 'FFFFFFFFFFFF';
378 + for (var x = 1; x <= 16; ++x) { magic += hexMac; }
379 + var magicbin = Buffer.from(magic, 'hex');
380 +
381 + for (var adapter in interfaces) {
382 + if (interfaces.hasOwnProperty(adapter)) {
383 + for (var i = 0; i < interfaces[adapter].length; ++i) {
384 + var addr = interfaces[adapter][i];
385 + if ((addr.family == 'IPv4') && (addr.mac != '00:00:00:00:00:00')) {
386 + var socket = require('dgram').createSocket({ type: "udp4" });
387 + socket.bind({ address: addr.address });
388 + socket.setBroadcast(true);
389 + socket.send(magicbin, 7, "255.255.255.255");
390 + count++;
391 + }
392 + }
393 + }
394 + }
395 + } catch (e) { }
396 + return count;
397 + }
398 +
399 + // Handle a mesh agent command
400 + function handleServerCommand(data) {
401 + if (typeof data == 'object') {
402 + // If this is a console command, parse it and call the console handler
403 + switch (data.action) {
404 + case 'msg': {
405 + switch (data.type) {
406 + case 'console': { // Process a console command
407 + if (data.value && data.sessionid) {
408 + var args = splitArgs(data.value);
409 + processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid);
410 + }
411 + break;
412 + }
413 + case 'tunnel': {
414 + if (data.value != null) { // Process a new tunnel connection request
415 + // Create a new tunnel object
416 + var xurl = getServerTargetUrlEx(data.value);
417 + if (xurl != null) {
418 + var woptions = http.parseUri(xurl);
419 + woptions.rejectUnauthorized = 0;
420 + //sendConsoleText(JSON.stringify(woptions));
421 + var tunnel = http.request(woptions);
422 + tunnel.upgrade = onTunnelUpgrade;
423 + tunnel.on('error', function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); });
424 + tunnel.sessionid = data.sessionid;
425 + tunnel.rights = data.rights;
426 + tunnel.state = 0;
427 + tunnel.url = xurl;
428 + tunnel.protocol = 0;
429 + tunnel.tcpaddr = data.tcpaddr;
430 + tunnel.tcpport = data.tcpport;
431 + tunnel.end();
432 + // Put the tunnel in the tunnels list
433 + var index = nextTunnelIndex++;
434 + tunnel.index = index;
435 + tunnels[index] = tunnel;
436 +
437 + //sendConsoleText('New tunnel connection #' + index + ': ' + tunnel.url + ', rights: ' + tunnel.rights, data.sessionid);
438 + }
439 + }
440 + break;
441 + }
442 + case 'ps': {
443 + // Return the list of running processes
444 + if (data.sessionid) {
445 + processManager.getProcesses(function (plist) { mesh.SendCommand({ "action": "msg", "type": "ps", "value": JSON.stringify(plist), "sessionid": data.sessionid }); });
446 + }
447 + break;
448 + }
449 + case 'pskill': {
450 + // Kill a process
451 + if (data.value) {
452 + try { process.kill(data.value); } catch (e) { sendConsoleText("pskill: " + JSON.stringify(e)); }
453 + }
454 + break;
455 + }
456 + case 'openUrl': {
457 + // Open a local web browser and return success/fail
458 + sendConsoleText('OpenURL: ' + data.url);
459 + if (data.url) { mesh.SendCommand({ "action": "msg", "type":"openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); }
460 + break;
461 + }
462 + case 'getclip': {
463 + // Send the load clipboard back to the user
464 + sendConsoleText('getClip: ' + JSON.stringify(data));
465 + require("clipboard").read().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); });
466 + break;
467 + }
468 + case 'setclip': {
469 + // Set the load clipboard to a user value
470 + sendConsoleText('setClip: ' + JSON.stringify(data));
471 + if (typeof data.data == 'string') {
472 + require("clipboard")(data.data); // Set the clipboard
473 + mesh.SendCommand({ "action": "msg", "type": "setclip", "sessionid": data.sessionid, "success": true });
474 + }
475 + break;
476 + }
477 + default:
478 + // Unknown action, ignore it.
479 + break;
480 + }
481 + break;
482 + }
483 + case 'wakeonlan': {
484 + // Send wake-on-lan on all interfaces for all MAC addresses in data.macs array. The array is a list of HEX MAC addresses.
485 + sendConsoleText('Server requesting wake-on-lan for: ' + data.macs.join(', '));
486 + for (var i in data.macs) { sendWakeOnLan(data.macs[i]); }
487 + break;
488 + }
489 + case 'poweraction': {
490 + // Server telling us to execute a power action
491 + if ((mesh.ExecPowerState != undefined) && (data.actiontype)) {
492 + var forced = 0;
493 + if (data.forced == 1) { forced = 1; }
494 + data.actiontype = parseInt(data.actiontype);
495 + sendConsoleText('Performing power action=' + data.actiontype + ', forced=' + forced + '.');
496 + var r = mesh.ExecPowerState(data.actiontype, forced);
497 + sendConsoleText('ExecPowerState returned code: ' + r);
498 + }
499 + break;
500 + }
501 + case 'iplocation': {
502 + // 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
503 + getIpLocationData(function (location) { mesh.SendCommand({ "action": "iplocation", "type": "publicip", "value": location }); });
504 + break;
505 + }
506 + case 'toast': {
507 + // Display a toast message
508 + if (data.title && data.msg) { require('toaster').Toast(data.title, data.msg); }
509 + break;
510 + }
511 + case 'openUrl': {
512 + // Open a local web browser and return success/fail
513 + sendConsoleText('OpenURL: ' + data.url);
514 + if (data.url) { mesh.SendCommand({ "action": "openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); }
515 + break;
516 + }
517 + case 'amtPolicy': {
518 + // Store the latest Intel AMT policy
519 + amtPolicy = data.amtPolicy;
520 + if (data.amtPolicy != null) { db.Put('amtPolicy', JSON.stringify(data.amtPolicy)); } else { db.Put('amtPolicy', null); }
521 + if (amt != null) { amt.setPolicy(amtPolicy); }
522 + break;
523 + }
524 + case 'getScript': {
525 + // Received a configuration script from the server
526 + sendConsoleText('getScript: ' + JSON.stringify(data));
527 + break;
528 + }
529 + default:
530 + // Unknown action, ignore it.
531 + break;
532 + }
533 + }
534 + }
535 +
536 + // Called when a file changed in the file system
537 + /*
538 + function onFileWatcher(a, b) {
539 + console.log('onFileWatcher', a, b, this.path);
540 + var response = getDirectoryInfo(this.path);
541 + if ((response != undefined) && (response != null)) { this.tunnel.s.write(JSON.stringify(response)); }
542 + }
543 + */
544 +
545 + // Get a formated response for a given directory path
546 + function getDirectoryInfo(reqpath) {
547 + var response = { path: reqpath, dir: [] };
548 + if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) {
549 + // List all the drives in the root, or the root itself
550 + var results = null;
551 + try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
552 + if (results != null) {
553 + for (var i = 0; i < results.length; ++i) {
554 + var drive = { n: results[i].name, t: 1 };
555 + if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons.
556 + response.dir.push(drive);
557 + }
558 + }
559 + } else {
560 + // List all the files and folders in this path
561 + if (reqpath == '') { reqpath = '/'; }
562 + var results = null, xpath = obj.path.join(reqpath, '*');
563 + //if (process.platform == "win32") { xpath = xpath.split('/').join('\\'); }
564 + try { results = fs.readdirSync(xpath); } catch (e) { }
565 + if (results != null) {
566 + for (var i = 0; i < results.length; ++i) {
567 + if ((results[i] != '.') && (results[i] != '..')) {
568 + var stat = null, p = obj.path.join(reqpath, results[i]);
569 + //if (process.platform == "win32") { p = p.split('/').join('\\'); }
570 + try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date
571 + if ((stat != null) && (stat != undefined)) {
572 + if (stat.isDirectory() == true) {
573 + response.dir.push({ n: results[i], t: 2, d: stat.mtime });
574 + } else {
575 + response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime });
576 + }
577 + }
578 + }
579 + }
580 + }
581 + }
582 + return response;
583 + }
584 +
585 + // Tunnel callback operations
586 + function onTunnelUpgrade(response, s, head) {
587 + this.s = s;
588 + s.httprequest = this;
589 + s.end = onTunnelClosed;
590 + s.tunnel = this;
591 +
592 + //sendConsoleText('onTunnelUpgrade');
593 +
594 + if (this.tcpport != null) {
595 + // This is a TCP relay connection, pause now and try to connect to the target.
596 + s.pause();
597 + s.data = onTcpRelayServerTunnelData;
598 + var connectionOptions = { port: parseInt(this.tcpport) };
599 + if (this.tcpaddr != null) { connectionOptions.host = this.tcpaddr; } else { connectionOptions.host = '127.0.0.1'; }
600 + s.tcprelay = net.createConnection(connectionOptions, onTcpRelayTargetTunnelConnect);
601 + s.tcprelay.peerindex = this.index;
602 + } else {
603 + // This is a normal connect for KVM/Terminal/Files
604 + s.data = onTunnelData;
605 + }
606 + }
607 +
608 + // Called when the TCP relay target is connected
609 + function onTcpRelayTargetTunnelConnect() {
610 + var peerTunnel = tunnels[this.peerindex];
611 + this.pipe(peerTunnel.s); // Pipe Target --> Server
612 + peerTunnel.s.first = true;
613 + peerTunnel.s.resume();
614 + }
615 +
616 + // Called when we get data from the server for a TCP relay (We have to skip the first received 'c' and pipe the rest)
617 + function onTcpRelayServerTunnelData(data) {
618 + if (this.first == true) { this.first = false; this.pipe(this.tcprelay); } // Pipe Server --> Target
619 + }
620 +
621 + function onTunnelClosed() {
622 + if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls.
623 + //sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid);
624 + delete tunnels[this.httprequest.index];
625 +
626 + /*
627 + // Close the watcher if required
628 + if (this.httprequest.watcher != undefined) {
629 + //console.log('Closing watcher: ' + this.httprequest.watcher.path);
630 + //this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!!
631 + delete this.httprequest.watcher;
632 + }
633 + */
634 +
635 + // If there is a upload or download active on this connection, close the file
636 + if (this.httprequest.uploadFile) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
637 + if (this.httprequest.downloadFile) { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; }
638 +
639 + // Clean up WebRTC
640 + if (this.webrtc != null) {
641 + 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; }
642 + if (this.webrtc.websocket) { delete this.webrtc.websocket; }
643 + try { this.webrtc.close(); } catch (e) { }
644 + this.webrtc.removeAllListeners('connected');
645 + this.webrtc.removeAllListeners('disconnected');
646 + this.webrtc.removeAllListeners('dataChannel');
647 + delete this.webrtc;
648 + }
649 +
650 + // Clean up WebSocket
651 + this.removeAllListeners('data');
652 + }
653 + function onTunnelSendOk() { /*sendConsoleText("Tunnel #" + this.index + " SendOK.", this.sessionid);*/ }
654 + function onTunnelData(data) {
655 + //console.log("OnTunnelData");
656 + //sendConsoleText('OnTunnelData, ' + data.length + ', ' + typeof data + ', ' + data);
657 +
658 + // If this is upload data, save it to file
659 + if (this.httprequest.uploadFile) {
660 + 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.
661 + this.write(new Buffer(JSON.stringify({ action: 'uploadack', reqid: this.httprequest.uploadFileid }))); // Ask for more data
662 + return;
663 + }
664 + /*
665 + // If this is a download, send more of the file
666 + if (this.httprequest.downloadFile) {
667 + var buf = new Buffer(4096);
668 + var len = fs.readSync(this.httprequest.downloadFile, buf, 0, 4096, null);
669 + this.httprequest.downloadFilePtr += len;
670 + if (len > 0) { this.write(buf.slice(0, len)); } else { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; this.end(); }
671 + return;
672 + }
673 + */
674 +
675 + if (this.httprequest.state == 0) {
676 + // Check if this is a relay connection
677 + if (data == 'c') { this.httprequest.state = 1; /*sendConsoleText("Tunnel #" + this.httprequest.index + " now active", this.httprequest.sessionid);*/ }
678 + } else {
679 + // Handle tunnel data
680 + if (this.httprequest.protocol == 0) { // 1 = Terminal, 2 = Desktop, 5 = Files
681 + // Take a look at the protocol
682 + this.httprequest.protocol = parseInt(data);
683 + if (typeof this.httprequest.protocol != 'number') { this.httprequest.protocol = 0; }
684 + if (this.httprequest.protocol == 1) {
685 + // Check user access rights for terminal
686 + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOTERMINAL) != 0))) {
687 + // Disengage this tunnel, user does not have the rights to do this!!
688 + this.httprequest.protocol = 999999;
689 + this.httprequest.s.end();
690 + sendConsoleText('Error: No Terminal Control Rights.');
691 + return;
692 + }
693 +
694 + // Remote terminal using native pipes
695 + if (process.platform == "win32")
696 + {
697 + this.httprequest._term = require('win-terminal').Start(80, 25);
698 + this.httprequest._term.pipe(this, { dataTypeSkip: 1 });
699 + this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false });
700 + this.prependListener('end', function () { this.httprequest._term.end(function () { console.log('Terminal was closed'); }); });
701 + //this.httprequest.process = childProcess.execFile("%windir%\\system32\\cmd.exe");
702 + } else {
703 + this.httprequest.process = childProcess.execFile("/bin/sh", ["sh"], { type: childProcess.SpawnTypes.TERM });
704 + this.httprequest.process.tunnel = this;
705 + this.httprequest.process.on('exit', function (ecode, sig) { this.tunnel.end(); });
706 + this.httprequest.process.stderr.on('data', function (chunk) { this.parent.tunnel.write(chunk); });
707 + this.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
708 + this.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
709 + this.prependListener('end', function () { this.httprequest.process.kill(); });
710 + }
711 +
712 + this.end = function () {
713 + if (process.platform == "win32") {
714 + // Unpipe the web socket
715 + this.unpipe(this.httprequest._term);
716 + this.httprequest._term.unpipe(this);
717 +
718 + // Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends).
719 + if (this.rtcchannel) {
720 + this.rtcchannel.unpipe(this.httprequest._term);
721 + this.httprequest._term.unpipe(this.rtcchannel);
722 + }
723 +
724 + // Clean up
725 + this.httprequest._term.end();
726 + this.httprequest._term = null;
727 + } else {
728 + // TODO!!
729 + }
730 + };
731 +
732 + this.removeAllListeners('data');
733 + this.on('data', onTunnelControlData);
734 + //this.write('MeshCore Terminal Hello');
735 + if (process.platform == 'linux') { this.httprequest.process.stdin.write("stty erase ^H\nalias ls='ls --color=auto'\nclear\n"); }
736 + } else if (this.httprequest.protocol == 2)
737 + {
738 + // Check user access rights for desktop
739 + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0)) {
740 + // Disengage this tunnel, user does not have the rights to do this!!
741 + this.httprequest.protocol = 999999;
742 + this.httprequest.s.end();
743 + sendConsoleText('Error: No Desktop Control Rights.');
744 + return;
745 + }
746 +
747 + // Remote desktop using native pipes
748 + this.httprequest.desktop = { state: 0, kvm: mesh.getRemoteDesktopStream(), tunnel: this };
749 + this.httprequest.desktop.kvm.parent = this.httprequest.desktop;
750 + this.desktop = this.httprequest.desktop;
751 +
752 + // Display a toast message
753 + //require('toaster').Toast('MeshCentral', 'Remote Desktop Control Started.');
754 +
755 + this.end = function () {
756 + --this.desktop.kvm.connectionCount;
757 +
758 + // Unpipe the web socket
759 + this.unpipe(this.httprequest.desktop.kvm);
760 + this.httprequest.desktop.kvm.unpipe(this);
761 +
762 + // Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends).
763 + if (this.rtcchannel) {
764 + this.rtcchannel.unpipe(this.httprequest.desktop.kvm);
765 + this.httprequest.desktop.kvm.unpipe(this.rtcchannel);
766 + }
767 +
768 + if (this.desktop.kvm.connectionCount == 0) {
769 + // Display a toast message
770 + //require('toaster').Toast('MeshCentral', 'Remote Desktop Control Ended.');
771 + this.httprequest.desktop.kvm.end();
772 + }
773 + };
774 + if (this.httprequest.desktop.kvm.hasOwnProperty("connectionCount")) { this.httprequest.desktop.kvm.connectionCount++; } else { this.httprequest.desktop.kvm.connectionCount = 1; }
775 +
776 + if ((this.httprequest.rights == 0xFFFFFFFF) || (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) != 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0))) {
777 + // If we have remote control rights, pipe the KVM input
778 + this.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. Pipe the Browser --> KVM input.
779 + } else {
780 + // We need to only pipe non-mouse & non-keyboard inputs.
781 + //sendConsoleText('Warning: No Remote Desktop Input Rights.');
782 + // TODO!!!
783 + }
784 +
785 + this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. Pipe the KVM --> Browser images.
786 + this.removeAllListeners('data');
787 + this.on('data', onTunnelControlData);
788 + //this.write('MeshCore KVM Hello!1');
789 + } else if (this.httprequest.protocol == 5) {
790 + // Check user access rights for files
791 + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOFILES) != 0))) {
792 + // Disengage this tunnel, user does not have the rights to do this!!
793 + this.httprequest.protocol = 999999;
794 + this.httprequest.s.end();
795 + sendConsoleText('Error: No Files Control Rights.');
796 + return;
797 + }
798 +
799 + // Setup files
800 + // NOP
801 + }
802 + } else if (this.httprequest.protocol == 1) {
803 + // Send data into terminal stdin
804 + //this.write(data); // Echo back the keys (Does not seem to be a good idea)
805 + this.httprequest.process.write(data);
806 + } else if (this.httprequest.protocol == 2) {
807 + // Send data into remote desktop
808 + if (this.httprequest.desktop.state == 0) {
809 + this.write(new Buffer(String.fromCharCode(0x11, 0xFE, 0x00, 0x00, 0x4D, 0x45, 0x53, 0x48, 0x00, 0x00, 0x00, 0x00, 0x02)));
810 + this.httprequest.desktop.state = 1;
811 + } else {
812 + this.httprequest.desktop.write(data);
813 + }
814 + } else if (this.httprequest.protocol == 5) {
815 + // Process files commands
816 + var cmd = null;
817 + try { cmd = JSON.parse(data); } catch (e) { };
818 + if (cmd == null) { return; }
819 + if ((cmd.ctrlChannel == '102938') || ((cmd.type == 'offer') && (cmd.sdp != null))) { onTunnelControlData(cmd, this); return; } // If this is control data, handle it now.
820 + if (cmd.action == undefined) { return; }
821 + //sendConsoleText('CMD: ' + JSON.stringify(cmd));
822 +
823 + if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
824 + //console.log(objToString(cmd, 0, ' '));
825 + switch (cmd.action) {
826 + case 'ls': {
827 + /*
828 + // Close the watcher if required
829 + var samepath = ((this.httprequest.watcher != undefined) && (cmd.path == this.httprequest.watcher.path));
830 + if ((this.httprequest.watcher != undefined) && (samepath == false)) {
831 + //console.log('Closing watcher: ' + this.httprequest.watcher.path);
832 + //this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!!
833 + delete this.httprequest.watcher;
834 + }
835 + */
836 +
837 + // Send the folder content to the browser
838 + var response = getDirectoryInfo(cmd.path);
839 + if (cmd.reqid != undefined) { response.reqid = cmd.reqid; }
840 + this.write(new Buffer(JSON.stringify(response)));
841 +
842 + /*
843 + // Start the directory watcher
844 + if ((cmd.path != '') && (samepath == false)) {
845 + var watcher = fs.watch(cmd.path, onFileWatcher);
846 + watcher.tunnel = this.httprequest;
847 + watcher.path = cmd.path;
848 + this.httprequest.watcher = watcher;
849 + //console.log('Starting watcher: ' + this.httprequest.watcher.path);
850 + }
851 + */
852 + break;
853 + }
854 + case 'mkdir': {
855 + // Create a new empty folder
856 + fs.mkdirSync(cmd.path);
857 + break;
858 + }
859 + case 'rm': {
860 + // Delete, possibly recursive delete
861 + for (var i in cmd.delfiles) {
862 + try { deleteFolderRecursive(obj.path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (e) { }
863 + }
864 + break;
865 + }
866 + case 'rename': {
867 + // Rename a file or folder
868 + var oldfullpath = obj.path.join(cmd.path, cmd.oldname);
869 + var newfullpath = obj.path.join(cmd.path, cmd.newname);
870 + try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); }
871 + break;
872 + }
873 + case 'download': {
874 + // Download a file
875 + var sendNextBlock = 0;
876 + if (cmd.sub == 'start') { // Setup the download
877 + if (this.filedownload != null) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
878 + this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
879 + 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; }
880 + if (this.filedownload) { this.write({ action: 'download', sub: 'start', id: cmd.id }); }
881 + } else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands
882 + if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; }
883 + }
884 + // Send the next download block(s)
885 + while (sendNextBlock > 0) {
886 + sendNextBlock--;
887 + var buf = new Buffer(4096);
888 + var len = fs.readSync(this.filedownload.f, buf, 4, 4092, null);
889 + this.filedownload.ptr += len;
890 + if (len < 4092) { buf.writeInt32BE(0x01000001, 0); fs.closeSync(this.filedownload.f); delete this.filedownload; sendNextBlock = 0; } else { buf.writeInt32BE(0x01000000, 0); }
891 + this.write(buf.slice(0, len + 4)); // Write as binary
892 + }
893 + break;
894 + }
895 + /*
896 + case 'download': {
897 + // Packet download of a file, agent to browser
898 + if (cmd.path == undefined) break;
899 + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path;
900 + //console.log('Download: ' + filepath);
901 + try { this.httprequest.downloadFile = fs.openSync(filepath, 'rbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'downloaderror', reqid: cmd.reqid }))); break; }
902 + this.httprequest.downloadFileId = cmd.reqid;
903 + this.httprequest.downloadFilePtr = 0;
904 + if (this.httprequest.downloadFile) { this.write(new Buffer(JSON.stringify({ action: 'downloadstart', reqid: this.httprequest.downloadFileId }))); }
905 + break;
906 + }
907 + case 'download2': {
908 + // Stream download of a file, agent to browser
909 + if (cmd.path == undefined) break;
910 + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path;
911 + try { this.httprequest.downloadFile = fs.createReadStream(filepath, { flags: 'rbN' }); } catch (e) { console.log(e); }
912 + this.httprequest.downloadFile.pipe(this);
913 + this.httprequest.downloadFile.end = function () { }
914 + break;
915 + }
916 + */
917 + case 'upload': {
918 + // Upload a file, browser to agent
919 + if (this.httprequest.uploadFile != undefined) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
920 + if (cmd.path == undefined) break;
921 + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path;
922 + try { this.httprequest.uploadFile = fs.openSync(filepath, 'wbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror', reqid: cmd.reqid }))); break; }
923 + this.httprequest.uploadFileid = cmd.reqid;
924 + if (this.httprequest.uploadFile) { this.write(new Buffer(JSON.stringify({ action: 'uploadstart', reqid: this.httprequest.uploadFileid }))); }
925 + break;
926 + }
927 + case 'copy': {
928 + // Copy a bunch of files from scpath to dspath
929 + for (var i in cmd.names) {
930 + var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]);
931 + if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
932 + }
933 + break;
934 + }
935 + case 'move': {
936 + // Move a bunch of files from scpath to dspath
937 + for (var i in cmd.names) {
938 + var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]);
939 + if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
940 + }
941 + break;
942 + }
943 + default:
944 + // Unknown action, ignore it.
945 + break;
946 + }
947 + }
948 + //sendConsoleText("Got tunnel #" + this.httprequest.index + " data: " + data, this.httprequest.sessionid);
949 + }
950 + }
951 +
952 + // Delete a directory with a files and directories within it
953 + function deleteFolderRecursive(path, rec) {
954 + if (fs.existsSync(path)) {
955 + if (rec == true) {
956 + fs.readdirSync(obj.path.join(path, '*')).forEach(function (file, index) {
957 + var curPath = obj.path.join(path, file);
958 + if (fs.statSync(curPath).isDirectory()) { // recurse
959 + deleteFolderRecursive(curPath, true);
960 + } else { // delete file
961 + fs.unlinkSync(curPath);
962 + }
963 + });
964 + }
965 + fs.unlinkSync(path);
966 + }
967 + };
968 +
969 + // Called when receiving control data on WebRTC
970 + function onTunnelWebRTCControlData(data) {
971 + if (typeof data != 'string') return;
972 + var obj;
973 + try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON on WebRTC: ' + data); return; }
974 + if (obj.type == 'close') {
975 + //sendConsoleText('Tunnel #' + this.xrtc.websocket.tunnel.index + ' WebRTC control close');
976 + try { this.close(); } catch (e) { }
977 + try { this.xrtc.close(); } catch (e) { }
978 + }
979 + }
980 +
981 + // Called when receiving control data on websocket
982 + function onTunnelControlData(data, ws) {
983 + var obj;
984 + if (ws == null) { ws = this; }
985 + if (typeof data == 'string') { try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON: ' + data); return; } }
986 + else if (typeof data == 'object') { obj = data; } else { return; }
987 + //sendConsoleText('onTunnelControlData(' + ws.httprequest.protocol + '): ' + JSON.stringify(data));
988 + //console.log('onTunnelControlData: ' + JSON.stringify(data));
989 +
990 + if (obj.action) {
991 + switch (obj.action) {
992 + case 'lock': {
993 + // Lock the current user out of the desktop
994 + try {
995 + if (process.platform == 'win32') {
996 + var child = require('child_process');
997 + child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 });
998 + }
999 + } catch (e) { }
1000 + break;
1001 + }
1002 + default:
1003 + // Unknown action, ignore it.
1004 + break;
1005 + }
1006 + return;
1007 + }
1008 +
1009 + if (obj.type == 'close') {
1010 + // We received the close on the websocket
1011 + //sendConsoleText('Tunnel #' + ws.tunnel.index + ' WebSocket control close');
1012 + try { ws.close(); } catch (e) { }
1013 + } else if (obj.type == 'webrtc0') { // Browser indicates we can start WebRTC switch-over.
1014 + if (ws.httprequest.protocol == 1) { // Terminal
1015 + // 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
1016 + if (process.platform == 'win32')
1017 + {
1018 + ws.httprequest._term.unpipe(ws);
1019 + }
1020 + else
1021 + {
1022 + ws.httprequest.process.stdout.unpipe(ws);
1023 + ws.httprequest.process.stderr.unpipe(ws);
1024 + }
1025 + } else if (ws.httprequest.protocol == 2) { // Desktop
1026 + // 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
1027 + ws.httprequest.desktop.kvm.unpipe(ws);
1028 + } else {
1029 + // Switch things around so all WebRTC data goes to onTunnelData().
1030 + ws.rtcchannel.httprequest = ws.httprequest;
1031 + ws.rtcchannel.removeAllListeners('data');
1032 + ws.rtcchannel.on('data', onTunnelData);
1033 + }
1034 + ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc1\"}"); // End of data marker
1035 + } else if (obj.type == 'webrtc1') {
1036 + if (ws.httprequest.protocol == 1) { // Terminal
1037 + // Switch the user input from websocket to webrtc at this point.
1038 + if (process.platform == 'win32')
1039 + {
1040 + ws.unpipe(ws.httprequest._term);
1041 + ws.rtcchannel.pipe(ws.httprequest._term, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
1042 + }
1043 + else
1044 + {
1045 + ws.unpipe(ws.httprequest.process.stdin);
1046 + ws.rtcchannel.pipe(ws.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
1047 + }
1048 + ws.resume(); // Resume the websocket to keep receiving control data
1049 + } else if (ws.httprequest.protocol == 2) { // Desktop
1050 + // Switch the user input from websocket to webrtc at this point.
1051 + ws.unpipe(ws.httprequest.desktop.kvm);
1052 + try { ws.webrtc.rtcchannel.pipe(ws.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); } catch (e) { sendConsoleText('EX2'); } // 0 = Binary, 1 = Text.
1053 + ws.resume(); // Resume the websocket to keep receiving control data
1054 + }
1055 + ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point.
1056 + } else if (obj.type == 'webrtc2') {
1057 + // Other side received websocket end of data marker, start sending data on WebRTC channel
1058 + if (ws.httprequest.protocol == 1) { // Terminal
1059 + if (process.platform == 'win32')
1060 + {
1061 + ws.httprequest._term.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
1062 + }
1063 + else
1064 + {
1065 + ws.httprequest.process.stdout.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
1066 + ws.httprequest.process.stderr.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
1067 + }
1068 + } else if (ws.httprequest.protocol == 2) { // Desktop
1069 + ws.httprequest.desktop.kvm.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
1070 + }
1071 + } else if (obj.type == 'offer') {
1072 + // This is a WebRTC offer.
1073 + if (ws.httprequest.protocol == 1) return; // TODO: Terminal is currently broken with WebRTC. Reject WebRTC upgrade for now.
1074 + ws.webrtc = rtc.createConnection();
1075 + ws.webrtc.websocket = ws;
1076 + ws.webrtc.on('connected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC connected');*/ });
1077 + ws.webrtc.on('disconnected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC disconnected');*/ });
1078 + ws.webrtc.on('dataChannel', function (rtcchannel) {
1079 + //sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol);
1080 + rtcchannel.xrtc = this;
1081 + rtcchannel.websocket = this.websocket;
1082 + this.rtcchannel = rtcchannel;
1083 + this.websocket.rtcchannel = rtcchannel;
1084 + this.websocket.rtcchannel.on('data', onTunnelWebRTCControlData);
1085 + this.websocket.rtcchannel.on('end', function () {
1086 + // The WebRTC channel closed, unpipe the KVM now. This is also done when the web socket closes.
1087 + //sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed');
1088 + if (this.websocket.desktop && this.websocket.desktop.kvm) {
1089 + this.unpipe(this.websocket.desktop.kvm);
1090 + this.websocket.httprequest.desktop.kvm.unpipe(this);
1091 + }
1092 + });
1093 + this.websocket.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc0\"}"); // Indicate we are ready for WebRTC switch-over.
1094 + });
1095 + var sdp = null;
1096 + try { sdp = ws.webrtc.setOffer(obj.sdp); } catch (ex) { }
1097 + if (sdp != null) { ws.write({ type: 'answer', ctrlChannel: '102938', sdp: sdp }); }
1098 + }
1099 + }
1100 +
1101 + // Console state
1102 + var consoleWebSockets = {};
1103 + var consoleHttpRequest = null;
1104 +
1105 + // Console HTTP response
1106 + function consoleHttpResponse(response) {
1107 + response.data = function (data) { sendConsoleText(rstr2hex(buf2rstr(data)), this.sessionid); consoleHttpRequest = null; }
1108 + response.close = function () { sendConsoleText('httprequest.response.close', this.sessionid); consoleHttpRequest = null; }
1109 + };
1110 +
1111 + // Open a web browser to a specified URL on current user's desktop
1112 + function openUserDesktopUrl(url) {
1113 + var child = null;
1114 + try {
1115 + switch (process.platform) {
1116 + case 'win32':
1117 + //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 });
1118 + child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe', ["/c", "start", url], { type: childProcess.SpawnTypes.USER });
1119 + break;
1120 + case 'linux':
1121 + child = require('child_process').execFile('/usr/bin/xdg-open', ['xdg-open', url], { uid: require('user-sessions').consoleUid() });
1122 + break;
1123 + case 'darwin':
1124 + child = require('child_process').execFile('/usr/bin/open', ['open', url], { uid: require('user-sessions').consoleUid() });
1125 + break;
1126 + default:
1127 + // Unknown platform, ignore this command.
1128 + break;
1129 + }
1130 + } catch (ex) { }
1131 + return child;
1132 + }
1133 +
1134 + // Process a mesh agent console command
1135 + function processConsoleCommand(cmd, args, rights, sessionid) {
1136 + try {
1137 + var response = null;
1138 + switch (cmd) {
1139 + case 'help': { // Displays available commands
1140 + 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.';
1141 + break;
1142 + }
1143 + /*
1144 + case 'border':
1145 + {
1146 + if ((args['_'].length == 1) && (args['_'][0] == 'on')) {
1147 + if (meshCoreObj.users.length > 0) {
1148 + obj.borderManager.Start(meshCoreObj.users[0]);
1149 + response = 'Border blinking is on.';
1150 + } else {
1151 + response = 'Cannot turn on border blinking, no logged in users.';
1152 + }
1153 + } else if ((args['_'].length == 1) && (args['_'][0] == 'off')) {
1154 + obj.borderManager.Stop();
1155 + response = 'Border blinking is off.';
1156 + } else {
1157 + response = 'Proper usage: border "on|off"'; // Display correct command usage
1158 + }
1159 + }
1160 + break;
1161 + */
1162 + case 'getclip': {
1163 + require("clipboard").read().then(function (str) { sendConsoleText(str, sessionid); });
1164 + break;
1165 + }
1166 + case 'setclip': {
1167 + if (args['_'].length != 1) { response = 'Proper usage: setclip (text)'; } else { require("clipboard")(args['_'][0]); response = 'Setting clipboard to: ' + args['_'][0]; }
1168 + break;
1169 + }
1170 + case 'amtreset': {
1171 + if (amt != null) { amt.reset(); response = 'Done.'; }
1172 + break;
1173 + }
1174 + case 'amtlmsreset': {
1175 + if (amt != null) { amt.lmsreset(); response = 'Done.'; }
1176 + break;
1177 + }
1178 + case 'amtccm': {
1179 + if (amt == null) { response = 'Intel AMT not supported.'; } else {
1180 + if (args['_'].length != 1) { response = 'Proper usage: amtccm (adminPassword)'; } // Display usage
1181 + else { amt.setPolicy({ type: 0 }); amt.activeToCCM(args['_'][0]); }
1182 + }
1183 + break;
1184 + }
1185 + case 'amtdeactivate': {
1186 + if (amt == null) { response = 'Intel AMT not supported.'; } else { amt.setPolicy({ type: 0 }); amt.deactivateCCM(); }
1187 + break;
1188 + }
1189 + case 'amtpolicy': {
1190 + if (amtPolicy == null) {
1191 + response = 'No Intel(R) AMT policy.';
1192 + } else {
1193 + response = JSON.stringify(amtPolicy);
1194 + }
1195 + break;
1196 + }
1197 + case 'openurl': {
1198 + if (args['_'].length != 1) { response = 'Proper usage: openurl (url)'; } // Display usage
1199 + else { if (openUserDesktopUrl(args['_'][0]) == null) { response = 'Failed.'; } else { response = 'Success.'; } }
1200 + break;
1201 + }
1202 + case 'users': {
1203 + if (meshCoreObj.users == null) { response = 'Active users are unknown.'; } else { response = 'Active Users: ' + meshCoreObj.users.join(', ') + '.'; }
1204 + require('user-sessions').enumerateUsers().then(function (u) { for (var i in u) { sendConsoleText(u[i]); } });
1205 + break;
1206 + }
1207 + case 'toast': {
1208 + if (process.platform == 'win32') {
1209 + if (args['_'].length < 1) { response = 'Proper usage: toast "message"'; } else {
1210 + require('toaster').Toast('MeshCentral', args['_'][0]);
1211 + response = 'ok';
1212 + }
1213 + } else {
1214 + response = 'Only supported on Windows.';
1215 + }
1216 + break;
1217 + }
1218 + case 'setdebug': {
1219 + if (args['_'].length < 1) { response = 'Proper usage: setdebug (target), 0 = Disabled, 1 = StdOut, 2 = This Console, * = All Consoles, 4 = WebLog, 8 = Logfile'; } // Display usage
1220 + else { if (args['_'][0] == '*') { console.setDestination(2); } else { console.setDestination(parseInt(args['_'][0]), sessionid); } }
1221 + break;
1222 + }
1223 + case 'ps': {
1224 + processManager.getProcesses(function (plist) {
1225 + var x = '';
1226 + for (var i in plist) { x += i + ', ' + plist[i].cmd + ((plist[i].user) ? (', ' + plist[i].user):'') + '\r\n'; }
1227 + sendConsoleText(x, sessionid);
1228 + });
1229 + break;
1230 + }
1231 + case 'kill': {
1232 + if ((args['_'].length < 1)) {
1233 + response = 'Proper usage: kill [pid]'; // Display correct command usage
1234 + } else {
1235 + process.kill(parseInt(args['_'][0]));
1236 + response = 'Killed process ' + args['_'][0] + '.';
1237 + }
1238 + break;
1239 + }
1240 + case 'smbios': {
1241 + if (SMBiosTables == null) { response = 'SMBios tables not available.'; } else { response = objToString(SMBiosTables, 0, ' ', true); }
1242 + break;
1243 + }
1244 + case 'rawsmbios': {
1245 + if (SMBiosTablesRaw == null) { response = 'SMBios tables not available.'; } else {
1246 + response = '';
1247 + for (var i in SMBiosTablesRaw) {
1248 + var header = false;
1249 + for (var j in SMBiosTablesRaw[i]) {
1250 + if (SMBiosTablesRaw[i][j].length > 0) {
1251 + if (header == false) { response += ('Table type #' + i + ((require('smbios').smTableTypes[i] == null) ? '' : (', ' + require('smbios').smTableTypes[i]))) + '\r\n'; header = true; }
1252 + response += (' ' + SMBiosTablesRaw[i][j].toString('hex')) + '\r\n';
1253 + }
1254 + }
1255 + }
1256 + }
1257 + break;
1258 + }
1259 + case 'eval': { // Eval JavaScript
1260 + if (args['_'].length < 1) {
1261 + response = 'Proper usage: eval "JavaScript code"'; // Display correct command usage
1262 + } else {
1263 + response = JSON.stringify(mesh.eval(args['_'][0]));
1264 + }
1265 + break;
1266 + }
1267 + case 'notify': { // Send a notification message to the mesh
1268 + if (args['_'].length != 1) {
1269 + response = 'Proper usage: notify "message" [--session]'; // Display correct command usage
1270 + } else {
1271 + var notification = { "action": "msg", "type": "notify", "value": args['_'][0], "tag": "console" };
1272 + if (args.session) { notification.sessionid = sessionid; } // If "--session" is specified, notify only this session, if not, the server will notify the mesh
1273 + mesh.SendCommand(notification); // no sessionid or userid specified, notification will go to the entire mesh
1274 + response = 'ok';
1275 + }
1276 + break;
1277 + }
1278 + case 'info': { // Return information about the agent and agent core module
1279 + 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 + '.';
1280 + if (amt != null) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amt.lmsstate] + '.'; }
1281 + if (meshCoreObj.osdesc) { response += '\r\nOS: ' + meshCoreObj.osdesc + '.'; }
1282 + response += '\r\nModules: ' + addedModules.join(', ') + '.';
1283 + response += '\r\nServer Connection: ' + mesh.isControlChannelConnected + ', State: ' + meshServerConnectionState + '.';
1284 + response += '\r\lastMeInfo: ' + lastMeInfo + '.';
1285 + var oldNodeId = db.Get('OldNodeId');
1286 + if (oldNodeId != null) { response += '\r\nOldNodeID: ' + oldNodeId + '.'; }
1287 + if (process.platform != 'win32') { response += '\r\nX11 support: ' + require('monitor-info').kvm_x11_support + '.'; }
1288 + break;
1289 + }
1290 + case 'osinfo': { // Return the operating system information
1291 + var i = 1;
1292 + if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; }
1293 + for (var j = 0; j < i; j++) {
1294 + var pr = require('os').name();
1295 + pr.sessionid = sessionid;
1296 + pr.then(function (v) { sendConsoleText("OS: " + v, this.sessionid); });
1297 + }
1298 + break;
1299 + }
1300 + case 'sendcaps': { // Send capability flags to the server
1301 + if (args['_'].length == 0) {
1302 + response = 'Proper usage: sendcaps (number)'; // Display correct command usage
1303 + } else {
1304 + meshCoreObj.caps = parseInt(args['_'][0]);
1305 + mesh.SendCommand(meshCoreObj);
1306 + response = JSON.stringify(meshCoreObj);
1307 + }
1308 + break;
1309 + }
1310 + case 'sendosdesc': { // Send OS description
1311 + if (args['_'].length > 0) {
1312 + meshCoreObj.osdesc = args['_'][0];
1313 + mesh.SendCommand(meshCoreObj);
1314 + response = JSON.stringify(meshCoreObj);
1315 + } else {
1316 + response = 'Proper usage: sendosdesc [os description]'; // Display correct command usage
1317 + }
1318 + break;
1319 + }
1320 + case 'args': { // Displays parsed command arguments
1321 + response = 'args ' + objToString(args, 0, ' ', true);
1322 + break;
1323 + }
1324 + case 'print': { // Print a message on the mesh agent console, does nothing when running in the background
1325 + var r = [];
1326 + for (var i in args['_']) { r.push(args['_'][i]); }
1327 + console.log(r.join(' '));
1328 + response = 'Message printed on agent console.';
1329 + break;
1330 + }
1331 + case 'type': { // Returns the content of a file
1332 + if (args['_'].length == 0) {
1333 + response = 'Proper usage: type (filepath) [maxlength]'; // Display correct command usage
1334 + } else {
1335 + var max = 4096;
1336 + if ((args['_'].length > 1) && (typeof args['_'][1] == 'number')) { max = args['_'][1]; }
1337 + if (max > 4096) max = 4096;
1338 + var buf = Buffer.alloc(max), fd = fs.openSync(args['_'][0], "r"), r = fs.readSync(fd, buf, 0, max); // Read the file content
1339 + response = buf.toString();
1340 + var i = response.indexOf('\n');
1341 + if ((i > 0) && (response[i - 1] != '\r')) { response = response.split('\n').join('\r\n'); }
1342 + if (r == max) response += '...';
1343 + fs.closeSync(fd);
1344 + }
1345 + break;
1346 + }
1347 + case 'dbkeys': { // Return all data store keys
1348 + response = JSON.stringify(db.Keys);
1349 + break;
1350 + }
1351 + case 'dbget': { // Return the data store value for a given key
1352 + if (db == null) { response = 'Database not accessible.'; break; }
1353 + if (args['_'].length != 1) {
1354 + response = 'Proper usage: dbget (key)'; // Display the value for a given database key
1355 + } else {
1356 + response = db.Get(args['_'][0]);
1357 + }
1358 + break;
1359 + }
1360 + case 'dbset': { // Set a data store key and value pair
1361 + if (db == null) { response = 'Database not accessible.'; break; }
1362 + if (args['_'].length != 2) {
1363 + response = 'Proper usage: dbset (key) (value)'; // Set a database key
1364 + } else {
1365 + var r = db.Put(args['_'][0], args['_'][1]);
1366 + response = 'Key set: ' + r;
1367 + }
1368 + break;
1369 + }
1370 + case 'dbcompact': { // Compact the data store
1371 + if (db == null) { response = 'Database not accessible.'; break; }
1372 + var r = db.Compact();
1373 + response = 'Database compacted: ' + r;
1374 + break;
1375 + }
1376 + case 'httpget': {
1377 + if (consoleHttpRequest != null) {
1378 + response = 'HTTP operation already in progress.';
1379 + } else {
1380 + if (args['_'].length != 1) {
1381 + response = 'Proper usage: httpget (url)';
1382 + } else {
1383 + var options = http.parseUri(args['_'][0]);
1384 + options.method = 'GET';
1385 + if (options == null) {
1386 + response = 'Invalid url.';
1387 + } else {
1388 + try { consoleHttpRequest = http.request(options, consoleHttpResponse); } catch (e) { response = 'Invalid HTTP GET request'; }
1389 + consoleHttpRequest.sessionid = sessionid;
1390 + if (consoleHttpRequest != null) {
1391 + consoleHttpRequest.end();
1392 + response = 'HTTPGET ' + options.protocol + '//' + options.host + ':' + options.port + options.path;
1393 + }
1394 + }
1395 + }
1396 + }
1397 + break;
1398 + }
1399 + case 'wslist': { // List all web sockets
1400 + response = '';
1401 + for (var i in consoleWebSockets) {
1402 + var httprequest = consoleWebSockets[i];
1403 + response += 'Websocket #' + i + ', ' + httprequest.url + '\r\n';
1404 + }
1405 + if (response == '') { response = 'no websocket sessions.'; }
1406 + break;
1407 + }
1408 + case 'wsconnect': { // Setup a web socket
1409 + if (args['_'].length == 0) {
1410 + response = 'Proper usage: wsconnect (url)\r\nFor example: wsconnect wss://localhost:443/meshrelay.ashx?id=abc'; // Display correct command usage
1411 + } else {
1412 + var httprequest = null;
1413 + try {
1414 + var options = http.parseUri(args['_'][0]);
1415 + options.rejectUnauthorized = 0;
1416 + httprequest = http.request(options);
1417 + } catch (e) { response = 'Invalid HTTP websocket request'; }
1418 + if (httprequest != null) {
1419 + httprequest.upgrade = onWebSocketUpgrade;
1420 + httprequest.on('error', function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); });
1421 +
1422 + var index = 1;
1423 + while (consoleWebSockets[index]) { index++; }
1424 + httprequest.sessionid = sessionid;
1425 + httprequest.index = index;
1426 + httprequest.url = args['_'][0];
1427 + consoleWebSockets[index] = httprequest;
1428 + response = 'New websocket session #' + index;
1429 + }
1430 + }
1431 + break;
1432 + }
1433 + case 'wssend': { // Send data on a web socket
1434 + if (args['_'].length == 0) {
1435 + response = 'Proper usage: wssend (socketnumber)\r\n'; // Display correct command usage
1436 + for (var i in consoleWebSockets) {
1437 + var httprequest = consoleWebSockets[i];
1438 + response += 'Websocket #' + i + ', ' + httprequest.url + '\r\n';
1439 + }
1440 + } else {
1441 + var i = parseInt(args['_'][0]);
1442 + var httprequest = consoleWebSockets[i];
1443 + if (httprequest != undefined) {
1444 + httprequest.s.write(args['_'][1]);
1445 + response = 'ok';
1446 + } else {
1447 + response = 'Invalid web socket number';
1448 + }
1449 + }
1450 + break;
1451 + }
1452 + case 'wsclose': { // Close a websocket
1453 + if (args['_'].length == 0) {
1454 + response = 'Proper usage: wsclose (socketnumber)'; // Display correct command usage
1455 + } else {
1456 + var i = parseInt(args['_'][0]);
1457 + var httprequest = consoleWebSockets[i];
1458 + if (httprequest != undefined) {
1459 + if (httprequest.s != null) { httprequest.s.end(); } else { httprequest.end(); }
1460 + response = 'ok';
1461 + } else {
1462 + response = 'Invalid web socket number';
1463 + }
1464 + }
1465 + break;
1466 + }
1467 + case 'tunnels': { // Show the list of current tunnels
1468 + response = '';
1469 + for (var i in tunnels) { response += 'Tunnel #' + i + ', ' + tunnels[i].url + '\r\n'; }
1470 + if (response == '') { response = 'No websocket sessions.'; }
1471 + break;
1472 + }
1473 + case 'ls': { // Show list of files and folders
1474 + response = '';
1475 + var xpath = '*';
1476 + if (args['_'].length > 0) { xpath = obj.path.join(args['_'][0], '*'); }
1477 + response = 'List of ' + xpath + '\r\n';
1478 + var results = fs.readdirSync(xpath);
1479 + for (var i = 0; i < results.length; ++i) {
1480 + var stat = null, p = obj.path.join(args['_'][0], results[i]);
1481 + try { stat = fs.statSync(p); } catch (e) { }
1482 + if ((stat == null) || (stat == undefined)) {
1483 + response += (results[i] + "\r\n");
1484 + } else {
1485 + response += (results[i] + " " + ((stat.isDirectory()) ? "(Folder)" : "(File)") + "\r\n");
1486 + }
1487 + }
1488 + break;
1489 + }
1490 + case 'lsx': { // Show list of files and folders
1491 + response = objToString(getDirectoryInfo(args['_'][0]), 0, ' ', true);
1492 + break;
1493 + }
1494 + case 'lock': { // Lock the current user out of the desktop
1495 + 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'; }
1496 + else { response = 'Not supported on the platform'; }
1497 + break;
1498 + }
1499 + case 'amt': { // Show Intel AMT status
1500 + if (amt != null) {
1501 + amt.getAmtInfo(function (state) {
1502 + var resp = 'Intel AMT not detected.';
1503 + if (state != null) { resp = objToString(state, 0, ' ', true); }
1504 + sendConsoleText(resp, sessionid);
1505 + });
1506 + }
1507 + break;
1508 + }
1509 + case 'netinfo': { // Show network interface information
1510 + //response = objToString(mesh.NetInfo, 0, ' ');
1511 + var interfaces = require('os').networkInterfaces();
1512 + response = objToString(interfaces, 0, ' ', true);
1513 + break;
1514 + }
1515 + case 'netinfo2': { // Show network interface information
1516 + response = objToString(mesh.NetInfo, 0, ' ', true);
1517 + break;
1518 + }
1519 + case 'wakeonlan': { // Send wake-on-lan
1520 + if ((args['_'].length != 1) || (args['_'][0].length != 12)) {
1521 + response = 'Proper usage: wakeonlan [mac], for example "wakeonlan 010203040506".';
1522 + } else {
1523 + var count = sendWakeOnLan(args['_'][0]);
1524 + response = 'Sent wake-on-lan on ' + count + ' interface(s).';
1525 + }
1526 + break;
1527 + }
1528 + case 'sendall': { // Send a message to all consoles on this mesh
1529 + sendConsoleText(args['_'].join(' '));
1530 + break;
1531 + }
1532 + case 'power': { // Execute a power action on this computer
1533 + if (mesh.ExecPowerState == undefined) {
1534 + response = 'Power command not supported on this agent.';
1535 + } else {
1536 + if ((args['_'].length == 0) || (typeof args['_'][0] != 'number')) {
1537 + 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
1538 + } else {
1539 + var r = mesh.ExecPowerState(args['_'][0], args['_'][1]);
1540 + response = 'Power action executed with return code: ' + r + '.';
1541 + }
1542 + }
1543 + break;
1544 + }
1545 + case 'location': {
1546 + getIpLocationData(function (location) {
1547 + sendConsoleText(objToString({ "action": "iplocation", "type": "publicip", "value": location }, 0, ' '));
1548 + });
1549 + break;
1550 + }
1551 + case 'parseuri': {
1552 + response = JSON.stringify(http.parseUri(args['_'][0]));
1553 + break;
1554 + }
1555 + case 'scanwifi': {
1556 + if (wifiScanner != null) {
1557 + var wifiPresent = wifiScanner.hasWireless;
1558 + if (wifiPresent) { response = "Perfoming Wifi scan..."; wifiScanner.Scan(); } else { response = "Wifi absent."; }
1559 + } else { response = "Wifi module not present."; }
1560 + break;
1561 + }
1562 + case 'scanamt': {
1563 + if (amtscanner != null) {
1564 + if (args['_'].length != 1) {
1565 + 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
1566 + } else {
1567 + response = 'Scanning: ' + args['_'][0] + '...';
1568 + amtscanner.scan(args['_'][0], 2000, function (data) {
1569 + if (data.length > 0) {
1570 + var r = '', pstates = ['NotActivated', 'InActivation', 'Activated'];
1571 + for (var i in data) {
1572 + var x = data[i];
1573 + if (r != '') { r += '\r\n'; }
1574 + r += x.address + ' - Intel AMT v' + x.majorVersion + '.' + x.minorVersion;
1575 + if (x.provisioningState < 3) { r += (', ' + pstates[x.provisioningState]); }
1576 + if (x.provisioningState == 2) { r += (', ' + x.openPorts.join(', ')); }
1577 + r += '.';
1578 + }
1579 + } else {
1580 + r = 'No Intel AMT found.';
1581 + }
1582 + sendConsoleText(r);
1583 + });
1584 + }
1585 + } else { response = "Intel AMT scanner module not present."; }
1586 + break;
1587 + }
1588 + case 'modules': {
1589 + response = JSON.stringify(addedModules);
1590 + break;
1591 + }
1592 + case 'getscript': {
1593 + if (args['_'].length != 1) {
1594 + response = 'Proper usage: getscript [scriptNumber].';
1595 + } else {
1596 + mesh.SendCommand({ "action": "getScript", "type": args['_'][0] });
1597 + }
1598 + break;
1599 + }
1600 + default: { // This is an unknown command, return an error message
1601 + response = 'Unknown command \"' + cmd + '\", type \"help\" for list of avaialble commands.';
1602 + break;
1603 + }
1604 + }
1605 + } catch (e) { response = 'Command returned an exception error: ' + e; console.log(e); }
1606 + if (response != null) { sendConsoleText(response, sessionid); }
1607 + }
1608 +
1609 + // Send a mesh agent console command
1610 + function sendConsoleText(text, sessionid) {
1611 + if (typeof text == 'object') { text = JSON.stringify(text); }
1612 + mesh.SendCommand({ "action": "msg", "type": "console", "value": text, "sessionid": sessionid });
1613 + }
1614 +
1615 + // Called before the process exits
1616 + //process.exit = function (code) { console.log("Exit with code: " + code.toString()); }
1617 +
1618 + // Called when the server connection state changes
1619 + function handleServerConnection(state) {
1620 + meshServerConnectionState = state;
1621 + if (meshServerConnectionState == 0) {
1622 + // Server disconnected
1623 + if (selfInfoUpdateTimer != null) { clearInterval(selfInfoUpdateTimer); selfInfoUpdateTimer = null; }
1624 + lastSelfInfo = null;
1625 + } else {
1626 + // Server connected, send mesh core information
1627 + var oldNodeId = db.Get('OldNodeId');
1628 + if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); }
1629 +
1630 + // Update the server with basic info, logged in users and more.
1631 + mesh.SendCommand(meshCoreObj);
1632 +
1633 + // Send SMBios tables if present
1634 + if (SMBiosTablesRaw != null) { mesh.SendCommand({ "action": "smbios", "value": SMBiosTablesRaw }); }
1635 +
1636 + // Update the server on more advanced stuff, like Intel ME and Network Settings
1637 + meInfoStr = null;
1638 + sendPeriodicServerUpdate();
1639 + //if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes
1640 + }
1641 + }
1642 +
1643 + // Update the server with the latest network interface information
1644 + var sendNetworkUpdateNagleTimer = null;
1645 + function sendNetworkUpdateNagle() { if (sendNetworkUpdateNagleTimer != null) { clearTimeout(sendNetworkUpdateNagleTimer); sendNetworkUpdateNagleTimer = null; } sendNetworkUpdateNagleTimer = setTimeout(sendNetworkUpdate, 5000); }
1646 + function sendNetworkUpdate(force) {
1647 + sendNetworkUpdateNagleTimer = null;
1648 +
1649 + // Update the network interfaces information data
1650 + var netInfo = mesh.NetInfo;
1651 + netInfo.action = 'netinfo';
1652 + var netInfoStr = JSON.stringify(netInfo);
1653 + if ((force == true) || (clearGatewayMac(netInfoStr) != clearGatewayMac(lastNetworkInfo))) { mesh.SendCommand(netInfo); lastNetworkInfo = netInfoStr; }
1654 + }
1655 +
1656 + // Called periodically to check if we need to send updates to the server
1657 + function sendPeriodicServerUpdate(flags) {
1658 + if (meshServerConnectionState == 0) return; // Not connected to server, do nothing.
1659 + if (!flags) { flags = 0xFFFFFFFF; }
1660 +
1661 + if ((flags & 1) && (amt != null)) {
1662 + // If we have a connected MEI, get Intel ME information
1663 + amt.getAmtInfo(function (meinfo) {
1664 + try {
1665 + if (meinfo == null) return;
1666 + var intelamt = {}, p = false;
1667 + if (meinfo.Versions && meinfo.Versions.AMT) { intelamt.ver = meinfo.Versions.AMT; p = true; }
1668 + if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; }
1669 + if (meinfo.Flags) { intelamt.flags = meinfo.Flags; p = true; }
1670 + if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; p = true; }
1671 + if (meinfo.UUID) { intelamt.uuid = meinfo.UUID; p = true; }
1672 + if (p == true) {
1673 + var meInfoStr = JSON.stringify(intelamt);
1674 + if (meInfoStr != lastMeInfo) {
1675 + meshCoreObj.intelamt = intelamt;
1676 + mesh.SendCommand(meshCoreObj);
1677 + lastMeInfo = meInfoStr;
1678 + }
1679 + }
1680 + } catch (ex) { }
1681 + });
1682 + }
1683 +
1684 + if (flags & 2) {
1685 + // Update network information
1686 + sendNetworkUpdateNagle(false);
1687 + }
1688 + }
1689 +
1690 +
1691 + // Starting function
1692 + obj.start = function () {
1693 + // Setup the mesh agent event handlers
1694 + mesh.AddCommandHandler(handleServerCommand);
1695 + mesh.AddConnectHandler(handleServerConnection);
1696 +
1697 + // Parse input arguments
1698 + //var args = parseArgs(process.argv);
1699 + //console.log(args);
1700 +
1701 + //resetMicroLms();
1702 +
1703 + // Setup logged in user monitoring (THIS IS BROKEN IN WIN7)
1704 + try {
1705 + var userSession = require('user-sessions');
1706 + userSession.on('changed', function onUserSessionChanged() {
1707 + userSession.enumerateUsers().then(function (users) {
1708 + var u = [], a = users.Active;
1709 + for (var i = 0; i < a.length; i++) {
1710 + var un = a[i].Domain ? (a[i].Domain + '\\' + a[i].Username) : (a[i].Username);
1711 + if (u.indexOf(un) == -1) { u.push(un); } // Only push users in the list once.
1712 + }
1713 + meshCoreObj.users = u;
1714 + mesh.SendCommand(meshCoreObj);
1715 + });
1716 + });
1717 + userSession.emit('changed');
1718 + //userSession.on('locked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has LOCKED the desktop'); });
1719 + //userSession.on('unlocked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has UNLOCKED the desktop'); });
1720 + } catch (ex) { }
1721 + }
1722 +
1723 + obj.stop = function () {
1724 + mesh.AddCommandHandler(null);
1725 + mesh.AddConnectHandler(null);
1726 + }
1727 +
1728 + function onWebSocketClosed() { sendConsoleText("WebSocket #" + this.httprequest.index + " closed.", this.httprequest.sessionid); delete consoleWebSockets[this.httprequest.index]; }
1729 + function onWebSocketData(data) { sendConsoleText("Got WebSocket #" + this.httprequest.index + " data: " + data, this.httprequest.sessionid); }
1730 + function onWebSocketSendOk() { sendConsoleText("WebSocket #" + this.index + " SendOK.", this.sessionid); }
1731 +
1732 + function onWebSocketUpgrade(response, s, head) {
1733 + sendConsoleText("WebSocket #" + this.index + " connected.", this.sessionid);
1734 + this.s = s;
1735 + s.httprequest = this;
1736 + s.end = onWebSocketClosed;
1737 + s.data = onWebSocketData;
1738 + }
1739 +
1740 + return obj;
1741 +}
1742 +
1743 +//
1744 +// Module startup
1745 +//
1746 +
1747 +try {
1748 + var xexports = null, mainMeshCore = null;
1749 + try { xexports = module.exports; } catch (e) { }
1750 +
1751 + if (xexports != null) {
1752 + // If we are running within NodeJS, export the core
1753 + module.exports.createMeshCore = createMeshCore;
1754 + } else {
1755 + // If we are not running in NodeJS, launch the core
1756 + mainMeshCore = createMeshCore();
1757 + mainMeshCore.start(null);
1758 + }
1759 +} catch (ex) {
1760 + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": "uncaughtException2: " + ex });
1761 +}
\ No newline at end of file
agents-new/meshcore.js new
+1776
@@ -0,0 +1,1776 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +process.on('uncaughtException', function (ex) {
18 + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": "uncaughtException1: " + ex });
19 +});
20 +
21 +// NOTE: This seems to cause big problems, don't enable the debugger in the server's meshcore.
22 +//attachDebugger({ webport: 9999, wait: 1 }).then(function (prt) { console.log('Point Browser for Debug to port: ' + prt); });
23 +
24 +// Mesh Rights
25 +var MESHRIGHT_EDITMESH = 1;
26 +var MESHRIGHT_MANAGEUSERS = 2;
27 +var MESHRIGHT_MANAGECOMPUTERS = 4;
28 +var MESHRIGHT_REMOTECONTROL = 8;
29 +var MESHRIGHT_AGENTCONSOLE = 16;
30 +var MESHRIGHT_SERVERFILES = 32;
31 +var MESHRIGHT_WAKEDEVICE = 64;
32 +var MESHRIGHT_SETNOTES = 128;
33 +var MESHRIGHT_REMOTEVIEW = 256;
34 +var MESHRIGHT_NOTERMINAL = 512;
35 +var MESHRIGHT_NOFILES = 1024;
36 +var MESHRIGHT_NOAMT = 2048;
37 +var MESHRIGHT_LIMITEDINPUT = 4096;
38 +
39 +function createMeshCore(agent) {
40 + var obj = {};
41 +
42 + /*
43 + function borderController() {
44 + this.container = null;
45 + this.Start = function Start(user) {
46 + if (this.container == null) {
47 + if (process.platform == 'win32') {
48 + try {
49 + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.SessionId });
50 + } catch (ex) {
51 + this.container = require('ScriptContainer').Create({ processIsolation: 1 });
52 + }
53 + } else {
54 + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.uid });
55 + }
56 + this.container.parent = this;
57 + this.container.addModule('monitor-info', getJSModule('monitor-info'));
58 + this.container.addModule('monitor-border', getJSModule('monitor-border'));
59 + this.container.addModule('promise', getJSModule('promise'));
60 + this.container.once('exit', function (code) { sendConsoleText('Border Process Exited with code: ' + code); this.parent.container = this.parent._container = null; });
61 + this.container.ExecuteString("var border = require('monitor-border'); border.Start();");
62 + }
63 + }
64 + this.Stop = function Stop() {
65 + if (this.container != null) {
66 + this._container = this.container;
67 + this._container.parent = this;
68 + this.container = null;
69 + this._container.exit();
70 + }
71 + }
72 + }
73 + obj.borderManager = new borderController();
74 + */
75 +
76 + // MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent.
77 + 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
78 +
79 + // Get the operating system description string
80 + try { require('os').name().then(function (v) { meshCoreObj.osdesc = v; }); } catch (ex) { }
81 +
82 + var meshServerConnectionState = 0;
83 + var tunnels = {};
84 + var lastMeInfo = null;
85 + var lastNetworkInfo = null;
86 + var lastPublicLocationInfo = null;
87 + var selfInfoUpdateTimer = null;
88 + var http = require('http');
89 + var net = require('net');
90 + var fs = require('fs');
91 + var rtc = require('ILibWebRTC');
92 + var amt = null;
93 + var processManager = require('process-manager');
94 + var wifiScannerLib = null;
95 + var wifiScanner = null;
96 + var networkMonitor = null;
97 + var amtscanner = null;
98 + var nextTunnelIndex = 1;
99 + var amtPolicy = null;
100 +
101 + // If we are running in Duktape, agent will be null
102 + if (agent == null) {
103 + // Running in native agent, Import libraries
104 + db = require('SimpleDataStore').Shared();
105 + sha = require('SHA256Stream');
106 + mesh = require('MeshAgent');
107 + childProcess = require('child_process');
108 + if (mesh.hasKVM == 1) { // if the agent is compiled with KVM support
109 + // Check if this computer supports a desktop
110 + try { if ((process.platform == 'win32') || (process.platform == 'darwin') || (require('monitor-info').kvm_x11_support)) { meshCoreObj.caps |= 1; } } catch (ex) { }
111 + }
112 + } else {
113 + // Running in nodejs
114 + meshCoreObj.value += '-NodeJS';
115 + meshCoreObj.caps = 8;
116 + mesh = agent.getMeshApi();
117 + }
118 +
119 + /*
120 + var AMTScanner = require("AMTScanner");
121 + var scan = new AMTScanner();
122 +
123 + scan.on("found", function (data) {
124 + if (typeof data === 'string') {
125 + console.log(data);
126 + } else {
127 + console.log(JSON.stringify(data, null, " "));
128 + }
129 + });
130 + scan.scan("10.2.55.140", 1000);
131 + scan.scan("10.2.55.139-10.2.55.145", 1000);
132 + scan.scan("10.2.55.128/25", 2000);
133 + */
134 +
135 + /*
136 + // Try to load up the network monitor
137 + try {
138 + networkMonitor = require('NetworkMonitor');
139 + networkMonitor.on('change', function () { sendNetworkUpdateNagle(); });
140 + networkMonitor.on('add', function (addr) { sendNetworkUpdateNagle(); });
141 + networkMonitor.on('remove', function (addr) { sendNetworkUpdateNagle(); });
142 + } catch (e) { networkMonitor = null; }
143 + */
144 +
145 + // Try to load up the Intel AMT scanner
146 + try {
147 + var AMTScannerModule = require('amt-scanner');
148 + amtscanner = new AMTScannerModule();
149 + //amtscanner.on('found', function (data) { if (typeof data != 'string') { data = JSON.stringify(data, null, " "); } sendConsoleText(data); });
150 + } catch (ex) { amtscanner = null; }
151 +
152 + // Fetch the SMBios Tables
153 + var SMBiosTables = null;
154 + var SMBiosTablesRaw = null;
155 + try {
156 + var SMBiosModule = null;
157 + try { SMBiosModule = require('smbios'); } catch (ex) { }
158 + if (SMBiosModule != null) {
159 + SMBiosModule.get(function (data) {
160 + if (data != null) {
161 + SMBiosTablesRaw = data;
162 + SMBiosTables = require('smbios').parse(data)
163 + if (mesh.isControlChannelConnected) { mesh.SendCommand({ "action": "smbios", "value": SMBiosTablesRaw }); }
164 +
165 + // If SMBios tables say that AMT is present, try to connect MEI
166 + if (SMBiosTables.amtInfo && (SMBiosTables.amtInfo.AMT == true)) {
167 + var amtmodule = require('amt-manage');
168 + amt = new amtmodule(mesh, db, true);
169 + amt.onStateChange = function (state) { if (state == 2) { sendPeriodicServerUpdate(1); } }
170 + if (amtPolicy != null) { amt.setPolicy(amtPolicy); }
171 + amt.start();
172 + }
173 + }
174 + });
175 + }
176 + } catch (ex) { sendConsoleText("ex1: " + ex); }
177 +
178 + // Try to load up the WIFI scanner
179 + try {
180 + var wifiScannerLib = require('wifi-scanner');
181 + wifiScanner = new wifiScannerLib();
182 + wifiScanner.on('accessPoint', function (data) { sendConsoleText("wifiScanner: " + data); });
183 + } catch (ex) { wifiScannerLib = null; wifiScanner = null; }
184 +
185 + // Get our location (lat/long) using our public IP address
186 + var getIpLocationDataExInProgress = false;
187 + var getIpLocationDataExCounts = [0, 0];
188 + function getIpLocationDataEx(func) {
189 + if (getIpLocationDataExInProgress == true) { return false; }
190 + try {
191 + getIpLocationDataExInProgress = true;
192 + getIpLocationDataExCounts[0]++;
193 + var options = http.parseUri("http://ipinfo.io/json");
194 + options.method = 'GET';
195 + http.request(options, function (resp) {
196 + if (resp.statusCode == 200) {
197 + var geoData = '';
198 + resp.data = function (geoipdata) { geoData += geoipdata; };
199 + resp.end = function () {
200 + var location = null;
201 + try {
202 + if (typeof geoData == 'string') {
203 + var result = JSON.parse(geoData);
204 + if (result.ip && result.loc) { location = result; }
205 + }
206 + } catch (e) { }
207 + if (func) { getIpLocationDataExCounts[1]++; func(location); }
208 + }
209 + } else { func(null); }
210 + getIpLocationDataExInProgress = false;
211 + }).end();
212 + return true;
213 + }
214 + catch (e) { return false; }
215 + }
216 +
217 + // Remove all Gateway MAC addresses for interface list. This is useful because the gateway MAC is not always populated reliably.
218 + function clearGatewayMac(str) {
219 + if (str == null) return null;
220 + var x = JSON.parse(str);
221 + for (var i in x.netif) { if (x.netif[i].gatewaymac) { delete x.netif[i].gatewaymac } }
222 + return JSON.stringify(x);
223 + }
224 +
225 + function getIpLocationData(func) {
226 + // Get the location information for the cache if possible
227 + var publicLocationInfo = db.Get('publicLocationInfo');
228 + if (publicLocationInfo != null) { publicLocationInfo = JSON.parse(publicLocationInfo); }
229 + if (publicLocationInfo == null) {
230 + // Nothing in the cache, fetch the data
231 + getIpLocationDataEx(function (locationData) {
232 + if (locationData != null) {
233 + publicLocationInfo = {};
234 + publicLocationInfo.netInfoStr = lastNetworkInfo;
235 + publicLocationInfo.locationData = locationData;
236 + var x = db.Put('publicLocationInfo', JSON.stringify(publicLocationInfo)); // Save to database
237 + if (func) func(locationData); // Report the new location
238 + } else {
239 + if (func) func(null); // Report no location
240 + }
241 + });
242 + } else {
243 + // Check the cache
244 + if (clearGatewayMac(publicLocationInfo.netInfoStr) == clearGatewayMac(lastNetworkInfo)) {
245 + // Cache match
246 + if (func) func(publicLocationInfo.locationData);
247 + } else {
248 + // Cache mismatch
249 + getIpLocationDataEx(function (locationData) {
250 + if (locationData != null) {
251 + publicLocationInfo = {};
252 + publicLocationInfo.netInfoStr = lastNetworkInfo;
253 + publicLocationInfo.locationData = locationData;
254 + var x = db.Put('publicLocationInfo', JSON.stringify(publicLocationInfo)); // Save to database
255 + if (func) func(locationData); // Report the new location
256 + } else {
257 + if (func) func(publicLocationInfo.locationData); // Can't get new location, report the old location
258 + }
259 + });
260 + }
261 + }
262 + }
263 +
264 + // Polyfill String.endsWith
265 + if (!String.prototype.endsWith) {
266 + String.prototype.endsWith = function (searchString, position) {
267 + var subjectString = this.toString();
268 + if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { position = subjectString.length; }
269 + position -= searchString.length;
270 + var lastIndex = subjectString.lastIndexOf(searchString, position);
271 + return lastIndex !== -1 && lastIndex === position;
272 + };
273 + }
274 +
275 + // Polyfill path.join
276 + obj.path = {
277 + join: function () {
278 + var x = [];
279 + for (var i in arguments) {
280 + var w = arguments[i];
281 + if (w != null) {
282 + while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
283 + if (i != 0) {
284 + while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); }
285 + }
286 + x.push(w);
287 + }
288 + }
289 + if (x.length == 0) return '/';
290 + return x.join('/');
291 + }
292 + };
293 +
294 + // Replace a string with a number if the string is an exact number
295 + function toNumberIfNumber(x) { if ((typeof x == 'string') && (+parseInt(x) === x)) { x = parseInt(x); } return x; }
296 +
297 + // Convert decimal to hex
298 + function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); }
299 +
300 + // Convert a raw string to a hex string
301 + function rstr2hex(input) { var r = '', i; for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); } return r; }
302 +
303 + // Convert a buffer into a string
304 + function buf2rstr(buf) { var r = ''; for (var i = 0; i < buf.length; i++) { r += String.fromCharCode(buf[i]); } return r; }
305 +
306 + // Convert a hex string to a raw string // TODO: Do this using Buffer(), will be MUCH faster
307 + function hex2rstr(d) {
308 + if (typeof d != "string" || d.length == 0) return '';
309 + var r = '', m = ('' + d).match(/../g), t;
310 + while (t = m.shift()) r += String.fromCharCode('0x' + t);
311 + return r
312 + }
313 +
314 + // Convert an object to string with all functions
315 + function objToString(x, p, pad, ret) {
316 + if (ret == undefined) ret = '';
317 + if (p == undefined) p = 0;
318 + if (x == null) { return '[null]'; }
319 + if (p > 8) { return '[...]'; }
320 + if (x == undefined) { return '[undefined]'; }
321 + if (typeof x == 'string') { if (p == 0) return x; return '"' + x + '"'; }
322 + if (typeof x == 'buffer') { return '[buffer]'; }
323 + if (typeof x != 'object') { return x; }
324 + var r = '{' + (ret ? '\r\n' : ' ');
325 + for (var i in x) { if (i != '_ObjectID') { r += (addPad(p + 2, pad) + i + ': ' + objToString(x[i], p + 2, pad, ret) + (ret ? '\r\n' : ' ')); } }
326 + return r + addPad(p, pad) + '}';
327 + }
328 +
329 + // Return p number of spaces
330 + function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ret; } return r; }
331 +
332 + // Split a string taking into account the quoats. Used for command line parsing
333 + function splitArgs(str) {
334 + var myArray = [], myRegexp = /[^\s"]+|"([^"]*)"/gi;
335 + do { var match = myRegexp.exec(str); if (match != null) { myArray.push(match[1] ? match[1] : match[0]); } } while (match != null);
336 + return myArray;
337 + }
338 +
339 + // Parse arguments string array into an object
340 + function parseArgs(argv) {
341 + var results = { '_': [] }, current = null;
342 + for (var i = 1, len = argv.length; i < len; i++) {
343 + var x = argv[i];
344 + if (x.length > 2 && x[0] == '-' && x[1] == '-') {
345 + if (current != null) { results[current] = true; }
346 + current = x.substring(2);
347 + } else {
348 + if (current != null) { results[current] = toNumberIfNumber(x); current = null; } else { results['_'].push(toNumberIfNumber(x)); }
349 + }
350 + }
351 + if (current != null) { results[current] = true; }
352 + return results;
353 + }
354 +
355 + // Get server target url with a custom path
356 + function getServerTargetUrl(path) {
357 + var x = mesh.ServerUrl;
358 + //sendConsoleText("mesh.ServerUrl: " + mesh.ServerUrl);
359 + if (x == null) { return null; }
360 + if (path == null) { path = ''; }
361 + x = http.parseUri(x);
362 + if (x == null) return null;
363 + return x.protocol + '//' + x.host + ':' + x.port + '/' + path;
364 + }
365 +
366 + // Get server url. If the url starts with "*/..." change it, it not use the url as is.
367 + function getServerTargetUrlEx(url) {
368 + if (url.substring(0, 2) == '*/') { return getServerTargetUrl(url.substring(2)); }
369 + return url;
370 + }
371 +
372 + // Send a wake-on-lan packet
373 + function sendWakeOnLan(hexMac) {
374 + var count = 0;
375 + try {
376 + var interfaces = require('os').networkInterfaces();
377 + var magic = 'FFFFFFFFFFFF';
378 + for (var x = 1; x <= 16; ++x) { magic += hexMac; }
379 + var magicbin = Buffer.from(magic, 'hex');
380 +
381 + for (var adapter in interfaces) {
382 + if (interfaces.hasOwnProperty(adapter)) {
383 + for (var i = 0; i < interfaces[adapter].length; ++i) {
384 + var addr = interfaces[adapter][i];
385 + if ((addr.family == 'IPv4') && (addr.mac != '00:00:00:00:00:00')) {
386 + var socket = require('dgram').createSocket({ type: "udp4" });
387 + socket.bind({ address: addr.address });
388 + socket.setBroadcast(true);
389 + socket.send(magicbin, 7, "255.255.255.255");
390 + count++;
391 + }
392 + }
393 + }
394 + }
395 + } catch (e) { }
396 + return count;
397 + }
398 +
399 + // Handle a mesh agent command
400 + function handleServerCommand(data) {
401 + if (typeof data == 'object') {
402 + // If this is a console command, parse it and call the console handler
403 + switch (data.action) {
404 + case 'msg': {
405 + switch (data.type) {
406 + case 'console': { // Process a console command
407 + if (data.value && data.sessionid) {
408 + var args = splitArgs(data.value);
409 + processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid);
410 + }
411 + break;
412 + }
413 + case 'tunnel': {
414 + if (data.value != null) { // Process a new tunnel connection request
415 + // Create a new tunnel object
416 + var xurl = getServerTargetUrlEx(data.value);
417 + if (xurl != null) {
418 + var woptions = http.parseUri(xurl);
419 + woptions.rejectUnauthorized = 0;
420 + //sendConsoleText(JSON.stringify(woptions));
421 + var tunnel = http.request(woptions);
422 + tunnel.upgrade = onTunnelUpgrade;
423 + tunnel.on('error', function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); });
424 + tunnel.sessionid = data.sessionid;
425 + tunnel.rights = data.rights;
426 + tunnel.state = 0;
427 + tunnel.url = xurl;
428 + tunnel.protocol = 0;
429 + tunnel.tcpaddr = data.tcpaddr;
430 + tunnel.tcpport = data.tcpport;
431 + tunnel.end();
432 + // Put the tunnel in the tunnels list
433 + var index = nextTunnelIndex++;
434 + tunnel.index = index;
435 + tunnels[index] = tunnel;
436 +
437 + //sendConsoleText('New tunnel connection #' + index + ': ' + tunnel.url + ', rights: ' + tunnel.rights, data.sessionid);
438 + }
439 + }
440 + break;
441 + }
442 + case 'ps': {
443 + // Return the list of running processes
444 + if (data.sessionid) {
445 + processManager.getProcesses(function (plist) { mesh.SendCommand({ "action": "msg", "type": "ps", "value": JSON.stringify(plist), "sessionid": data.sessionid }); });
446 + }
447 + break;
448 + }
449 + case 'pskill': {
450 + // Kill a process
451 + if (data.value) {
452 + try { process.kill(data.value); } catch (e) { sendConsoleText("pskill: " + JSON.stringify(e)); }
453 + }
454 + break;
455 + }
456 + case 'openUrl': {
457 + // Open a local web browser and return success/fail
458 + sendConsoleText('OpenURL: ' + data.url);
459 + if (data.url) { mesh.SendCommand({ "action": "msg", "type":"openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); }
460 + break;
461 + }
462 + case 'getclip': {
463 + // Send the load clipboard back to the user
464 + sendConsoleText('getClip: ' + JSON.stringify(data));
465 + if (require('MeshAgent').isService)
466 + {
467 + require('clipboard').dispatchRead().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); });
468 + }
469 + else
470 + {
471 + require("clipboard").read().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); });
472 + }
473 + break;
474 + }
475 + case 'setclip': {
476 + // Set the load clipboard to a user value
477 + sendConsoleText('setClip: ' + JSON.stringify(data));
478 + if (typeof data.data == 'string')
479 + {
480 + if (require('MeshAgent').isService)
481 + {
482 + require('clipboard').dispatchWrite(data.data);
483 + }
484 + else
485 + {
486 + require("clipboard")(data.data); // Set the clipboard
487 + }
488 + mesh.SendCommand({ "action": "msg", "type": "setclip", "sessionid": data.sessionid, "success": true });
489 + }
490 + break;
491 + }
492 + default:
493 + // Unknown action, ignore it.
494 + break;
495 + }
496 + break;
497 + }
498 + case 'wakeonlan': {
499 + // Send wake-on-lan on all interfaces for all MAC addresses in data.macs array. The array is a list of HEX MAC addresses.
500 + sendConsoleText('Server requesting wake-on-lan for: ' + data.macs.join(', '));
501 + for (var i in data.macs) { sendWakeOnLan(data.macs[i]); }
502 + break;
503 + }
504 + case 'poweraction': {
505 + // Server telling us to execute a power action
506 + if ((mesh.ExecPowerState != undefined) && (data.actiontype)) {
507 + var forced = 0;
508 + if (data.forced == 1) { forced = 1; }
509 + data.actiontype = parseInt(data.actiontype);
510 + sendConsoleText('Performing power action=' + data.actiontype + ', forced=' + forced + '.');
511 + var r = mesh.ExecPowerState(data.actiontype, forced);
512 + sendConsoleText('ExecPowerState returned code: ' + r);
513 + }
514 + break;
515 + }
516 + case 'iplocation': {
517 + // 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
518 + getIpLocationData(function (location) { mesh.SendCommand({ "action": "iplocation", "type": "publicip", "value": location }); });
519 + break;
520 + }
521 + case 'toast': {
522 + // Display a toast message
523 + if (data.title && data.msg) { require('toaster').Toast(data.title, data.msg); }
524 + break;
525 + }
526 + case 'openUrl': {
527 + // Open a local web browser and return success/fail
528 + sendConsoleText('OpenURL: ' + data.url);
529 + if (data.url) { mesh.SendCommand({ "action": "openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); }
530 + break;
531 + }
532 + case 'amtPolicy': {
533 + // Store the latest Intel AMT policy
534 + amtPolicy = data.amtPolicy;
535 + if (data.amtPolicy != null) { db.Put('amtPolicy', JSON.stringify(data.amtPolicy)); } else { db.Put('amtPolicy', null); }
536 + if (amt != null) { amt.setPolicy(amtPolicy); }
537 + break;
538 + }
539 + case 'getScript': {
540 + // Received a configuration script from the server
541 + sendConsoleText('getScript: ' + JSON.stringify(data));
542 + break;
543 + }
544 + default:
545 + // Unknown action, ignore it.
546 + break;
547 + }
548 + }
549 + }
550 +
551 + // Called when a file changed in the file system
552 + /*
553 + function onFileWatcher(a, b) {
554 + console.log('onFileWatcher', a, b, this.path);
555 + var response = getDirectoryInfo(this.path);
556 + if ((response != undefined) && (response != null)) { this.tunnel.s.write(JSON.stringify(response)); }
557 + }
558 + */
559 +
560 + // Get a formated response for a given directory path
561 + function getDirectoryInfo(reqpath) {
562 + var response = { path: reqpath, dir: [] };
563 + if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) {
564 + // List all the drives in the root, or the root itself
565 + var results = null;
566 + try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
567 + if (results != null) {
568 + for (var i = 0; i < results.length; ++i) {
569 + var drive = { n: results[i].name, t: 1 };
570 + if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons.
571 + response.dir.push(drive);
572 + }
573 + }
574 + } else {
575 + // List all the files and folders in this path
576 + if (reqpath == '') { reqpath = '/'; }
577 + var results = null, xpath = obj.path.join(reqpath, '*');
578 + //if (process.platform == "win32") { xpath = xpath.split('/').join('\\'); }
579 + try { results = fs.readdirSync(xpath); } catch (e) { }
580 + if (results != null) {
581 + for (var i = 0; i < results.length; ++i) {
582 + if ((results[i] != '.') && (results[i] != '..')) {
583 + var stat = null, p = obj.path.join(reqpath, results[i]);
584 + //if (process.platform == "win32") { p = p.split('/').join('\\'); }
585 + try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date
586 + if ((stat != null) && (stat != undefined)) {
587 + if (stat.isDirectory() == true) {
588 + response.dir.push({ n: results[i], t: 2, d: stat.mtime });
589 + } else {
590 + response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime });
591 + }
592 + }
593 + }
594 + }
595 + }
596 + }
597 + return response;
598 + }
599 +
600 + // Tunnel callback operations
601 + function onTunnelUpgrade(response, s, head) {
602 + this.s = s;
603 + s.httprequest = this;
604 + s.end = onTunnelClosed;
605 + s.tunnel = this;
606 +
607 + //sendConsoleText('onTunnelUpgrade');
608 +
609 + if (this.tcpport != null) {
610 + // This is a TCP relay connection, pause now and try to connect to the target.
611 + s.pause();
612 + s.data = onTcpRelayServerTunnelData;
613 + var connectionOptions = { port: parseInt(this.tcpport) };
614 + if (this.tcpaddr != null) { connectionOptions.host = this.tcpaddr; } else { connectionOptions.host = '127.0.0.1'; }
615 + s.tcprelay = net.createConnection(connectionOptions, onTcpRelayTargetTunnelConnect);
616 + s.tcprelay.peerindex = this.index;
617 + } else {
618 + // This is a normal connect for KVM/Terminal/Files
619 + s.data = onTunnelData;
620 + }
621 + }
622 +
623 + // Called when the TCP relay target is connected
624 + function onTcpRelayTargetTunnelConnect() {
625 + var peerTunnel = tunnels[this.peerindex];
626 + this.pipe(peerTunnel.s); // Pipe Target --> Server
627 + peerTunnel.s.first = true;
628 + peerTunnel.s.resume();
629 + }
630 +
631 + // Called when we get data from the server for a TCP relay (We have to skip the first received 'c' and pipe the rest)
632 + function onTcpRelayServerTunnelData(data) {
633 + if (this.first == true) { this.first = false; this.pipe(this.tcprelay); } // Pipe Server --> Target
634 + }
635 +
636 + function onTunnelClosed() {
637 + if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls.
638 + //sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid);
639 + delete tunnels[this.httprequest.index];
640 +
641 + /*
642 + // Close the watcher if required
643 + if (this.httprequest.watcher != undefined) {
644 + //console.log('Closing watcher: ' + this.httprequest.watcher.path);
645 + //this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!!
646 + delete this.httprequest.watcher;
647 + }
648 + */
649 +
650 + // If there is a upload or download active on this connection, close the file
651 + if (this.httprequest.uploadFile) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
652 + if (this.httprequest.downloadFile) { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; }
653 +
654 + // Clean up WebRTC
655 + if (this.webrtc != null) {
656 + 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; }
657 + if (this.webrtc.websocket) { delete this.webrtc.websocket; }
658 + try { this.webrtc.close(); } catch (e) { }
659 + this.webrtc.removeAllListeners('connected');
660 + this.webrtc.removeAllListeners('disconnected');
661 + this.webrtc.removeAllListeners('dataChannel');
662 + delete this.webrtc;
663 + }
664 +
665 + // Clean up WebSocket
666 + this.removeAllListeners('data');
667 + }
668 + function onTunnelSendOk() { /*sendConsoleText("Tunnel #" + this.index + " SendOK.", this.sessionid);*/ }
669 + function onTunnelData(data) {
670 + //console.log("OnTunnelData");
671 + //sendConsoleText('OnTunnelData, ' + data.length + ', ' + typeof data + ', ' + data);
672 +
673 + // If this is upload data, save it to file
674 + if (this.httprequest.uploadFile) {
675 + 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.
676 + this.write(new Buffer(JSON.stringify({ action: 'uploadack', reqid: this.httprequest.uploadFileid }))); // Ask for more data
677 + return;
678 + }
679 + /*
680 + // If this is a download, send more of the file
681 + if (this.httprequest.downloadFile) {
682 + var buf = new Buffer(4096);
683 + var len = fs.readSync(this.httprequest.downloadFile, buf, 0, 4096, null);
684 + this.httprequest.downloadFilePtr += len;
685 + if (len > 0) { this.write(buf.slice(0, len)); } else { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; this.end(); }
686 + return;
687 + }
688 + */
689 +
690 + if (this.httprequest.state == 0) {
691 + // Check if this is a relay connection
692 + if (data == 'c') { this.httprequest.state = 1; /*sendConsoleText("Tunnel #" + this.httprequest.index + " now active", this.httprequest.sessionid);*/ }
693 + } else {
694 + // Handle tunnel data
695 + if (this.httprequest.protocol == 0) { // 1 = Terminal, 2 = Desktop, 5 = Files
696 + // Take a look at the protocol
697 + this.httprequest.protocol = parseInt(data);
698 + if (typeof this.httprequest.protocol != 'number') { this.httprequest.protocol = 0; }
699 + if (this.httprequest.protocol == 1) {
700 + // Check user access rights for terminal
701 + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOTERMINAL) != 0))) {
702 + // Disengage this tunnel, user does not have the rights to do this!!
703 + this.httprequest.protocol = 999999;
704 + this.httprequest.s.end();
705 + sendConsoleText('Error: No Terminal Control Rights.');
706 + return;
707 + }
708 +
709 + // Remote terminal using native pipes
710 + if (process.platform == "win32")
711 + {
712 + this.httprequest._term = require('win-terminal').Start(80, 25);
713 + this.httprequest._term.pipe(this, { dataTypeSkip: 1 });
714 + this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false });
715 + this.prependListener('end', function () { this.httprequest._term.end(function () { console.log('Terminal was closed'); }); });
716 + //this.httprequest.process = childProcess.execFile("%windir%\\system32\\cmd.exe");
717 + } else {
718 + this.httprequest.process = childProcess.execFile("/bin/sh", ["sh"], { type: childProcess.SpawnTypes.TERM });
719 + this.httprequest.process.tunnel = this;
720 + this.httprequest.process.on('exit', function (ecode, sig) { this.tunnel.end(); });
721 + this.httprequest.process.stderr.on('data', function (chunk) { this.parent.tunnel.write(chunk); });
722 + this.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
723 + this.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
724 + this.prependListener('end', function () { this.httprequest.process.kill(); });
725 + }
726 +
727 + this.end = function () {
728 + if (process.platform == "win32") {
729 + // Unpipe the web socket
730 + this.unpipe(this.httprequest._term);
731 + this.httprequest._term.unpipe(this);
732 +
733 + // Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends).
734 + if (this.rtcchannel) {
735 + this.rtcchannel.unpipe(this.httprequest._term);
736 + this.httprequest._term.unpipe(this.rtcchannel);
737 + }
738 +
739 + // Clean up
740 + this.httprequest._term.end();
741 + this.httprequest._term = null;
742 + } else {
743 + // TODO!!
744 + }
745 + };
746 +
747 + this.removeAllListeners('data');
748 + this.on('data', onTunnelControlData);
749 + //this.write('MeshCore Terminal Hello');
750 + if (process.platform == 'linux') { this.httprequest.process.stdin.write("stty erase ^H\nalias ls='ls --color=auto'\nclear\n"); }
751 + } else if (this.httprequest.protocol == 2)
752 + {
753 + // Check user access rights for desktop
754 + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0)) {
755 + // Disengage this tunnel, user does not have the rights to do this!!
756 + this.httprequest.protocol = 999999;
757 + this.httprequest.s.end();
758 + sendConsoleText('Error: No Desktop Control Rights.');
759 + return;
760 + }
761 +
762 + // Remote desktop using native pipes
763 + this.httprequest.desktop = { state: 0, kvm: mesh.getRemoteDesktopStream(), tunnel: this };
764 + this.httprequest.desktop.kvm.parent = this.httprequest.desktop;
765 + this.desktop = this.httprequest.desktop;
766 +
767 + // Display a toast message
768 + //require('toaster').Toast('MeshCentral', 'Remote Desktop Control Started.');
769 +
770 + this.end = function () {
771 + --this.desktop.kvm.connectionCount;
772 +
773 + // Unpipe the web socket
774 + this.unpipe(this.httprequest.desktop.kvm);
775 + this.httprequest.desktop.kvm.unpipe(this);
776 +
777 + // Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends).
778 + if (this.rtcchannel) {
779 + this.rtcchannel.unpipe(this.httprequest.desktop.kvm);
780 + this.httprequest.desktop.kvm.unpipe(this.rtcchannel);
781 + }
782 +
783 + if (this.desktop.kvm.connectionCount == 0) {
784 + // Display a toast message
785 + //require('toaster').Toast('MeshCentral', 'Remote Desktop Control Ended.');
786 + this.httprequest.desktop.kvm.end();
787 + }
788 + };
789 + if (this.httprequest.desktop.kvm.hasOwnProperty("connectionCount")) { this.httprequest.desktop.kvm.connectionCount++; } else { this.httprequest.desktop.kvm.connectionCount = 1; }
790 +
791 + if ((this.httprequest.rights == 0xFFFFFFFF) || (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) != 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0))) {
792 + // If we have remote control rights, pipe the KVM input
793 + this.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. Pipe the Browser --> KVM input.
794 + } else {
795 + // We need to only pipe non-mouse & non-keyboard inputs.
796 + //sendConsoleText('Warning: No Remote Desktop Input Rights.');
797 + // TODO!!!
798 + }
799 +
800 + this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. Pipe the KVM --> Browser images.
801 + this.removeAllListeners('data');
802 + this.on('data', onTunnelControlData);
803 + //this.write('MeshCore KVM Hello!1');
804 + } else if (this.httprequest.protocol == 5) {
805 + // Check user access rights for files
806 + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOFILES) != 0))) {
807 + // Disengage this tunnel, user does not have the rights to do this!!
808 + this.httprequest.protocol = 999999;
809 + this.httprequest.s.end();
810 + sendConsoleText('Error: No Files Control Rights.');
811 + return;
812 + }
813 +
814 + // Setup files
815 + // NOP
816 + }
817 + } else if (this.httprequest.protocol == 1) {
818 + // Send data into terminal stdin
819 + //this.write(data); // Echo back the keys (Does not seem to be a good idea)
820 + this.httprequest.process.write(data);
821 + } else if (this.httprequest.protocol == 2) {
822 + // Send data into remote desktop
823 + if (this.httprequest.desktop.state == 0) {
824 + this.write(new Buffer(String.fromCharCode(0x11, 0xFE, 0x00, 0x00, 0x4D, 0x45, 0x53, 0x48, 0x00, 0x00, 0x00, 0x00, 0x02)));
825 + this.httprequest.desktop.state = 1;
826 + } else {
827 + this.httprequest.desktop.write(data);
828 + }
829 + } else if (this.httprequest.protocol == 5) {
830 + // Process files commands
831 + var cmd = null;
832 + try { cmd = JSON.parse(data); } catch (e) { };
833 + if (cmd == null) { return; }
834 + if ((cmd.ctrlChannel == '102938') || ((cmd.type == 'offer') && (cmd.sdp != null))) { onTunnelControlData(cmd, this); return; } // If this is control data, handle it now.
835 + if (cmd.action == undefined) { return; }
836 + //sendConsoleText('CMD: ' + JSON.stringify(cmd));
837 +
838 + if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
839 + //console.log(objToString(cmd, 0, ' '));
840 + switch (cmd.action) {
841 + case 'ls': {
842 + /*
843 + // Close the watcher if required
844 + var samepath = ((this.httprequest.watcher != undefined) && (cmd.path == this.httprequest.watcher.path));
845 + if ((this.httprequest.watcher != undefined) && (samepath == false)) {
846 + //console.log('Closing watcher: ' + this.httprequest.watcher.path);
847 + //this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!!
848 + delete this.httprequest.watcher;
849 + }
850 + */
851 +
852 + // Send the folder content to the browser
853 + var response = getDirectoryInfo(cmd.path);
854 + if (cmd.reqid != undefined) { response.reqid = cmd.reqid; }
855 + this.write(new Buffer(JSON.stringify(response)));
856 +
857 + /*
858 + // Start the directory watcher
859 + if ((cmd.path != '') && (samepath == false)) {
860 + var watcher = fs.watch(cmd.path, onFileWatcher);
861 + watcher.tunnel = this.httprequest;
862 + watcher.path = cmd.path;
863 + this.httprequest.watcher = watcher;
864 + //console.log('Starting watcher: ' + this.httprequest.watcher.path);
865 + }
866 + */
867 + break;
868 + }
869 + case 'mkdir': {
870 + // Create a new empty folder
871 + fs.mkdirSync(cmd.path);
872 + break;
873 + }
874 + case 'rm': {
875 + // Delete, possibly recursive delete
876 + for (var i in cmd.delfiles) {
877 + try { deleteFolderRecursive(obj.path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (e) { }
878 + }
879 + break;
880 + }
881 + case 'rename': {
882 + // Rename a file or folder
883 + var oldfullpath = obj.path.join(cmd.path, cmd.oldname);
884 + var newfullpath = obj.path.join(cmd.path, cmd.newname);
885 + try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); }
886 + break;
887 + }
888 + case 'download': {
889 + // Download a file
890 + var sendNextBlock = 0;
891 + if (cmd.sub == 'start') { // Setup the download
892 + if (this.filedownload != null) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
893 + this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
894 + 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; }
895 + if (this.filedownload) { this.write({ action: 'download', sub: 'start', id: cmd.id }); }
896 + } else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands
897 + if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; }
898 + }
899 + // Send the next download block(s)
900 + while (sendNextBlock > 0) {
901 + sendNextBlock--;
902 + var buf = new Buffer(4096);
903 + var len = fs.readSync(this.filedownload.f, buf, 4, 4092, null);
904 + this.filedownload.ptr += len;
905 + if (len < 4092) { buf.writeInt32BE(0x01000001, 0); fs.closeSync(this.filedownload.f); delete this.filedownload; sendNextBlock = 0; } else { buf.writeInt32BE(0x01000000, 0); }
906 + this.write(buf.slice(0, len + 4)); // Write as binary
907 + }
908 + break;
909 + }
910 + /*
911 + case 'download': {
912 + // Packet download of a file, agent to browser
913 + if (cmd.path == undefined) break;
914 + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path;
915 + //console.log('Download: ' + filepath);
916 + try { this.httprequest.downloadFile = fs.openSync(filepath, 'rbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'downloaderror', reqid: cmd.reqid }))); break; }
917 + this.httprequest.downloadFileId = cmd.reqid;
918 + this.httprequest.downloadFilePtr = 0;
919 + if (this.httprequest.downloadFile) { this.write(new Buffer(JSON.stringify({ action: 'downloadstart', reqid: this.httprequest.downloadFileId }))); }
920 + break;
921 + }
922 + case 'download2': {
923 + // Stream download of a file, agent to browser
924 + if (cmd.path == undefined) break;
925 + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path;
926 + try { this.httprequest.downloadFile = fs.createReadStream(filepath, { flags: 'rbN' }); } catch (e) { console.log(e); }
927 + this.httprequest.downloadFile.pipe(this);
928 + this.httprequest.downloadFile.end = function () { }
929 + break;
930 + }
931 + */
932 + case 'upload': {
933 + // Upload a file, browser to agent
934 + if (this.httprequest.uploadFile != undefined) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
935 + if (cmd.path == undefined) break;
936 + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path;
937 + try { this.httprequest.uploadFile = fs.openSync(filepath, 'wbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror', reqid: cmd.reqid }))); break; }
938 + this.httprequest.uploadFileid = cmd.reqid;
939 + if (this.httprequest.uploadFile) { this.write(new Buffer(JSON.stringify({ action: 'uploadstart', reqid: this.httprequest.uploadFileid }))); }
940 + break;
941 + }
942 + case 'copy': {
943 + // Copy a bunch of files from scpath to dspath
944 + for (var i in cmd.names) {
945 + var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]);
946 + if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
947 + }
948 + break;
949 + }
950 + case 'move': {
951 + // Move a bunch of files from scpath to dspath
952 + for (var i in cmd.names) {
953 + var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]);
954 + if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
955 + }
956 + break;
957 + }
958 + default:
959 + // Unknown action, ignore it.
960 + break;
961 + }
962 + }
963 + //sendConsoleText("Got tunnel #" + this.httprequest.index + " data: " + data, this.httprequest.sessionid);
964 + }
965 + }
966 +
967 + // Delete a directory with a files and directories within it
968 + function deleteFolderRecursive(path, rec) {
969 + if (fs.existsSync(path)) {
970 + if (rec == true) {
971 + fs.readdirSync(obj.path.join(path, '*')).forEach(function (file, index) {
972 + var curPath = obj.path.join(path, file);
973 + if (fs.statSync(curPath).isDirectory()) { // recurse
974 + deleteFolderRecursive(curPath, true);
975 + } else { // delete file
976 + fs.unlinkSync(curPath);
977 + }
978 + });
979 + }
980 + fs.unlinkSync(path);
981 + }
982 + };
983 +
984 + // Called when receiving control data on WebRTC
985 + function onTunnelWebRTCControlData(data) {
986 + if (typeof data != 'string') return;
987 + var obj;
988 + try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON on WebRTC: ' + data); return; }
989 + if (obj.type == 'close') {
990 + //sendConsoleText('Tunnel #' + this.xrtc.websocket.tunnel.index + ' WebRTC control close');
991 + try { this.close(); } catch (e) { }
992 + try { this.xrtc.close(); } catch (e) { }
993 + }
994 + }
995 +
996 + // Called when receiving control data on websocket
997 + function onTunnelControlData(data, ws) {
998 + var obj;
999 + if (ws == null) { ws = this; }
1000 + if (typeof data == 'string') { try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON: ' + data); return; } }
1001 + else if (typeof data == 'object') { obj = data; } else { return; }
1002 + //sendConsoleText('onTunnelControlData(' + ws.httprequest.protocol + '): ' + JSON.stringify(data));
1003 + //console.log('onTunnelControlData: ' + JSON.stringify(data));
1004 +
1005 + if (obj.action) {
1006 + switch (obj.action) {
1007 + case 'lock': {
1008 + // Lock the current user out of the desktop
1009 + try {
1010 + if (process.platform == 'win32') {
1011 + var child = require('child_process');
1012 + child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 });
1013 + }
1014 + } catch (e) { }
1015 + break;
1016 + }
1017 + default:
1018 + // Unknown action, ignore it.
1019 + break;
1020 + }
1021 + return;
1022 + }
1023 +
1024 + if (obj.type == 'close') {
1025 + // We received the close on the websocket
1026 + //sendConsoleText('Tunnel #' + ws.tunnel.index + ' WebSocket control close');
1027 + try { ws.close(); } catch (e) { }
1028 + } else if (obj.type == 'webrtc0') { // Browser indicates we can start WebRTC switch-over.
1029 + if (ws.httprequest.protocol == 1) { // Terminal
1030 + // 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
1031 + if (process.platform == 'win32')
1032 + {
1033 + ws.httprequest._term.unpipe(ws);
1034 + }
1035 + else
1036 + {
1037 + ws.httprequest.process.stdout.unpipe(ws);
1038 + ws.httprequest.process.stderr.unpipe(ws);
1039 + }
1040 + } else if (ws.httprequest.protocol == 2) { // Desktop
1041 + // 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
1042 + ws.httprequest.desktop.kvm.unpipe(ws);
1043 + } else {
1044 + // Switch things around so all WebRTC data goes to onTunnelData().
1045 + ws.rtcchannel.httprequest = ws.httprequest;
1046 + ws.rtcchannel.removeAllListeners('data');
1047 + ws.rtcchannel.on('data', onTunnelData);
1048 + }
1049 + ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc1\"}"); // End of data marker
1050 + } else if (obj.type == 'webrtc1') {
1051 + if (ws.httprequest.protocol == 1) { // Terminal
1052 + // Switch the user input from websocket to webrtc at this point.
1053 + if (process.platform == 'win32')
1054 + {
1055 + ws.unpipe(ws.httprequest._term);
1056 + ws.rtcchannel.pipe(ws.httprequest._term, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
1057 + }
1058 + else
1059 + {
1060 + ws.unpipe(ws.httprequest.process.stdin);
1061 + ws.rtcchannel.pipe(ws.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
1062 + }
1063 + ws.resume(); // Resume the websocket to keep receiving control data
1064 + } else if (ws.httprequest.protocol == 2) { // Desktop
1065 + // Switch the user input from websocket to webrtc at this point.
1066 + ws.unpipe(ws.httprequest.desktop.kvm);
1067 + try { ws.webrtc.rtcchannel.pipe(ws.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); } catch (e) { sendConsoleText('EX2'); } // 0 = Binary, 1 = Text.
1068 + ws.resume(); // Resume the websocket to keep receiving control data
1069 + }
1070 + ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point.
1071 + } else if (obj.type == 'webrtc2') {
1072 + // Other side received websocket end of data marker, start sending data on WebRTC channel
1073 + if (ws.httprequest.protocol == 1) { // Terminal
1074 + if (process.platform == 'win32')
1075 + {
1076 + ws.httprequest._term.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
1077 + }
1078 + else
1079 + {
1080 + ws.httprequest.process.stdout.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
1081 + ws.httprequest.process.stderr.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
1082 + }
1083 + } else if (ws.httprequest.protocol == 2) { // Desktop
1084 + ws.httprequest.desktop.kvm.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
1085 + }
1086 + } else if (obj.type == 'offer') {
1087 + // This is a WebRTC offer.
1088 + if (ws.httprequest.protocol == 1) return; // TODO: Terminal is currently broken with WebRTC. Reject WebRTC upgrade for now.
1089 + ws.webrtc = rtc.createConnection();
1090 + ws.webrtc.websocket = ws;
1091 + ws.webrtc.on('connected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC connected');*/ });
1092 + ws.webrtc.on('disconnected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC disconnected');*/ });
1093 + ws.webrtc.on('dataChannel', function (rtcchannel) {
1094 + //sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol);
1095 + rtcchannel.xrtc = this;
1096 + rtcchannel.websocket = this.websocket;
1097 + this.rtcchannel = rtcchannel;
1098 + this.websocket.rtcchannel = rtcchannel;
1099 + this.websocket.rtcchannel.on('data', onTunnelWebRTCControlData);
1100 + this.websocket.rtcchannel.on('end', function () {
1101 + // The WebRTC channel closed, unpipe the KVM now. This is also done when the web socket closes.
1102 + //sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed');
1103 + if (this.websocket.desktop && this.websocket.desktop.kvm) {
1104 + this.unpipe(this.websocket.desktop.kvm);
1105 + this.websocket.httprequest.desktop.kvm.unpipe(this);
1106 + }
1107 + });
1108 + this.websocket.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc0\"}"); // Indicate we are ready for WebRTC switch-over.
1109 + });
1110 + var sdp = null;
1111 + try { sdp = ws.webrtc.setOffer(obj.sdp); } catch (ex) { }
1112 + if (sdp != null) { ws.write({ type: 'answer', ctrlChannel: '102938', sdp: sdp }); }
1113 + }
1114 + }
1115 +
1116 + // Console state
1117 + var consoleWebSockets = {};
1118 + var consoleHttpRequest = null;
1119 +
1120 + // Console HTTP response
1121 + function consoleHttpResponse(response) {
1122 + response.data = function (data) { sendConsoleText(rstr2hex(buf2rstr(data)), this.sessionid); consoleHttpRequest = null; }
1123 + response.close = function () { sendConsoleText('httprequest.response.close', this.sessionid); consoleHttpRequest = null; }
1124 + };
1125 +
1126 + // Open a web browser to a specified URL on current user's desktop
1127 + function openUserDesktopUrl(url) {
1128 + var child = null;
1129 + try {
1130 + switch (process.platform) {
1131 + case 'win32':
1132 + //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 });
1133 + child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe', ["/c", "start", url], { type: childProcess.SpawnTypes.USER });
1134 + break;
1135 + case 'linux':
1136 + child = require('child_process').execFile('/usr/bin/xdg-open', ['xdg-open', url], { uid: require('user-sessions').consoleUid() });
1137 + break;
1138 + case 'darwin':
1139 + child = require('child_process').execFile('/usr/bin/open', ['open', url], { uid: require('user-sessions').consoleUid() });
1140 + break;
1141 + default:
1142 + // Unknown platform, ignore this command.
1143 + break;
1144 + }
1145 + } catch (ex) { }
1146 + return child;
1147 + }
1148 +
1149 + // Process a mesh agent console command
1150 + function processConsoleCommand(cmd, args, rights, sessionid) {
1151 + try {
1152 + var response = null;
1153 + switch (cmd) {
1154 + case 'help': { // Displays available commands
1155 + 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.';
1156 + break;
1157 + }
1158 + /*
1159 + case 'border':
1160 + {
1161 + if ((args['_'].length == 1) && (args['_'][0] == 'on')) {
1162 + if (meshCoreObj.users.length > 0) {
1163 + obj.borderManager.Start(meshCoreObj.users[0]);
1164 + response = 'Border blinking is on.';
1165 + } else {
1166 + response = 'Cannot turn on border blinking, no logged in users.';
1167 + }
1168 + } else if ((args['_'].length == 1) && (args['_'][0] == 'off')) {
1169 + obj.borderManager.Stop();
1170 + response = 'Border blinking is off.';
1171 + } else {
1172 + response = 'Proper usage: border "on|off"'; // Display correct command usage
1173 + }
1174 + }
1175 + break;
1176 + */
1177 + case 'getclip': {
1178 + require("clipboard").read().then(function (str) { sendConsoleText(str, sessionid); });
1179 + break;
1180 + }
1181 + case 'setclip': {
1182 + if (args['_'].length != 1) { response = 'Proper usage: setclip (text)'; } else { require("clipboard")(args['_'][0]); response = 'Setting clipboard to: ' + args['_'][0]; }
1183 + break;
1184 + }
1185 + case 'amtreset': {
1186 + if (amt != null) { amt.reset(); response = 'Done.'; }
1187 + break;
1188 + }
1189 + case 'amtlmsreset': {
1190 + if (amt != null) { amt.lmsreset(); response = 'Done.'; }
1191 + break;
1192 + }
1193 + case 'amtccm': {
1194 + if (amt == null) { response = 'Intel AMT not supported.'; } else {
1195 + if (args['_'].length != 1) { response = 'Proper usage: amtccm (adminPassword)'; } // Display usage
1196 + else { amt.setPolicy({ type: 0 }); amt.activeToCCM(args['_'][0]); }
1197 + }
1198 + break;
1199 + }
1200 + case 'amtdeactivate': {
1201 + if (amt == null) { response = 'Intel AMT not supported.'; } else { amt.setPolicy({ type: 0 }); amt.deactivateCCM(); }
1202 + break;
1203 + }
1204 + case 'amtpolicy': {
1205 + if (amtPolicy == null) {
1206 + response = 'No Intel(R) AMT policy.';
1207 + } else {
1208 + response = JSON.stringify(amtPolicy);
1209 + }
1210 + break;
1211 + }
1212 + case 'openurl': {
1213 + if (args['_'].length != 1) { response = 'Proper usage: openurl (url)'; } // Display usage
1214 + else { if (openUserDesktopUrl(args['_'][0]) == null) { response = 'Failed.'; } else { response = 'Success.'; } }
1215 + break;
1216 + }
1217 + case 'users': {
1218 + if (meshCoreObj.users == null) { response = 'Active users are unknown.'; } else { response = 'Active Users: ' + meshCoreObj.users.join(', ') + '.'; }
1219 + require('user-sessions').enumerateUsers().then(function (u) { for (var i in u) { sendConsoleText(u[i]); } });
1220 + break;
1221 + }
1222 + case 'toast': {
1223 + if (process.platform == 'win32') {
1224 + if (args['_'].length < 1) { response = 'Proper usage: toast "message"'; } else {
1225 + require('toaster').Toast('MeshCentral', args['_'][0]);
1226 + response = 'ok';
1227 + }
1228 + } else {
1229 + response = 'Only supported on Windows.';
1230 + }
1231 + break;
1232 + }
1233 + case 'setdebug': {
1234 + if (args['_'].length < 1) { response = 'Proper usage: setdebug (target), 0 = Disabled, 1 = StdOut, 2 = This Console, * = All Consoles, 4 = WebLog, 8 = Logfile'; } // Display usage
1235 + else { if (args['_'][0] == '*') { console.setDestination(2); } else { console.setDestination(parseInt(args['_'][0]), sessionid); } }
1236 + break;
1237 + }
1238 + case 'ps': {
1239 + processManager.getProcesses(function (plist) {
1240 + var x = '';
1241 + for (var i in plist) { x += i + ', ' + plist[i].cmd + ((plist[i].user) ? (', ' + plist[i].user):'') + '\r\n'; }
1242 + sendConsoleText(x, sessionid);
1243 + });
1244 + break;
1245 + }
1246 + case 'kill': {
1247 + if ((args['_'].length < 1)) {
1248 + response = 'Proper usage: kill [pid]'; // Display correct command usage
1249 + } else {
1250 + process.kill(parseInt(args['_'][0]));
1251 + response = 'Killed process ' + args['_'][0] + '.';
1252 + }
1253 + break;
1254 + }
1255 + case 'smbios': {
1256 + if (SMBiosTables == null) { response = 'SMBios tables not available.'; } else { response = objToString(SMBiosTables, 0, ' ', true); }
1257 + break;
1258 + }
1259 + case 'rawsmbios': {
1260 + if (SMBiosTablesRaw == null) { response = 'SMBios tables not available.'; } else {
1261 + response = '';
1262 + for (var i in SMBiosTablesRaw) {
1263 + var header = false;
1264 + for (var j in SMBiosTablesRaw[i]) {
1265 + if (SMBiosTablesRaw[i][j].length > 0) {
1266 + if (header == false) { response += ('Table type #' + i + ((require('smbios').smTableTypes[i] == null) ? '' : (', ' + require('smbios').smTableTypes[i]))) + '\r\n'; header = true; }
1267 + response += (' ' + SMBiosTablesRaw[i][j].toString('hex')) + '\r\n';
1268 + }
1269 + }
1270 + }
1271 + }
1272 + break;
1273 + }
1274 + case 'eval': { // Eval JavaScript
1275 + if (args['_'].length < 1) {
1276 + response = 'Proper usage: eval "JavaScript code"'; // Display correct command usage
1277 + } else {
1278 + response = JSON.stringify(mesh.eval(args['_'][0]));
1279 + }
1280 + break;
1281 + }
1282 + case 'notify': { // Send a notification message to the mesh
1283 + if (args['_'].length != 1) {
1284 + response = 'Proper usage: notify "message" [--session]'; // Display correct command usage
1285 + } else {
1286 + var notification = { "action": "msg", "type": "notify", "value": args['_'][0], "tag": "console" };
1287 + if (args.session) { notification.sessionid = sessionid; } // If "--session" is specified, notify only this session, if not, the server will notify the mesh
1288 + mesh.SendCommand(notification); // no sessionid or userid specified, notification will go to the entire mesh
1289 + response = 'ok';
1290 + }
1291 + break;
1292 + }
1293 + case 'info': { // Return information about the agent and agent core module
1294 + 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 + '.';
1295 + if (amt != null) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amt.lmsstate] + '.'; }
1296 + if (meshCoreObj.osdesc) { response += '\r\nOS: ' + meshCoreObj.osdesc + '.'; }
1297 + response += '\r\nModules: ' + addedModules.join(', ') + '.';
1298 + response += '\r\nServer Connection: ' + mesh.isControlChannelConnected + ', State: ' + meshServerConnectionState + '.';
1299 + response += '\r\lastMeInfo: ' + lastMeInfo + '.';
1300 + var oldNodeId = db.Get('OldNodeId');
1301 + if (oldNodeId != null) { response += '\r\nOldNodeID: ' + oldNodeId + '.'; }
1302 + if (process.platform != 'win32') { response += '\r\nX11 support: ' + require('monitor-info').kvm_x11_support + '.'; }
1303 + break;
1304 + }
1305 + case 'osinfo': { // Return the operating system information
1306 + var i = 1;
1307 + if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; }
1308 + for (var j = 0; j < i; j++) {
1309 + var pr = require('os').name();
1310 + pr.sessionid = sessionid;
1311 + pr.then(function (v) { sendConsoleText("OS: " + v, this.sessionid); });
1312 + }
1313 + break;
1314 + }
1315 + case 'sendcaps': { // Send capability flags to the server
1316 + if (args['_'].length == 0) {
1317 + response = 'Proper usage: sendcaps (number)'; // Display correct command usage
1318 + } else {
1319 + meshCoreObj.caps = parseInt(args['_'][0]);
1320 + mesh.SendCommand(meshCoreObj);
1321 + response = JSON.stringify(meshCoreObj);
1322 + }
1323 + break;
1324 + }
1325 + case 'sendosdesc': { // Send OS description
1326 + if (args['_'].length > 0) {
1327 + meshCoreObj.osdesc = args['_'][0];
1328 + mesh.SendCommand(meshCoreObj);
1329 + response = JSON.stringify(meshCoreObj);
1330 + } else {
1331 + response = 'Proper usage: sendosdesc [os description]'; // Display correct command usage
1332 + }
1333 + break;
1334 + }
1335 + case 'args': { // Displays parsed command arguments
1336 + response = 'args ' + objToString(args, 0, ' ', true);
1337 + break;
1338 + }
1339 + case 'print': { // Print a message on the mesh agent console, does nothing when running in the background
1340 + var r = [];
1341 + for (var i in args['_']) { r.push(args['_'][i]); }
1342 + console.log(r.join(' '));
1343 + response = 'Message printed on agent console.';
1344 + break;
1345 + }
1346 + case 'type': { // Returns the content of a file
1347 + if (args['_'].length == 0) {
1348 + response = 'Proper usage: type (filepath) [maxlength]'; // Display correct command usage
1349 + } else {
1350 + var max = 4096;
1351 + if ((args['_'].length > 1) && (typeof args['_'][1] == 'number')) { max = args['_'][1]; }
1352 + if (max > 4096) max = 4096;
1353 + var buf = Buffer.alloc(max), fd = fs.openSync(args['_'][0], "r"), r = fs.readSync(fd, buf, 0, max); // Read the file content
1354 + response = buf.toString();
1355 + var i = response.indexOf('\n');
1356 + if ((i > 0) && (response[i - 1] != '\r')) { response = response.split('\n').join('\r\n'); }
1357 + if (r == max) response += '...';
1358 + fs.closeSync(fd);
1359 + }
1360 + break;
1361 + }
1362 + case 'dbkeys': { // Return all data store keys
1363 + response = JSON.stringify(db.Keys);
1364 + break;
1365 + }
1366 + case 'dbget': { // Return the data store value for a given key
1367 + if (db == null) { response = 'Database not accessible.'; break; }
1368 + if (args['_'].length != 1) {
1369 + response = 'Proper usage: dbget (key)'; // Display the value for a given database key
1370 + } else {
1371 + response = db.Get(args['_'][0]);
1372 + }
1373 + break;
1374 + }
1375 + case 'dbset': { // Set a data store key and value pair
1376 + if (db == null) { response = 'Database not accessible.'; break; }
1377 + if (args['_'].length != 2) {
1378 + response = 'Proper usage: dbset (key) (value)'; // Set a database key
1379 + } else {
1380 + var r = db.Put(args['_'][0], args['_'][1]);
1381 + response = 'Key set: ' + r;
1382 + }
1383 + break;
1384 + }
1385 + case 'dbcompact': { // Compact the data store
1386 + if (db == null) { response = 'Database not accessible.'; break; }
1387 + var r = db.Compact();
1388 + response = 'Database compacted: ' + r;
1389 + break;
1390 + }
1391 + case 'httpget': {
1392 + if (consoleHttpRequest != null) {
1393 + response = 'HTTP operation already in progress.';
1394 + } else {
1395 + if (args['_'].length != 1) {
1396 + response = 'Proper usage: httpget (url)';
1397 + } else {
1398 + var options = http.parseUri(args['_'][0]);
1399 + options.method = 'GET';
1400 + if (options == null) {
1401 + response = 'Invalid url.';
1402 + } else {
1403 + try { consoleHttpRequest = http.request(options, consoleHttpResponse); } catch (e) { response = 'Invalid HTTP GET request'; }
1404 + consoleHttpRequest.sessionid = sessionid;
1405 + if (consoleHttpRequest != null) {
1406 + consoleHttpRequest.end();
1407 + response = 'HTTPGET ' + options.protocol + '//' + options.host + ':' + options.port + options.path;
1408 + }
1409 + }
1410 + }
1411 + }
1412 + break;
1413 + }
1414 + case 'wslist': { // List all web sockets
1415 + response = '';
1416 + for (var i in consoleWebSockets) {
1417 + var httprequest = consoleWebSockets[i];
1418 + response += 'Websocket #' + i + ', ' + httprequest.url + '\r\n';
1419 + }
1420 + if (response == '') { response = 'no websocket sessions.'; }
1421 + break;
1422 + }
1423 + case 'wsconnect': { // Setup a web socket
1424 + if (args['_'].length == 0) {
1425 + response = 'Proper usage: wsconnect (url)\r\nFor example: wsconnect wss://localhost:443/meshrelay.ashx?id=abc'; // Display correct command usage
1426 + } else {
1427 + var httprequest = null;
1428 + try {
1429 + var options = http.parseUri(args['_'][0]);
1430 + options.rejectUnauthorized = 0;
1431 + httprequest = http.request(options);
1432 + } catch (e) { response = 'Invalid HTTP websocket request'; }
1433 + if (httprequest != null) {
1434 + httprequest.upgrade = onWebSocketUpgrade;
1435 + httprequest.on('error', function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); });
1436 +
1437 + var index = 1;
1438 + while (consoleWebSockets[index]) { index++; }
1439 + httprequest.sessionid = sessionid;
1440 + httprequest.index = index;
1441 + httprequest.url = args['_'][0];
1442 + consoleWebSockets[index] = httprequest;
1443 + response = 'New websocket session #' + index;
1444 + }
1445 + }
1446 + break;
1447 + }
1448 + case 'wssend': { // Send data on a web socket
1449 + if (args['_'].length == 0) {
1450 + response = 'Proper usage: wssend (socketnumber)\r\n'; // Display correct command usage
1451 + for (var i in consoleWebSockets) {
1452 + var httprequest = consoleWebSockets[i];
1453 + response += 'Websocket #' + i + ', ' + httprequest.url + '\r\n';
1454 + }
1455 + } else {
1456 + var i = parseInt(args['_'][0]);
1457 + var httprequest = consoleWebSockets[i];
1458 + if (httprequest != undefined) {
1459 + httprequest.s.write(args['_'][1]);
1460 + response = 'ok';
1461 + } else {
1462 + response = 'Invalid web socket number';
1463 + }
1464 + }
1465 + break;
1466 + }
1467 + case 'wsclose': { // Close a websocket
1468 + if (args['_'].length == 0) {
1469 + response = 'Proper usage: wsclose (socketnumber)'; // Display correct command usage
1470 + } else {
1471 + var i = parseInt(args['_'][0]);
1472 + var httprequest = consoleWebSockets[i];
1473 + if (httprequest != undefined) {
1474 + if (httprequest.s != null) { httprequest.s.end(); } else { httprequest.end(); }
1475 + response = 'ok';
1476 + } else {
1477 + response = 'Invalid web socket number';
1478 + }
1479 + }
1480 + break;
1481 + }
1482 + case 'tunnels': { // Show the list of current tunnels
1483 + response = '';
1484 + for (var i in tunnels) { response += 'Tunnel #' + i + ', ' + tunnels[i].url + '\r\n'; }
1485 + if (response == '') { response = 'No websocket sessions.'; }
1486 + break;
1487 + }
1488 + case 'ls': { // Show list of files and folders
1489 + response = '';
1490 + var xpath = '*';
1491 + if (args['_'].length > 0) { xpath = obj.path.join(args['_'][0], '*'); }
1492 + response = 'List of ' + xpath + '\r\n';
1493 + var results = fs.readdirSync(xpath);
1494 + for (var i = 0; i < results.length; ++i) {
1495 + var stat = null, p = obj.path.join(args['_'][0], results[i]);
1496 + try { stat = fs.statSync(p); } catch (e) { }
1497 + if ((stat == null) || (stat == undefined)) {
1498 + response += (results[i] + "\r\n");
1499 + } else {
1500 + response += (results[i] + " " + ((stat.isDirectory()) ? "(Folder)" : "(File)") + "\r\n");
1501 + }
1502 + }
1503 + break;
1504 + }
1505 + case 'lsx': { // Show list of files and folders
1506 + response = objToString(getDirectoryInfo(args['_'][0]), 0, ' ', true);
1507 + break;
1508 + }
1509 + case 'lock': { // Lock the current user out of the desktop
1510 + 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'; }
1511 + else { response = 'Not supported on the platform'; }
1512 + break;
1513 + }
1514 + case 'amt': { // Show Intel AMT status
1515 + if (amt != null) {
1516 + amt.getAmtInfo(function (state) {
1517 + var resp = 'Intel AMT not detected.';
1518 + if (state != null) { resp = objToString(state, 0, ' ', true); }
1519 + sendConsoleText(resp, sessionid);
1520 + });
1521 + }
1522 + break;
1523 + }
1524 + case 'netinfo': { // Show network interface information
1525 + //response = objToString(mesh.NetInfo, 0, ' ');
1526 + var interfaces = require('os').networkInterfaces();
1527 + response = objToString(interfaces, 0, ' ', true);
1528 + break;
1529 + }
1530 + case 'netinfo2': { // Show network interface information
1531 + response = objToString(mesh.NetInfo, 0, ' ', true);
1532 + break;
1533 + }
1534 + case 'wakeonlan': { // Send wake-on-lan
1535 + if ((args['_'].length != 1) || (args['_'][0].length != 12)) {
1536 + response = 'Proper usage: wakeonlan [mac], for example "wakeonlan 010203040506".';
1537 + } else {
1538 + var count = sendWakeOnLan(args['_'][0]);
1539 + response = 'Sent wake-on-lan on ' + count + ' interface(s).';
1540 + }
1541 + break;
1542 + }
1543 + case 'sendall': { // Send a message to all consoles on this mesh
1544 + sendConsoleText(args['_'].join(' '));
1545 + break;
1546 + }
1547 + case 'power': { // Execute a power action on this computer
1548 + if (mesh.ExecPowerState == undefined) {
1549 + response = 'Power command not supported on this agent.';
1550 + } else {
1551 + if ((args['_'].length == 0) || (typeof args['_'][0] != 'number')) {
1552 + 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
1553 + } else {
1554 + var r = mesh.ExecPowerState(args['_'][0], args['_'][1]);
1555 + response = 'Power action executed with return code: ' + r + '.';
1556 + }
1557 + }
1558 + break;
1559 + }
1560 + case 'location': {
1561 + getIpLocationData(function (location) {
1562 + sendConsoleText(objToString({ "action": "iplocation", "type": "publicip", "value": location }, 0, ' '));
1563 + });
1564 + break;
1565 + }
1566 + case 'parseuri': {
1567 + response = JSON.stringify(http.parseUri(args['_'][0]));
1568 + break;
1569 + }
1570 + case 'scanwifi': {
1571 + if (wifiScanner != null) {
1572 + var wifiPresent = wifiScanner.hasWireless;
1573 + if (wifiPresent) { response = "Perfoming Wifi scan..."; wifiScanner.Scan(); } else { response = "Wifi absent."; }
1574 + } else { response = "Wifi module not present."; }
1575 + break;
1576 + }
1577 + case 'scanamt': {
1578 + if (amtscanner != null) {
1579 + if (args['_'].length != 1) {
1580 + 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
1581 + } else {
1582 + response = 'Scanning: ' + args['_'][0] + '...';
1583 + amtscanner.scan(args['_'][0], 2000, function (data) {
1584 + if (data.length > 0) {
1585 + var r = '', pstates = ['NotActivated', 'InActivation', 'Activated'];
1586 + for (var i in data) {
1587 + var x = data[i];
1588 + if (r != '') { r += '\r\n'; }
1589 + r += x.address + ' - Intel AMT v' + x.majorVersion + '.' + x.minorVersion;
1590 + if (x.provisioningState < 3) { r += (', ' + pstates[x.provisioningState]); }
1591 + if (x.provisioningState == 2) { r += (', ' + x.openPorts.join(', ')); }
1592 + r += '.';
1593 + }
1594 + } else {
1595 + r = 'No Intel AMT found.';
1596 + }
1597 + sendConsoleText(r);
1598 + });
1599 + }
1600 + } else { response = "Intel AMT scanner module not present."; }
1601 + break;
1602 + }
1603 + case 'modules': {
1604 + response = JSON.stringify(addedModules);
1605 + break;
1606 + }
1607 + case 'getscript': {
1608 + if (args['_'].length != 1) {
1609 + response = 'Proper usage: getscript [scriptNumber].';
1610 + } else {
1611 + mesh.SendCommand({ "action": "getScript", "type": args['_'][0] });
1612 + }
1613 + break;
1614 + }
1615 + default: { // This is an unknown command, return an error message
1616 + response = 'Unknown command \"' + cmd + '\", type \"help\" for list of avaialble commands.';
1617 + break;
1618 + }
1619 + }
1620 + } catch (e) { response = 'Command returned an exception error: ' + e; console.log(e); }
1621 + if (response != null) { sendConsoleText(response, sessionid); }
1622 + }
1623 +
1624 + // Send a mesh agent console command
1625 + function sendConsoleText(text, sessionid) {
1626 + if (typeof text == 'object') { text = JSON.stringify(text); }
1627 + mesh.SendCommand({ "action": "msg", "type": "console", "value": text, "sessionid": sessionid });
1628 + }
1629 +
1630 + // Called before the process exits
1631 + //process.exit = function (code) { console.log("Exit with code: " + code.toString()); }
1632 +
1633 + // Called when the server connection state changes
1634 + function handleServerConnection(state) {
1635 + meshServerConnectionState = state;
1636 + if (meshServerConnectionState == 0) {
1637 + // Server disconnected
1638 + if (selfInfoUpdateTimer != null) { clearInterval(selfInfoUpdateTimer); selfInfoUpdateTimer = null; }
1639 + lastSelfInfo = null;
1640 + } else {
1641 + // Server connected, send mesh core information
1642 + var oldNodeId = db.Get('OldNodeId');
1643 + if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); }
1644 +
1645 + // Update the server with basic info, logged in users and more.
1646 + mesh.SendCommand(meshCoreObj);
1647 +
1648 + // Send SMBios tables if present
1649 + if (SMBiosTablesRaw != null) { mesh.SendCommand({ "action": "smbios", "value": SMBiosTablesRaw }); }
1650 +
1651 + // Update the server on more advanced stuff, like Intel ME and Network Settings
1652 + meInfoStr = null;
1653 + sendPeriodicServerUpdate();
1654 + //if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes
1655 + }
1656 + }
1657 +
1658 + // Update the server with the latest network interface information
1659 + var sendNetworkUpdateNagleTimer = null;
1660 + function sendNetworkUpdateNagle() { if (sendNetworkUpdateNagleTimer != null) { clearTimeout(sendNetworkUpdateNagleTimer); sendNetworkUpdateNagleTimer = null; } sendNetworkUpdateNagleTimer = setTimeout(sendNetworkUpdate, 5000); }
1661 + function sendNetworkUpdate(force) {
1662 + sendNetworkUpdateNagleTimer = null;
1663 +
1664 + // Update the network interfaces information data
1665 + var netInfo = mesh.NetInfo;
1666 + netInfo.action = 'netinfo';
1667 + var netInfoStr = JSON.stringify(netInfo);
1668 + if ((force == true) || (clearGatewayMac(netInfoStr) != clearGatewayMac(lastNetworkInfo))) { mesh.SendCommand(netInfo); lastNetworkInfo = netInfoStr; }
1669 + }
1670 +
1671 + // Called periodically to check if we need to send updates to the server
1672 + function sendPeriodicServerUpdate(flags) {
1673 + if (meshServerConnectionState == 0) return; // Not connected to server, do nothing.
1674 + if (!flags) { flags = 0xFFFFFFFF; }
1675 +
1676 + if ((flags & 1) && (amt != null)) {
1677 + // If we have a connected MEI, get Intel ME information
1678 + amt.getAmtInfo(function (meinfo) {
1679 + try {
1680 + if (meinfo == null) return;
1681 + var intelamt = {}, p = false;
1682 + if (meinfo.Versions && meinfo.Versions.AMT) { intelamt.ver = meinfo.Versions.AMT; p = true; }
1683 + if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; }
1684 + if (meinfo.Flags) { intelamt.flags = meinfo.Flags; p = true; }
1685 + if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; p = true; }
1686 + if (meinfo.UUID) { intelamt.uuid = meinfo.UUID; p = true; }
1687 + if (p == true) {
1688 + var meInfoStr = JSON.stringify(intelamt);
1689 + if (meInfoStr != lastMeInfo) {
1690 + meshCoreObj.intelamt = intelamt;
1691 + mesh.SendCommand(meshCoreObj);
1692 + lastMeInfo = meInfoStr;
1693 + }
1694 + }
1695 + } catch (ex) { }
1696 + });
1697 + }
1698 +
1699 + if (flags & 2) {
1700 + // Update network information
1701 + sendNetworkUpdateNagle(false);
1702 + }
1703 + }
1704 +
1705 +
1706 + // Starting function
1707 + obj.start = function () {
1708 + // Setup the mesh agent event handlers
1709 + mesh.AddCommandHandler(handleServerCommand);
1710 + mesh.AddConnectHandler(handleServerConnection);
1711 +
1712 + // Parse input arguments
1713 + //var args = parseArgs(process.argv);
1714 + //console.log(args);
1715 +
1716 + //resetMicroLms();
1717 +
1718 + // Setup logged in user monitoring (THIS IS BROKEN IN WIN7)
1719 + try {
1720 + var userSession = require('user-sessions');
1721 + userSession.on('changed', function onUserSessionChanged() {
1722 + userSession.enumerateUsers().then(function (users) {
1723 + var u = [], a = users.Active;
1724 + for (var i = 0; i < a.length; i++) {
1725 + var un = a[i].Domain ? (a[i].Domain + '\\' + a[i].Username) : (a[i].Username);
1726 + if (u.indexOf(un) == -1) { u.push(un); } // Only push users in the list once.
1727 + }
1728 + meshCoreObj.users = u;
1729 + mesh.SendCommand(meshCoreObj);
1730 + });
1731 + });
1732 + userSession.emit('changed');
1733 + //userSession.on('locked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has LOCKED the desktop'); });
1734 + //userSession.on('unlocked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has UNLOCKED the desktop'); });
1735 + } catch (ex) { }
1736 + }
1737 +
1738 + obj.stop = function () {
1739 + mesh.AddCommandHandler(null);
1740 + mesh.AddConnectHandler(null);
1741 + }
1742 +
1743 + function onWebSocketClosed() { sendConsoleText("WebSocket #" + this.httprequest.index + " closed.", this.httprequest.sessionid); delete consoleWebSockets[this.httprequest.index]; }
1744 + function onWebSocketData(data) { sendConsoleText("Got WebSocket #" + this.httprequest.index + " data: " + data, this.httprequest.sessionid); }
1745 + function onWebSocketSendOk() { sendConsoleText("WebSocket #" + this.index + " SendOK.", this.sessionid); }
1746 +
1747 + function onWebSocketUpgrade(response, s, head) {
1748 + sendConsoleText("WebSocket #" + this.index + " connected.", this.sessionid);
1749 + this.s = s;
1750 + s.httprequest = this;
1751 + s.end = onWebSocketClosed;
1752 + s.data = onWebSocketData;
1753 + }
1754 +
1755 + return obj;
1756 +}
1757 +
1758 +//
1759 +// Module startup
1760 +//
1761 +
1762 +try {
1763 + var xexports = null, mainMeshCore = null;
1764 + try { xexports = module.exports; } catch (e) { }
1765 +
1766 + if (xexports != null) {
1767 + // If we are running within NodeJS, export the core
1768 + module.exports.createMeshCore = createMeshCore;
1769 + } else {
1770 + // If we are not running in NodeJS, launch the core
1771 + mainMeshCore = createMeshCore();
1772 + mainMeshCore.start(null);
1773 + }
1774 +} catch (ex) {
1775 + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": "uncaughtException2: " + ex });
1776 +}
\ No newline at end of file
agents-new/meshinstall-initd.sh new
+82
@@ -0,0 +1,82 @@
1 +#!/bin/sh
2 +### BEGIN INIT INFO
3 +# Provides: <NAME>
4 +# Required-Start: $local_fs $network $named $time $syslog
5 +# Required-Stop: $local_fs $network $named $time $syslog
6 +# Default-Start: 2 3 4 5
7 +# Default-Stop: 0 1 6
8 +# Description: <DESCRIPTION>
9 +### END INIT INFO
10 +
11 +SCRIPT=/usr/local/mesh/meshagent
12 +RUNAS=root
13 +
14 +PIDFILE=/var/run/meshagent.pid
15 +LOGFILE=/var/log/meshagent.log
16 +
17 +start() {
18 + if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") 2>/dev/null; then
19 + echo 'Service already running' >&2
20 + return 1
21 + fi
22 + echo 'Starting service…' >&2
23 + local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
24 + su -c "$CMD" $RUNAS > "$PIDFILE"
25 + echo 'Service started' >&2
26 +}
27 +
28 +stop() {
29 + if [ ! -f "$PIDFILE" ]; then
30 + echo 'Service not running' >&2
31 + return 1
32 + else
33 + pid=$( cat "$PIDFILE" )
34 + if kill -0 $pid 2>/dev/null; then
35 + echo 'Stopping service…' >&2
36 + kill -16 $pid
37 + echo 'Service stopped' >&2
38 + else
39 + echo 'Service not running'
40 + fi
41 + rm -f $"PIDFILE"
42 + fi
43 +}
44 +restart(){
45 + stop
46 + start
47 +}
48 +status(){
49 + if [ -f "$PIDFILE" ]
50 + then
51 + pid=$( cat "$PIDFILE" )
52 + if kill -0 $pid 2>/dev/null; then
53 + echo "meshagent start/running, process $pid"
54 + else
55 + echo 'meshagent stop/waiting'
56 + fi
57 + else
58 + echo 'meshagent stop/waiting'
59 + fi
60 +
61 +}
62 +
63 +
64 +case "$1" in
65 + start)
66 + start
67 + ;;
68 + stop)
69 + stop
70 + ;;
71 + restart)
72 + stop
73 + start
74 + ;;
75 + status)
76 + status
77 + ;;
78 + *)
79 + echo "Usage: service meshagent {start|stop|restart|status}"
80 + ;;
81 +esac
82 +exit 0
agents-new/meshinstall-linux.sh new
+235
@@ -0,0 +1,235 @@
1 +#!/bin/bash
2 +
3 +CheckStartupType() {
4 + # echo "Checking process autostart system..."
5 + starttype=`ps -p 1 | awk '/1/ {print $4}'`
6 + # Systemd
7 + if [[ $starttype == 'systemd' ]]; then return 1;
8 + elif [[ $starttype == 'init' ]];
9 + then
10 + # Upstart
11 + if [[ `/sbin/init --version` =~ upstart ]]; then return 2;
12 + # Sysv-init
13 + return 3;
14 + fi
15 + fi
16 + return 0;
17 +}
18 +
19 +# Add "StartupType=(type)" to .msh file
20 +UpdateMshFile() {
21 + # Remove all lines that start with "StartupType="
22 + sed '/^StartupType=/ d' < /usr/local/mesh/meshagent.msh >> /usr/local/mesh/meshagent2.msh
23 + # Add the startup type to the file
24 + echo "StartupType=$starttype" >> /usr/local/mesh/meshagent2.msh
25 + mv /usr/local/mesh/meshagent2.msh /usr/local/mesh/meshagent.msh
26 +}
27 +
28 +CheckInstallAgent() {
29 + # echo "Checking mesh identifier..."
30 + if [ -e "/usr/local" ]
31 + then
32 + installpath="/usr/local/mesh"
33 + else
34 + installpath="/usr/mesh"
35 + fi
36 + if [ $# -ge 2 ]
37 + then
38 + url=$1
39 + meshid=$2
40 + meshidlen=${#meshid}
41 + if [ $meshidlen -eq 64 ]
42 + then
43 + machineid=0
44 + machinetype=$( uname -m )
45 +
46 + # If we have 3 arguments...
47 + if [ $# -ge 3 ]
48 + then
49 + # echo "Computer type is specified..."
50 + machineid=$3
51 + else
52 + # echo "Detecting computer type..."
53 + if [ $machinetype == 'x86_64' ] || [ $machinetype == 'amd64' ]
54 + then
55 + # Linux x86, 64 bit
56 + machineid=6
57 + fi
58 + if [ $machinetype == 'x86' ] || [ $machinetype == 'i686' ] || [ $machinetype == 'i586' ]
59 + then
60 + # Linux x86, 32 bit
61 + machineid=5
62 + fi
63 + if [ $machinetype == 'armv6l' ] || [ $machinetype == 'armv7l' ]
64 + then
65 + # RaspberryPi 1 (armv6l) or RaspberryPi 2/3 (armv7l)
66 + machineid=25
67 + fi
68 + # Add more machine types, detect KVM support... here.
69 + fi
70 +
71 + if [ $machineid -eq 0 ]
72 + then
73 + echo "Unsupported machine type: $machinetype."
74 + else
75 + DownloadAgent $url $meshid $machineid
76 + fi
77 +
78 + else
79 + echo "MeshID is not correct, must be 64 characters long."
80 + fi
81 + else
82 + echo "URI and/or MeshID have not been specified, must be passed in as arguments."
83 + return 0;
84 + fi
85 +}
86 +
87 +DownloadAgent() {
88 + url=$1
89 + meshid=$2
90 + machineid=$3
91 + # Create folder
92 + mkdir -p /usr/local/mesh
93 + cd /usr/local/mesh
94 + echo "Downloading Mesh agent #$machineid..."
95 + wget $url/meshagents?id=$machineid --no-check-certificate {{{noproxy}}}-O /usr/local/mesh/meshagent
96 +
97 + # If it did not work, try again using http
98 + if [ $? != 0 ]
99 + then
100 + url=${url/"https://"/"http://"}
101 + wget $url/meshagents?id=$machineid {{{noproxy}}}-O /usr/local/mesh/meshagent
102 + fi
103 +
104 + if [ $? -eq 0 ]
105 + then
106 + echo "Mesh agent downloaded."
107 + # TODO: We could check the meshagent sha256 hash, but best to authenticate the server.
108 + chmod 755 /usr/local/mesh/meshagent
109 + wget $url/meshsettings?id=$meshid --no-check-certificate {{{noproxy}}}-O /usr/local/mesh/meshagent.msh
110 +
111 + # If it did not work, try again using http
112 + if [ $? -ne 0 ]
113 + then
114 + wget $url/meshsettings?id=$meshid {{{noproxy}}}-O /usr/local/mesh/meshagent.msh
115 + fi
116 +
117 + if [ $? -eq 0 ]
118 + then
119 + UpdateMshFile
120 + if [ $starttype -eq 1 ]
121 + then
122 + # systemd
123 + if [ -d "/lib/systemd/system/" ]
124 + then
125 + 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
126 + else
127 + # Some distros have the systemd folder at a different place
128 + if [ -d "/usr/lib/systemd/system/" ]
129 + then
130 + 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
131 + else
132 + echo "Unable to find systemd folder."
133 + fi
134 + fi
135 + systemctl enable meshagent
136 + systemctl start meshagent
137 + echo 'meshagent installed as systemd service.'
138 + echo 'To start service: sudo systemctl start meshagent'
139 + echo 'To stop service: sudo systemctl stop meshagent'
140 + elif [ $starttype -eq 3 ]
141 + then
142 + # initd
143 + wget $url/meshagents?script=2 --no-check-certificate {{{noproxy}}}-O /etc/init.d/meshagent
144 + chmod +x /etc/init.d/meshagent
145 + # creates symlinks for rc.d
146 + update-rc.d meshagent defaults
147 + service meshagent start
148 + echo 'meshagent installed as init.d service.'
149 + echo 'To start service: sudo service meshagent start'
150 + echo 'To stop service: sudo service meshagent stop'
151 + elif [ $starttype -eq 2 ]
152 + then
153 + # upstart
154 + 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
155 + service meshagent start
156 + echo 'meshagent installed as upstart/init.d service.'
157 + echo 'To start service: sudo initctl start meshagent'
158 + echo 'To stop service: sudo initctl stop meshagent'
159 + else
160 + # unknown
161 + echo "Unknown Service Platform Type. (ie: init, systemd, etc)"
162 + echo "Unable to install meshagent as service."
163 + fi
164 + echo "Mesh agent started."
165 + else
166 + echo "Unable to download mesh settings at: $url/meshsettings?id=$meshid."
167 + fi
168 + else
169 + echo "Unable to download mesh agent at: $url/meshagents?id=$machineid."
170 + fi
171 +}
172 +
173 +UninstallAgent() {
174 +# Uninstall agent
175 + if [ -e "/usr/local" ]
176 + then
177 + installpath="/usr/local/mesh"
178 + else
179 + installpath="/usr/mesh"
180 + fi
181 +
182 + if [ $starttype -eq 1 ]
183 + then
184 + # systemd
185 + rm -f /sbin/meshcmd /lib/systemd/system/meshagent.service
186 + systemctl disable meshagent
187 + systemctl stop meshagent
188 + else
189 + if [ $starttype -eq 3 ]; then
190 + # initd
191 + service meshagent stop
192 + update-rc.d -f meshagent remove
193 + rm -f /sbin/meshcmd /etc/init.d/meshagent
194 + elif [ $starttype -eq 2 ]; then
195 + # upstart
196 + service meshagent stop
197 + rm -f /sbin/meshcmd
198 + rm -f /etc/init/meshagent.conf
199 + rm -f /etc/rc2.d/S20mesh /etc/rc3.d/S20mesh /etc/rc5.d/S20mesh
200 + fi
201 + fi
202 +
203 + if [ -e $installpath ]
204 + then
205 + rm -rf $installpath/*
206 + rmdir $installpath
207 + fi
208 + echo "Agent uninstalled."
209 +}
210 +
211 +
212 +CheckStartupType
213 +starttype=$?
214 +#echo "Type: $starttype"
215 +
216 +currentuser=$( whoami )
217 +if [ $currentuser == 'root' ]
218 +then
219 + if [ $# -eq 0 ]
220 + then
221 + echo -e "This script will install or uninstall a mesh agent, usage:\n $0 [serverurl] [meshid] (machineid)\n $0 uninstall"
222 + else
223 + if [ $# -eq 1 ]
224 + then
225 + if [ $1 == 'uninstall' ] || [ $1 == 'UNINSTALL' ]
226 + then
227 + UninstallAgent
228 + fi
229 + else
230 + CheckInstallAgent $1 $2 $3
231 + fi
232 + fi
233 +else
234 + echo "Must be root to install or uninstall mesh agent."
235 +fi
agents-new/modules_meshcmd/amt-lme.js new
+895
@@ -0,0 +1,895 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var MemoryStream = require('MemoryStream');
18 +var lme_id = 0; // Our next channel identifier
19 +var lme_port_offset = 0; // Debug: Set this to "-100" to bind to 16892 & 16893 and IN_ADDRANY. This is for LMS debugging.
20 +var xmlParser = require('amt-xml');
21 +
22 +// Documented in: https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/HTMLDocuments/MPSDocuments/Intel%20AMT%20Port%20Forwarding%20Protocol%20Reference%20Manual.pdf
23 +var APF_DISCONNECT = 1;
24 +var APF_SERVICE_REQUEST = 5;
25 +var APF_SERVICE_ACCEPT = 6;
26 +var APF_USERAUTH_REQUEST = 50;
27 +var APF_USERAUTH_FAILURE = 51;
28 +var APF_USERAUTH_SUCCESS = 52;
29 +var APF_GLOBAL_REQUEST = 80;
30 +var APF_REQUEST_SUCCESS = 81;
31 +var APF_REQUEST_FAILURE = 82;
32 +var APF_CHANNEL_OPEN = 90;
33 +var APF_CHANNEL_OPEN_CONFIRMATION = 91;
34 +var APF_CHANNEL_OPEN_FAILURE = 92;
35 +var APF_CHANNEL_WINDOW_ADJUST = 93;
36 +var APF_CHANNEL_DATA = 94;
37 +var APF_CHANNEL_CLOSE = 97;
38 +var APF_PROTOCOLVERSION = 192;
39 +
40 +
41 +function lme_object() {
42 + this.ourId = ++lme_id;
43 + this.amtId = -1;
44 + this.LME_CHANNEL_STATUS = 'LME_CS_FREE';
45 + this.txWindow = 0;
46 + this.rxWindow = 0;
47 + this.localPort = 0;
48 + this.errorCount = 0;
49 +}
50 +
51 +function stream_bufferedWrite() {
52 + var emitterUtils = require('events').inherits(this);
53 + this.buffer = [];
54 + this._readCheckImmediate = undefined;
55 + this._ObjectID = "bufferedWriteStream";
56 + // Writable Events
57 + emitterUtils.createEvent('close');
58 + emitterUtils.createEvent('drain');
59 + emitterUtils.createEvent('error');
60 + emitterUtils.createEvent('finish');
61 + emitterUtils.createEvent('pipe');
62 + emitterUtils.createEvent('unpipe');
63 +
64 + // Readable Events
65 + emitterUtils.createEvent('readable');
66 + this.isEmpty = function () {
67 + return (this.buffer.length == 0);
68 + };
69 + this.isWaiting = function () {
70 + return (this._readCheckImmediate == undefined);
71 + };
72 + this.write = function (chunk) {
73 + for (var args in arguments) { if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; } }
74 + var tmp = Buffer.alloc(chunk.length);
75 + chunk.copy(tmp);
76 + this.buffer.push({ offset: 0, data: tmp });
77 + this.emit('readable');
78 + return (this.buffer.length == 0 ? true : false);
79 + };
80 + this.read = function () {
81 + var size = arguments.length == 0 ? undefined : arguments[0];
82 + var bytesRead = 0;
83 + var list = [];
84 + while ((size == undefined || bytesRead < size) && this.buffer.length > 0) {
85 + var len = this.buffer[0].data.length - this.buffer[0].offset;
86 + var offset = this.buffer[0].offset;
87 +
88 + if (len > (size - bytesRead)) {
89 + // Only reading a subset
90 + list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead));
91 + this.buffer[0].offset += (size - bytesRead);
92 + bytesRead += (size - bytesRead);
93 + } else {
94 + // Reading the entire thing
95 + list.push(this.buffer[0].data.slice(offset));
96 + bytesRead += len;
97 + this.buffer.shift();
98 + }
99 + }
100 + this._readCheckImmediate = setImmediate(function (buffered) {
101 + buffered._readCheckImmediate = undefined;
102 + if (buffered.buffer.length == 0) {
103 + buffered.emit('drain'); // Drained
104 + } else {
105 + buffered.emit('readable'); // Not drained
106 + }
107 + }, this);
108 + return (Buffer.concat(list));
109 + };
110 +}
111 +
112 +
113 +function lme_heci(options) {
114 + var emitterUtils = require('events').inherits(this);
115 + emitterUtils.createEvent('error');
116 + emitterUtils.createEvent('connect');
117 + emitterUtils.createEvent('notify');
118 + emitterUtils.createEvent('bind');
119 +
120 + if ((options != null) && (options.debug == true)) { lme_port_offset = -100; } // LMS debug mode
121 +
122 + var heci = require('heci');
123 + this.INITIAL_RXWINDOW_SIZE = 4096;
124 +
125 + this._ObjectID = "lme";
126 + this._LME = heci.create();
127 + this._LME._binded = {};
128 + this._LME.LMS = this;
129 + this._LME.on('error', function (e) { this.LMS.emit('error', e); });
130 + this._LME.on('connect', function () {
131 + this.on('data', function (chunk) {
132 + // this = HECI
133 + var cmd = chunk.readUInt8(0);
134 + //console.log('LME Command ' + cmd + ', ' + chunk.length + ' byte(s).');
135 +
136 + switch (cmd) {
137 + default:
138 + console.log('Unhandled LME Command ' + cmd + ', ' + chunk.length + ' byte(s).');
139 + break;
140 + case APF_SERVICE_REQUEST:
141 + var nameLen = chunk.readUInt32BE(1);
142 + var name = chunk.slice(5, nameLen + 5);
143 + //console.log("Service Request for: " + name);
144 + if (name == 'pfwd@amt.intel.com' || name == 'auth@amt.intel.com') {
145 + var outBuffer = Buffer.alloc(5 + nameLen);
146 + outBuffer.writeUInt8(6, 0);
147 + outBuffer.writeUInt32BE(nameLen, 1);
148 + outBuffer.write(name.toString(), 5);
149 + this.write(outBuffer);
150 + //console.log('Answering APF_SERVICE_REQUEST');
151 + } else {
152 + //console.log('UNKNOWN APF_SERVICE_REQUEST');
153 + }
154 + break;
155 + case APF_GLOBAL_REQUEST:
156 + var nameLen = chunk.readUInt32BE(1);
157 + var name = chunk.slice(5, nameLen + 5).toString();
158 +
159 + switch (name) {
160 + case 'tcpip-forward':
161 + var len = chunk.readUInt32BE(nameLen + 6);
162 + var port = chunk.readUInt32BE(nameLen + 10 + len);
163 + //console.log("[" + chunk.length + "/" + len + "] APF_GLOBAL_REQUEST for: " + name + " on port " + port);
164 + if (this[name] == undefined) { this[name] = {}; }
165 + if (this[name][port] != null) { // Close the existing binding
166 + for (var i in this.sockets) {
167 + var channel = this.sockets[i];
168 + if (channel.localPort == port) { this.sockets[i].end(); delete this.sockets[i]; } // Close this socket
169 + }
170 + }
171 + if (this[name][port] == null)
172 + { // Bind a new server socket if not already present
173 + this[name][port] = require('net').createServer();
174 + this[name][port].HECI = this;
175 + if (lme_port_offset == 0) {
176 + this[name][port].listen({ port: port, host: '127.0.0.1' }); // Normal mode
177 + } else {
178 + this[name][port].listen({ port: (port + lme_port_offset) }); // Debug mode
179 + }
180 + this[name][port].on('connection', function (socket) {
181 + //console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort);
182 + this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort - lme_port_offset);
183 + });
184 + this._binded[port] = true;
185 + this.LMS.emit('bind', this._binded);
186 + }
187 + var outBuffer = Buffer.alloc(5);
188 + outBuffer.writeUInt8(81, 0);
189 + outBuffer.writeUInt32BE(port, 1);
190 + this.write(outBuffer);
191 + break;
192 + case 'cancel-tcpip-forward':
193 + var outBuffer = Buffer.alloc(1);
194 + outBuffer.writeUInt8(APF_REQUEST_SUCCESS, 0);
195 + this.write(outBuffer);
196 + break;
197 + case 'udp-send-to@amt.intel.com':
198 + var outBuffer = Buffer.alloc(1);
199 + outBuffer.writeUInt8(APF_REQUEST_FAILURE, 0);
200 + this.write(outBuffer);
201 + break;
202 + default:
203 + //console.log("Unknown APF_GLOBAL_REQUEST for: " + name);
204 + break;
205 + }
206 + break;
207 + case APF_CHANNEL_OPEN_CONFIRMATION:
208 + var rChannel = chunk.readUInt32BE(1);
209 + var sChannel = chunk.readUInt32BE(5);
210 + var wSize = chunk.readUInt32BE(9);
211 + //console.log('rChannel/' + rChannel + ', sChannel/' + sChannel + ', wSize/' + wSize);
212 + if (this.sockets[rChannel] != undefined) {
213 + this.sockets[rChannel].lme.amtId = sChannel;
214 + this.sockets[rChannel].lme.rxWindow = wSize;
215 + this.sockets[rChannel].lme.txWindow = wSize;
216 + this.sockets[rChannel].lme.LME_CHANNEL_STATUS = 'LME_CS_CONNECTED';
217 + //console.log('LME_CS_CONNECTED');
218 + this.sockets[rChannel].bufferedStream = new stream_bufferedWrite();
219 + this.sockets[rChannel].bufferedStream.socket = this.sockets[rChannel];
220 + this.sockets[rChannel].bufferedStream.on('readable', function () {
221 + if (this.socket.lme.txWindow > 0) {
222 + var buffer = this.read(this.socket.lme.txWindow);
223 + var packet = Buffer.alloc(9 + buffer.length);
224 + packet.writeUInt8(APF_CHANNEL_DATA, 0);
225 + packet.writeUInt32BE(this.socket.lme.amtId, 1);
226 + packet.writeUInt32BE(buffer.length, 5);
227 + buffer.copy(packet, 9);
228 + this.socket.lme.txWindow -= buffer.length;
229 + this.socket.HECI.write(packet);
230 + }
231 + });
232 + this.sockets[rChannel].bufferedStream.on('drain', function () {
233 + this.socket.resume();
234 + });
235 + this.sockets[rChannel].on('data', function (chunk) {
236 + if (!this.bufferedStream.write(chunk)) { this.pause(); }
237 + });
238 + this.sockets[rChannel].on('end', function () {
239 + var outBuffer = Buffer.alloc(5);
240 + outBuffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
241 + outBuffer.writeUInt32BE(this.lme.amtId, 1);
242 + this.HECI.write(outBuffer);
243 + });
244 + this.sockets[rChannel].resume();
245 + }
246 +
247 + break;
248 + case APF_PROTOCOLVERSION:
249 + var major = chunk.readUInt32BE(1);
250 + var minor = chunk.readUInt32BE(5);
251 + var reason = chunk.readUInt32BE(9);
252 + var outBuffer = Buffer.alloc(93);
253 + outBuffer.writeUInt8(192, 0);
254 + outBuffer.writeUInt32BE(1, 1);
255 + outBuffer.writeUInt32BE(0, 5);
256 + outBuffer.writeUInt32BE(reason, 9);
257 + //console.log('Answering PROTOCOL_VERSION');
258 + this.write(outBuffer);
259 + break;
260 + case APF_CHANNEL_WINDOW_ADJUST:
261 + var rChannelId = chunk.readUInt32BE(1);
262 + var bytesToAdd = chunk.readUInt32BE(5);
263 + if (this.sockets[rChannelId] != undefined) {
264 + this.sockets[rChannelId].lme.txWindow += bytesToAdd;
265 + if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) {
266 + this.sockets[rChannelId].bufferedStream.emit('readable');
267 + }
268 + } else {
269 + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST');
270 + }
271 + break;
272 + case APF_CHANNEL_DATA:
273 + var rChannelId = chunk.readUInt32BE(1);
274 + var dataLen = chunk.readUInt32BE(5);
275 + var data = chunk.slice(9, 9 + dataLen);
276 + if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) {
277 + this.sockets[rChannelId].pendingBytes.push(data.length);
278 + this.sockets[rChannelId].write(data, function () {
279 + var written = this.pendingBytes.shift();
280 + //console.log('adjust', this.lme.amtId, written);
281 + var outBuffer = Buffer.alloc(9);
282 + outBuffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
283 + outBuffer.writeUInt32BE(this.lme.amtId, 1);
284 + outBuffer.writeUInt32BE(written, 5);
285 + this.HECI.write(outBuffer);
286 + });
287 + } else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) {
288 + var channel = this.insockets[rChannelId];
289 + if (channel.data == null) { channel.data = data.toString(); } else { channel.data += data.toString(); }
290 + channel.rxWindow += dataLen;
291 + //console.log('IN DATA', channel.rxWindow, channel.data.length, dataLen, channel.amtId, data.toString());
292 + var httpData = parseHttp(channel.data);
293 + if ((httpData != null) || (channel.data.length >= 8000)) {
294 + // Parse the WSMAN
295 + var notify = null;
296 + try { notify = xmlParser.ParseWsman(httpData); } catch (e) { }
297 +
298 + // Event the http data
299 + if (notify != null) { this.LMS.emit('notify', notify, channel.options, _lmsNotifyToString(notify), _lmsNotifyToCode(notify)); }
300 +
301 + // Send channel close
302 + var buffer = Buffer.alloc(5);
303 + buffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
304 + buffer.writeUInt32BE(amtId, 1);
305 + this.write(buffer);
306 + } else {
307 + if (channel.rxWindow > 6000) {
308 + // Send window adjust
309 + var buffer = Buffer.alloc(9);
310 + buffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
311 + buffer.writeUInt32BE(channel.amtId, 1);
312 + buffer.writeUInt32BE(channel.rxWindow, 5);
313 + this.write(buffer);
314 + channel.rxWindow = 0;
315 + }
316 + }
317 + } else {
318 + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA');
319 + }
320 + break;
321 + case APF_CHANNEL_OPEN_FAILURE:
322 + var rChannelId = chunk.readUInt32BE(1);
323 + var reasonCode = chunk.readUInt32BE(5);
324 + if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) {
325 + this.sockets[rChannelId].end();
326 + delete this.sockets[rChannelId];
327 + } else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) {
328 + delete this.insockets[rChannelId];
329 + } else {
330 + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_OPEN_FAILURE');
331 + }
332 + break;
333 + case APF_CHANNEL_CLOSE:
334 + var rChannelId = chunk.readUInt32BE(1);
335 + if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) {
336 + this.sockets[rChannelId].end();
337 + var amtId = this.sockets[rChannelId].lme.amtId;
338 + var buffer = Buffer.alloc(5);
339 + delete this.sockets[rChannelId];
340 +
341 + buffer.writeUInt8(APF_CHANNEL_CLOSE, 0); // ????????????????????????????
342 + buffer.writeUInt32BE(amtId, 1);
343 + this.write(buffer);
344 + } else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) {
345 + delete this.insockets[rChannelId];
346 + // Should I send a close back????
347 + } else {
348 + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE');
349 + }
350 + break;
351 + case APF_CHANNEL_OPEN:
352 + var nameLen = chunk.readUInt32BE(1);
353 + var name = chunk.slice(5, nameLen + 5).toString();
354 + var channelSender = chunk.readUInt32BE(nameLen + 5);
355 + var initialWindowSize = chunk.readUInt32BE(nameLen + 9);
356 + var hostToConnectLen = chunk.readUInt32BE(nameLen + 17);
357 + var hostToConnect = chunk.slice(nameLen + 21, nameLen + 21 + hostToConnectLen).toString();
358 + var portToConnect = chunk.readUInt32BE(nameLen + 21 + hostToConnectLen);
359 + var originatorIpLen = chunk.readUInt32BE(nameLen + 25 + hostToConnectLen);
360 + var originatorIp = chunk.slice(nameLen + 29 + hostToConnectLen, nameLen + 29 + hostToConnectLen + originatorIpLen).toString();
361 + var originatorPort = chunk.readUInt32BE(nameLen + 29 + hostToConnectLen + originatorIpLen);
362 + //console.log('APF_CHANNEL_OPEN', name, channelSender, initialWindowSize, 'From: ' + originatorIp + ':' + originatorPort, 'To: ' + hostToConnect + ':' + portToConnect);
363 +
364 + if (this.insockets == null) { this.insockets = {}; }
365 + var ourId = ++lme_id;
366 + var insocket = new lme_object();
367 + insocket.ourId = ourId;
368 + insocket.amtId = channelSender;
369 + insocket.txWindow = initialWindowSize;
370 + insocket.rxWindow = 0;
371 + insocket.options = { target: hostToConnect, targetPort: portToConnect, source: originatorIp, sourcePort: originatorPort };
372 + this.insockets[ourId] = insocket;
373 +
374 + var buffer = Buffer.alloc(17);
375 + buffer.writeUInt8(APF_CHANNEL_OPEN_CONFIRMATION, 0);
376 + buffer.writeUInt32BE(channelSender, 1); // Intel AMT sender channel
377 + buffer.writeUInt32BE(ourId, 5); // Our receiver channel id
378 + buffer.writeUInt32BE(4000, 9); // Initial Window Size
379 + buffer.writeUInt32BE(0xFFFFFFFF, 13); // Reserved
380 + this.write(buffer);
381 +
382 + /*
383 + var buffer = Buffer.alloc(17);
384 + buffer.writeUInt8(APF_CHANNEL_OPEN_FAILURE, 0);
385 + buffer.writeUInt32BE(channelSender, 1); // Intel AMT sender channel
386 + buffer.writeUInt32BE(2, 5); // Reason code
387 + buffer.writeUInt32BE(0, 9); // Reserved
388 + buffer.writeUInt32BE(0, 13); // Reserved
389 + this.write(buffer);
390 + console.log('Sent APF_CHANNEL_OPEN_FAILURE', channelSender);
391 + */
392 +
393 + break;
394 + }
395 + });
396 + this.LMS.emit('connect');
397 + this.resume();
398 +
399 + });
400 +
401 + this.bindDuplexStream = function (duplexStream, remoteFamily, localPort) {
402 + var socket = duplexStream;
403 + //console.log('New [' + remoteFamily + '] Virtual Connection/' + socket.localPort);
404 + socket.pendingBytes = [];
405 + socket.HECI = this._LME;
406 + socket.LMS = this;
407 + socket.lme = new lme_object();
408 + socket.lme.Socket = socket;
409 + socket.localPort = localPort;
410 + var buffer = new MemoryStream();
411 + buffer.writeUInt8(0x5A);
412 + buffer.writeUInt32BE(15);
413 + buffer.write('forwarded-tcpip');
414 + buffer.writeUInt32BE(socket.lme.ourId);
415 + buffer.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE);
416 + buffer.writeUInt32BE(0xFFFFFFFF);
417 + for (var i = 0; i < 2; ++i) {
418 + if (remoteFamily == 'IPv6') {
419 + buffer.writeUInt32BE(3);
420 + buffer.write('::1');
421 + } else {
422 + buffer.writeUInt32BE(9);
423 + buffer.write('127.0.0.1');
424 + }
425 + buffer.writeUInt32BE(localPort);
426 + }
427 + this._LME.write(buffer.buffer);
428 + if (this._LME.sockets == undefined) { this._LME.sockets = {}; }
429 + this._LME.sockets[socket.lme.ourId] = socket;
430 + socket.pause();
431 + };
432 +
433 + this._LME.connect(heci.GUIDS.LME, { noPipeline: 0 });
434 +}
435 +
436 +function parseHttp(httpData) {
437 + var i = httpData.indexOf('\r\n\r\n');
438 + if ((i == -1) || (httpData.length < (i + 2))) { return null; }
439 + var headers = require('http-headers')(httpData.substring(0, i), true);
440 + var contentLength = parseInt(headers['content-length']);
441 + if (httpData.length >= contentLength + i + 4) { return httpData.substring(i + 4, i + 4 + contentLength); }
442 + return null;
443 +}
444 +
445 +function _lmsNotifyToCode(notify) {
446 + if ((notify == null) || (notify.Body == null) || (notify.Body.MessageID == null)) return null;
447 + var msgid = notify.Body.MessageID;
448 + try { msgid += '-' + notify.Body.MessageArguments[0]; } catch (e) { }
449 + return msgid;
450 +}
451 +
452 +function _lmsNotifyToString(notify) {
453 + if ((notify == null) || (notify.Body == null) || (notify.Body.MessageID == null)) return null;
454 + var msgid = notify.Body.MessageID;
455 + try { msgid += '-' + notify.Body.MessageArguments[0]; } catch (e) { }
456 + if (lmsEvents[msgid]) { return lmsEvents[msgid]; }
457 + return null;
458 +}
459 +
460 +var lmsEvents = {
461 + "iAMT0001": "System Defense Policy %1s triggered.",
462 + "iAMT0002": "Agent Presence Agent %1s not started.",
463 + "iAMT0003": "Agent Presence Agent %1s stopped.",
464 + "iAMT0004": "Agent Presence Agent %1s running.",
465 + "iAMT0005": "Agent Presence Agent %1s expired.",
466 + "iAMT0006": "Agent Presence Agent %1s suspended.",
467 + "iAMT0007": "Host software attempt to disable AMT Network link detected.",
468 + "iAMT0008": "Host software attempt to disable AMT Network link detected -- Host Network link blocked.",
469 + "iAMT0009": "AMT clock or FLASH wear-out protection disabled.",
470 + "iAMT0010": "Intel(R) AMT Network Interface %1s heuristics defense slow threshold trespassed.",
471 + "iAMT0011": "Intel(R) AMT Network Interface %1s heuristics defense fast threshold trespassed.",
472 + "iAMT0012": "Intel(R) AMT Network Interface %1s heuristics defense factory defined threshold trespassed.",
473 + "iAMT0013": "Intel(R) AMT Network Interface %1s heuristics defense Encounter timeout expired.",
474 + "iAMT0014": "General certificate error.",
475 + "iAMT0015": "Certificate expired.",
476 + "iAMT0016": "No trusted root certificate.",
477 + "iAMT0017": "Not configured to work with server certificate.",
478 + "iAMT0018": "Certificate revoked.",
479 + "iAMT0019": "RSA exponent too large.",
480 + "iAMT0020": "RSA modulus too large.",
481 + "iAMT0021": "Unsupported digest.",
482 + "iAMT0022": "Distinguished name too long.",
483 + "iAMT0023": "Key usage missing.",
484 + "iAMT0024": "General SSL handshake error.",
485 + "iAMT0025": "General 802.1x error.",
486 + "iAMT0026": "AMT Diagnostic AlertEAC error - General NAC error.",
487 + "iAMT0027": "AMT Diagnostic AlertEAC error - attempt to get a NAC posture while AMT NAC is disabled.",
488 + "iAMT0028": "AMT Diagnostic AlertEAC error - attempt to get a posture of an unsupported type.",
489 + "iAMT0029": "Audit log storage is 50% full.",
490 + "iAMT0030": "Audit log storage is 75% full.",
491 + "iAMT0031": "Audit log storage is 85% full.",
492 + "iAMT0032": "Audit log storage is 95% full.",
493 + "iAMT0033": "Audit log storage is full.",
494 + "iAMT0034": "Firmware Update Event - Partial.",
495 + "iAMT0035": "Firmware Update Event - Failure.",
496 + "iAMT0036": "Remote connectivity initiated.",
497 + "iAMT0037": "ME Presence event.",
498 + "iAMT0038-0": "AMT is being unprovisioned using BIOS command.",
499 + "iAMT0038-1": "AMT is being unprovisioned using Local MEI command.",
500 + "iAMT0038-2": "AMT is being unprovisioned using Local WS-MAN/SOAP command.",
501 + "iAMT0038-3": "AMT is being unprovisioned using Remote WS-MAN/SOAP command.",
502 + "iAMT0039": "HW Asset Error.",
503 + "iAMT0050": "User Notification Alert - General Notification.",
504 + "iAMT0050-16": "User Notification Alert - Circuit Breaker notification (CB Drop TX filter hit.).",
505 + "iAMT0050-17": "User Notification Alert - Circuit Breaker notification (CB Rate Limit TX filter hit.).",
506 + "iAMT0050-18": "User Notification Alert - Circuit Breaker notification (CB Drop RX filter hit.).",
507 + "iAMT0050-19": "User Notification Alert - Circuit Breaker notification (CB Rate Limit RX filter hit.).",
508 + "iAMT0050-32": "User Notification Alert - EAC notification.",
509 + "iAMT0050-48": "User Notification Alert - Remote diagnostics - (Remote Redirection session started - SOL).",
510 + "iAMT0050-49": "User Notification Alert - Remote diagnostics - (Remote Redirection session stopped - SOL).",
511 + "iAMT0050-50": "User Notification Alert - Remote diagnostics. (Remote Redirection session started - IDE-R).",
512 + "iAMT0050-51": "User Notification Alert - Remote diagnostics. (Remote Redirection session stopped - IDE-R).",
513 + "iAMT0050-66": "User Notification Alert - WLAN notification (Host profile mismatch - Management Interface ignored).",
514 + "iAMT0050-67": "User Notification Alert - WLAN notification (Management device overrides host radio).",
515 + "iAMT0050-68": "User Notification Alert - WLAN notification (Host profile security mismatch).",
516 + "iAMT0050-69": "User Notification Alert - WLAN notification (Management device relinquishes control over host Radio).",
517 + "iAMT0051": "User Notification Alert - SecIo event.",
518 + "iAMT0051-0": "User Notification Alert - SecIo event semaphore at host.",
519 + "iAMT0051-1": "User Notification Alert - semaphore at ME.",
520 + "iAMT0051-2": "User Notification Alert - SecIo event - semaphore timeout.",
521 + "iAMT0052": "User Notification Alert - KVM session event.",
522 + "iAMT0052-0": "User Notification Alert - KVM session requested.",
523 + "iAMT0052-1": "User Notification Alert - KVM session started.",
524 + "iAMT0052-2": "User Notification Alert - KVM session stopped.",
525 + "iAMT0052-3": "User Notification Alert - KVM data channel.",
526 + "iAMT0053": "User Notification Alert - RCS notification.",
527 + "iAMT0053-50": "User Notification Alert - RCS notification (HW button pressed. Connection initiated automatically).",
528 + "iAMT0053-52": "User Notification Alert - RCS notification (HW button pressed. Connection wasn't initiated automatically).",
529 + "iAMT0053-53": "User Notification Alert - RCS notification (Contracts updated).",
530 + "iAMT0054": "User Notification Alert - WLAN notification. Wireless Profile sync enablement state changed.",
531 + "iAMT0055": "User Notification Alert - Provisioning state change notification.",
532 + "iAMT0055-0": "User Notification Alert - Provisioning state change notification - Pre-configuration.",
533 + "iAMT0055-1": "User Notification Alert - Provisioning state change notification - In configuration.",
534 + "iAMT0055-2": "User Notification Alert - Provisioning state change notification - Post-configuration.",
535 + "iAMT0055-3": "User Notification Alert - Provisioning state change notification - Unprovision process has started.",
536 + "iAMT0056": "User Notification Alert - System Defense change notification.",
537 + "iAMT0057": "User Notification Alert - Network State change notification.",
538 + "iAMT0058": "User Notification Alert - Remote Access change notification.",
539 + "iAMT0058-1": "User Notification Alert - Remote Access change notification - tunnel is closed.",
540 + //"iAMT0058-1": "User Notification Alert - Remote Access change notification - tunnel is open.", // TODO
541 + "iAMT0059": "User Notification Alert - KVM enabled event.",
542 + "iAMT0059-0": "User Notification Alert - KVM enabled event - KVM disabled.",
543 + "iAMT0059-1": "User Notification Alert - KVM enabled event - KVM enabled (both from MEBx and PTNI).",
544 + "iAMT0060": "User Notification Alert - SecIO configuration event.",
545 + "iAMT0061": "ME FW reset occurred.",
546 + "iAMT0062": "User Notification Alert - IpSyncEnabled event.",
547 + "iAMT0062-0": "User Notification Alert - IpSyncEnabled event - IpSync disabled.",
548 + "iAMT0062-1": "User Notification Alert - IpSyncEnabled event - IpSync enabled.",
549 + "iAMT0063": "User Notification Alert - HTTP Proxy sync enabled event.",
550 + "iAMT0063-0": "User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync disabled.",
551 + "iAMT0063-1": "User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync enabled.",
552 + "iAMT0064": "User Notification Alert - User Consent event.",
553 + "iAMT0064-1": "User Notification Alert - User Consent event - User Consent granted.",
554 + "iAMT0064-2": "User Notification Alert - User Consent event - User Consent ended.",
555 + "iAMT0067-0": "Graceful Remote Control Operation - Shutdown.",
556 + "iAMT0067-1": "Graceful Remote Control Operation - Reset.",
557 + "iAMT0067-2": "Graceful Remote Control Operation - Hibernate.",
558 + "iAMT0068-0": "Link Protection Notification - No link protection.",
559 + "iAMT0068-1": "Link Protection Notification - Passive link protection.",
560 + "iAMT0068-2": "Link Protection Notification - High link protection.",
561 + "iAMT0069-0": "Local Time Sync Enablement Notification - Local Time Sync Disabled.",
562 + "iAMT0069-1": "Local Time Sync Enablement Notification - Local Time Sync Enabled.",
563 + "iAMT0070": "Host Reset Triggered by WD Expiration Notification.",
564 + "PLAT0004": "The chassis %1s was opened.",
565 + "PLAT0005": "The chassis %1s was closed.",
566 + "PLAT0006": "The drive bay %1s was opened.",
567 + "PLAT0007": "The drive bay %1s was closed.",
568 + "PLAT0008": "The I/O card area %1s was opened.",
569 + "PLAT0009": "The I/O card area %1s was closed.",
570 + "PLAT0010": "The processor area %1s was opened.",
571 + "PLAT0011": "The processor area %1s was closed.",
572 + "PLAT0012": "The LAN %1s has been disconnected.",
573 + "PLAT0013": "The LAN %1s has been connected.",
574 + "PLAT0016": "The permission to insert package %1s has been granted.",
575 + "PLAT0017": "The permission to insert package %1s has been removed.",
576 + "PLAT0018": "The fan card area %1s is open.",
577 + "PLAT0019": "The fan card area %1s is closed.",
578 + "PLAT0022": "The computer system %1s has detected a secure mode violation.",
579 + "PLAT0024": "The computer system %1s has detected a pre-boot user password violation.",
580 + "PLAT0026": "The computer system %1s has detected a pre-boot setup password violation.",
581 + "PLAT0028": "The computer system %1s has detected a network boot password violation.",
582 + "PLAT0030": "The computer system %1s has detected a password violation.",
583 + "PLAT0032": "The management controller %1s has detected an out-of-band password violation.",
584 + "PLAT0034": "The processor %1s has been added.",
585 + "PLAT0035": "The processor %1s has been removed.",
586 + "PLAT0036": "An over-temperature condition has been detected on the processor %1s.",
587 + "PLAT0037": "An over-temperature condition has been removed on the processor %1s.",
588 + "PLAT0038": "The processor %1s is operating in a degraded State.",
589 + "PLAT0039": "The processor %1s is no longer operating in a degraded State.",
590 + "PLAT0040": "The processor %1s has failed.",
591 + "PLAT0042": "The processor %1s has failed.",
592 + "PLAT0044": "The processor %1s has failed.",
593 + "PLAT0046": "The processor %1s has failed.",
594 + "PLAT0048": "The processor %1s has failed.",
595 + "PLAT0060": "The processor %1s has been enabled.",
596 + "PLAT0061": "The processor %1s has been disabled.",
597 + "PLAT0062": "The processor %1s has a configuration mismatch.",
598 + "PLAT0064": "A terminator has been detected on the processor %1s.",
599 + "PLAT0084": "The Power Supply %1s has been added.",
600 + "PLAT0085": "The Power Supply %1s has been removed.",
601 + "PLAT0086": "The Power Supply %1s has failed.",
602 + "PLAT0088": "Failure predicted on power supply %1s.",
603 + "PLAT0096": "The input to power supply %1s has been lost or fallen out of range.",
604 + "PLAT0098": "The power supply %1s is operating in an input state that is out of range.",
605 + "PLAT0099": "The power supply %1s has returned to a normal input state.",
606 + "PLAT0100": "The power supply %1s has lost input.",
607 + "PLAT0104": "The power supply %1s has a configuration mismatch.",
608 + "PLAT0106": "Power supply %1s has been disabled.",
609 + "PLAT0107": "Power supply %1s has been enabled.",
610 + "PLAT0108": "Power supply %1s has been power cycled.",
611 + "PLAT0110": "Power supply %1s has encountered an error during power down.",
612 + "PLAT0112": "Power supply %1s has lost power.",
613 + "PLAT0114": "Soft power control has failed for power supply %1s.",
614 + "PLAT0116": "Power supply %1s has failed.",
615 + "PLAT0118": "Failure predicted on power supply %1s.",
616 + "PLAT0120": "Memory subsystem failure.",
617 + "PLAT0122": "DIMM missing.",
618 + "PLAT0124": "Memory error detected & corrected for DIMM %1s.",
619 + "PLAT0128": "Memory DIMM %1s added.",
620 + "PLAT0129": "Memory DIMM %1s removed.",
621 + "PLAT0130": "Memory DIMM %1s enabled.",
622 + "PLAT0131": "Memory DIMM %1s disabled.",
623 + "PLAT0134": "Memory parity error for DIMM %1s.",
624 + "PLAT0136": "Memory scrub failure for DIMM %1s.",
625 + "PLAT0138": "Memory uncorrectable error detected for DIMM %1s.",
626 + "PLAT0140": "Memory sparing initiated for DIMM %1s.",
627 + "PLAT0141": "Memory sparing concluded for DIMM %1s.",
628 + "PLAT0142": "Memory DIMM %1s Throttled.",
629 + "PLAT0144": "Memory logging limit reached for DIMM %1s.",
630 + "PLAT0145": "Memory logging limit removed for DIMM %1s.",
631 + "PLAT0146": "An over-temperature condition has been detected on the Memory DIMM %1s.",
632 + "PLAT0147": "An over-temperature condition has been removed on the Memory DIMM %1s.",
633 + "PLAT0162": "The drive %1s has been added.",
634 + "PLAT0163": "The drive %1s has been removed.",
635 + "PLAT0164": "The drive %1s has been disabled due to a detected fault.",
636 + "PLAT0167": "The drive %1s has been enabled.",
637 + "PLAT0168": "Failure predicted on drive %1s.",
638 + "PLAT0170": "Hot spare enabled for %1s.",
639 + "PLAT0171": "Hot spare disabled for %1s.",
640 + "PLAT0172": "Consistency check has begun for %1s.",
641 + "PLAT0173": "Consistency check completed for %1s.",
642 + "PLAT0174": "Array %1s is in critical condition.",
643 + "PLAT0176": "Array %1s has failed.",
644 + "PLAT0177": "Array %1s has been restored.",
645 + "PLAT0178": "Rebuild in progress for array %1s.",
646 + "PLAT0179": "Rebuild completed for array %1s.",
647 + "PLAT0180": "Rebuild Aborted for array %1s.",
648 + "PLAT0184": "The system %1s encountered a POST error.",
649 + "PLAT0186": "The system %1s encountered a firmware hang.",
650 + "PLAT0188": "The system %1s encountered firmware progress.",
651 + "PLAT0192": "The log %1s has been disabled.",
652 + "PLAT0193": "The log %1s has been enabled.",
653 + "PLAT0194": "The log %1s has been disabled.",
654 + "PLAT0195": "The log %1s has been enabled.",
655 + "PLAT0196": "The log %1s has been disabled.",
656 + "PLAT0198": "The log %1s has been enabled.",
657 + "PLAT0200": "The log %1s has been cleared.",
658 + "PLAT0202": "The log %1s is full.",
659 + "PLAT0203": "The log %1s is no longer full.",
660 + "PLAT0204": "The log %1s is almost full.",
661 + "PLAT0208": "The log %1s has a configuration error.",
662 + "PLAT0210": "The system %1s has been reconfigured.",
663 + "PLAT0212": "The system %1s has encountered an OEM system boot event.",
664 + "PLAT0214": "The system %1s has encountered an unknown system hardware fault.",
665 + "PLAT0216": "The system %1s has generated an auxiliary log entry.",
666 + "PLAT0218": "The system %1s has executed a PEF action.",
667 + "PLAT0220": "The system %1s has synchronized the system clock.",
668 + "PLAT0222": "A diagnostic interrupt has occurred on system %1s.",
669 + "PLAT0224": "A bus timeout has occurred on system %1s.",
670 + "PLAT0226": "An I/O channel check NMI has occurred on system %1s.",
671 + "PLAT0228": "A software NMI has occurred on system %1s.",
672 + "PLAT0230": "System %1s has recovered from an NMI.",
673 + "PLAT0232": "A PCI PERR has occurred on system %1s.",
674 + "PLAT0234": "A PCI SERR has occurred on system %1s.",
675 + "PLAT0236": "An EISA fail safe timeout occurred on system %1s.",
676 + "PLAT0238": "A correctable bus error has occurred on system %1s.",
677 + "PLAT0240": "An uncorrectable bus error has occurred on system %1s.",
678 + "PLAT0242": "A fatal NMI error has occurred on system %1s.",
679 + "PLAT0244": "A fatal bus error has occurred on system %1s.",
680 + "PLAT0246": "A bus on system %1s is operating in a degraded state.",
681 + "PLAT0247": "A bus on system %1s is no longer operating in a degraded state.",
682 + "PLAT0248": "The power button %1s has been pressed.",
683 + "PLAT0249": "The power button %1s has been released.",
684 + "PLAT0250": "The sleep button %1s has been pressed.",
685 + "PLAT0251": "The sleep button %1s has been released.",
686 + "PLAT0252": "The reset button %1s has been pressed.",
687 + "PLAT0253": "The reset button %1s has been released.",
688 + "PLAT0254": "The latch to %1s has been opened.",
689 + "PLAT0255": "The latch to %1s has been closed.",
690 + "PLAT0256": "The service request %1s has been enabled.",
691 + "PLAT0257": "The service request %1s has been completed.",
692 + "PLAT0258": "Power control of system %1s has failed.",
693 + "PLAT0262": "The network port %1s has been connected.",
694 + "PLAT0263": "The network port %1s has been disconnected.",
695 + "PLAT0266": "The connector %1s has encountered a configuration error.",
696 + "PLAT0267": "The connector %1s configuration error has been repaired.",
697 + "PLAT0272": "Power on for system %1s.",
698 + "PLAT0274": "Power cycle hard requested for system %1s.",
699 + "PLAT0276": "Power cycle soft requested for system %1s.",
700 + "PLAT0278": "PXE boot requested for system %1s.",
701 + "PLAT0280": "Diagnostics boot requested for system %1s.",
702 + "PLAT0282": "System restart requested for system %1s.",
703 + "PLAT0284": "System restart begun for system %1s.",
704 + "PLAT0286": "No bootable media available for system %1s.",
705 + "PLAT0288": "Non-bootable media selected for system %1s.",
706 + "PLAT0290": "PXE server not found for system %1s.",
707 + "PLAT0292": "User timeout on boot for system %1s.",
708 + "PLAT0296": "System %1s boot from floppy initiated.",
709 + "PLAT0298": "System %1s boot from local drive initiated.",
710 + "PLAT0300": "System %1s boot from PXE on network port initiated.",
711 + "PLAT0302": "System %1s boot diagnostics initiated.",
712 + "PLAT0304": "System %1s boot from CD initiated.",
713 + "PLAT0306": "System %1s boot from ROM initiated.",
714 + "PLAT0312": "System %1s boot initiated.",
715 + "PLAT0320": "Critical stop during OS load on system %1s.",
716 + "PLAT0322": "Run-time critical stop on system %1s.",
717 + "PLAT0324": "OS graceful stop on system %1s.",
718 + "PLAT0326": "OS graceful shutdown begun on system %1s.",
719 + "PLAT0327": "OS graceful shutdown completed on system %1s.",
720 + "PLAT0328": "Agent not responding on system %1s.",
721 + "PLAT0329": "Agent has begun responding on system %1s.",
722 + "PLAT0330": "Fault in slot on system %1s.",
723 + "PLAT0331": "Fault condition removed on system %1s.",
724 + "PLAT0332": "Identifying slot on system %1s.",
725 + "PLAT0333": "Identify stopped on slot for system %1s.",
726 + "PLAT0334": "Package installed in slot for system %1s.",
727 + "PLAT0336": "Slot empty system %1s.",
728 + "PLAT0338": "Slot in system %1s is ready for installation.",
729 + "PLAT0340": "Slot in system %1s is ready for removal.",
730 + "PLAT0342": "Power is off on slot of system %1s.",
731 + "PLAT0344": "Power is on for slot of system %1s.",
732 + "PLAT0346": "Removal requested for slot of system %1s.",
733 + "PLAT0348": "Interlock activated on slot of system %1s.",
734 + "PLAT0349": "Interlock de-asserted on slot of system %1s.",
735 + "PLAT0350": "Slot disabled on system %1s.",
736 + "PLAT0351": "Slot enabled on system %1s.",
737 + "PLAT0352": "Slot of system %1s holds spare.",
738 + "PLAT0353": "Slot of system %1s no longer holds spare.",
739 + "PLAT0354": "Computer system %1s enabled.",
740 + "PLAT0356": "Computer system %1s is in sleep - light mode.",
741 + "PLAT0358": "Computer system %1s is in hibernate.",
742 + "PLAT0360": "Computer system %1s is in standby.",
743 + "PLAT0362": "Computer system %1s is in soft off mode.",
744 + "PLAT0364": "Computer system %1s is in hard off mode.",
745 + "PLAT0366": "Computer system %1s is sleeping.",
746 + "PLAT0368": "Watchdog timer expired for %1s.",
747 + "PLAT0370": "Reboot of system initiated by watchdog %1s.",
748 + "PLAT0372": "Powering off system initiated by watchdog %1s.",
749 + "PLAT0374": "Power cycle of system initiated by watchdog %1s.",
750 + "PLAT0376": "Watchdog timer interrupt occurred for %1s.",
751 + "PLAT0378": "A page alert has been generated for system %1s.",
752 + "PLAT0380": "A LAN alert has been generated for system %1s.",
753 + "PLAT0382": "An event trap has been generated for system %1s.",
754 + "PLAT0384": "An SNMP trap has been generated for system %1s.",
755 + "PLAT0390": "%1s detected as present.",
756 + "PLAT0392": "%1s detected as absent.",
757 + "PLAT0394": "%1s has been disabled.",
758 + "PLAT0395": "%1s has been enabled.",
759 + "PLAT0396": "Heartbeat lost for LAN %1s.",
760 + "PLAT0397": "Heartbeat detected for LAN %1s.",
761 + "PLAT0398": "Sensor %1s is unavailable or degraded on management system.",
762 + "PLAT0399": "Sensor %1s has returned to normal on management system.",
763 + "PLAT0400": "Controller %1s is unavailable or degraded on management system.",
764 + "PLAT0401": "Controller %1s has returned to normal on management system.",
765 + "PLAT0402": "Management system %1s is off-line.",
766 + "PLAT0404": "Management system %1s is disabled.",
767 + "PLAT0405": "Management system %1s is enabled.",
768 + "PLAT0406": "Sensor %1s has failed on management system.",
769 + "PLAT0408": "FRU %1s has failed on management system.",
770 + "PLAT0424": "The battery %1s is critically low.",
771 + "PLAT0427": "The battery %1s is no longer critically low.",
772 + "PLAT0430": "The battery %1s has been removed from unit.",
773 + "PLAT0431": "The battery %1s has been added.",
774 + "PLAT0432": "The battery %1s has failed.",
775 + "PLAT0434": "Session audit is deactivated on system %1s.",
776 + "PLAT0435": "Session audit is activated on system %1s.",
777 + "PLAT0436": "A hardware change occurred on system %1s.",
778 + "PLAT0438": "A firmware or software change occurred on system %1s.",
779 + "PLAT0440": "A hardware incompatibility was detected on system %1s.",
780 + "PLAT0442": "A firmware or software incompatibility was detected on system %1s.",
781 + "PLAT0444": "Invalid or unsupported hardware was detected on system %1s.",
782 + "PLAT0446": "Invalid or unsupported firmware or software was detected on system %1s.",
783 + "PLAT0448": "A successful hardware change was detected on system %1s.",
784 + "PLAT0450": "A successful software or firmware change was detected on system %1s.",
785 + "PLAT0464": "FRU %1s not installed on system.",
786 + "PLAT0465": "FRU %1s installed on system.",
787 + "PLAT0466": "Activation requested for FRU %1s on system.",
788 + "PLAT0467": "FRU %1s on system is active.",
789 + "PLAT0468": "Activation in progress for FRU %1s on system.",
790 + "PLAT0470": "Deactivation request for FRU %1s on system.",
791 + "PLAT0471": "FRU %1s on system is in standby or \"hot spare\" state.",
792 + "PLAT0472": "Deactivation in progress for FRU %1s on system.",
793 + "PLAT0474": "Communication lost with FRU %1s on system.",
794 + "PLAT0476": "Numeric sensor %1s going low (lower non-critical).",
795 + "PLAT0478": "Numeric sensor %1s going high (lower non-critical).",
796 + "PLAT0480": "Numeric sensor %1s going low (lower critical).",
797 + "PLAT0482": "Numeric sensor %1s going high (lower critical).",
798 + "PLAT0484": "Numeric sensor %1s going low (lower non-recoverable).",
799 + "PLAT0486": "Numeric sensor %1s going high (lower non-critical).",
800 + "PLAT0488": "Numeric sensor %1s going low (upper non-critical).",
801 + "PLAT0490": "Numeric sensor %1s going high (upper non-critical).",
802 + "PLAT0492": "Numeric sensor %1s going low (upper critical).",
803 + "PLAT0494": "Numeric sensor %1s going high (upper critical).",
804 + "PLAT0496": "Numeric sensor %1s going low (upper non-recoverable).",
805 + "PLAT0498": "Numeric sensor %1s going high (upper non-recoverable).",
806 + "PLAT0500": "Sensor %1s has transitioned to idle.",
807 + "PLAT0502": "Sensor %1s has transitioned to active.",
808 + "PLAT0504": "Sensor %1s has transitioned to busy.",
809 + "PLAT0508": "Sensor %1s has asserted.",
810 + "PLAT0509": "Sensor %1s has de-asserted.",
811 + "PLAT0510": "Sensor %1s is asserting predictive failure.",
812 + "PLAT0511": "Sensor %1s is de-asserting predictive failure.",
813 + "PLAT0512": "Sensor %1s has indicated limit exceeded.",
814 + "PLAT0513": "Sensor %1s has indicated limit no longer exceeded.",
815 + "PLAT0514": "Sensor %1s has indicated performance met.",
816 + "PLAT0516": "Sensor %1s has indicated performance lags.",
817 + "PLAT0518": "Sensor %1s has transitioned to normal state.",
818 + "PLAT0520": "Sensor %1s has transitioned from normal to non-critical state.",
819 + "PLAT0522": "Sensor %1s has transitioned to critical from a less severe state.",
820 + "PLAT0524": "Sensor %1s has transitioned to non-recoverable from a less severe state.",
821 + "PLAT0526": "Sensor %1s has transitioned to non-critical from a more severe state.",
822 + "PLAT0528": "Sensor %1s has transitioned to critical from a non-recoverable state.",
823 + "PLAT0530": "Sensor %1s has transitioned to non-recoverable.",
824 + "PLAT0532": "Sensor %1s indicates a monitor state.",
825 + "PLAT0534": "Sensor %1s has an informational state.",
826 + "PLAT0536": "Device %1s has been added.",
827 + "PLAT0537": "Device %1s has been removed from unit.",
828 + "PLAT0538": "Device %1s has been enabled.",
829 + "PLAT0539": "Device %1s has been disabled.",
830 + "PLAT0540": "Sensor %1s has indicated a running state.",
831 + "PLAT0544": "Sensor %1s has indicated a power off state.",
832 + "PLAT0546": "Sensor %1s has indicated an on-line state.",
833 + "PLAT0548": "Sensor %1s has indicated an off-line state.",
834 + "PLAT0550": "Sensor %1s has indicated an off-duty state.",
835 + "PLAT0552": "Sensor %1s has indicated a degraded state.",
836 + "PLAT0554": "Sensor %1s has indicated a power save state.",
837 + "PLAT0556": "Sensor %1s has indicated an install error.",
838 + "PLAT0558": "Redundancy %1s has been lost.",
839 + "PLAT0560": "Redundancy %1s has been reduced.",
840 + "PLAT0561": "Redundancy %1s has been restored.",
841 + "PLAT0562": "%1s has transitioned to a D0 power state.",
842 + "PLAT0564": "%1s has transitioned to a D1 power state.",
843 + "PLAT0566": "%1s has transitioned to a D2 power state.",
844 + "PLAT0568": "%1s has transitioned to a D3 power state.",
845 + "PLAT0720": "The System %1s encountered firmware progress - memory initialization entry.",
846 + "PLAT0721": "The System %1s encountered firmware progress - memory initialization exit.",
847 + "PLAT0722": "The System %1s encountered firmware progress - hard drive initialization entry.",
848 + "PLAT0723": "The System %1s encountered firmware progress - hard drive initialization exit.",
849 + "PLAT0724": "The System %1s encountered firmware progress - user authentication.",
850 + "PLAT0728": "The System %1s encountered firmware progress - USR resource configuration entry.",
851 + "PLAT0729": "The System %1s encountered firmware progress - USR resource configuration exit.",
852 + "PLAT0730": "The System %1s encountered firmware progress - PCI recource configuration entry.",
853 + "PLAT0731": "The System %1s encountered firmware progress - PCI recource configuration exit.",
854 + "PLAT0732": "The System %1s encountered firmware progress - Option ROM initialization entry.",
855 + "PLAT0733": "The System %1s encountered firmware progress - Option ROM initialization entry exit.",
856 + "PLAT0734": "The System %1s encountered firmware progress -video initialization entry entry.",
857 + "PLAT0735": "The System %1s encountered firmware progress - video initialization entry exit.",
858 + "PLAT0736": "The System %1s encountered firmware progress - cache initialization entry.",
859 + "PLAT0737": "The System %1s encountered firmware progress - cache initialization exit.",
860 + "PLAT0738": "The System %1s encountered firmware progress - keyboard controller initialization entry.",
861 + "PLAT0739": "The System %1s encountered firmware progress - keyboard controller initialization exit.",
862 + "PLAT0740": "The System %1s encountered firmware progress - motherboard initialization entry.",
863 + "PLAT0741": "The System %1s encountered firmware progress - motherboard initialization exit.",
864 + "PLAT0742": "The System %1s encountered firmware progress - floppy disk initialization entry.",
865 + "PLAT0743": "The System %1s encountered firmware progress - floppy disk initialization exit.",
866 + "PLAT0744": "The System %1s encountered firmware progress - keyboard test entry.",
867 + "PLAT0745": "The System %1s encountered firmware progress - keyboard test exit.",
868 + "PLAT0746": "The System %1s encountered firmware progress - pointing device test entry.",
869 + "PLAT0747": "The System %1s encountered firmware progress - pointing device test exit.",
870 + "PLAT0750": "The System %1s encountered firmware progress - dock enable entry.",
871 + "PLAT0751": "The System %1s encountered firmware progress - dock enable exit.",
872 + "PLAT0752": "The System %1s encountered firmware progress - dock disable entry.",
873 + "PLAT0753": "The System %1s encountered firmware progress - dock disable exit.",
874 + "PLAT0760": "The System %1s encountered firmware progress - start OS boot process.",
875 + "PLAT0762": "The System %1s encountered firmware progress - call OS wake vector.",
876 + "PLAT0764": "The System %1s encountered firmware progress - unrecoverable keyboard failure.",
877 + "PLAT0766": "The System %1s encountered firmware progress - no video device detected.",
878 + "PLAT0768": "The System %1s encountered firmware progress - SMART alert detected on drive.",
879 + "PLAT0770": "The System %1s encountered firmware progress - unrecoverable boot device failure.",
880 + "PLAT0789": "Corrupt BIOS detected.",
881 + "PLAT0790": "The System %1s encountered PCI configuration failure.",
882 + "PLAT0791": "The System %1s encountered a video subsystem failure.",
883 + "PLAT0792": "The System %1s encountered a storage subsystem failure.",
884 + "PLAT0793": "The System %1s encountered a USB subsystem failure.",
885 + "PLAT0794": "The System %1s has detected no memory in the system.",
886 + "PLAT0795": "The System %1s encountered a motherboard failure.",
887 + "PLAT0796": "The System %1s encountered a memory Regulator Voltage Bad.",
888 + "PLAT0797": "%1s PCI reset is not deasserting.",
889 + "PLAT0798": "%1s Non-Motherboard Regulator Failure.",
890 + "PLAT0799": "%1s Power Supply Cable failure.",
891 + "PLAT0800": "%1s Motherboard regulator failure.",
892 + "PLAT0801": "%1s System component compatibility mismatch."
893 +}
894 +
895 +module.exports = lme_heci;
agents-new/modules_meshcmd/amt-mei.js new
+417
@@ -0,0 +1,417 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var Q = require('queue');
18 +function amt_heci() {
19 + var emitterUtils = require('events').inherits(this);
20 + emitterUtils.createEvent('error');
21 +
22 + var heci = require('heci');
23 +
24 + this._ObjectID = "pthi";
25 + this._rq = new Q();
26 + this._setupPTHI = function _setupPTHI()
27 + {
28 + this._amt = heci.create();
29 + this._amt.BiosVersionLen = 65;
30 + this._amt.UnicodeStringLen = 20;
31 +
32 + this._amt.Parent = this;
33 + this._amt.on('error', function _amtOnError(e)
34 + {
35 + if(this.Parent._rq.isEmpty())
36 + {
37 + this.Parent.emit('error', e); // No pending requests, so propagate the error up
38 + }
39 + else
40 + {
41 + // There is a pending request, so fail the pending request
42 + var user = this.Parent._rq.deQueue();
43 + var params = user.optional;
44 + var callback = user.func;
45 + params.unshift({ Status: -1 }); // Relay an error
46 + callback.apply(this.Parent, params);
47 +
48 + if(!this.Parent._rq.isEmpty())
49 + {
50 + // There are still more pending requests, so try to re-helpconnect MEI
51 + this.connect(heci.GUIDS.AMT, { noPipeline: 1 });
52 + }
53 + }
54 + });
55 + this._amt.on('connect', function _amtOnConnect()
56 + {
57 + this.on('data', function _amtOnData(chunk)
58 + {
59 + //console.log("Received: " + chunk.length + " bytes");
60 + var header = this.Parent.getCommand(chunk);
61 + //console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
62 +
63 + var user = this.Parent._rq.deQueue();
64 + var params = user.optional;
65 + var callback = user.func;
66 +
67 + params.unshift(header);
68 + callback.apply(this.Parent, params);
69 +
70 + if(this.Parent._rq.isEmpty())
71 + {
72 + // No More Requests, we can close PTHI
73 + this.Parent._amt.disconnect();
74 + this.Parent._amt = null;
75 + }
76 + else
77 + {
78 + // Send the next request
79 + this.write(this.Parent._rq.peekQueue().send);
80 + }
81 + });
82 +
83 + // Start sending requests
84 + this.write(this.Parent._rq.peekQueue().send);
85 + });
86 + };
87 + function trim(x) { var y = x.indexOf('\0'); if (y >= 0) { return x.substring(0, y); } else { return x; } }
88 + this.getCommand = function getCommand(chunk) {
89 + var command = chunk.length == 0 ? (this._rq.peekQueue().cmd | 0x800000) : chunk.readUInt32LE(4);
90 + 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 };
91 + return (ret);
92 + };
93 +
94 + this.sendCommand = function sendCommand()
95 + {
96 + if (arguments.length < 3 || typeof (arguments[0]) != 'number' || typeof (arguments[1]) != 'object' || typeof (arguments[2]) != 'function') { throw ('invalid parameters'); }
97 + var args = [];
98 + for (var i = 3; i < arguments.length; ++i) { args.push(arguments[i]); }
99 +
100 + var header = Buffer.from('010100000000000000000000', 'hex');
101 + header.writeUInt32LE(arguments[0] | 0x04000000, 4);
102 + header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8);
103 + this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args , send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]]))});
104 +
105 + if(!this._amt)
106 + {
107 + this._setupPTHI();
108 + this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
109 + }
110 + }
111 +
112 + this.getVersion = function getVersion(callback) {
113 + var optional = [];
114 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
115 + this.sendCommand(26, null, function (header, fn, opt) {
116 + if (header.Status == 0) {
117 + var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, this._amt.BiosVersionLen).toString(), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4);
118 + for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen) ; ++i) {
119 + 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() };
120 + v = v.slice(4 + (2 * this._amt.UnicodeStringLen));
121 + }
122 + if (val.BiosVersion.indexOf('\0') > 0) { val.BiosVersion = val.BiosVersion.substring(0, val.BiosVersion.indexOf('\0')); }
123 + opt.unshift(val);
124 + } else {
125 + opt.unshift(null);
126 + }
127 + fn.apply(this, opt);
128 + }, callback, optional);
129 + };
130 +
131 + // Fill the left with zeros until the string is of a given length
132 + function zeroLeftPad(str, len) {
133 + if ((len == null) && (typeof (len) != 'number')) { return null; }
134 + if (str == null) str = ''; // If null, this is to generate zero leftpad string
135 + var zlp = '';
136 + for (var i = 0; i < len - str.length; i++) { zlp += '0'; }
137 + return zlp + str;
138 + }
139 +
140 + this.getUuid = function getUuid(callback) {
141 + var optional = [];
142 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
143 + this.sendCommand(0x5c, null, function (header, fn, opt) {
144 + if (header.Status == 0) {
145 + var result = {};
146 + result.uuid = [zeroLeftPad(header.Data.readUInt32LE(0).toString(16), 8),
147 + zeroLeftPad(header.Data.readUInt16LE(4).toString(16), 4),
148 + zeroLeftPad(header.Data.readUInt16LE(6).toString(16), 4),
149 + zeroLeftPad(header.Data.readUInt16BE(8).toString(16), 4),
150 + zeroLeftPad(header.Data.slice(10).toString('hex').toLowerCase(), 12)].join('-');
151 + opt.unshift(result);
152 + } else {
153 + opt.unshift(null);
154 + }
155 + fn.apply(this, opt);
156 + }, callback, optional);
157 + };
158 +
159 + this.getProvisioningState = function getProvisioningState(callback) {
160 + var optional = [];
161 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
162 + this.sendCommand(17, null, function (header, fn, opt) {
163 + if (header.Status == 0) {
164 + var result = {};
165 + result.state = header.Data.readUInt32LE(0);
166 + if (result.state < 3) { result.stateStr = ["PRE", "IN", "POST"][result.state]; }
167 + opt.unshift(result);
168 + } else {
169 + opt.unshift(null);
170 + }
171 + fn.apply(this, opt);
172 + }, callback, optional);
173 + };
174 + this.getProvisioningMode = function getProvisioningMode(callback) {
175 + var optional = [];
176 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
177 + this.sendCommand(8, null, function (header, fn, opt) {
178 + if (header.Status == 0) {
179 + var result = {};
180 + result.mode = header.Data.readUInt32LE(0);
181 + if (result.mode < 4) { result.modeStr = ["NONE", "ENTERPRISE", "SMALL_BUSINESS", "REMOTE_ASSISTANCE"][result.mode]; }
182 + result.legacy = header.Data.readUInt32LE(4) == 0 ? false : true;
183 + opt.unshift(result);
184 + } else {
185 + opt.unshift(null);
186 + }
187 + fn.apply(this, opt);
188 + }, callback, optional);
189 + };
190 + this.getEHBCState = function getEHBCState(callback) {
191 + var optional = [];
192 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
193 + this.sendCommand(132, null, function (header, fn, opt) {
194 + if (header.Status == 0) {
195 + opt.unshift({ EHBC: header.Data.readUInt32LE(0) != 0 });
196 + } else {
197 + opt.unshift(null);
198 + }
199 + fn.apply(this, opt);
200 + }, callback, optional);
201 + };
202 + this.getControlMode = function getControlMode(callback) {
203 + var optional = [];
204 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
205 + this.sendCommand(107, null, function (header, fn, opt) {
206 + if (header.Status == 0) {
207 + var result = {};
208 + result.controlMode = header.Data.readUInt32LE(0);
209 + if (result.controlMode < 3) { result.controlModeStr = ["NONE_RPAT", "CLIENT", "ADMIN", "REMOTE_ASSISTANCE"][result.controlMode]; }
210 + opt.unshift(result);
211 + } else {
212 + opt.unshift(null);
213 + }
214 + fn.apply(this, opt);
215 + }, callback, optional);
216 + };
217 + this.getMACAddresses = function getMACAddresses(callback) {
218 + var optional = [];
219 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
220 + this.sendCommand(37, null, function (header, fn, opt) {
221 + if (header.Status == 0) {
222 + opt.unshift({ DedicatedMAC: header.Data.slice(0, 6).toString('hex:'), HostMAC: header.Data.slice(6, 12).toString('hex:') });
223 + } else { opt.unshift({ DedicatedMAC: null, HostMAC: null }); }
224 + fn.apply(this, opt);
225 + }, callback, optional);
226 + };
227 + this.getDnsSuffix = function getDnsSuffix(callback) {
228 + var optional = [];
229 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
230 + this.sendCommand(54, null, function (header, fn, opt) {
231 + if (header.Status == 0) {
232 + var resultLen = header.Data.readUInt16LE(0);
233 + if (resultLen > 0) { opt.unshift(header.Data.slice(2, 2 + resultLen).toString()); } else { opt.unshift(null); }
234 + } else {
235 + opt.unshift(null);
236 + }
237 + fn.apply(this, opt);
238 + }, callback, optional);
239 + };
240 + this.getHashHandles = function getHashHandles(callback) {
241 + var optional = [];
242 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
243 + this.sendCommand(0x2C, null, function (header, fn, opt) {
244 + var result = [];
245 + if (header.Status == 0) {
246 + var resultLen = header.Data.readUInt32LE(0);
247 + for (var i = 0; i < resultLen; ++i) {
248 + result.push(header.Data.readUInt32LE(4 + (4 * i)));
249 + }
250 + }
251 + opt.unshift(result);
252 + fn.apply(this, opt);
253 + }, callback, optional);
254 + };
255 + this.getCertHashEntry = function getCertHashEntry(handle, callback) {
256 + var optional = [];
257 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
258 +
259 + var data = Buffer.alloc(4);
260 + data.writeUInt32LE(handle, 0);
261 +
262 + this.sendCommand(0x2D, data, function (header, fn, opt) {
263 + if (header.Status == 0) {
264 + var result = {};
265 + result.isDefault = header.Data.readUInt32LE(0);
266 + result.isActive = header.Data.readUInt32LE(4);
267 + result.hashAlgorithm = header.Data.readUInt8(72);
268 + if (result.hashAlgorithm < 4) {
269 + result.hashAlgorithmStr = ["MD5", "SHA1", "SHA256", "SHA512"][result.hashAlgorithm];
270 + result.hashAlgorithmSize = [16, 20, 32, 64][result.hashAlgorithm];
271 + result.certificateHash = header.Data.slice(8, 8 + result.hashAlgorithmSize).toString('hex');
272 + }
273 + result.name = header.Data.slice(73 + 2, 73 + 2 + header.Data.readUInt16LE(73)).toString();
274 + opt.unshift(result);
275 + } else {
276 + opt.unshift(null);
277 + }
278 + fn.apply(this, opt);
279 + }, callback, optional);
280 + };
281 + this.getCertHashEntries = function getCertHashEntries(callback) {
282 + var optional = [];
283 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
284 +
285 + this.getHashHandles(function (handles, fn, opt) {
286 + var entries = [];
287 + this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
288 + }, callback, optional);
289 + };
290 +
291 + this._getHashEntrySink = function _getHashEntrySink(result, fn, opt, entries, handles) {
292 + entries.push(result);
293 + if (handles.length > 0) {
294 + this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
295 + } else {
296 + opt.unshift(entries);
297 + fn.apply(this, opt);
298 + }
299 + }
300 + this.getLocalSystemAccount = function getLocalSystemAccount(callback) {
301 + var optional = [];
302 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
303 + this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt)
304 + {
305 + if (header.Status == 0 && header.Data.length == 68)
306 + {
307 + opt.unshift({ user: trim(header.Data.slice(0, 33).toString()), pass: trim(header.Data.slice(33, 67).toString()), raw: header.Data });
308 + }
309 + else
310 + {
311 + opt.unshift(null);
312 + }
313 + fn.apply(this, opt);
314 + }, callback, optional);
315 + }
316 + this.getLanInterfaceSettings = function getLanInterfaceSettings(index, callback)
317 + {
318 + var optional = [];
319 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
320 + var ifx = Buffer.alloc(4);
321 + ifx.writeUInt32LE(index);
322 + this.sendCommand(0x48, ifx, function onGetLanInterfaceSettings(header, fn, opt)
323 + {
324 + if(header.Status == 0)
325 + {
326 + var info = {};
327 + info.enabled = header.Data.readUInt32LE(0);
328 + info.dhcpEnabled = header.Data.readUInt32LE(8);
329 + switch(header.Data[12])
330 + {
331 + case 1:
332 + info.dhcpMode = 'ACTIVE'
333 + break;
334 + case 2:
335 + info.dhcpMode = 'PASSIVE'
336 + break;
337 + default:
338 + info.dhcpMode = 'UNKNOWN';
339 + break;
340 + }
341 + info.mac = header.Data.slice(14).toString('hex:');
342 +
343 + var addr = header.Data.readUInt32LE(4);
344 + info.address = ((addr >> 24) & 255) + '.' + ((addr >> 16) & 255) + '.' + ((addr >> 8) & 255) + '.' + (addr & 255);
345 + opt.unshift(info);
346 + fn.apply(this, opt);
347 + }
348 + else
349 + {
350 + opt.unshift(null);
351 + fn.apply(this, opt);
352 + }
353 + }, callback, optional);
354 +
355 + };
356 + this.unprovision = function unprovision(mode, callback) {
357 + var optional = [];
358 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
359 + var data = Buffer.alloc(4);
360 + data.writeUInt32LE(mode, 0);
361 + this.sendCommand(16, data, function (header, fn, opt) {
362 + opt.unshift(header.Status);
363 + fn.apply(this, opt);
364 + }, callback, optional);
365 + }
366 + this.startConfiguration = function startConfiguration() {
367 + var optional = [];
368 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
369 + this.sendCommand(0x29, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
370 + }
371 + this.stopConfiguration = function stopConfiguration() {
372 + var optional = [];
373 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
374 + this.sendCommand(0x5E, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
375 + }
376 + this.openUserInitiatedConnection = function openUserInitiatedConnection() {
377 + var optional = [];
378 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
379 + this.sendCommand(0x44, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
380 + }
381 + this.closeUserInitiatedConnection = function closeUnserInitiatedConnected() {
382 + var optional = [];
383 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
384 + this.sendCommand(0x45, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
385 + }
386 + this.getRemoteAccessConnectionStatus = function getRemoteAccessConnectionStatus() {
387 + var optional = [];
388 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
389 + this.sendCommand(0x46, data, function (header, fn, opt) {
390 + if (header.Status == 0) {
391 + var hostname = v.slice(14, header.Data.readUInt16LE(12) + 14).toString()
392 + 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 });
393 + } else {
394 + opt.unshift({ status: header.Status });
395 + }
396 + fn.apply(this, opt);
397 + }, callback, optional);
398 + }
399 + this.getProtocolVersion = function getProtocolVersion(callback) {
400 + var optional = [];
401 + for (var i = 1; i < arguments.length; ++i) { opt.push(arguments[i]); }
402 +
403 + heci.doIoctl(heci.IOCTL.HECI_VERSION, Buffer.alloc(5), Buffer.alloc(5), function (status, buffer, self, fn, opt) {
404 + if (status == 0) {
405 + var result = buffer.readUInt8(0).toString() + '.' + buffer.readUInt8(1).toString() + '.' + buffer.readUInt8(2).toString() + '.' + buffer.readUInt16BE(3).toString();
406 + opt.unshift(result);
407 + fn.apply(self, opt);
408 + }
409 + else {
410 + opt.unshift(null);
411 + fn.apply(self, opt);
412 + }
413 + }, this, callback, optional);
414 + }
415 +}
416 +
417 +module.exports = amt_heci;
\ No newline at end of file
agents-new/modules_meshcmd/amt-scanner.js new
+105
@@ -0,0 +1,105 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +/**
18 +* @description Meshcentral Intel AMT Local Scanner
19 +* @author Ylian Saint-Hilaire & Joko Sastriawan
20 +* @version v0.0.1
21 +*/
22 +
23 +// Construct a Intel AMT Scanner object
24 +
25 +function AMTScanner() {
26 + var emitterUtils = require('events').inherits(this);
27 + emitterUtils.createEvent('found');
28 +
29 + this.dgram = require('dgram');
30 +
31 + this.buildRmcpPing = function (tag) {
32 + var packet = Buffer.from('06000006000011BE80000000', 'hex');
33 + packet[9] = tag;
34 + return packet;
35 + };
36 +
37 + this.parseRmcpPacket = function (server, data, rinfo, func) {
38 + if (data == null || data.length < 20) return;
39 + var res = {};
40 + if (((data[12] == 0) || (data[13] != 0) || (data[14] != 1) || (data[15] != 0x57)) && (data[21] & 32)) {
41 + res.servertag = data[9];
42 + res.minorVersion = data[18] & 0x0F;
43 + res.majorVersion = (data[18] >> 4) & 0x0F;
44 + res.provisioningState = data[19] & 0x03; // Pre = 0, In = 1, Post = 2
45 +
46 + var openPort = (data[16] * 256) + data[17];
47 + var dualPorts = ((data[19] & 0x04) != 0) ? true : false;
48 + res.openPorts = [openPort];
49 + res.address = rinfo.address;
50 + if (dualPorts == true) { res.openPorts = [16992, 16993]; }
51 + if (func !== undefined) {
52 + func(server, res);
53 + }
54 + }
55 + }
56 +
57 + this.parseIPv4Range = function (range) {
58 + if (range == undefined || range == null) return null;
59 + var x = range.split('-');
60 + if (x.length == 2) { return { min: this.parseIpv4Addr(x[0]), max: this.parseIpv4Addr(x[1]) }; }
61 + x = range.split('/');
62 + if (x.length == 2) {
63 + var ip = this.parseIpv4Addr(x[0]), masknum = parseInt(x[1]), mask = 0;
64 + if (masknum <= 16 || masknum > 32) return null;
65 + masknum = 32 - masknum;
66 + for (var i = 0; i < masknum; i++) { mask = (mask << 1); mask++; }
67 + return { min: ip & (0xFFFFFFFF - mask), max: (ip & (0xFFFFFFFF - mask)) + mask };
68 + }
69 + x = this.parseIpv4Addr(range);
70 + if (x == null) return null;
71 + return { min: x, max: x };
72 + };
73 +
74 + // Parse IP address. Takes a
75 + this.parseIpv4Addr = function (addr) {
76 + var x = addr.split('.');
77 + if (x.length == 4) { return (parseInt(x[0]) << 24) + (parseInt(x[1]) << 16) + (parseInt(x[2]) << 8) + (parseInt(x[3]) << 0); }
78 + return null;
79 + }
80 +
81 + // IP address number to string
82 + this.IPv4NumToStr = function (num) {
83 + return ((num >> 24) & 0xFF) + '.' + ((num >> 16) & 0xFF) + '.' + ((num >> 8) & 0xFF) + '.' + (num & 0xFF);
84 + }
85 +
86 + this.scan = function (rangestr, timeout) {
87 + var iprange = this.parseIPv4Range(rangestr);
88 + var rmcp = this.buildRmcpPing(0);
89 + var server = this.dgram.createSocket({ type: 'udp4' });
90 + server.parent = this;
91 + server.scanResults = [];
92 + server.on('error', function (err) { console.log('Error:' + err); });
93 + server.on('message', function (msg, rinfo) { if (rinfo.size > 4) { this.parent.parseRmcpPacket(this, msg, rinfo, function (s, res) { s.scanResults.push(res); }) }; });
94 + server.on('listening', function () { for (var i = iprange.min; i <= iprange.max; i++) { server.send(rmcp, 623, server.parent.IPv4NumToStr(i)); } });
95 + server.bind({ address: '0.0.0.0', port: 0, exclusive: true });
96 + var tmout = setTimeout(function cb() {
97 + //console.log("Server closed");
98 + server.close();
99 + server.parent.emit('found', server.scanResults);
100 + delete server;
101 + }, timeout);
102 + };
103 +}
104 +
105 +module.exports = AMTScanner;
agents-new/modules_meshcmd/amt-script.js new
+401
@@ -0,0 +1,401 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +/**
18 +* @fileoverview Script Compiler / Decompiler / Runner
19 +* @author Ylian Saint-Hilaire
20 +* @version v0.1.0e
21 +*/
22 +
23 +// Core functions
24 +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'];
25 +
26 +// functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
27 +script_functionTable2 = ['encodeuri', 'decodeuri', 'passwordcheck', 'atob', 'btoa', 'hex2str', 'str2hex', 'random', 'md5', 'maketoarray', 'readshort', 'readshortx', 'readint', 'readsint', 'readintx', 'shorttostr', 'shorttostrx', 'inttostr', 'inttostrx'];
28 +
29 +// functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
30 +script_functionTableX2 = [encodeURI, decodeURI, passwordcheck, atob, btoa, hex2rstr, rstr2hex, random, rstr_md5, MakeToArray, ReadShort, ReadShortX, ReadInt, ReadSInt, ReadIntX, ShortToStr, ShortToStrX, IntToStr, IntToStrX];
31 +
32 +
33 +function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; }
34 +function ReadShort(v, p) { return (v[p] << 8) + v[p + 1]; }
35 +function ReadShortX(v, p) { return (v[p + 1] << 8) + v[p]; }
36 +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.
37 +function ReadSInt(v, p) { return (v[p] << 24) + (v[p + 1] << 16) + (v[p + 2] << 8) + v[p + 3]; }
38 +function ReadIntX(v, p) { return (v[p + 3] * 0x1000000) + (v[p + 2] << 16) + (v[p + 1] << 8) + v[p]; }
39 +function ShortToStr(v) { return String.fromCharCode((v >> 8) & 0xFF, v & 0xFF); }
40 +function ShortToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF); }
41 +function IntToStr(v) { return String.fromCharCode((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); }
42 +function IntToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF); }
43 +//function ShortToStr(v) { var b = Buffer.alloc(2); b.writeInt16BE(v); return b; }
44 +//function ShortToStrX(v) { var b = Buffer.alloc(2); b.writeInt16LE(v); return b; }
45 +//function IntToStr(v) { var b = Buffer.alloc(4); b.writeInt32BE(v); return b; }
46 +//function IntToStrX(v) { var b = Buffer.alloc(4); b.writeInt32LE(v); return b; }
47 +function btoa(x) { return Buffer.from(x).toString('base64');}
48 +function atob(x) { var z = null; try { z = Buffer.from(x, 'base64').toString(); } catch (e) { console.log(e); } return z; }
49 +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); }
50 +function hex2rstr(x) { Buffer.from(x, 'hex').toString(); }
51 +function rstr2hex(x) { Buffer.from(x).toString('hex'); }
52 +function random() { return Math.floor(Math.random()*max); }
53 +function rstr_md5(str) { return hex2rstr(hex_md5(str)); }
54 +function getItem(x, y, z) { for (var i in x) { if (x[i][y] == z) return x[i]; } return null; }
55 +
56 +var httpErrorTable = {
57 + 200: 'OK',
58 + 401: 'Authentication Error',
59 + 408: 'Timeout Error',
60 + 601: 'WSMAN Parsing Error',
61 + 602: 'Unable to parse HTTP response header',
62 + 603: 'Unexpected HTTP enum response',
63 + 604: 'Unexpected HTTP pull response',
64 + 998: 'Invalid TLS certificate'
65 +}
66 +
67 +// Setup the script state
68 +module.exports.setup = function(binary, startvars) {
69 + var obj = { startvars: startvars, onCompleted: null };
70 + if (binary.length < 6) { console.error('Invalid script length'); return null; } // Script must have at least 6 byte header
71 + if (ReadInt(binary, 0) != 0x247D2945) { console.error('Invalid binary script'); return null; } // Check the script magic header
72 + if (ReadShort(binary, 4) > 1) { console.error('Unsupported script version'); return null; } // Check the script version
73 + obj.script = binary.slice(6);
74 +
75 + // Reset the script to the start
76 + obj.reset = function (stepspeed) {
77 + obj.stop();
78 + obj.ip = 0;
79 + obj.variables = startvars;
80 + obj.state = 1;
81 + }
82 +
83 + // Start the script
84 + obj.start = function (stepspeed) {
85 + obj.stop();
86 + if (stepspeed == null) { obj.stepspeed = 10; } else { obj.stepspeed = stepspeed; }
87 + if (obj.stepspeed > 0) { obj.timer = setInterval(function () { obj.step() }, obj.stepspeed); }
88 + }
89 +
90 + // Stop the script
91 + obj.stop = function () {
92 + if (obj.timer != null) { clearInterval(obj.timer); }
93 + obj.timer = null;
94 + obj.stepspeed = 0;
95 + }
96 +
97 + // function used to load and store variable values
98 + obj.getVar = function (name) { if (name == undefined) return undefined; return obj.getVarEx(name.split('.'), obj.variables); }
99 + 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; } }
100 + obj.setVar = function (name, val) { obj.setVarEx(name.split('.'), obj.variables, val); }
101 + obj.setVarEx = function (name, vars, val) { if (name.length == 1) { vars[name[0]] = val; } else { obj.setVarEx(name.slice(1), vars[name[0]], val); } }
102 +
103 + // Run the script one step forward
104 + obj.step = function () {
105 + if (obj.state != 1) return;
106 + if (obj.ip < obj.script.length) {
107 + var cmdid = ReadShort(obj.script, obj.ip);
108 + var cmdlen = ReadShort(obj.script, obj.ip + 2);
109 + var argcount = ReadShort(obj.script, obj.ip + 4);
110 + var argptr = obj.ip + 6;
111 + var args = [];
112 +
113 + // Clear all temp variables (This is optional)
114 + for (var i in obj.variables) { if (i.startsWith('__')) { delete obj.variables[i]; } }
115 +
116 + // Loop on each argument, moving forward by the argument length each time
117 + for (var i = 0; i < argcount; i++) {
118 + var arglen = ReadShort(obj.script, argptr);
119 + var argval = obj.script.slice(argptr + 2, argptr + 2 + arglen);
120 + var argtyp = argval[0];
121 + argval = argval.slice(1);
122 + if (argtyp < 2) {
123 + // Get the value and replace all {var} with variable values
124 + argval = argval.toString();
125 + while (argval.split("{").length > 1) { var t = argval.split("{").pop().split("}").shift(); argval = argval.replace('{' + t + '}', obj.getVar(t)); }
126 + if (argtyp == 1) { obj.variables['__' + i] = decodeURI(argval); argval = '__' + i; } // If argtyp is 1, this is a literal. Store in temp variable.
127 + args.push(argval);
128 + }
129 + if (argtyp == 2 || argtyp == 3) {
130 + obj.variables['__' + i] = ReadSInt(argval, 0);
131 + args.push('__' + i);
132 + }
133 + argptr += (2 + arglen);
134 + }
135 +
136 + // Move instruction pointer forward by command size
137 + obj.ip += cmdlen;
138 +
139 + // Get all variable values
140 + var argsval = [];
141 + for (var i = 0; i < 10; i++) { argsval.push(obj.getVar(args[i])); }
142 + var storeInArg0;
143 + try {
144 + if (cmdid < 10000) {
145 + // Lets run the actual command
146 + switch (cmdid) {
147 + case 0: // nop
148 + break;
149 + case 1: // jump(label) or jump(label, a, compare, b)
150 + if (argsval[2]) {
151 + if (
152 + (argsval[2] == '<' && argsval[1] < argsval[3]) ||
153 + (argsval[2] == '<=' && argsval[1] <= argsval[3]) ||
154 + (argsval[2] == '!=' && argsval[1] != argsval[3]) ||
155 + (argsval[2] == '=' && argsval[1] == argsval[3]) ||
156 + (argsval[2] == '>=' && argsval[1] >= argsval[3]) ||
157 + (argsval[2] == '>' && argsval[1] > argsval[3])
158 + ) {
159 + obj.ip = argsval[0];
160 + }
161 + } else {
162 + obj.ip = argsval[0]; // Set the instruction pointer to the new location in the script
163 + }
164 + break;
165 + case 2: // set(variable, value)
166 + if (args[1] == undefined) delete obj.variables[args[0]]; else obj.setVar(args[0], argsval[1]);
167 + break;
168 + case 3: // print(message)
169 + var v = obj.toString(argsval[0]);
170 + if (v.indexOf('INFO: ') == 0) { v = v.substring(6); }
171 + if (v.indexOf('SUCCESS: ') == 0) { v = v.substring(9); }
172 + if (obj.onConsole) { obj.onConsole(v, obj); } else { console.log(v); }
173 + // Q(obj.consoleid).value += () + '\n'); Q(obj.console).scrollTop = Q(obj.console).scrollHeight;
174 + break;
175 + case 4: // dialog(title, content, buttons)
176 + obj.state = 2;
177 + obj.dialog = true;
178 + setDialogMode(11, argsval[0], argsval[2], obj.xxStepDialogOk, argsval[1], obj);
179 + break;
180 + case 5: // getitem(a, b, c)
181 + for (var i in argsval[1]) { if (argsval[1][i][argsval[2]] == argsval[3]) { storeInArg0 = i; } };
182 + break;
183 + case 6: // substr(variable_dest, variable_src, index, len)
184 + storeInArg0 = argsval[1].substr(argsval[2], argsval[3]);
185 + break;
186 + case 7: // indexOf(variable_dest, variable_src, index, len)
187 + storeInArg0 = argsval[1].indexOf(argsval[2]);
188 + break;
189 + case 8: // split(variable_dest, variable_src, separator)
190 + storeInArg0 = argsval[1].split(argsval[2]);
191 + break;
192 + case 9: // join(variable_dest, variable_src, separator)
193 + storeInArg0 = argsval[1].join(argsval[2]);
194 + break;
195 + case 10: // length(variable_dest, variable_src)
196 + if (argsval[1] == null) { storeInArg0 = 0; } else { storeInArg0 = argsval[1].length; }
197 + break;
198 + case 11: // jsonparse(variable_dest, json)
199 + storeInArg0 = JSON.parse(argsval[1]);
200 + break;
201 + case 12: // jsonstr(variable_dest, variable_src)
202 + storeInArg0 = JSON.stringify(argsval[1]);
203 + break;
204 + case 13: // add(variable_dest, variable_src, value)
205 + storeInArg0 = (argsval[1] + argsval[2]);
206 + break;
207 + case 14: // substract(variable_dest, variable_src, value)
208 + storeInArg0 = (argsval[1] - argsval[2]);
209 + break;
210 + case 15: // parseInt(variable_dest, variable_src)
211 + storeInArg0 = parseInt(argsval[1]);
212 + break;
213 + case 16: // wsbatchenum(name, objectList)
214 + obj.state = 2;
215 + obj.amtstack.BatchEnum(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
216 + break;
217 + case 17: // wsput(name, args)
218 + obj.state = 2;
219 + obj.amtstack.Put(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
220 + break;
221 + case 18: // wscreate(name, args)
222 + obj.state = 2;
223 + obj.amtstack.Create(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
224 + break;
225 + case 19: // wsdelete(name, args)
226 + obj.state = 2;
227 + obj.amtstack.Delete(argsval[0], argsval[1], obj.xxWsmanReturn, obj);
228 + break;
229 + case 20: // wsexec(name, method, args, selectors)
230 + obj.state = 2;
231 + obj.amtstack.Exec(argsval[0], argsval[1], argsval[2], obj.xxWsmanReturn, obj, 0, argsval[3]);
232 + break;
233 + case 21: // Script Speed
234 + obj.stepspeed = argsval[0];
235 + if (obj.timer != null) { clearInterval(obj.timer); obj.timer = setInterval(function () { obj.step() }, obj.stepspeed); }
236 + break;
237 + case 22: // wssubscribe(name, delivery, url, selectors, opaque, user, pass)
238 + obj.state = 2;
239 + obj.amtstack.Subscribe(argsval[0], argsval[1], argsval[2], obj.xxWsmanReturn, obj, 0, argsval[3], argsval[4], argsval[5], argsval[6]);
240 + break;
241 + case 23: // wsunsubscribe(name, selectors)
242 + obj.state = 2;
243 + obj.amtstack.UnSubscribe(argsval[0], obj.xxWsmanReturn, obj, 0, argsval[1]);
244 + break;
245 + case 24: // readchar(str, pos)
246 + console.log(argsval[1], argsval[2], argsval[1].charCodeAt(argsval[2]));
247 + storeInArg0 = argsval[1].charCodeAt(argsval[2]);
248 + break;
249 + case 25: // signWithDummyCa
250 + // Not supported
251 + break;
252 + default: {
253 + obj.state = 9;
254 + console.error("Script Error, unknown command: " + cmdid);
255 + }
256 + }
257 + } else {
258 + if (cmdid < 20000) {
259 + // functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
260 + storeInArg0 = script_functionTableX2[cmdid - 10000](argsval[1], argsval[2], argsval[3], argsval[4], argsval[5], argsval[6]);
261 + } else {
262 + // Optional functions of type ARG1 = func(ARG2, ARG3, ARG4, ARG5, ARG6)
263 + //if (script_functionTableX3 && script_functionTableX3[cmdid - 20000]) {
264 + // 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.
265 + //}
266 + }
267 + }
268 + if (storeInArg0 != undefined) obj.setVar(args[0], storeInArg0);
269 + } catch (e) {
270 + if (typeof e == 'object') { e = e.message; }
271 + obj.setVar('_exception', e);
272 + }
273 + }
274 +
275 + if (obj.state == 1 && obj.ip >= obj.script.length) { obj.state = 0; obj.stop(); if (obj.onCompleted) { obj.onCompleted(); } }
276 + if (obj.onStep) obj.onStep(obj);
277 + return obj;
278 + }
279 +
280 + obj.xxStepDialogOk = function (button) {
281 + obj.variables['DialogSelect'] = button;
282 + obj.state = 1;
283 + obj.dialog = false;
284 + if (obj.onStep) obj.onStep(obj);
285 + }
286 +
287 + obj.xxWsmanReturn = function (stack, name, responses, status) {
288 + obj.setVar(name, responses);
289 + obj.setVar('wsman_result', status);
290 + obj.setVar('wsman_result_str', ((httpErrorTable[status]) ? (httpErrorTable[status]) : ('Error #' + status)));
291 + obj.state = 1;
292 + if (obj.onStep) obj.onStep(obj);
293 + }
294 +
295 + obj.toString = function (x) { if (typeof x == 'object') return JSON.stringify(x); return x; }
296 +
297 + obj.reset();
298 + return obj;
299 +}
300 +
301 +// Argument types: 0 = Variable, 1 = String, 2 = Integer, 3 = Label
302 +module.exports.compile = function(script, onmsg) {
303 + var r = '', scriptlines = script.split('\n'), labels = {}, labelswap = [], swaps = [];
304 + // Go thru each script line and encode it
305 + for (var i in scriptlines) {
306 + var scriptline = scriptlines[i];
307 + if (scriptline.startsWith('##SWAP ')) { var x = scriptline.split(' '); if (x.length == 3) { swaps[x[1]] = x[2]; } } // Add a swap instance
308 + if (scriptline[0] == '#' || scriptline.length == 0) continue; // Skip comments & blank lines
309 + for (var x in swaps) { scriptline = scriptline.split(x).join(swaps[x]); } // Apply all swaps
310 + var keywords = scriptline.match(/"[^"]*"|[^\s"]+/g);
311 + if (keywords.length == 0) continue; // Skip blank lines
312 + if (scriptline[0] == ':') { labels[keywords[0].toUpperCase()] = r.length; continue; } // Mark a label position
313 + var funcIndex = script_functionTable1.indexOf(keywords[0].toLowerCase());
314 + if (funcIndex == -1) { funcIndex = script_functionTable2.indexOf(keywords[0].toLowerCase()); if (funcIndex >= 0) funcIndex += 10000; }
315 + if (funcIndex == -1) { if (onmsg) { onmsg("Unabled to compile, unknown command: " + keywords[0]); } return ''; }
316 + // Encode CommandId, CmdSize, ArgCount, Arg1Len, Arg1, Arg2Len, Arg2...
317 + var cmd = ShortToStr(keywords.length - 1);
318 + for (var j in keywords) {
319 + if (j == 0) continue;
320 + if (keywords[j][0] == ':') {
321 + labelswap.push([keywords[j], r.length + cmd.length + 7]); // Add a label swap
322 + cmd += ShortToStr(5) + String.fromCharCode(3) + IntToStr(0xFFFFFFFF); // Put an empty label
323 + } else {
324 + var argint = parseInt(keywords[j]);
325 + if (argint == keywords[j]) {
326 + cmd += ShortToStr(5) + String.fromCharCode(2) + IntToStr(argint);
327 + } else {
328 + if (keywords[j][0] == '"' && keywords[j][keywords[j].length - 1] == '"') {
329 + cmd += ShortToStr(keywords[j].length - 1) + String.fromCharCode(1) + keywords[j].substring(1, keywords[j].length - 1);
330 + } else {
331 + cmd += ShortToStr(keywords[j].length + 1) + String.fromCharCode(0) + keywords[j];
332 + }
333 + }
334 + }
335 + }
336 + cmd = ShortToStr(funcIndex) + ShortToStr(cmd.length + 4) + cmd;
337 + r += cmd;
338 + }
339 + // Perform all the needed label swaps
340 + for (i in labelswap) {
341 + var label = labelswap[i][0].toUpperCase(), position = labelswap[i][1], target = labels[label];
342 + if (target == undefined) { if (onmsg) { onmsg("Unabled to compile, unknown label: " + label); } return ''; }
343 + r = r.substr(0, position) + IntToStr(target) + r.substr(position + 4);
344 + }
345 + return IntToStr(0x247D2945) + ShortToStr(1) + r;
346 +}
347 +
348 +// Decompile the script, intended for debugging only
349 +module.exports.decompile = function(binary, onecmd) {
350 + var r = '', ptr = 6, labelcount = 0, labels = {};
351 + if (onecmd >= 0) {
352 + ptr = onecmd; // If we are decompiling just one command, set the ptr to that command.
353 + } else {
354 + if (binary.length < 6) { return '# Invalid script length'; }
355 + var magic = ReadInt(binary, 0);
356 + var version = ReadShort(binary, 4);
357 + if (magic != 0x247D2945) { return '# Invalid binary script: ' + magic; }
358 + if (version != 1) { return '# Invalid script version'; }
359 + }
360 + // Loop on each command, moving forward by the command length each time.
361 + while (ptr < binary.length) {
362 + var cmdid = ReadShort(binary, ptr);
363 + var cmdlen = ReadShort(binary, ptr + 2);
364 + var argcount = ReadShort(binary, ptr + 4);
365 + var argptr = ptr + 6;
366 + var argstr = '';
367 + if (!(onecmd >= 0)) r += ":label" + (ptr - 6) + "\n";
368 + // Loop on each argument, moving forward by the argument length each time
369 + for (var i = 0; i < argcount; i++) {
370 + var arglen = ReadShort(binary, argptr);
371 + var argval = binary.substring(argptr + 2, argptr + 2 + arglen);
372 + var argtyp = argval.charCodeAt(0);
373 + if (argtyp == 0) { argstr += ' ' + argval.substring(1); } // Variable
374 + else if (argtyp == 1) { argstr += ' \"' + argval.substring(1) + '\"'; } // String
375 + else if (argtyp == 2) { argstr += ' ' + ReadInt(argval, 1); } // Integer
376 + else if (argtyp == 3) { // Label
377 + var target = ReadInt(argval, 1);
378 + var label = labels[target];
379 + if (!label) { label = ":label" + target; labels[label] = target; }
380 + argstr += ' ' + label;
381 + }
382 + argptr += (2 + arglen);
383 + }
384 + // Go in the script function table to decode the function
385 + if (cmdid < 10000) {
386 + r += script_functionTable1[cmdid] + argstr + "\n";
387 + } else {
388 + if ((cmdid >= 10000) && (cmdid < 10000)) { r += script_functionTable2[cmdid - 10000] + argstr + "\n"; }
389 + }
390 + ptr += cmdlen;
391 + if (onecmd >= 0) return r; // If we are decompiling just one command, exit now
392 + }
393 + // Remove all unused labels
394 + var scriptlines = r.split('\n');
395 + r = '';
396 + for (var i in scriptlines) {
397 + var line = scriptlines[i];
398 + if (line[0] != ':') { r += line + '\n'; } else { if (labels[line]) { r += line + '\n'; } }
399 + }
400 + return r;
401 +}
agents-new/modules_meshcmd/amt-wsman-duk.js new
+144
@@ -0,0 +1,144 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +/**
18 +* @description WSMAN communication using duktape http
19 +* @author Ylian Saint-Hilaire
20 +* @version v0.2.0c
21 +*/
22 +
23 +// Construct a WSMAN communication object
24 +function CreateWsmanComm(/*host, port, user, pass, tls, extra*/)
25 +{
26 + var obj = {};
27 + obj.PendingAjax = []; // List of pending AJAX calls. When one frees up, another will start.
28 + obj.ActiveAjaxCount = 0; // Number of currently active AJAX calls
29 + obj.MaxActiveAjaxCount = 1; // Maximum number of activate AJAX calls at the same time.
30 + obj.FailAllError = 0; // Set this to non-zero to fail all AJAX calls with that error status, 999 causes responses to be silent.
31 + obj.digest = null;
32 + obj.RequestCount = 0;
33 +
34 + if (arguments.length == 1 && typeof(arguments[0] == 'object'))
35 + {
36 + obj.host = arguments[0].host;
37 + obj.port = arguments[0].port;
38 + obj.authToken = arguments[0].authToken;
39 + obj.tls = arguments[0].tls;
40 + }
41 + else
42 + {
43 + obj.host = arguments[0];
44 + obj.port = arguments[1];
45 + obj.user = arguments[2];
46 + obj.pass = arguments[3];
47 + obj.tls = arguments[4];
48 + }
49 +
50 +
51 + // Private method
52 + // pri = priority, if set to 1, the call is high priority and put on top of the stack.
53 + obj.PerformAjax = function (postdata, callback, tag, pri, url, action) {
54 + if ((obj.ActiveAjaxCount == 0 || ((obj.ActiveAjaxCount < obj.MaxActiveAjaxCount) && (obj.challengeParams != null))) && obj.PendingAjax.length == 0) {
55 + // There are no pending AJAX calls, perform the call now.
56 + obj.PerformAjaxEx(postdata, callback, tag, url, action);
57 + } else {
58 + // If this is a high priority call, put this call in front of the array, otherwise put it in the back.
59 + if (pri == 1) { obj.PendingAjax.unshift([postdata, callback, tag, url, action]); } else { obj.PendingAjax.push([postdata, callback, tag, url, action]); }
60 + }
61 + }
62 +
63 + // Private method
64 + obj.PerformNextAjax = function () {
65 + if (obj.ActiveAjaxCount >= obj.MaxActiveAjaxCount || obj.PendingAjax.length == 0) return;
66 + var x = obj.PendingAjax.shift();
67 + obj.PerformAjaxEx(x[0], x[1], x[2], x[3], x[4]);
68 + obj.PerformNextAjax();
69 + }
70 +
71 + // Private method
72 + obj.PerformAjaxEx = function (postdata, callback, tag, url, action) {
73 + if (obj.FailAllError != 0) { if (obj.FailAllError != 999) { obj.gotNextMessagesError({ status: obj.FailAllError }, 'error', null, [postdata, callback, tag]); } return; }
74 + if (!postdata) postdata = "";
75 + //console.log("SEND: " + postdata); // DEBUG
76 +
77 + // We are in a DukTape environement
78 + if (obj.digest == null)
79 + {
80 + if (obj.authToken)
81 + {
82 + obj.digest = require('http-digest').create({ authToken: obj.authToken });
83 + }
84 + else
85 + {
86 + obj.digest = require('http-digest').create(obj.user, obj.pass);
87 + }
88 + obj.digest.http = require('http');
89 + }
90 + 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)); } };
91 + var req = obj.digest.request(request);
92 + //console.log('Request ' + (obj.RequestCount++));
93 + req.on('error', function (e) { obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); });
94 + req.on('response', function (response) {
95 + //console.log('Response: ' + response.statusCode);
96 + if (response.statusCode != 200) {
97 + //console.log('ERR:' + JSON.stringify(response));
98 + obj.gotNextMessagesError({ status: response.statusCode }, 'error', null, [postdata, callback, tag]);
99 + } else {
100 + response.acc = '';
101 + response.on('data', function (data2) { this.acc += data2; });
102 + response.on('end', function () { obj.gotNextMessages(response.acc, 'success', { status: response.statusCode }, [postdata, callback, tag]); });
103 + }
104 + });
105 +
106 + // Send POST body, this work with binary.
107 + req.end(postdata);
108 + obj.ActiveAjaxCount++;
109 + return req;
110 + }
111 +
112 + // AJAX specific private method
113 + obj.pendingAjaxCall = [];
114 +
115 + // Private method
116 + obj.gotNextMessages = function (data, status, request, callArgs) {
117 + obj.ActiveAjaxCount--;
118 + if (obj.FailAllError == 999) return;
119 + //console.log("RECV: " + data); // DEBUG
120 + if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
121 + if (request.status != 200) { callArgs[1](null, request.status, callArgs[2]); return; }
122 + callArgs[1](data, 200, callArgs[2]);
123 + obj.PerformNextAjax();
124 + }
125 +
126 + // Private method
127 + obj.gotNextMessagesError = function (request, status, errorThrown, callArgs) {
128 + obj.ActiveAjaxCount--;
129 + if (obj.FailAllError == 999) return;
130 + if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
131 + //if (status != 200) { console.log("ERROR, status=" + status + "\r\n\r\nreq=" + callArgs[0]); } // Debug: Display the request & response if something did not work.
132 + if (obj.FailAllError != 999) { callArgs[1]({ Header: { HttpError: request.status } }, request.status, callArgs[2]); }
133 + obj.PerformNextAjax();
134 + }
135 +
136 + // Cancel all pending queries with given status
137 + obj.CancelAllQueries = function (s) {
138 + while (obj.PendingAjax.length > 0) { var x = obj.PendingAjax.shift(); x[1](null, s, x[2]); }
139 + }
140 +
141 + return obj;
142 +}
143 +
144 +module.exports = CreateWsmanComm;
agents-new/modules_meshcmd/amt-wsman.js new
+211
@@ -0,0 +1,211 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +/**
18 +* @description Intel(r) AMT WSMAN Stack
19 +* @author Ylian Saint-Hilaire
20 +* @version v0.2.0
21 +*/
22 +
23 +// Construct a MeshServer object
24 +function WsmanStackCreateService(/*CreateWsmanComm, host, port, user, pass, tls, extra*/)
25 +{
26 + var obj = {_ObjectID: 'WSMAN'};
27 + //obj.onDebugMessage = null; // Set to a function if you want to get debug messages.
28 + obj.NextMessageId = 1; // Next message number, used to label WSMAN calls.
29 + obj.Address = '/wsman';
30 + obj.xmlParser = require('amt-xml');
31 +
32 + if (arguments.length == 1 && typeof (arguments[0] == 'object'))
33 + {
34 + var CreateWsmanComm = arguments[0].transport;
35 + if (CreateWsmanComm) { obj.comm = new CreateWsmanComm(arguments[0]); }
36 + }
37 + else
38 + {
39 + var CreateWsmanComm = arguments[0];
40 + if (CreateWsmanComm) { obj.comm = new CreateWsmanComm(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]); }
41 + }
42 +
43 + obj.PerformAjax = function PerformAjax(postdata, callback, tag, pri, namespaces) {
44 + if (namespaces == null) namespaces = '';
45 + obj.comm.PerformAjax('<?xml version=\"1.0\" encoding=\"utf-8\"?><Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns=\"http://www.w3.org/2003/05/soap-envelope\" ' + namespaces + '><Header><a:Action>' + postdata, function (data, status, tag) {
46 + if (status != 200) { callback(obj, null, { Header: { HttpError: status } }, status, tag); return; }
47 + var wsresponse = obj.xmlParser.ParseWsman(data);
48 + if (!wsresponse || wsresponse == null) { callback(obj, null, { Header: { HttpError: status } }, 601, tag); } else { callback(obj, wsresponse.Header["ResourceURI"], wsresponse, 200, tag); }
49 + }, tag, pri);
50 + }
51 +
52 + // Private method
53 + //obj.Debug = function (msg) { /*console.log(msg);*/ }
54 +
55 + // Cancel all pending queries with given status
56 + obj.CancelAllQueries = function CancelAllQueries(s) { obj.comm.CancelAllQueries(s); }
57 +
58 + // Get the last element of a URI string
59 + obj.GetNameFromUrl = function (resuri) {
60 + var x = resuri.lastIndexOf("/");
61 + return (x == -1)?resuri:resuri.substring(x + 1);
62 + }
63 +
64 + // Perform a WSMAN Subscribe operation
65 + obj.ExecSubscribe = function ExecSubscribe(resuri, delivery, url, callback, tag, pri, selectors, opaque, user, pass) {
66 + var digest = "", digest2 = "", opaque = "";
67 + if (user != null && pass != null) { digest = '<t:IssuedTokens xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:se="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><t:RequestSecurityTokenResponse><t:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</t:TokenType><t:RequestedSecurityToken><se:UsernameToken><se:Username>' + user + '</se:Username><se:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText">' + pass + '</se:Password></se:UsernameToken></t:RequestedSecurityToken></t:RequestSecurityTokenResponse></t:IssuedTokens>'; digest2 = '<w:Auth Profile="http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/http/digest"/>'; }
68 + if (opaque != null) { opaque = '<a:ReferenceParameters><m:arg>' + opaque + '</m:arg></a:ReferenceParameters>'; }
69 + if (delivery == 'PushWithAck') { delivery = 'dmtf.org/wbem/wsman/1/wsman/PushWithAck'; } else if (delivery == 'Push') { delivery = 'xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push'; }
70 + var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + digest + '</Header><Body><e:Subscribe><e:Delivery Mode="http://schemas.' + delivery + '"><e:NotifyTo><a:Address>' + url + '</a:Address>' + opaque + '</e:NotifyTo>' + digest2 + '</e:Delivery></e:Subscribe>';
71 + obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:m="http://x.com"');
72 + }
73 +
74 + // Perform a WSMAN UnSubscribe operation
75 + obj.ExecUnSubscribe = function ExecUnSubscribe(resuri, callback, tag, pri, selectors) {
76 + var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + '</Header><Body><e:Unsubscribe/>';
77 + obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"');
78 + }
79 +
80 + // Perform a WSMAN PUT operation
81 + obj.ExecPut = function ExecPut(resuri, putobj, callback, tag, pri, selectors) {
82 + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Put</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + '</Header><Body>' + _PutObjToBodyXml(resuri, putobj);
83 + obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri);
84 + }
85 +
86 + // Perform a WSMAN CREATE operation
87 + obj.ExecCreate = function ExecCreate(resuri, putobj, callback, tag, pri, selectors) {
88 + var objname = obj.GetNameFromUrl(resuri);
89 + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><g:" + objname + " xmlns:g=\"" + resuri + "\">";
90 + for (var n in putobj) { data += "<g:" + n + ">" + putobj[n] + "</g:" + n + ">" }
91 + obj.PerformAjax(data + "</g:" + objname + "></Body></Envelope>", callback, tag, pri);
92 + }
93 +
94 + // Perform a WSMAN DELETE operation
95 + obj.ExecDelete = function ExecDelete(resuri, putobj, callback, tag, pri) {
96 + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(putobj) + "</Header><Body /></Envelope>";
97 + obj.PerformAjax(data, callback, tag, pri);
98 + }
99 +
100 + // Perform a WSMAN GET operation
101 + obj.ExecGet = function ExecGet(resuri, callback, tag, pri) {
102 + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body /></Envelope>", callback, tag, pri);
103 + }
104 +
105 + // Perform a WSMAN method call operation
106 + obj.ExecMethod = function ExecMethod(resuri, method, args, callback, tag, pri, selectors) {
107 + var argsxml = "";
108 + for (var i in args) { if (args[i] != null) { if (Array.isArray(args[i])) { for (var x in args[i]) { argsxml += "<r:" + i + ">" + args[i][x] + "</r:" + i + ">"; } } else { argsxml += "<r:" + i + ">" + args[i] + "</r:" + i + ">"; } } }
109 + obj.ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors);
110 + }
111 +
112 + // Perform a WSMAN method call operation. The arguments are already formatted in XML.
113 + obj.ExecMethodXml = function ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors) {
114 + obj.PerformAjax(resuri + "/" + method + "</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><r:" + method + '_INPUT' + " xmlns:r=\"" + resuri + "\">" + argsxml + "</r:" + method + "_INPUT></Body></Envelope>", callback, tag, pri);
115 + }
116 +
117 + // Perform a WSMAN ENUM operation
118 + obj.ExecEnum = function ExecEnum(resuri, callback, tag, pri) {
119 + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Enumerate xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\" /></Body></Envelope>", callback, tag, pri);
120 + }
121 +
122 + // Perform a WSMAN PULL operation
123 + obj.ExecPull = function ExecPull(resuri, enumctx, callback, tag, pri) {
124 + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\"><EnumerationContext>" + enumctx + "</EnumerationContext><MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters></Pull></Body></Envelope>", callback, tag, pri);
125 + }
126 +
127 + function _PutObjToBodyXml(resuri, putObj) {
128 + if (!resuri || putObj == null) return '';
129 + var objname = obj.GetNameFromUrl(resuri);
130 + var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';
131 +
132 + for (var prop in putObj) {
133 + if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue;
134 + if (putObj[prop] == null || typeof putObj[prop] === 'function') continue;
135 + if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) {
136 + result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>';
137 + var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector'];
138 + if (Array.isArray(selectorArray)) {
139 + for (var i=0; i< selectorArray.length; i++) {
140 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
141 + }
142 + }
143 + else {
144 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
145 + }
146 + result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>';
147 + }
148 + else {
149 + if (Array.isArray(putObj[prop])) {
150 + for (var i = 0; i < putObj[prop].length; i++) {
151 + result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>';
152 + }
153 + } else {
154 + result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>';
155 + }
156 + }
157 + }
158 +
159 + result += '</r:' + objname + '>';
160 + return result;
161 + }
162 +
163 + /*
164 + convert
165 + { @Name: 'InstanceID', @AttrName: 'Attribute Value'}
166 + into
167 + ' Name="InstanceID" AttrName="Attribute Value" '
168 + */
169 + function _ObjectToXmlAttributes(objWithAttributes) {
170 + if(!objWithAttributes) return '';
171 + var result = ' ';
172 + for (var propName in objWithAttributes) {
173 + if (!objWithAttributes.hasOwnProperty(propName) || propName.indexOf('@') !== 0) continue;
174 + result += propName.substring(1) + '="' + objWithAttributes[propName] + '" ';
175 + }
176 + return result;
177 + }
178 +
179 + function _PutObjToSelectorsXml(selectorSet) {
180 + if (!selectorSet) return '';
181 + if (typeof selectorSet == 'string') return selectorSet;
182 + if (selectorSet['InstanceID']) return "<w:SelectorSet><w:Selector Name=\"InstanceID\">" + selectorSet['InstanceID'] + "</w:Selector></w:SelectorSet>";
183 + var result = '<w:SelectorSet>';
184 + for(var propName in selectorSet) {
185 + if (!selectorSet.hasOwnProperty(propName)) continue;
186 + result += '<w:Selector Name="' + propName + '">';
187 + if (selectorSet[propName]['ReferenceParameters']) {
188 + result += '<a:EndpointReference>';
189 + result += '<a:Address>' + selectorSet[propName]['Address'] + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + selectorSet[propName]['ReferenceParameters']['ResourceURI'] + '</w:ResourceURI><w:SelectorSet>';
190 + var selectorArray = selectorSet[propName]['ReferenceParameters']['SelectorSet']['Selector'];
191 + if (Array.isArray(selectorArray)) {
192 + for (var i = 0; i < selectorArray.length; i++) {
193 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
194 + }
195 + } else {
196 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
197 + }
198 + result += '</w:SelectorSet></a:ReferenceParameters></a:EndpointReference>';
199 + } else {
200 + result += selectorSet[propName];
201 + }
202 + result += '</w:Selector>';
203 + }
204 + result += '</w:SelectorSet>';
205 + return result;
206 + }
207 +
208 + return obj;
209 +}
210 +
211 +module.exports = WsmanStackCreateService;
agents-new/modules_meshcmd/amt-xml.js new
+185
@@ -0,0 +1,185 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { }
18 +
19 +
20 +// Parse XML and return JSON
21 +module.exports.ParseWsman = function (xml) {
22 + try {
23 + if (!xml.childNodes) xml = _turnToXml(xml);
24 + var r = { Header: {} }, header = xml.getElementsByTagName("Header")[0], t;
25 + if (!header) header = xml.getElementsByTagName("a:Header")[0];
26 + if (!header) return null;
27 + for (var i = 0; i < header.childNodes.length; i++) {
28 + var child = header.childNodes[i];
29 + r.Header[child.localName] = child.textContent;
30 + }
31 + var body = xml.getElementsByTagName("Body")[0];
32 + if (!body) body = xml.getElementsByTagName("a:Body")[0];
33 + if (!body) return null;
34 + if (body.childNodes.length > 0) {
35 + t = body.childNodes[0].localName;
36 + if (t.indexOf("_OUTPUT") == t.length - 7) { t = t.substring(0, t.length - 7); }
37 + r.Header['Method'] = t;
38 + r.Body = _ParseWsmanRec(body.childNodes[0]);
39 + }
40 + return r;
41 + } catch (e) {
42 + console.error("Unable to parse XML: " + xml, e);
43 + return null;
44 + }
45 +}
46 +
47 +// Private method
48 +function _ParseWsmanRec(node) {
49 + var data, r = {};
50 + for (var i = 0; i < node.childNodes.length; i++) {
51 + var child = node.childNodes[i];
52 + if ((child.childElementCount == null) || (child.childElementCount == 0)) { data = child.textContent; } else { data = _ParseWsmanRec(child); }
53 + if (data == 'true') data = true; // Convert 'true' into true
54 + if (data == 'false') data = false; // Convert 'false' into false
55 + if ((parseInt(data) + '') === data) data = parseInt(data); // Convert integers
56 +
57 + var childObj = data;
58 + if ((child.attributes != null) && (child.attributes.length > 0)) {
59 + childObj = { 'Value': data };
60 + for (var j = 0; j < child.attributes.length; j++) {
61 + childObj['@' + child.attributes[j].name] = child.attributes[j].value;
62 + }
63 + }
64 +
65 + if (r[child.localName] instanceof Array) { r[child.localName].push(childObj); }
66 + else if (r[child.localName] == null) { r[child.localName] = childObj; }
67 + else { r[child.localName] = [r[child.localName], childObj]; }
68 + }
69 + return r;
70 +}
71 +
72 +function _PutObjToBodyXml(resuri, putObj) {
73 + if (!resuri || putObj == null) return '';
74 + var objname = obj.GetNameFromUrl(resuri);
75 + var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';
76 +
77 + for (var prop in putObj) {
78 + if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue;
79 + if (putObj[prop] == null || typeof putObj[prop] === 'function') continue;
80 + if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) {
81 + result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>';
82 + var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector'];
83 + if (Array.isArray(selectorArray)) {
84 + for (var i = 0; i < selectorArray.length; i++) {
85 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
86 + }
87 + }
88 + else {
89 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
90 + }
91 + result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>';
92 + }
93 + else {
94 + if (Array.isArray(putObj[prop])) {
95 + for (var i = 0; i < putObj[prop].length; i++) {
96 + result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>';
97 + }
98 + } else {
99 + result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>';
100 + }
101 + }
102 + }
103 +
104 + result += '</r:' + objname + '>';
105 + return result;
106 +}
107 +
108 +// This is a drop-in replacement to _turnToXml() that works without xml parser dependency.
109 +function _treeBuilder() {
110 + this.tree = [];
111 + this.push = function (element) { this.tree.push(element); };
112 + 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); };
113 + this.peek = function () { return (this.tree.peek()); }
114 + 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; } } } } }
115 + 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; }
116 +}
117 +function _turnToXml(text) { if (text == null) return null; return ({ childNodes: [_turnToXmlRec(text)], getElementsByTagName: _getElementsByTagName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS }); }
118 +function _getElementsByTagNameNS(ns, name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name && (node.namespace == ns || ns == '*')) { ret.push(node); } }); return ret; }
119 +function _getElementsByTagName(name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name) { ret.push(node); } }); return ret; }
120 +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); }
121 +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); }
122 +function _xmlTraverseAllRec(nodes, func) { for (var i in nodes) { func(nodes[i]); if (nodes[i].childNodes) { _xmlTraverseAllRec(nodes[i].childNodes, func); } } }
123 +function _turnToXmlRec(text) {
124 + var elementStack = new _treeBuilder(), lastElement = null, x1 = text.split('<'), ret = [], element = null, currentElementName = null;
125 + for (var i in x1) {
126 + var x2 = x1[i].split('>'), x3 = x2[0].split(' '), elementName = x3[0];
127 + if ((elementName.length > 0) && (elementName[0] != '?')) {
128 + if (elementName[0] != '/') {
129 + var attributes = [], localName, localname2 = elementName.split(' ')[0].split(':'), localName = (localname2.length > 1) ? localname2[1] : localname2[0];
130 + Object.defineProperty(attributes, "get",
131 + {
132 + value: function () {
133 + if (arguments.length == 1) {
134 + for (var a in this) { if (this[a].name == arguments[0]) { return (this[a]); } }
135 + }
136 + else if (arguments.length == 2) {
137 + for (var a in this) { if (this[a].name == arguments[1] && (arguments[0] == '*' || this[a].namespace == arguments[0])) { return (this[a]); } }
138 + }
139 + else {
140 + throw ('attributes.get(): Invalid number of parameters');
141 + }
142 + }
143 + });
144 + elementStack.push({ name: elementName, localName: localName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS, getChildElementsByTagNameNS: _getChildElementsByTagNameNS, attributes: attributes, childNodes: [], nsTable: {} });
145 + // Parse Attributes
146 + if (x3.length > 0) {
147 + var skip = false;
148 + for (var j in x3) {
149 + if (x3[j] == '/') {
150 + // This is an empty Element
151 + elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
152 + elementStack.peek().textContent = '';
153 + lastElement = elementStack.pop();
154 + skip = true;
155 + break;
156 + }
157 + var k = x3[j].indexOf('=');
158 + if (k > 0) {
159 + var attrName = x3[j].substring(0, k);
160 + var attrValue = x3[j].substring(k + 2, x3[j].length - 1);
161 + var attrNS = elementStack.getNamespace('*');
162 +
163 + if (attrName == 'xmlns') {
164 + elementStack.addNamespace('*', attrValue);
165 + attrNS = attrValue;
166 + } else if (attrName.startsWith('xmlns:')) {
167 + elementStack.addNamespace(attrName.substring(6), attrValue);
168 + } else {
169 + var ax = attrName.split(':');
170 + if (ax.length == 2) { attrName = ax[1]; attrNS = elementStack.getNamespace(ax[0]); }
171 + }
172 + var x = { name: attrName, value: attrValue }
173 + if (attrNS != null) x.namespace = attrNS;
174 + elementStack.peek().attributes.push(x);
175 + }
176 + }
177 + if (skip) { continue; }
178 + }
179 + elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
180 + if (x2[1]) { elementStack.peek().textContent = x2[1]; }
181 + } else { lastElement = elementStack.pop(); }
182 + }
183 + }
184 + return lastElement;
185 +}
agents-new/modules_meshcmd/amt.js new
+1017
@@ -0,0 +1,1017 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +/**
18 +* @fileoverview Intel(r) AMT Communication StackXX
19 +* @author Ylian Saint-Hilaire
20 +* @version v0.2.0b
21 +*/
22 +
23 +/**
24 + * Construct a AmtStackCreateService object, this ia the main Intel AMT communication stack.
25 + * @constructor
26 + */
27 +function AmtStackCreateService(wsmanStack) {
28 + var obj = new Object();
29 + obj._ObjectID = 'AMT'
30 + obj.wsman = wsmanStack;
31 + 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/"];
32 + obj.PendingEnums = [];
33 + obj.PendingBatchOperations = 0;
34 + obj.ActiveEnumsCount = 0;
35 + obj.MaxActiveEnumsCount = 1; // Maximum number of enumerations that can be done at the same time.
36 + obj.onProcessChanged = null;
37 + var _MaxProcess = 0;
38 + var _LastProcess = 0;
39 +
40 + // Return the number of pending actions
41 + obj.GetPendingActions = function () { return (obj.PendingEnums.length * 2) + (obj.ActiveEnumsCount) + obj.wsman.comm.PendingAjax.length + obj.wsman.comm.ActiveAjaxCount + obj.PendingBatchOperations; }
42 +
43 + // Private Method, Update the current processing status, this gives the application an idea of what progress is being done by the WSMAN stack
44 + function _up() {
45 + var x = obj.GetPendingActions();
46 + if (_MaxProcess < x) _MaxProcess = x;
47 + if (obj.onProcessChanged != null && _LastProcess != x) {
48 + //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);
49 + _LastProcess = x;
50 + obj.onProcessChanged(x, _MaxProcess);
51 + }
52 + if (x == 0) _MaxProcess = 0;
53 + }
54 +
55 + // Perform a WSMAN "SUBSCRIBE" operation.
56 + 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(); }
57 +
58 + // Perform a WSMAN "UNSUBSCRIBE" operation.
59 + 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(); }
60 +
61 + // Perform a WSMAN "GET" operation.
62 + 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(); }
63 +
64 + // Perform a WSMAN "PUT" operation.
65 + 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(); }
66 +
67 + // Perform a WSMAN "CREATE" operation.
68 + 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(); }
69 +
70 + // Perform a WSMAN "DELETE" operation.
71 + 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(); }
72 +
73 + // Perform a WSMAN method call operation.
74 + 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(); }
75 +
76 + // Perform a WSMAN method call operation.
77 + 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(); }
78 +
79 + // Perform a WSMAN "ENUMERATE" operation.
80 + obj.Enum = function Enum(name, callback, tag, pri) {
81 + if (obj.ActiveEnumsCount < obj.MaxActiveEnumsCount) {
82 + obj.ActiveEnumsCount++; obj.wsman.ExecEnum(obj.CompleteName(name), function (ws, resuri, response, xstatus, tag0) { _up(); _EnumStartSink(name, response, callback, resuri, xstatus, tag0); }, tag, pri);
83 + } else {
84 + obj.PendingEnums.push([name, callback, tag, pri]);
85 + }
86 + _up();
87 + }
88 +
89 + // Private method
90 + function _EnumStartSink(name, response, callback, resuri, status, tag, pri) {
91 + if (status != 200) { callback.call(obj, obj, name, null, status, tag); _EnumDoNext(1); return; }
92 + if (response == null || response.Header["Method"] != "EnumerateResponse" || !response.Body["EnumerationContext"]) { callback.call(obj, obj, name, null, 603, tag); _EnumDoNext(1); return; }
93 + var enumctx = response.Body["EnumerationContext"];
94 + obj.wsman.ExecPull(resuri, enumctx, function (ws, resuri, response, xstatus) { _EnumContinueSink(name, response, callback, resuri, [], xstatus, tag, pri); });
95 + }
96 +
97 + // Private method
98 + function _EnumContinueSink(name, response, callback, resuri, items, status, tag, pri) {
99 + if (status != 200) { callback.call(obj, obj, name, null, status, tag); _EnumDoNext(1); return; }
100 + if (response == null || response.Header["Method"] != "PullResponse") { callback.call(obj, obj, name, null, 604, tag); _EnumDoNext(1); return; }
101 + for (var i in response.Body["Items"]) {
102 + if (response.Body["Items"][i] instanceof Array) {
103 + for (var j in response.Body["Items"][i]) { items.push(response.Body["Items"][i][j]); }
104 + } else {
105 + items.push(response.Body["Items"][i]);
106 + }
107 + }
108 + if (response.Body["EnumerationContext"]) {
109 + var enumctx = response.Body["EnumerationContext"];
110 + obj.wsman.ExecPull(resuri, enumctx, function (ws, resuri, response, xstatus) { _EnumContinueSink(name, response, callback, resuri, items, xstatus, tag, 1); });
111 + } else {
112 + _EnumDoNext(1);
113 + callback.call(obj, obj, name, items, status, tag);
114 + _up();
115 + }
116 + }
117 +
118 + // Private method
119 + function _EnumDoNext(dec) {
120 + obj.ActiveEnumsCount -= dec;
121 + if (obj.ActiveEnumsCount >= obj.MaxActiveEnumsCount || obj.PendingEnums.length == 0) return;
122 + var x = obj.PendingEnums.shift();
123 + obj.Enum(x[0], x[1], x[2]);
124 + _EnumDoNext(0);
125 + }
126 +
127 + // Perform a batch of WSMAN "ENUM" operations.
128 + obj.BatchEnum = function (batchname, names, callback, tag, continueOnError, pri) {
129 + obj.PendingBatchOperations += (names.length * 2);
130 + _BatchNextEnum(batchname, Clone(names), callback, tag, {}, continueOnError, pri); _up();
131 + }
132 +
133 + function Clone(v) { return JSON.parse(JSON.stringify(v)); }
134 +
135 + // Request each enum in the batch, stopping if something does not return status 200
136 + function _BatchNextEnum(batchname, names, callback, tag, results, continueOnError, pri) {
137 + obj.PendingBatchOperations -= 2;
138 + var n = names.shift(), f = obj.Enum;
139 + 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.
140 + //console.log((f == obj.Get?'Get ':'Enum ') + n);
141 + // Perform a GET/ENUM action
142 + f(n, function (stack, name, responses, status, tag0) {
143 + tag0[2][name] = { response: (responses==null?null:responses.Body), responses: responses, status: status };
144 + 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); }
145 + else { _up(); _BatchNextEnum(batchname, names, callback, tag, tag0[2], pri); }
146 + }, [batchname, names, results], pri);
147 + _up();
148 + }
149 +
150 + // Perform a batch of WSMAN "GET" operations.
151 + obj.BatchGet = function (batchname, names, callback, tag, pri) {
152 + _FetchNext({ name: batchname, names: names, callback: callback, current: 0, responses: {}, tag: tag, pri: pri }); _up();
153 + }
154 +
155 + // Private method
156 + function _FetchNext(batch) {
157 + if (batch.names.length <= batch.current) {
158 + batch.callback.call(obj, obj, batch.name, batch.responses, 200, batch.tag);
159 + } else {
160 + obj.wsman.ExecGet(obj.CompleteName(batch.names[batch.current]), function (ws, resuri, response, xstatus) { _Fetched(batch, response, xstatus); }, batch.pri);
161 + batch.current++;
162 + }
163 + _up();
164 + }
165 +
166 + // Private method
167 + function _Fetched(batch, response, status) {
168 + if (response == null || status != 200) {
169 + batch.callback.call(obj, obj, batch.name, null, status, batch.tag);
170 + } else {
171 + batch.responses[response.Header["Method"]] = response;
172 + _FetchNext(batch);
173 + }
174 + }
175 +
176 + // Private method
177 + obj.CompleteName = function(name) {
178 + if (name.indexOf("AMT_") == 0) return obj.pfx[0] + name;
179 + if (name.indexOf("CIM_") == 0) return obj.pfx[1] + name;
180 + if (name.indexOf("IPS_") == 0) return obj.pfx[2] + name;
181 + }
182 +
183 + obj.CompleteExecResponse = function (resp) {
184 + if (resp && resp != null && resp.Body && (resp.Body["ReturnValue"] != undefined)) { resp.Body.ReturnValueStr = obj.AmtStatusToStr(resp.Body["ReturnValue"]); }
185 + return resp;
186 + }
187 +
188 + obj.RequestPowerStateChange = function (PowerState, callback_func) {
189 + obj.CIM_PowerManagementService_RequestPowerStateChange(PowerState, "<Address xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><ResourceURI xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystem</ResourceURI><SelectorSet xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\"><Selector Name=\"CreationClassName\">CIM_ComputerSystem</Selector><Selector Name=\"Name\">ManagedSystem</Selector></SelectorSet></ReferenceParameters>", null, null, callback_func);
190 + }
191 +
192 + obj.SetBootConfigRole = function (Role, callback_func) {
193 + obj.CIM_BootService_SetBootConfigRole("<Address xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><ResourceURI xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_BootConfigSetting</ResourceURI><SelectorSet xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\"><Selector Name=\"InstanceID\">Intel(r) AMT: Boot Configuration 0</Selector></SelectorSet></ReferenceParameters>", Role, callback_func);
194 + }
195 +
196 + // Cancel all pending queries with given status
197 + obj.CancelAllQueries = function (s) {
198 + obj.wsman.CancelAllQueries(s);
199 + }
200 +
201 + // Auto generated methods
202 + obj.AMT_AgentPresenceWatchdog_RegisterAgent = function (callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "RegisterAgent", {}, callback_func, tag, pri, selectors); }
203 + obj.AMT_AgentPresenceWatchdog_AssertPresence = function (SequenceNumber, callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func, tag, pri, selectors); }
204 + obj.AMT_AgentPresenceWatchdog_AssertShutdown = function (SequenceNumber, callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func, tag, pri, selectors); }
205 + 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); }
206 + obj.AMT_AgentPresenceWatchdog_DeleteAllActions = function (callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "DeleteAllActions", {}, callback_func, tag, pri, selectors); }
207 + obj.AMT_AgentPresenceWatchdogAction_GetActionEac = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdogAction", "GetActionEac", {}, callback_func); }
208 + obj.AMT_AgentPresenceWatchdogVA_RegisterAgent = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "RegisterAgent", {}, callback_func); }
209 + obj.AMT_AgentPresenceWatchdogVA_AssertPresence = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func); }
210 + obj.AMT_AgentPresenceWatchdogVA_AssertShutdown = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func); }
211 + 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); }
212 + obj.AMT_AgentPresenceWatchdogVA_DeleteAllActions = function (_method_dummy, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "DeleteAllActions", { "_method_dummy": _method_dummy }, callback_func); }
213 + obj.AMT_AlarmClockService_AddAlarm = function AlarmClockService_AddAlarm(alarmInstance, callback_func)
214 + {
215 + var id = alarmInstance.InstanceID;
216 + var nm = alarmInstance.ElementName;
217 + var start = alarmInstance.StartTime.Datetime;
218 + var interval = alarmInstance.Interval ? alarmInstance.Interval.Datetime : undefined;
219 + var doc = alarmInstance.DeleteOnCompletion;
220 + var tpl = "<d:AlarmTemplate xmlns:d=\"http://intel.com/wbem/wscim/1/amt-schema/1/AMT_AlarmClockService\" xmlns:s=\"http://intel.com/wbem/wscim/1/ips-schema/1/IPS_AlarmClockOccurrence\"><s:InstanceID>" + id + "</s:InstanceID><s:ElementName>" + nm + "</s:ElementName><s:StartTime><p:Datetime xmlns:p=\"http://schemas.dmtf.org/wbem/wscim/1/common\">" + start + "</p:Datetime></s:StartTime>" + ((interval!=undefined)?("<s:Interval><p:Interval xmlns:p=\"http://schemas.dmtf.org/wbem/wscim/1/common\">" + interval + "</p:Interval></s:Interval>"):"") + "<s:DeleteOnCompletion>" + doc + "</s:DeleteOnCompletion></d:AlarmTemplate>"
221 + obj.wsman.ExecMethodXml(obj.CompleteName("AMT_AlarmClockService"), "AddAlarm", tpl, callback_func);
222 + };
223 + obj.AMT_AuditLog_ClearLog = function (callback_func) { obj.Exec("AMT_AuditLog", "ClearLog", {}, callback_func); }
224 + obj.AMT_AuditLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_AuditLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
225 + obj.AMT_AuditLog_ReadRecords = function (StartIndex, callback_func, tag) { obj.Exec("AMT_AuditLog", "ReadRecords", { "StartIndex": StartIndex }, callback_func, tag); }
226 + obj.AMT_AuditLog_SetAuditLock = function (LockTimeoutInSeconds, Flag, Handle, callback_func) { obj.Exec("AMT_AuditLog", "SetAuditLock", { "LockTimeoutInSeconds": LockTimeoutInSeconds, "Flag": Flag, "Handle": Handle }, callback_func); }
227 + obj.AMT_AuditLog_ExportAuditLogSignature = function (SigningMechanism, callback_func) { obj.Exec("AMT_AuditLog", "ExportAuditLogSignature", { "SigningMechanism": SigningMechanism }, callback_func); }
228 + 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); }
229 + 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); }
230 + 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); }
231 + 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); }
232 + obj.AMT_AuthorizationService_EnumerateUserAclEntries = function (StartIndex, callback_func) { obj.Exec("AMT_AuthorizationService", "EnumerateUserAclEntries", { "StartIndex": StartIndex }, callback_func); }
233 + obj.AMT_AuthorizationService_GetUserAclEntryEx = function (Handle, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "GetUserAclEntryEx", { "Handle": Handle }, callback_func, tag); }
234 + 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); }
235 + obj.AMT_AuthorizationService_RemoveUserAclEntry = function (Handle, callback_func) { obj.Exec("AMT_AuthorizationService", "RemoveUserAclEntry", { "Handle": Handle }, callback_func); }
236 + obj.AMT_AuthorizationService_SetAdminAclEntryEx = function (Username, DigestPassword, callback_func) { obj.Exec("AMT_AuthorizationService", "SetAdminAclEntryEx", { "Username": Username, "DigestPassword": DigestPassword }, callback_func); }
237 + obj.AMT_AuthorizationService_GetAdminAclEntry = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminAclEntry", {}, callback_func); }
238 + obj.AMT_AuthorizationService_GetAdminAclEntryStatus = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminAclEntryStatus", {}, callback_func); }
239 + obj.AMT_AuthorizationService_GetAdminNetAclEntryStatus = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminNetAclEntryStatus", {}, callback_func); }
240 + obj.AMT_AuthorizationService_SetAclEnabledState = function (Handle, Enabled, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "SetAclEnabledState", { "Handle": Handle, "Enabled": Enabled }, callback_func, tag); }
241 + obj.AMT_AuthorizationService_GetAclEnabledState = function (Handle, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "GetAclEnabledState", { "Handle": Handle }, callback_func, tag); }
242 + obj.AMT_EndpointAccessControlService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
243 + obj.AMT_EndpointAccessControlService_GetPosture = function (PostureType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetPosture", { "PostureType": PostureType }, callback_func); }
244 + obj.AMT_EndpointAccessControlService_GetPostureHash = function (PostureType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetPostureHash", { "PostureType": PostureType }, callback_func); }
245 + obj.AMT_EndpointAccessControlService_UpdatePostureState = function (UpdateType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "UpdatePostureState", { "UpdateType": UpdateType }, callback_func); }
246 + obj.AMT_EndpointAccessControlService_GetEacOptions = function (callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetEacOptions", {}, callback_func); }
247 + obj.AMT_EndpointAccessControlService_SetEacOptions = function (EacVendors, PostureHashAlgorithm, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "SetEacOptions", { "EacVendors": EacVendors, "PostureHashAlgorithm": PostureHashAlgorithm }, callback_func); }
248 + obj.AMT_EnvironmentDetectionSettingData_SetSystemDefensePolicy = function (Policy, callback_func) { obj.Exec("AMT_EnvironmentDetectionSettingData", "SetSystemDefensePolicy", { "Policy": Policy }, callback_func); }
249 + obj.AMT_EnvironmentDetectionSettingData_EnableVpnRouting = function (Enable, callback_func) { obj.Exec("AMT_EnvironmentDetectionSettingData", "EnableVpnRouting", { "Enable": Enable }, callback_func); }
250 + obj.AMT_EthernetPortSettings_SetLinkPreference = function (LinkPreference, Timeout, callback_func) { obj.Exec("AMT_EthernetPortSettings", "SetLinkPreference", { "LinkPreference": LinkPreference, "Timeout": Timeout }, callback_func); }
251 + obj.AMT_HeuristicPacketFilterStatistics_ResetSelectedStats = function (SelectedStatistics, callback_func) { obj.Exec("AMT_HeuristicPacketFilterStatistics", "ResetSelectedStats", { "SelectedStatistics": SelectedStatistics }, callback_func); }
252 + obj.AMT_KerberosSettingData_GetCredentialCacheState = function (callback_func) { obj.Exec("AMT_KerberosSettingData", "GetCredentialCacheState", {}, callback_func); }
253 + obj.AMT_KerberosSettingData_SetCredentialCacheState = function (Enable, callback_func) { obj.Exec("AMT_KerberosSettingData", "SetCredentialCacheState", { "Enable": Enable }, callback_func); }
254 + obj.AMT_MessageLog_CancelIteration = function (IterationIdentifier, callback_func) { obj.Exec("AMT_MessageLog", "CancelIteration", { "IterationIdentifier": IterationIdentifier }, callback_func); }
255 + obj.AMT_MessageLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_MessageLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
256 + obj.AMT_MessageLog_ClearLog = function (callback_func) { obj.Exec("AMT_MessageLog", "ClearLog", { }, callback_func); }
257 + obj.AMT_MessageLog_GetRecords = function (IterationIdentifier, MaxReadRecords, callback_func, tag) { obj.Exec("AMT_MessageLog", "GetRecords", { "IterationIdentifier": IterationIdentifier, "MaxReadRecords": MaxReadRecords }, callback_func, tag); }
258 + obj.AMT_MessageLog_GetRecord = function (IterationIdentifier, PositionToNext, callback_func) { obj.Exec("AMT_MessageLog", "GetRecord", { "IterationIdentifier": IterationIdentifier, "PositionToNext": PositionToNext }, callback_func); }
259 + obj.AMT_MessageLog_PositionAtRecord = function (IterationIdentifier, MoveAbsolute, RecordNumber, callback_func) { obj.Exec("AMT_MessageLog", "PositionAtRecord", { "IterationIdentifier": IterationIdentifier, "MoveAbsolute": MoveAbsolute, "RecordNumber": RecordNumber }, callback_func); }
260 + obj.AMT_MessageLog_PositionToFirstRecord = function (callback_func, tag) { obj.Exec("AMT_MessageLog", "PositionToFirstRecord", {}, callback_func, tag); }
261 + obj.AMT_MessageLog_FreezeLog = function (Freeze, callback_func) { obj.Exec("AMT_MessageLog", "FreezeLog", { "Freeze": Freeze }, callback_func); }
262 + obj.AMT_PublicKeyManagementService_AddCRL = function (Url, SerialNumbers, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddCRL", { "Url": Url, "SerialNumbers": SerialNumbers }, callback_func); }
263 + obj.AMT_PublicKeyManagementService_ResetCRLList = function (_method_dummy, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "ResetCRLList", { "_method_dummy": _method_dummy }, callback_func); }
264 + obj.AMT_PublicKeyManagementService_AddCertificate = function (CertificateBlob, callback_func, tag) { obj.Exec("AMT_PublicKeyManagementService", "AddCertificate", { "CertificateBlob": CertificateBlob }, callback_func, tag); }
265 + obj.AMT_PublicKeyManagementService_AddTrustedRootCertificate = function (CertificateBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddTrustedRootCertificate", { "CertificateBlob": CertificateBlob }, callback_func); }
266 + obj.AMT_PublicKeyManagementService_AddKey = function (KeyBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddKey", { "KeyBlob": KeyBlob }, callback_func); }
267 + obj.AMT_PublicKeyManagementService_GeneratePKCS10Request = function (KeyPair, DNName, Usage, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GeneratePKCS10Request", { "KeyPair": KeyPair, "DNName": DNName, "Usage": Usage }, callback_func); }
268 + obj.AMT_PublicKeyManagementService_GeneratePKCS10RequestEx = function (KeyPair, SigningAlgorithm, NullSignedCertificateRequest, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GeneratePKCS10RequestEx", { "KeyPair": KeyPair, "SigningAlgorithm": SigningAlgorithm, "NullSignedCertificateRequest": NullSignedCertificateRequest }, callback_func); }
269 + obj.AMT_PublicKeyManagementService_GenerateKeyPair = function (KeyAlgorithm, KeyLength, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GenerateKeyPair", { "KeyAlgorithm": KeyAlgorithm, "KeyLength": KeyLength }, callback_func); }
270 + obj.AMT_RedirectionService_RequestStateChange = function (RequestedState, callback_func) { obj.Exec("AMT_RedirectionService", "RequestStateChange", { "RequestedState": RequestedState }, callback_func); }
271 + obj.AMT_RedirectionService_TerminateSession = function (SessionType, callback_func) { obj.Exec("AMT_RedirectionService", "TerminateSession", { "SessionType": SessionType }, callback_func); }
272 + 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); }
273 + 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); }
274 + obj.AMT_RemoteAccessService_CloseRemoteAccessConnection = function (_method_dummy, callback_func) { obj.Exec("AMT_RemoteAccessService", "CloseRemoteAccessConnection", { "_method_dummy": _method_dummy }, callback_func); }
275 + obj.AMT_SetupAndConfigurationService_CommitChanges = function (_method_dummy, callback_func, tag) { obj.Exec("AMT_SetupAndConfigurationService", "CommitChanges", { "_method_dummy": _method_dummy }, callback_func, tag); }
276 + obj.AMT_SetupAndConfigurationService_Unprovision = function (ProvisioningMode, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "Unprovision", { "ProvisioningMode": ProvisioningMode }, callback_func); }
277 + obj.AMT_SetupAndConfigurationService_PartialUnprovision = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "PartialUnprovision", { "_method_dummy": _method_dummy }, callback_func); }
278 + obj.AMT_SetupAndConfigurationService_ResetFlashWearOutProtection = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "ResetFlashWearOutProtection", { "_method_dummy": _method_dummy }, callback_func); }
279 + obj.AMT_SetupAndConfigurationService_ExtendProvisioningPeriod = function (Duration, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "ExtendProvisioningPeriod", { "Duration": Duration }, callback_func); }
280 + obj.AMT_SetupAndConfigurationService_SetMEBxPassword = function (Password, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "SetMEBxPassword", { "Password": Password }, callback_func); }
281 + obj.AMT_SetupAndConfigurationService_SetTLSPSK = function (PID, PPS, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "SetTLSPSK", { "PID": PID, "PPS": PPS }, callback_func); }
282 + obj.AMT_SetupAndConfigurationService_GetProvisioningAuditRecord = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetProvisioningAuditRecord", {}, callback_func); }
283 + obj.AMT_SetupAndConfigurationService_GetUuid = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetUuid", {}, callback_func); }
284 + obj.AMT_SetupAndConfigurationService_GetUnprovisionBlockingComponents = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetUnprovisionBlockingComponents", {}, callback_func); }
285 + obj.AMT_SetupAndConfigurationService_GetProvisioningAuditRecordV2 = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetProvisioningAuditRecordV2", {}, callback_func); }
286 + obj.AMT_SystemDefensePolicy_GetTimeout = function (callback_func) { obj.Exec("AMT_SystemDefensePolicy", "GetTimeout", {}, callback_func); }
287 + obj.AMT_SystemDefensePolicy_SetTimeout = function (Timeout, callback_func) { obj.Exec("AMT_SystemDefensePolicy", "SetTimeout", { "Timeout": Timeout }, callback_func); }
288 + 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); }
289 + obj.AMT_SystemPowerScheme_SetPowerScheme = function (callback_func, schemeInstanceId, tag) { obj.Exec("AMT_SystemPowerScheme", "SetPowerScheme", {}, callback_func, tag, 0, { "InstanceID": schemeInstanceId }); }
290 + obj.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch = function (callback_func, tag) { obj.Exec("AMT_TimeSynchronizationService", "GetLowAccuracyTimeSynch", {}, callback_func, tag); }
291 + 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); }
292 + obj.AMT_TLSCredentialContext_Create = function AMT_TLSCredentialContext_Create(ElementInContext, ElementProvidingContext, callback_func, tag) { obj.Create("AMT_TLSCredentialContext", { "ElementInContext": ElementInContext, "ElementProvidingContext": ElementProvidingContext }, callback_func, tag); }
293 + obj.AMT_UserInitiatedConnectionService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_UserInitiatedConnectionService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
294 + obj.AMT_WebUIService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func, tag) { obj.Exec("AMT_WebUIService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func, tag); }
295 + 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); }
296 + 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); }
297 + obj.AMT_WiFiPortConfigurationService_DeleteAllITProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllITProfiles", { "_method_dummy": _method_dummy }, callback_func); }
298 + obj.AMT_WiFiPortConfigurationService_DeleteAllUserProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllUserProfiles", { "_method_dummy": _method_dummy }, callback_func); }
299 + obj.CIM_Account_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Account", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
300 + obj.CIM_AccountManagementService_CreateAccount = function (System, AccountTemplate, callback_func) { obj.Exec("CIM_AccountManagementService", "CreateAccount", { "System": System, "AccountTemplate": AccountTemplate }, callback_func); }
301 + obj.CIM_BootConfigSetting_ChangeBootOrder = function (Source, callback_func) { obj.Exec("CIM_BootConfigSetting", "ChangeBootOrder", { "Source": Source }, callback_func); }
302 + obj.CIM_BootService_SetBootConfigRole = function (BootConfigSetting, Role, callback_func) { obj.Exec("CIM_BootService", "SetBootConfigRole", { "BootConfigSetting": BootConfigSetting, "Role": Role }, callback_func, 0, 1); }
303 + obj.CIM_Card_ConnectorPower = function (Connector, PoweredOn, callback_func) { obj.Exec("CIM_Card", "ConnectorPower", { "Connector": Connector, "PoweredOn": PoweredOn }, callback_func); }
304 + obj.CIM_Card_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_Card", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
305 + obj.CIM_Chassis_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_Chassis", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
306 + obj.CIM_Fan_SetSpeed = function (DesiredSpeed, callback_func) { obj.Exec("CIM_Fan", "SetSpeed", { "DesiredSpeed": DesiredSpeed }, callback_func); }
307 + obj.CIM_KVMRedirectionSAP_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_KVMRedirectionSAP", "RequestStateChange", { "RequestedState": RequestedState/*, "TimeoutPeriod": TimeoutPeriod */}, callback_func); }
308 + obj.CIM_MediaAccessDevice_LockMedia = function (Lock, callback_func) { obj.Exec("CIM_MediaAccessDevice", "LockMedia", { "Lock": Lock }, callback_func); }
309 + obj.CIM_MediaAccessDevice_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_MediaAccessDevice", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
310 + obj.CIM_MediaAccessDevice_Reset = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "Reset", {}, callback_func); }
311 + obj.CIM_MediaAccessDevice_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_MediaAccessDevice", "EnableDevice", { "Enabled": Enabled }, callback_func); }
312 + obj.CIM_MediaAccessDevice_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_MediaAccessDevice", "OnlineDevice", { "Online": Online }, callback_func); }
313 + obj.CIM_MediaAccessDevice_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_MediaAccessDevice", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
314 + obj.CIM_MediaAccessDevice_SaveProperties = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "SaveProperties", {}, callback_func); }
315 + obj.CIM_MediaAccessDevice_RestoreProperties = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "RestoreProperties", {}, callback_func); }
316 + obj.CIM_MediaAccessDevice_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_MediaAccessDevice", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
317 + obj.CIM_PhysicalFrame_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_PhysicalFrame", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
318 + obj.CIM_PhysicalPackage_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_PhysicalPackage", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
319 + 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); }
320 + obj.CIM_PowerSupply_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_PowerSupply", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
321 + obj.CIM_PowerSupply_Reset = function (callback_func) { obj.Exec("CIM_PowerSupply", "Reset", {}, callback_func); }
322 + obj.CIM_PowerSupply_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_PowerSupply", "EnableDevice", { "Enabled": Enabled }, callback_func); }
323 + obj.CIM_PowerSupply_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_PowerSupply", "OnlineDevice", { "Online": Online }, callback_func); }
324 + obj.CIM_PowerSupply_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_PowerSupply", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
325 + obj.CIM_PowerSupply_SaveProperties = function (callback_func) { obj.Exec("CIM_PowerSupply", "SaveProperties", {}, callback_func); }
326 + obj.CIM_PowerSupply_RestoreProperties = function (callback_func) { obj.Exec("CIM_PowerSupply", "RestoreProperties", {}, callback_func); }
327 + obj.CIM_PowerSupply_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_PowerSupply", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
328 + obj.CIM_Processor_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Processor", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
329 + obj.CIM_Processor_Reset = function (callback_func) { obj.Exec("CIM_Processor", "Reset", {}, callback_func); }
330 + obj.CIM_Processor_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Processor", "EnableDevice", { "Enabled": Enabled }, callback_func); }
331 + obj.CIM_Processor_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Processor", "OnlineDevice", { "Online": Online }, callback_func); }
332 + obj.CIM_Processor_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Processor", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
333 + obj.CIM_Processor_SaveProperties = function (callback_func) { obj.Exec("CIM_Processor", "SaveProperties", {}, callback_func); }
334 + obj.CIM_Processor_RestoreProperties = function (callback_func) { obj.Exec("CIM_Processor", "RestoreProperties", {}, callback_func); }
335 + obj.CIM_Processor_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Processor", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
336 + obj.CIM_RecordLog_ClearLog = function (callback_func) { obj.Exec("CIM_RecordLog", "ClearLog", {}, callback_func); }
337 + obj.CIM_RecordLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_RecordLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
338 + obj.CIM_RedirectionService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_RedirectionService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
339 + obj.CIM_Sensor_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Sensor", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
340 + obj.CIM_Sensor_Reset = function (callback_func) { obj.Exec("CIM_Sensor", "Reset", {}, callback_func); }
341 + obj.CIM_Sensor_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Sensor", "EnableDevice", { "Enabled": Enabled }, callback_func); }
342 + obj.CIM_Sensor_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Sensor", "OnlineDevice", { "Online": Online }, callback_func); }
343 + obj.CIM_Sensor_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Sensor", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
344 + obj.CIM_Sensor_SaveProperties = function (callback_func) { obj.Exec("CIM_Sensor", "SaveProperties", {}, callback_func); }
345 + obj.CIM_Sensor_RestoreProperties = function (callback_func) { obj.Exec("CIM_Sensor", "RestoreProperties", {}, callback_func); }
346 + obj.CIM_Sensor_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Sensor", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
347 + obj.CIM_StatisticalData_ResetSelectedStats = function (SelectedStatistics, callback_func) { obj.Exec("CIM_StatisticalData", "ResetSelectedStats", { "SelectedStatistics": SelectedStatistics }, callback_func); }
348 + obj.CIM_Watchdog_KeepAlive = function (callback_func) { obj.Exec("CIM_Watchdog", "KeepAlive", {}, callback_func); }
349 + obj.CIM_Watchdog_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Watchdog", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
350 + obj.CIM_Watchdog_Reset = function (callback_func) { obj.Exec("CIM_Watchdog", "Reset", {}, callback_func); }
351 + obj.CIM_Watchdog_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Watchdog", "EnableDevice", { "Enabled": Enabled }, callback_func); }
352 + obj.CIM_Watchdog_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Watchdog", "OnlineDevice", { "Online": Online }, callback_func); }
353 + obj.CIM_Watchdog_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Watchdog", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
354 + obj.CIM_Watchdog_SaveProperties = function (callback_func) { obj.Exec("CIM_Watchdog", "SaveProperties", {}, callback_func); }
355 + obj.CIM_Watchdog_RestoreProperties = function (callback_func) { obj.Exec("CIM_Watchdog", "RestoreProperties", {}, callback_func); }
356 + obj.CIM_Watchdog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Watchdog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
357 + obj.CIM_WiFiPort_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_WiFiPort", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
358 + obj.CIM_WiFiPort_Reset = function (callback_func) { obj.Exec("CIM_WiFiPort", "Reset", {}, callback_func); }
359 + obj.CIM_WiFiPort_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_WiFiPort", "EnableDevice", { "Enabled": Enabled }, callback_func); }
360 + obj.CIM_WiFiPort_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_WiFiPort", "OnlineDevice", { "Online": Online }, callback_func); }
361 + obj.CIM_WiFiPort_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_WiFiPort", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
362 + obj.CIM_WiFiPort_SaveProperties = function (callback_func) { obj.Exec("CIM_WiFiPort", "SaveProperties", {}, callback_func); }
363 + obj.CIM_WiFiPort_RestoreProperties = function (callback_func) { obj.Exec("CIM_WiFiPort", "RestoreProperties", {}, callback_func); }
364 + obj.CIM_WiFiPort_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_WiFiPort", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
365 + 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); }
366 + obj.IPS_HostBasedSetupService_AddNextCertInChain = function (NextCertificate, IsLeafCertificate, IsRootCertificate, callback_func) { obj.Exec("IPS_HostBasedSetupService", "AddNextCertInChain", { "NextCertificate": NextCertificate, "IsLeafCertificate": IsLeafCertificate, "IsRootCertificate": IsRootCertificate }, callback_func); }
367 + 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); }
368 + obj.IPS_HostBasedSetupService_UpgradeClientToAdmin = function (McNonce, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "UpgradeClientToAdmin", { "McNonce": McNonce, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); }
369 + obj.IPS_HostBasedSetupService_DisableClientControlMode = function (_method_dummy, callback_func) { obj.Exec("IPS_HostBasedSetupService", "DisableClientControlMode", { "_method_dummy": _method_dummy }, callback_func); }
370 + obj.IPS_KVMRedirectionSettingData_TerminateSession = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "TerminateSession", {}, callback_func); }
371 + obj.IPS_KVMRedirectionSettingData_DataChannelRead = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelRead", {}, callback_func); }
372 + obj.IPS_KVMRedirectionSettingData_DataChannelWrite = function (Data, callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelWrite", { "DataMessage": Data }, callback_func); }
373 + obj.IPS_OptInService_StartOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "StartOptIn", {}, callback_func); }
374 + obj.IPS_OptInService_CancelOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "CancelOptIn", {}, callback_func); }
375 + obj.IPS_OptInService_SendOptInCode = function (OptInCode, callback_func) { obj.Exec("IPS_OptInService", "SendOptInCode", { "OptInCode": OptInCode }, callback_func); }
376 + obj.IPS_OptInService_StartService = function (callback_func) { obj.Exec("IPS_OptInService", "StartService", {}, callback_func); }
377 + obj.IPS_OptInService_StopService = function (callback_func) { obj.Exec("IPS_OptInService", "StopService", {}, callback_func); }
378 + obj.IPS_OptInService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_OptInService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
379 + obj.IPS_ProvisioningRecordLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_ProvisioningRecordLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
380 + obj.IPS_ProvisioningRecordLog_ClearLog = function (_method_dummy, callback_func) { obj.Exec("IPS_ProvisioningRecordLog", "ClearLog", { "_method_dummy": _method_dummy }, callback_func); }
381 + obj.IPS_SecIOService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_SecIOService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
382 +
383 + obj.AmtStatusToStr = function (code) { if (obj.AmtStatusCodes[code]) return obj.AmtStatusCodes[code]; else return "UNKNOWN_ERROR" }
384 + obj.AmtStatusCodes = {
385 + 0x0000: "SUCCESS",
386 + 0x0001: "INTERNAL_ERROR",
387 + 0x0002: "NOT_READY",
388 + 0x0003: "INVALID_PT_MODE",
389 + 0x0004: "INVALID_MESSAGE_LENGTH",
390 + 0x0005: "TABLE_FINGERPRINT_NOT_AVAILABLE",
391 + 0x0006: "INTEGRITY_CHECK_FAILED",
392 + 0x0007: "UNSUPPORTED_ISVS_VERSION",
393 + 0x0008: "APPLICATION_NOT_REGISTERED",
394 + 0x0009: "INVALID_REGISTRATION_DATA",
395 + 0x000A: "APPLICATION_DOES_NOT_EXIST",
396 + 0x000B: "NOT_ENOUGH_STORAGE",
397 + 0x000C: "INVALID_NAME",
398 + 0x000D: "BLOCK_DOES_NOT_EXIST",
399 + 0x000E: "INVALID_BYTE_OFFSET",
400 + 0x000F: "INVALID_BYTE_COUNT",
401 + 0x0010: "NOT_PERMITTED",
402 + 0x0011: "NOT_OWNER",
403 + 0x0012: "BLOCK_LOCKED_BY_OTHER",
404 + 0x0013: "BLOCK_NOT_LOCKED",
405 + 0x0014: "INVALID_GROUP_PERMISSIONS",
406 + 0x0015: "GROUP_DOES_NOT_EXIST",
407 + 0x0016: "INVALID_MEMBER_COUNT",
408 + 0x0017: "MAX_LIMIT_REACHED",
409 + 0x0018: "INVALID_AUTH_TYPE",
410 + 0x0019: "AUTHENTICATION_FAILED",
411 + 0x001A: "INVALID_DHCP_MODE",
412 + 0x001B: "INVALID_IP_ADDRESS",
413 + 0x001C: "INVALID_DOMAIN_NAME",
414 + 0x001D: "UNSUPPORTED_VERSION",
415 + 0x001E: "REQUEST_UNEXPECTED",
416 + 0x001F: "INVALID_TABLE_TYPE",
417 + 0x0020: "INVALID_PROVISIONING_STATE",
418 + 0x0021: "UNSUPPORTED_OBJECT",
419 + 0x0022: "INVALID_TIME",
420 + 0x0023: "INVALID_INDEX",
421 + 0x0024: "INVALID_PARAMETER",
422 + 0x0025: "INVALID_NETMASK",
423 + 0x0026: "FLASH_WRITE_LIMIT_EXCEEDED",
424 + 0x0027: "INVALID_IMAGE_LENGTH",
425 + 0x0028: "INVALID_IMAGE_SIGNATURE",
426 + 0x0029: "PROPOSE_ANOTHER_VERSION",
427 + 0x002A: "INVALID_PID_FORMAT",
428 + 0x002B: "INVALID_PPS_FORMAT",
429 + 0x002C: "BIST_COMMAND_BLOCKED",
430 + 0x002D: "CONNECTION_FAILED",
431 + 0x002E: "CONNECTION_TOO_MANY",
432 + 0x002F: "RNG_GENERATION_IN_PROGRESS",
433 + 0x0030: "RNG_NOT_READY",
434 + 0x0031: "CERTIFICATE_NOT_READY",
435 + 0x0400: "DISABLED_BY_POLICY",
436 + 0x0800: "NETWORK_IF_ERROR_BASE",
437 + 0x0801: "UNSUPPORTED_OEM_NUMBER",
438 + 0x0802: "UNSUPPORTED_BOOT_OPTION",
439 + 0x0803: "INVALID_COMMAND",
440 + 0x0804: "INVALID_SPECIAL_COMMAND",
441 + 0x0805: "INVALID_HANDLE",
442 + 0x0806: "INVALID_PASSWORD",
443 + 0x0807: "INVALID_REALM",
444 + 0x0808: "STORAGE_ACL_ENTRY_IN_USE",
445 + 0x0809: "DATA_MISSING",
446 + 0x080A: "DUPLICATE",
447 + 0x080B: "EVENTLOG_FROZEN",
448 + 0x080C: "PKI_MISSING_KEYS",
449 + 0x080D: "PKI_GENERATING_KEYS",
450 + 0x080E: "INVALID_KEY",
451 + 0x080F: "INVALID_CERT",
452 + 0x0810: "CERT_KEY_NOT_MATCH",
453 + 0x0811: "MAX_KERB_DOMAIN_REACHED",
454 + 0x0812: "UNSUPPORTED",
455 + 0x0813: "INVALID_PRIORITY",
456 + 0x0814: "NOT_FOUND",
457 + 0x0815: "INVALID_CREDENTIALS",
458 + 0x0816: "INVALID_PASSPHRASE",
459 + 0x0818: "NO_ASSOCIATION",
460 + 0x081B: "AUDIT_FAIL",
461 + 0x081C: "BLOCKING_COMPONENT",
462 + 0x0821: "USER_CONSENT_REQUIRED",
463 + 0x1000: "APP_INTERNAL_ERROR",
464 + 0x1001: "NOT_INITIALIZED",
465 + 0x1002: "LIB_VERSION_UNSUPPORTED",
466 + 0x1003: "INVALID_PARAM",
467 + 0x1004: "RESOURCES",
468 + 0x1005: "HARDWARE_ACCESS_ERROR",
469 + 0x1006: "REQUESTOR_NOT_REGISTERED",
470 + 0x1007: "NETWORK_ERROR",
471 + 0x1008: "PARAM_BUFFER_TOO_SHORT",
472 + 0x1009: "COM_NOT_INITIALIZED_IN_THREAD",
473 + 0x100A: "URL_REQUIRED"
474 + }
475 +
476 + //
477 + // Methods used for getting the event log
478 + //
479 +
480 + obj.GetMessageLog = function (func, tag) {
481 + obj.AMT_MessageLog_PositionToFirstRecord(_GetMessageLog0, [func, tag, []]);
482 + }
483 + function _GetMessageLog0(stack, name, responses, status, tag) {
484 + if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; }
485 + obj.AMT_MessageLog_GetRecords(responses.Body["IterationIdentifier"], 390, _GetMessageLog1, tag);
486 + }
487 + function _GetMessageLog1(stack, name, responses, status, tag) {
488 + if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; }
489 + var i, j, x, e, AmtMessages = tag[2], t = new Date(), TimeStamp, ra = responses.Body["RecordArray"];
490 + if (typeof ra === 'string') { responses.Body["RecordArray"] = [responses.Body["RecordArray"]]; }
491 +
492 + for (i in ra) {
493 + e = Buffer.from(ra[i], 'base64');
494 + if (e != null) {
495 + TimeStamp = ReadIntX(e, 0);
496 + if ((TimeStamp > 0) && (TimeStamp < 0xFFFFFFFF)) {
497 + 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) };
498 + for (j = 13; j < 21; j++) { x['EventData'].push(e[j]); }
499 + x['EntityStr'] = _SystemEntityTypes[x['Entity']];
500 + x['Desc'] = _GetEventDetailStr(x['EventSensorType'], x['EventOffset'], x['EventData'], x['Entity']);
501 + if (!x['EntityStr']) x['EntityStr'] = "Unknown";
502 + AmtMessages.push(x);
503 + }
504 + }
505 + }
506 +
507 + 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]); }
508 + }
509 +
510 + 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('|');
511 + 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('|');
512 + 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('|');
513 + 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('|');
514 + 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('|');
515 + obj.WatchdogCurrentStates = { 1: 'Not Started', 2: 'Stopped', 4: 'Running', 8: 'Expired', 16: 'Suspended' };
516 +
517 + function _GetEventDetailStr(eventSensorType, eventOffset, eventDataField, entity) {
518 +
519 + if (eventSensorType == 15)
520 + {
521 + if (eventDataField[0] == 235) return "Invalid Data";
522 + if (eventOffset == 0) return _SystemFirmwareError[eventDataField[1]];
523 + return _SystemFirmwareProgress[eventDataField[1]];
524 + }
525 +
526 + if (eventSensorType == 18 && eventDataField[0] == 170) // System watchdog event
527 + {
528 + 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]];
529 + }
530 +
531 + //if (eventSensorType == 5 && eventOffset == 0) // System chassis
532 + //{
533 + // return "Case intrusion";
534 + //}
535 +
536 + //if (eventSensorType == 192 && eventOffset == 0 && eventDataField[0] == 170 && eventDataField[1] == 48)
537 + //{
538 + // if (eventDataField[2] == 0) return "A remote Serial Over LAN session was established.";
539 + // if (eventDataField[2] == 1) return "Remote Serial Over LAN session finished. User control was restored.";
540 + // if (eventDataField[2] == 2) return "A remote IDE-Redirection session was established.";
541 + // if (eventDataField[2] == 3) return "Remote IDE-Redirection session finished. User control was restored.";
542 + //}
543 +
544 + //if (eventSensorType == 36)
545 + //{
546 + // long handle = ((long)(eventDataField[1]) << 24) + ((long)(eventDataField[2]) << 16) + ((long)(eventDataField[3]) << 8) + (long)(eventDataField[4]);
547 + // string nic = string.Format("#{0}", eventDataField[0]);
548 + // if (eventDataField[0] == 0xAA) nic = "wired"; // TODO: Add wireless *****
549 + // //if (eventDataField[0] == 0xAA) nic = "wireless";
550 +
551 + // if (handle == 4294967293) { return string.Format("All received packet filter was matched on {0} interface.", nic); }
552 + // if (handle == 4294967292) { return string.Format("All outbound packet filter was matched on {0} interface.", nic); }
553 + // if (handle == 4294967290) { return string.Format("Spoofed packet filter was matched on {0} interface.", nic); }
554 + // return string.Format("Filter {0} was matched on {1} interface.", handle, nic);
555 + //}
556 +
557 + //if (eventSensorType == 192)
558 + //{
559 + // if (eventDataField[2] == 0) return "Security policy invoked. Some or all network traffic (TX) was stopped.";
560 + // if (eventDataField[2] == 2) return "Security policy invoked. Some or all network traffic (RX) was stopped.";
561 + // return "Security policy invoked.";
562 + //}
563 +
564 + //if (eventSensorType == 193)
565 + //{
566 + // if (eventDataField[0] == 0xAA && eventDataField[1] == 0x30 && eventDataField[2] == 0x00 && eventDataField[3] == 0x00) { return "User request for remote connection."; }
567 + // 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 }
568 + // if (eventDataField[0] == 0xAA && eventDataField[1] == 0x20 && eventDataField[2] == 0x04 && eventDataField[3] == 0x00) { return "Certificate revoked. "; }
569 + //}
570 +
571 + if (eventSensorType == 6) return "Authentication failed " + (eventDataField[1] + (eventDataField[2] << 8)) + " times. The system may be under attack.";
572 + if (eventSensorType == 30) return "No bootable media";
573 + if (eventSensorType == 32) return "Operating system lockup or power interrupt";
574 + if (eventSensorType == 35) return "System boot failure";
575 + if (eventSensorType == 37) return "System firmware started (at least one CPU is properly executing).";
576 + return "Unknown Sensor Type #" + eventSensorType;
577 + }
578 +
579 +// ###BEGIN###{AuditLog}
580 +
581 + // Useful link: https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Fsecurityadminevents.htm
582 +
583 + var _AmtAuditStringTable =
584 + {
585 + 16: 'Security Admin',
586 + 17: 'RCO',
587 + 18: 'Redirection Manager',
588 + 19: 'Firmware Update Manager',
589 + 20: 'Security Audit Log',
590 + 21: 'Network Time',
591 + 22: 'Network Administration',
592 + 23: 'Storage Administration',
593 + 24: 'Event Manager',
594 + 25: 'Circuit Breaker Manager',
595 + 26: 'Agent Presence Manager',
596 + 27: 'Wireless Configuration',
597 + 28: 'EAC',
598 + 29: 'KVM',
599 + 30: 'User Opt-In Events',
600 + 32: 'Screen Blanking',
601 + 33: 'Watchdog Events',
602 + 1600: 'Provisioning Started',
603 + 1601: 'Provisioning Completed',
604 + 1602: 'ACL Entry Added',
605 + 1603: 'ACL Entry Modified',
606 + 1604: 'ACL Entry Removed',
607 + 1605: 'ACL Access with Invalid Credentials',
608 + 1606: 'ACL Entry State',
609 + 1607: 'TLS State Changed',
610 + 1608: 'TLS Server Certificate Set',
611 + 1609: 'TLS Server Certificate Remove',
612 + 1610: 'TLS Trusted Root Certificate Added',
613 + 1611: 'TLS Trusted Root Certificate Removed',
614 + 1612: 'TLS Preshared Key Set',
615 + 1613: 'Kerberos Settings Modified',
616 + 1614: 'Kerberos Master Key Modified',
617 + 1615: 'Flash Wear out Counters Reset',
618 + 1616: 'Power Package Modified',
619 + 1617: 'Set Realm Authentication Mode',
620 + 1618: 'Upgrade Client to Admin Control Mode',
621 + 1619: 'Unprovisioning Started',
622 + 1700: 'Performed Power Up',
623 + 1701: 'Performed Power Down',
624 + 1702: 'Performed Power Cycle',
625 + 1703: 'Performed Reset',
626 + 1704: 'Set Boot Options',
627 + 1800: 'IDER Session Opened',
628 + 1801: 'IDER Session Closed',
629 + 1802: 'IDER Enabled',
630 + 1803: 'IDER Disabled',
631 + 1804: 'SoL Session Opened',
632 + 1805: 'SoL Session Closed',
633 + 1806: 'SoL Enabled',
634 + 1807: 'SoL Disabled',
635 + 1808: 'KVM Session Started',
636 + 1809: 'KVM Session Ended',
637 + 1810: 'KVM Enabled',
638 + 1811: 'KVM Disabled',
639 + 1812: 'VNC Password Failed 3 Times',
640 + 1900: 'Firmware Updated',
641 + 1901: 'Firmware Update Failed',
642 + 2000: 'Security Audit Log Cleared',
643 + 2001: 'Security Audit Policy Modified',
644 + 2002: 'Security Audit Log Disabled',
645 + 2003: 'Security Audit Log Enabled',
646 + 2004: 'Security Audit Log Exported',
647 + 2005: 'Security Audit Log Recovered',
648 + 2100: 'Intel(R) ME Time Set',
649 + 2200: 'TCPIP Parameters Set',
650 + 2201: 'Host Name Set',
651 + 2202: 'Domain Name Set',
652 + 2203: 'VLAN Parameters Set',
653 + 2204: 'Link Policy Set',
654 + 2205: 'IPv6 Parameters Set',
655 + 2300: 'Global Storage Attributes Set',
656 + 2301: 'Storage EACL Modified',
657 + 2302: 'Storage FPACL Modified',
658 + 2303: 'Storage Write Operation',
659 + 2400: 'Alert Subscribed',
660 + 2401: 'Alert Unsubscribed',
661 + 2402: 'Event Log Cleared',
662 + 2403: 'Event Log Frozen',
663 + 2500: 'CB Filter Added',
664 + 2501: 'CB Filter Removed',
665 + 2502: 'CB Policy Added',
666 + 2503: 'CB Policy Removed',
667 + 2504: 'CB Default Policy Set',
668 + 2505: 'CB Heuristics Option Set',
669 + 2506: 'CB Heuristics State Cleared',
670 + 2600: 'Agent Watchdog Added',
671 + 2601: 'Agent Watchdog Removed',
672 + 2602: 'Agent Watchdog Action Set',
673 + 2700: 'Wireless Profile Added',
674 + 2701: 'Wireless Profile Removed',
675 + 2702: 'Wireless Profile Updated',
676 + 2800: 'EAC Posture Signer SET',
677 + 2801: 'EAC Enabled',
678 + 2802: 'EAC Disabled',
679 + 2803: 'EAC Posture State',
680 + 2804: 'EAC Set Options',
681 + 2900: 'KVM Opt-in Enabled',
682 + 2901: 'KVM Opt-in Disabled',
683 + 2902: 'KVM Password Changed',
684 + 2903: 'KVM Consent Succeeded',
685 + 2904: 'KVM Consent Failed',
686 + 3000: 'Opt-In Policy Change',
687 + 3001: 'Send Consent Code Event',
688 + 3002: 'Start Opt-In Blocked Event'
689 + }
690 +
691 + // Return human readable extended audit log data
692 + // TODO: Just put some of them here, but many more still need to be added, helpful link here:
693 + // https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Fsecurityadminevents.htm
694 + obj.GetAuditLogExtendedDataStr = function (id, data) {
695 + if ((id == 1602 || id == 1604) && data[0] == 0) { return bufToArray(data).splice(2, 2 + data[1]).toString(); } // ACL Entry Added/Removed (Digest)
696 + if (id == 1603) { if (data[1] == 0) { return bufToArray(data).splice(3).toString(); } return null; } // ACL Entry Modified
697 + if (id == 1605) { return ["Invalid ME access", "Invalid MEBx access"][data[0]]; } // ACL Access with Invalid Credentials
698 + if (id == 1606) { var r = ["Disabled", "Enabled"][data[0]]; if (data[1] == 0) { r += ", " + data[3]; } return r; } // ACL Entry State
699 + if (id == 1607) { return "Remote " + ["NoAuth", "ServerAuth", "MutualAuth"][data[0]] + ", Local " + ["NoAuth", "ServerAuth", "MutualAuth"][data[1]]; } // TLS State Changed
700 + if (id == 1617) { return obj.RealmNames[ReadInt(data, 0)] + ", " + ["NoAuth", "Auth", "Disabled"][data[4]]; } // Set Realm Authentication Mode
701 + if (id == 1619) { return ["BIOS", "MEBx", "Local MEI", "Local WSMAN", "Remote WSAMN"][data[0]]; } // Intel AMT Unprovisioning Started
702 + 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
703 + if (id == 2100) { var t4 = new Date(); t4.setTime(ReadInt(data, 0) * 1000 + (new Date().getTimezoneOffset() * 60000)); return t4.toLocaleString(); } // Intel AMT Time Set
704 + if (id == 3000) { return "From " + ["None", "KVM", "All"][data[0]] + " to " + ["None", "KVM", "All"][data[1]]; } // Opt-In Policy Change
705 + if (id == 3001) { return ["Success", "Failed 3 times"][data[0]]; } // Send Consent Code Event
706 + return null;
707 + }
708 +
709 + obj.GetAuditLog = function (func) {
710 + obj.AMT_AuditLog_ReadRecords(1, _GetAuditLog0, [func, []]);
711 + }
712 +
713 + function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; }
714 + function ReadShort(v, p) { return (v[p] << 8) + v[p + 1]; }
715 + 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.
716 + function ReadIntX(v, p) { return (v[p + 3] * 0x1000000) + (v[p + 2] << 16) + (v[p + 1] << 8) + v[p]; }
717 + function btoa(x) { return Buffer.from(x).toString('base64'); }
718 + function atob(x) { var z = null; try { z = Buffer.from(x, 'base64').toString(); } catch (e) { console.log(e); } return z; }
719 + function bufToArray(buf) { var r = []; for (var i in buf) { r.push(buf[i]); } return r; }
720 +
721 + function _GetAuditLog0(stack, name, responses, status, tag) {
722 + if (status != 200) { tag[0](obj, [], status); return; }
723 + var ptr, i, e, es, x, r = tag[1], t = new Date(), TimeStamp;
724 +
725 + if (responses.Body['RecordsReturned'] > 0) {
726 + responses.Body['EventRecords'] = MakeToArray(responses.Body['EventRecords']);
727 +
728 + for (i in responses.Body['EventRecords']) {
729 + e = null;
730 + try {
731 + es = atob(responses.Body['EventRecords'][i]);
732 + e = Buffer.from(es);
733 + } catch (ex) {
734 + console.log(ex + " " + responses.Body['EventRecords'][i])
735 + }
736 +
737 + x = { 'AuditAppID': ReadShort(e, 0), 'EventID': ReadShort(e, 2), 'InitiatorType': e[4] };
738 + x['AuditApp'] = _AmtAuditStringTable[x['AuditAppID']];
739 + x['Event'] = _AmtAuditStringTable[(x['AuditAppID'] * 100) + x['EventID']];
740 + if (!x['Event']) x['Event'] = '#' + x['EventID'];
741 +
742 + // Read and process the initiator
743 + if (x['InitiatorType'] == 0) {
744 + // HTTP digest
745 + var userlen = e[5];
746 + x['Initiator'] = e.slice(6, 6 + userlen).toString();
747 + ptr = 6 + userlen;
748 + }
749 + if (x['InitiatorType'] == 1) {
750 + // Kerberos
751 + x['KerberosUserInDomain'] = ReadInt(e, 5);
752 + var userlen = e[9];
753 + x['Initiator'] = GetSidString(e.slice(10, 10 + userlen));
754 + ptr = 10 + userlen;
755 + }
756 + if (x['InitiatorType'] == 2) {
757 + // Local
758 + x['Initiator'] = 'Local';
759 + ptr = 5;
760 + }
761 + if (x['InitiatorType'] == 3) {
762 + // KVM Default Port
763 + x['Initiator'] = 'KVM Default Port';
764 + ptr = 5;
765 + }
766 +
767 + // Read timestamp
768 + TimeStamp = ReadInt(e, ptr);
769 + x['Time'] = new Date((TimeStamp + (t.getTimezoneOffset() * 60)) * 1000);
770 + ptr += 4;
771 +
772 + // Read network access
773 + x['MCLocationType'] = e[ptr++];
774 + var netlen = e[ptr++];
775 +
776 + x['NetAddress'] = e.slice(ptr, ptr + netlen).toString();
777 +
778 + // Read extended data
779 + ptr += netlen;
780 + var exlen = e[ptr++];
781 + x['Ex'] = e.slice(ptr, ptr + exlen);
782 + x['ExStr'] = obj.GetAuditLogExtendedDataStr((x['AuditAppID'] * 100) + x['EventID'], x['Ex']);
783 + r.push(x);
784 + }
785 + }
786 + if (responses.Body['TotalRecordCount'] > r.length) {
787 + obj.AMT_AuditLog_ReadRecords(r.length + 1, _GetAuditLog0, [tag[0], r]);
788 + } else {
789 + tag[0](obj, r, status);
790 + }
791 + }
792 +
793 + // ###END###{AuditLog}
794 +
795 + /*
796 + // ###BEGIN###{Certificates}
797 +
798 + // Forge MD5
799 + function hex_md5(str) { return forge.md.md5.create().update(str).digest().toHex(); }
800 +
801 + // ###END###{Certificates}
802 +
803 + // ###BEGIN###{!Certificates}
804 +
805 + // TinyMD5 from https://github.com/jbt/js-crypto
806 +
807 + // Perform MD5 setup
808 + var md5_k = [];
809 + for (var i = 0; i < 64;) { md5_k[i] = 0 | (Math.abs(Math.sin(++i)) * 4294967296); }
810 +
811 + // Perform MD5 on raw string and return hex
812 + function hex_md5(str) {
813 + var b, c, d, j,
814 + x = [],
815 + str2 = unescape(encodeURI(str)),
816 + a = str2.length,
817 + h = [b = 1732584193, c = -271733879, ~b, ~c],
818 + i = 0;
819 +
820 + for (; i <= a;) x[i >> 2] |= (str2.charCodeAt(i) || 128) << 8 * (i++ % 4);
821 +
822 + x[str = (a + 8 >> 6) * 16 + 14] = a * 8;
823 + i = 0;
824 +
825 + for (; i < str; i += 16) {
826 + a = h; j = 0;
827 + for (; j < 64;) {
828 + a = [
829 + d = a[3],
830 + ((b = a[1] | 0) +
831 + ((d = (
832 + (a[0] +
833 + [
834 + b & (c = a[2]) | ~b & d,
835 + d & b | ~d & c,
836 + b ^ c ^ d,
837 + c ^ (b | ~d)
838 + ][a = j >> 4]
839 + ) +
840 + (md5_k[j] +
841 + (x[[
842 + j,
843 + 5 * j + 1,
844 + 3 * j + 5,
845 + 7 * j
846 + ][a] % 16 + i] | 0)
847 + )
848 + )) << (a = [
849 + 7, 12, 17, 22,
850 + 5, 9, 14, 20,
851 + 4, 11, 16, 23,
852 + 6, 10, 15, 21
853 + ][4 * a + j++ % 4]) | d >>> 32 - a)
854 + ),
855 + b,
856 + c
857 + ];
858 + }
859 + for (j = 4; j;) h[--j] = h[j] + a[j];
860 + }
861 +
862 + str = '';
863 + for (; j < 32;) str += ((h[j >> 3] >> ((1 ^ j++ & 7) * 4)) & 15).toString(16);
864 + return str;
865 + }
866 +
867 + // ###END###{!Certificates}
868 +
869 + // Perform MD5 on raw string and return raw string result
870 + function rstr_md5(str) { return hex2rstr(hex_md5(str)); }
871 + */
872 + /*
873 + Convert arguments into selector set and body XML. Used by AMT_WiFiPortConfigurationService_UpdateWiFiSettings.
874 + args = {
875 + "WiFiEndpoint": {
876 + __parameterType: 'reference',
877 + __resourceUri: 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpoint',
878 + Name: 'WiFi Endpoint 0'
879 + },
880 + "WiFiEndpointSettingsInput":
881 + {
882 + __parameterType: 'instance',
883 + __namespace: 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpointSettings',
884 + ElementName: document.querySelector('#editProfile-profileName').value,
885 + InstanceID: 'Intel(r) AMT:WiFi Endpoint Settings ' + document.querySelector('#editProfile-profileName').value,
886 + AuthenticationMethod: document.querySelector('#editProfile-networkAuthentication').value,
887 + //BSSType: 3, // Intel(r) AMT supports only infrastructure networks
888 + EncryptionMethod: document.querySelector('#editProfile-encryption').value,
889 + SSID: document.querySelector('#editProfile-networkName').value,
890 + Priority: 100,
891 + PSKPassPhrase: document.querySelector('#editProfile-passPhrase').value
892 + },
893 + "IEEE8021xSettingsInput": null,
894 + "ClientCredential": null,
895 + "CACredential": null
896 + },
897 + */
898 + function execArgumentsToXml(args) {
899 + if (args === undefined || args === null) return null;
900 +
901 + var result = '';
902 + for (var argName in args) {
903 + var arg = args[argName];
904 + if (!arg) continue;
905 + if (arg['__parameterType'] === 'reference') result += referenceToXml(argName, arg);
906 + else result += instanceToXml(argName, arg);
907 + //if(arg['__isInstance']) result += instanceToXml(argName, arg);
908 + }
909 + return result;
910 + }
911 +
912 + /**
913 + * Convert JavaScript object into XML
914 +
915 + <r:WiFiEndpointSettingsInput xmlns:q="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpointSettings">
916 + <q:ElementName>Wireless-Profile-Admin</q:ElementName>
917 + <q:InstanceID>Intel(r) AMT:WiFi Endpoint Settings Wireless-Profile-Admin</q:InstanceID>
918 + <q:AuthenticationMethod>6</q:AuthenticationMethod>
919 + <q:EncryptionMethod>4</q:EncryptionMethod>
920 + <q:Priority>100</q:Priority>
921 + <q:PSKPassPhrase>P@ssw0rd</q:PSKPassPhrase>
922 + </r:WiFiEndpointSettingsInput>
923 + */
924 + function instanceToXml(instanceName, inInstance) {
925 + if (inInstance === undefined || inInstance === null) return null;
926 +
927 + var hasNamespace = !!inInstance['__namespace'];
928 + var startTag = hasNamespace ? '<q:' : '<';
929 + var endTag = hasNamespace ? '</q:' : '</';
930 + var namespaceDef = hasNamespace ? (' xmlns:q="' + inInstance['__namespace'] + '"') : '';
931 + var result = '<r:' + instanceName + namespaceDef + '>';
932 + for (var prop in inInstance) {
933 + if (!inInstance.hasOwnProperty(prop) || prop.indexOf('__') === 0) continue;
934 +
935 + if (typeof inInstance[prop] === 'function' || Array.isArray(inInstance[prop])) continue;
936 +
937 + if (typeof inInstance[prop] === 'object') {
938 + //result += startTag + prop +'>' + instanceToXml('prop', inInstance[prop]) + endTag + prop +'>';
939 + console.error('only convert one level down...');
940 + }
941 + else {
942 + result += startTag + prop + '>' + inInstance[prop].toString() + endTag + prop + '>';
943 + }
944 + }
945 + result += '</r:' + instanceName + '>';
946 + return result;
947 + }
948 +
949 +
950 + /**
951 + * Convert a selector set into XML. Expect no nesting.
952 + * {
953 + * selectorName : selectorValue,
954 + * selectorName : selectorValue,
955 + * ... ...
956 + * }
957 +
958 + <r:WiFiEndpoint>
959 + <a:Address>http://192.168.1.103:16992/wsman</a:Address>
960 + <a:ReferenceParameters>
961 + <w:ResourceURI>http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpoint</w:ResourceURI>
962 + <w:SelectorSet>
963 + <w:Selector Name="Name">WiFi Endpoint 0</w:Selector>
964 + </w:SelectorSet>
965 + </a:ReferenceParameters>
966 + </r:WiFiEndpoint>
967 +
968 + */
969 + function referenceToXml(referenceName, inReference) {
970 + if (inReference === undefined || inReference === null) return null;
971 +
972 + var result = '<r:' + referenceName + '><a:Address>/wsman</a:Address><a:ReferenceParameters><w:ResourceURI>' + inReference['__resourceUri'] + '</w:ResourceURI><w:SelectorSet>';
973 + for (var selectorName in inReference) {
974 + if (!inReference.hasOwnProperty(selectorName) || selectorName.indexOf('__') === 0) continue;
975 +
976 + if (typeof inReference[selectorName] === 'function' ||
977 + typeof inReference[selectorName] === 'object' ||
978 + Array.isArray(inReference[selectorName]))
979 + continue;
980 +
981 + result += '<w:Selector Name="' + selectorName + '">' + inReference[selectorName].toString() + '</w:Selector>';
982 + }
983 +
984 + result += '</w:SelectorSet></a:ReferenceParameters></r:' + referenceName + '>';
985 + return result;
986 + }
987 +
988 + // Convert a byte array of SID into string
989 + function GetSidString(sid) {
990 + var r = "S-" + sid.charCodeAt(0) + "-" + sid.charCodeAt(7);
991 + for (var i = 2; i < (sid.length / 4); i++) r += "-" + ReadIntX(sid, i * 4);
992 + return r;
993 + }
994 +
995 + // Convert a SID readable string into bytes
996 + function GetSidByteArray(sidString) {
997 + if (!sidString || sidString == null) return null;
998 + var sidParts = sidString.split('-');
999 +
1000 + // Make sure the SID has at least 4 parts and starts with 'S'
1001 + if (sidParts.length < 4 || (sidParts[0] != 's' && sidParts[0] != 'S')) return null;
1002 +
1003 + // Check that each part of the SID is really an integer
1004 + for (var i = 1; i < sidParts.length; i++) { var y = parseInt(sidParts[i]); if (y != sidParts[i]) return null; sidParts[i] = y; }
1005 +
1006 + // 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.
1007 + var r = String.fromCharCode(sidParts[1]) + String.fromCharCode(sidParts.length - 3) + ShortToStr(Math.floor(sidParts[2] / Math.pow(2, 32))) + IntToStr((sidParts[2]) & 0xFFFF);
1008 +
1009 + // the rest are in 32 bit in little endian
1010 + for (var i = 3; i < sidParts.length; i++) r += IntToStrX(sidParts[i]);
1011 + return r;
1012 + }
1013 +
1014 + return obj;
1015 +}
1016 +
1017 +module.exports = AmtStackCreateService;
agents-new/modules_meshcmd/service-host.js new
+389
@@ -0,0 +1,389 @@
1 +/*
2 +Copyright 2018 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +
18 +var SERVICE_WIN32 = 0x00000010 | 0x00000020;
19 +var SERVICE_STATE = { STOPPED: 0x00000001, SERVICE_START_PENDING: 0x00000002, SERVICE_STOP_PENDING: 0x00000003, RUNNING: 0x00000004 };
20 +var SERVICE_ACCEPT = { SERVICE_ACCEPT_STOP: 0x00000001, SERVICE_ACCEPT_SHUTDOWN: 0x00000004, SERVICE_ACCEPT_POWEREVENT: 0x00000040, SERVICE_ACCEPT_SESSIONCHANGE: 0x00000080 };
21 +
22 +var SERVICE_CONTROL = { SERVICE_CONTROL_SHUTDOWN: 0x00000005, SERVICE_CONTROL_STOP: 0x00000001, SERVICE_CONTROL_POWEREVENT: 0x0000000D, SERVICE_CONTROL_SESSIONCHANGE: 0x0000000E};
23 +var SESSION_CHANGE_TYPE =
24 +{
25 + WTS_CONSOLE_CONNECT: 0x1,
26 + WTS_CONSOLE_DISCONNECT: 0x2,
27 + WTS_REMOTE_CONNECT: 0x3,
28 + WTS_REMOTE_DISCONNECT: 0x4,
29 + WTS_SESSION_LOGON: 0x5,
30 + WTS_SESSION_LOGOFF: 0x6,
31 + WTS_SESSION_LOCK: 0x7,
32 + WTS_SESSION_UNLOCK: 0x8,
33 + WTS_SESSION_REMOTE_CONTROL: 0x9,
34 + WTS_SESSION_CREATE: 0xa,
35 + WTS_SESSION_TERMINATE: 0xb
36 +};
37 +
38 +
39 +var NO_ERROR = 0;
40 +
41 +var serviceManager = require('service-manager');
42 +
43 +function serviceHost(serviceName)
44 +{
45 + this._ObjectID = 'service-host';
46 + var emitterUtils = require('events').inherits(this);
47 + emitterUtils.createEvent('serviceStart');
48 + emitterUtils.createEvent('serviceStop');
49 + emitterUtils.createEvent('normalStart');
50 + emitterUtils.createEvent('session');
51 + emitterUtils.createEvent('powerStateChange');
52 +
53 + if (process.platform == 'win32')
54 + {
55 + this.GM = require('_GenericMarshal');
56 + this.Advapi = this.GM.CreateNativeProxy('Advapi32.dll');
57 + this.Advapi.CreateMethod({ method: 'StartServiceCtrlDispatcherA', threadDispatch: 1 });
58 + this.Advapi.CreateMethod('RegisterServiceCtrlHandlerExA');
59 + this.Advapi.CreateMethod('SetServiceStatus');
60 + this.Kernel32 = this.GM.CreateNativeProxy('Kernel32.dll');
61 + this.Kernel32.CreateMethod('GetLastError');
62 +
63 + this.Ole32 = this.GM.CreateNativeProxy('Ole32.dll');
64 + this.Ole32.CreateMethod('CoInitializeEx');
65 + this.Ole32.CreateMethod('CoUninitialize');
66 +
67 + this._ServiceName = this.GM.CreateVariable(typeof (serviceName) == 'string' ? serviceName : serviceName.name);
68 + this._ServiceMain = this.GM.GetGenericGlobalCallback(2);
69 + this._ServiceMain.Parent = this;
70 + this._ServiceMain.GM = this.GM;
71 + this._ServiceMain.on('GlobalCallback', function onGlobalCallback(argc, argv)
72 + {
73 + //ToDo: Check to make sure this is for us
74 +
75 + this.Parent._ServiceStatus = this.GM.CreateVariable(28);
76 + //typedef struct _SERVICE_STATUS {
77 + // DWORD dwServiceType;
78 + // DWORD dwCurrentState;
79 + // DWORD dwControlsAccepted;
80 + // DWORD dwWin32ExitCode;
81 + // DWORD dwServiceSpecificExitCode;
82 + // DWORD dwCheckPoint;
83 + // DWORD dwWaitHint;
84 + //} SERVICE_STATUS, *LPSERVICE_STATUS;
85 +
86 + // Initialise service status
87 + this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_WIN32);
88 + this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.SERVICE_STOPPED, 4);
89 + this.Parent._ServiceStatusHandle = this.Parent.Advapi.RegisterServiceCtrlHandlerExA(this.Parent._ServiceName, this.Parent._ServiceControlHandler, this.Parent.GM.StashObject(this.Parent._ServiceControlHandler));
90 + if(this.Parent._ServiceStatusHandle.Val == 0)
91 + {
92 + process.exit(1);
93 + }
94 +
95 + // Service is starting
96 + this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.SERVICE_START_PENDING, 4);
97 + this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus);
98 +
99 + // Service running
100 + this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.RUNNING, 4);
101 + this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_ACCEPT.SERVICE_ACCEPT_STOP | SERVICE_ACCEPT.SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT.SERVICE_ACCEPT_SESSIONCHANGE, 8);
102 + this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus);
103 +
104 + this.Parent.Ole32.CoInitializeEx(0, 2);
105 + this.Parent.on('~', function OnServiceHostFinalizer()
106 + {
107 + var GM = require('_GenericMarshal');
108 + var Advapi = GM.CreateNativeProxy('Advapi32.dll');
109 + Advapi.CreateMethod('SetServiceStatus');
110 +
111 + Kernel32 = this.GM.CreateNativeProxy('Kernel32.dll');
112 + Kernel32.CreateMethod('GetLastError');
113 +
114 + var status = GM.CreateVariable(28);
115 +
116 + // Service was stopped
117 + status.toBuffer().writeUInt32LE(SERVICE_WIN32);
118 + status.toBuffer().writeUInt32LE(0x00000001, 4);
119 + status.toBuffer().writeUInt32LE(0, 8);
120 +
121 + Advapi.SetServiceStatus(this._ServiceStatusHandle, status);
122 +
123 + this.Ole32.CoUninitialize();
124 + });
125 +
126 + this.Parent.emit('serviceStart');
127 + });
128 + this._ServiceControlHandler = this.GM.GetGenericGlobalCallback(4);
129 + this._ServiceControlHandler.Parent = this;
130 + this._ServiceControlHandler.GM = this.GM;
131 + this._ServiceControlHandler.on('GlobalCallback', function onServiceControlHandler(code, eventType, eventData, context)
132 + {
133 + var j = this.Parent.GM.UnstashObject(context);
134 + if (j != null && j == this)
135 + {
136 + switch (code.Val)
137 + {
138 + case SERVICE_CONTROL.SERVICE_CONTROL_SHUTDOWN:
139 + case SERVICE_CONTROL.SERVICE_CONTROL_STOP:
140 + this.Parent.emit('serviceStop');
141 + return;
142 + case SERVICE_CONTROL.SERVICE_CONTROL_SESSIONCHANGE:
143 + var sessionId = eventData.Deref(4, 4).toBuffer().readUInt32LE();
144 + switch(eventType.Val)
145 + {
146 + case SESSION_CHANGE_TYPE.WTS_SESSION_LOGON:
147 + case SESSION_CHANGE_TYPE.WTS_SESSION_LOGOFF:
148 + require('user-sessions').emit('changed');
149 + break;
150 + }
151 + break;
152 + default:
153 + break;
154 + }
155 +
156 + this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus);
157 + }
158 + });
159 + }
160 +
161 + if (serviceName) { this._ServiceOptions = typeof (serviceName) == 'object' ? serviceName : { name: serviceName }; }
162 + else
163 + {
164 + throw ('Must specify either ServiceName or Options');
165 + }
166 + if (!this._ServiceOptions.servicePath)
167 + {
168 + this._ServiceOptions.servicePath = process.execPath;
169 + }
170 +
171 + this.run = function run()
172 + {
173 + var serviceOperation = 0;
174 +
175 + for(var i = 0; i<process.argv.length; ++i)
176 + {
177 + switch(process.argv[i])
178 + {
179 + case '-install':
180 + if (!this._svcManager) { this._svcManager = new serviceManager(); }
181 + try
182 + {
183 + this._svcManager.installService(this._ServiceOptions);
184 + }
185 + catch(e)
186 + {
187 + console.log(e);
188 + process.exit();
189 + }
190 +
191 + console.log(this._ServiceOptions.name + ' installed');
192 + process.exit();
193 + break;
194 + case '-uninstall':
195 + if (!this._svcManager) { this._svcManager = new serviceManager(); }
196 + try
197 + {
198 + this._svcManager.uninstallService(this._ServiceOptions);
199 + }
200 + catch(e)
201 + {
202 + console.log(e);
203 + process.exit();
204 + }
205 + if (process.platform == 'win32' || process.platform == 'darwin')
206 + {
207 + // Only do this on Windows/MacOS, becuase Linux is async... It'll complete later
208 + console.log(this._ServiceOptions.name + ' uninstalled');
209 + process.exit();
210 + }
211 + i = process.argv.length;
212 + serviceOperation = 1;
213 + break;
214 + case 'start':
215 + case '-d':
216 + if (process.platform != 'win32') { break; }
217 + if (!this._svcManager) { this._svcManager = new serviceManager(); }
218 + this._svcManager.getService(this._ServiceOptions.name).start();
219 + console.log(this._ServiceOptions.name + ' starting...');
220 + process.exit();
221 + break;
222 + case 'stop':
223 + case '-s':
224 + if (process.platform != 'win32') { break; }
225 + if (!this._svcManager) { this._svcManager = new serviceManager(); }
226 + this._svcManager.getService(this._ServiceOptions.name).stop();
227 + console.log(this._ServiceOptions.name + ' stopping...');
228 + process.exit();
229 + break;
230 +
231 + }
232 + }
233 +
234 + if (process.platform == 'win32')
235 + {
236 + var serviceTable = this.GM.CreateVariable(4 * this.GM.PointerSize);
237 + this._ServiceName.pointerBuffer().copy(serviceTable.toBuffer());
238 + this._ServiceMain.pointerBuffer().copy(serviceTable.toBuffer(), this.GM.PointerSize);
239 + this._sscd = this.Advapi.StartServiceCtrlDispatcherA(serviceTable);
240 + this._sscd.parent = this;
241 + this._sscd.on('done', function OnStartServiceCtrlDispatcherA(retVal) {
242 + if (retVal.Val == 0)
243 + {
244 + this.parent.emit('normalStart');
245 + }
246 + });
247 + return;
248 + }
249 + else if (process.platform == 'linux')
250 + {
251 + var moduleName = this._ServiceOptions ? this._ServiceOptions.name : process.execPath.substring(1 + process.execPath.lastIndexOf('/'));
252 +
253 + for (var i = 0; i < process.argv.length; ++i) {
254 + switch (process.argv[i]) {
255 + case 'start':
256 + case '-d':
257 + var child = require('child_process').execFile(process.execPath, [moduleName], { type: require('child_process').SpawnTypes.DETACHED });
258 + var pstream = null;
259 + try {
260 + pstream = require('fs').createWriteStream('/var/run/' + moduleName + '.pid', { flags: 'w' });
261 + }
262 + catch (e) {
263 + }
264 + if (pstream == null) {
265 + pstream = require('fs').createWriteStream('.' + moduleName + '.pid', { flags: 'w' });
266 + }
267 + pstream.end(child.pid.toString());
268 +
269 + console.log(moduleName + ' started!');
270 + process.exit();
271 + break;
272 + case 'stop':
273 + case '-s':
274 + var pid = null;
275 + try {
276 + pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' }));
277 + require('fs').unlinkSync('/var/run/' + moduleName + '.pid');
278 + }
279 + catch (e) {
280 + }
281 + if (pid == null) {
282 + try {
283 + pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' }));
284 + require('fs').unlinkSync('.' + moduleName + '.pid');
285 + }
286 + catch (e) {
287 + }
288 + }
289 +
290 + if (pid) {
291 + process.kill(pid);
292 + console.log(moduleName + ' stopped');
293 + }
294 + else {
295 + console.log(moduleName + ' not running');
296 + }
297 + process.exit();
298 + break;
299 + }
300 + }
301 +
302 + if (serviceOperation == 0) {
303 + // This is non-windows, so we need to check how this binary was started to determine if this was a service start
304 +
305 + // Start by checking if we were started with start/stop
306 + var pid = null;
307 + try {
308 + pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' }));
309 + }
310 + catch (e) {
311 + }
312 + if (pid == null) {
313 + try {
314 + pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' }));
315 + }
316 + catch (e) {
317 + }
318 + }
319 +
320 + if (pid != null && pid == process.pid) {
321 + this.emit('serviceStart');
322 + }
323 + else {
324 + // Now we need to check if we were started with systemd
325 + if (require('process-manager').getProcessInfo(1).Name == 'systemd') {
326 + this._checkpid = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
327 + this._checkpid.result = '';
328 + this._checkpid.parent = this;
329 + this._checkpid.on('exit', function onCheckPIDExit() {
330 + var lines = this.result.split('\r\n');
331 + for (i in lines) {
332 + if (lines[i].startsWith(' Main PID:')) {
333 + var tokens = lines[i].split(' ');
334 + if (parseInt(tokens[3]) == process.pid) {
335 + this.parent.emit('serviceStart');
336 + }
337 + else {
338 + this.parent.emit('normalStart');
339 + }
340 + delete this.parent._checkpid;
341 + return;
342 + }
343 + }
344 + this.parent.emit('normalStart');
345 + delete this.parent._checkpid;
346 + });
347 + this._checkpid.stdout.on('data', function (chunk) { this.parent.result += chunk.toString(); });
348 + this._checkpid.stdin.write("systemctl status " + moduleName + " | grep 'Main PID:'\n");
349 + this._checkpid.stdin.write('exit\n');
350 + }
351 + else {
352 + // This isn't even a systemd platform, so this couldn't have been a service start
353 + this.emit('normalStart');
354 + }
355 + }
356 + }
357 + }
358 + else if(process.platform == 'darwin')
359 + {
360 + // First let's fetch all the PIDs of running services
361 + var child = require('child_process').execFile('/bin/sh', ['sh']);
362 + child.stdout.str = '';
363 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
364 + child.stdin.write('launchctl list\nexit\n');
365 + child.waitExit();
366 +
367 + var lines = child.stdout.str.split('\n');
368 + var tokens, i;
369 + var p = {};
370 + for (i = 1; i < lines.length; ++i)
371 + {
372 + tokens = lines[i].split('\t');
373 + if (tokens[0] && tokens[0] != '-') { p[tokens[0]] = tokens[0]; }
374 + }
375 +
376 + if(p[process.pid.toString()])
377 + {
378 + // We are a service!
379 + this.emit('serviceStart');
380 + }
381 + else
382 + {
383 + this.emit('normalStart');
384 + }
385 + }
386 + };
387 +}
388 +
389 +module.exports = serviceHost;
\ No newline at end of file
agents-new/modules_meshcmd/service-manager.js new
+497
@@ -0,0 +1,497 @@
1 +/*
2 +Copyright 2018 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +function parseServiceStatus(token)
18 +{
19 + var j = {};
20 + var serviceType = token.Deref(0, 4).IntVal;
21 + j.isFileSystemDriver = ((serviceType & 0x00000002) == 0x00000002);
22 + j.isKernelDriver = ((serviceType & 0x00000001) == 0x00000001);
23 + j.isSharedProcess = ((serviceType & 0x00000020) == 0x00000020);
24 + j.isOwnProcess = ((serviceType & 0x00000010) == 0x00000010);
25 + j.isInteractive = ((serviceType & 0x00000100) == 0x00000100);
26 + switch (token.Deref((1 * 4), 4).toBuffer().readUInt32LE())
27 + {
28 + case 0x00000005:
29 + j.state = 'CONTINUE_PENDING';
30 + break;
31 + case 0x00000006:
32 + j.state = 'PAUSE_PENDING';
33 + break;
34 + case 0x00000007:
35 + j.state = 'PAUSED';
36 + break;
37 + case 0x00000004:
38 + j.state = 'RUNNING';
39 + break;
40 + case 0x00000002:
41 + j.state = 'START_PENDING';
42 + break;
43 + case 0x00000003:
44 + j.state = 'STOP_PENDING';
45 + break;
46 + case 0x00000001:
47 + j.state = 'STOPPED';
48 + break;
49 + }
50 + var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE();
51 + j.controlsAccepted = [];
52 + if ((controlsAccepted & 0x00000010) == 0x00000010)
53 + {
54 + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDADD');
55 + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDREMOVE');
56 + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDENABLE');
57 + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDDISABLE');
58 + }
59 + if ((controlsAccepted & 0x00000008) == 0x00000008) { j.controlsAccepted.push('SERVICE_CONTROL_PARAMCHANGE'); }
60 + if ((controlsAccepted & 0x00000002) == 0x00000002) { j.controlsAccepted.push('SERVICE_CONTROL_PAUSE'); j.controlsAccepted.push('SERVICE_CONTROL_CONTINUE'); }
61 + if ((controlsAccepted & 0x00000100) == 0x00000100) { j.controlsAccepted.push('SERVICE_CONTROL_PRESHUTDOWN'); }
62 + if ((controlsAccepted & 0x00000004) == 0x00000004) { j.controlsAccepted.push('SERVICE_CONTROL_SHUTDOWN'); }
63 + if ((controlsAccepted & 0x00000001) == 0x00000001) { j.controlsAccepted.push('SERVICE_CONTROL_STOP'); }
64 + if ((controlsAccepted & 0x00000020) == 0x00000020) { j.controlsAccepted.push('SERVICE_CONTROL_HARDWAREPROFILECHANGE'); }
65 + if ((controlsAccepted & 0x00000040) == 0x00000040) { j.controlsAccepted.push('SERVICE_CONTROL_POWEREVENT'); }
66 + if ((controlsAccepted & 0x00000080) == 0x00000080) { j.controlsAccepted.push('SERVICE_CONTROL_SESSIONCHANGE'); }
67 + j.pid = token.Deref((7 * 4), 4).toBuffer().readUInt32LE();
68 + return (j);
69 +}
70 +
71 +function serviceManager()
72 +{
73 + this._ObjectID = 'service-manager';
74 + if (process.platform == 'win32')
75 + {
76 + this.GM = require('_GenericMarshal');
77 + this.proxy = this.GM.CreateNativeProxy('Advapi32.dll');
78 + this.proxy.CreateMethod('OpenSCManagerA');
79 + this.proxy.CreateMethod('EnumServicesStatusExA');
80 + this.proxy.CreateMethod('OpenServiceA');
81 + this.proxy.CreateMethod('QueryServiceStatusEx');
82 + this.proxy.CreateMethod('ControlService');
83 + this.proxy.CreateMethod('StartServiceA');
84 + this.proxy.CreateMethod('CloseServiceHandle');
85 + this.proxy.CreateMethod('CreateServiceA');
86 + this.proxy.CreateMethod('ChangeServiceConfig2A');
87 + this.proxy.CreateMethod('DeleteService');
88 + this.proxy.CreateMethod('AllocateAndInitializeSid');
89 + this.proxy.CreateMethod('CheckTokenMembership');
90 + this.proxy.CreateMethod('FreeSid');
91 +
92 + this.proxy2 = this.GM.CreateNativeProxy('Kernel32.dll');
93 + this.proxy2.CreateMethod('GetLastError');
94 +
95 + this.isAdmin = function isAdmin() {
96 + var NTAuthority = this.GM.CreateVariable(6);
97 + NTAuthority.toBuffer().writeInt8(5, 5);
98 + var AdministratorsGroup = this.GM.CreatePointer();
99 + var admin = false;
100 +
101 + if (this.proxy.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0)
102 + {
103 + var member = this.GM.CreateInteger();
104 + if (this.proxy.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0)
105 + {
106 + if (member.toBuffer().readUInt32LE() != 0) { admin = true; }
107 + }
108 + this.proxy.FreeSid(AdministratorsGroup.Deref());
109 + }
110 + return admin;
111 + };
112 + this.getProgramFolder = function getProgramFolder()
113 + {
114 + if (require('os').arch() == 'x64')
115 + {
116 + // 64 bit Windows
117 + if (this.GM.PointerSize == 4)
118 + {
119 + return process.env['ProgramFiles(x86)']; // 32 Bit App
120 + }
121 + return process.env['ProgramFiles']; // 64 bit App
122 + }
123 +
124 + // 32 bit Windows
125 + return process.env['ProgramFiles'];
126 + };
127 + this.getServiceFolder = function getServiceFolder() { return this.getProgramFolder() + '\\mesh'; };
128 +
129 + this.enumerateService = function () {
130 + var machineName = this.GM.CreatePointer();
131 + var dbName = this.GM.CreatePointer();
132 + var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0001 | 0x0004);
133 +
134 + var bytesNeeded = this.GM.CreatePointer();
135 + var servicesReturned = this.GM.CreatePointer();
136 + var resumeHandle = this.GM.CreatePointer();
137 + //var services = this.proxy.CreateVariable(262144);
138 + var success = this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, 0x00, 0x00, bytesNeeded, servicesReturned, resumeHandle, 0x00);
139 + if (bytesNeeded.IntVal <= 0) {
140 + throw ('error enumerating services');
141 + }
142 + var sz = bytesNeeded.IntVal;
143 + var services = this.GM.CreateVariable(sz);
144 + this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, services, sz, bytesNeeded, servicesReturned, resumeHandle, 0x00);
145 + console.log("servicesReturned", servicesReturned.IntVal);
146 +
147 + var ptrSize = dbName._size;
148 + var blockSize = 36 + (2 * ptrSize);
149 + blockSize += ((ptrSize - (blockSize % ptrSize)) % ptrSize);
150 + var retVal = [];
151 + for (var i = 0; i < servicesReturned.IntVal; ++i) {
152 + var token = services.Deref(i * blockSize, blockSize);
153 + var j = {};
154 + j.name = token.Deref(0, ptrSize).Deref().String;
155 + j.displayName = token.Deref(ptrSize, ptrSize).Deref().String;
156 + j.status = parseServiceStatus(token.Deref(2 * ptrSize, 36));
157 + retVal.push(j);
158 + }
159 + this.proxy.CloseServiceHandle(handle);
160 + return (retVal);
161 + }
162 + this.getService = function (name) {
163 + var serviceName = this.GM.CreateVariable(name);
164 + var ptr = this.GM.CreatePointer();
165 + var bytesNeeded = this.GM.CreateVariable(ptr._size);
166 + var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0001 | 0x0004 | 0x0020 | 0x0010);
167 + if (handle.Val == 0) { throw ('could not open ServiceManager'); }
168 + var h = this.proxy.OpenServiceA(handle, serviceName, 0x0004 | 0x0020 | 0x0010 | 0x00010000);
169 + if (h.Val != 0) {
170 + var success = this.proxy.QueryServiceStatusEx(h, 0, 0, 0, bytesNeeded);
171 + var status = this.GM.CreateVariable(bytesNeeded.toBuffer().readUInt32LE());
172 + success = this.proxy.QueryServiceStatusEx(h, 0, status, status._size, bytesNeeded);
173 + if (success != 0) {
174 + retVal = {};
175 + retVal.status = parseServiceStatus(status);
176 + retVal._scm = handle;
177 + retVal._service = h;
178 + retVal._GM = this.GM;
179 + retVal._proxy = this.proxy;
180 + require('events').inherits(retVal);
181 + retVal.on('~', function () { this._proxy.CloseServiceHandle(this); this._proxy.CloseServiceHandle(this._scm); });
182 + retVal.name = name;
183 + retVal.stop = function () {
184 + if (this.status.state == 'RUNNING') {
185 + var newstate = this._GM.CreateVariable(36);
186 + var success = this._proxy.ControlService(this._service, 0x00000001, newstate);
187 + if (success == 0) {
188 + throw (this.name + '.stop() failed');
189 + }
190 + }
191 + else {
192 + throw ('cannot call ' + this.name + '.stop(), when current state is: ' + this.status.state);
193 + }
194 + }
195 + retVal.start = function () {
196 + if (this.status.state == 'STOPPED') {
197 + var success = this._proxy.StartServiceA(this._service, 0, 0);
198 + if (success == 0) {
199 + throw (this.name + '.start() failed');
200 + }
201 + }
202 + else {
203 + throw ('cannot call ' + this.name + '.start(), when current state is: ' + this.status.state);
204 + }
205 + }
206 + return (retVal);
207 + }
208 + else {
209 +
210 + }
211 + }
212 +
213 + this.proxy.CloseServiceHandle(handle);
214 + throw ('could not find service: ' + name);
215 + }
216 + }
217 + else
218 + {
219 + this.isAdmin = function isAdmin()
220 + {
221 + return (require('user-sessions').isRoot());
222 + }
223 + }
224 + this.installService = function installService(options)
225 + {
226 + if (process.platform == 'win32')
227 + {
228 + if (!this.isAdmin()) { throw ('Installing as Service, requires admin'); }
229 +
230 + // Before we start, we need to copy the binary to the right place
231 + var folder = this.getServiceFolder();
232 + if (!require('fs').existsSync(folder)) { require('fs').mkdirSync(folder); }
233 + require('fs').copyFileSync(options.servicePath, folder + '\\' + options.name + '.exe');
234 + options.servicePath = folder + '\\' + options.name + '.exe';
235 +
236 + var servicePath = this.GM.CreateVariable('"' + options.servicePath + '"');
237 + var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0002);
238 + if (handle.Val == 0) { throw ('error opening SCManager'); }
239 + var serviceName = this.GM.CreateVariable(options.name);
240 + var displayName = this.GM.CreateVariable(options.name);
241 + var allAccess = 0x000F01FF;
242 + var serviceType;
243 +
244 +
245 + switch (options.startType) {
246 + case 'BOOT_START':
247 + serviceType = 0x00;
248 + break;
249 + case 'SYSTEM_START':
250 + serviceType = 0x01;
251 + break;
252 + case 'AUTO_START':
253 + serviceType = 0x02;
254 + break;
255 + case 'DEMAND_START':
256 + serviceType = 0x03;
257 + break;
258 + default:
259 + serviceType = 0x04; // Disabled
260 + break;
261 + }
262 +
263 + var h = this.proxy.CreateServiceA(handle, serviceName, displayName, allAccess, 0x10 | 0x100, serviceType, 0, servicePath, 0, 0, 0, 0, 0);
264 + if (h.Val == 0) { this.proxy.CloseServiceHandle(handle); throw ('Error Creating Service: ' + this.proxy2.GetLastError().Val); }
265 + if (options.description) {
266 + console.log(options.description);
267 +
268 + var dscPtr = this.GM.CreatePointer();
269 + dscPtr.Val = this.GM.CreateVariable(options.description);
270 +
271 + if (this.proxy.ChangeServiceConfig2A(h, 1, dscPtr) == 0) {
272 + this.proxy.CloseServiceHandle(h);
273 + this.proxy.CloseServiceHandle(handle);
274 + throw ('Unable to set description');
275 + }
276 + }
277 + this.proxy.CloseServiceHandle(h);
278 + this.proxy.CloseServiceHandle(handle);
279 + return (this.getService(options.name));
280 + }
281 + if(process.platform == 'linux')
282 + {
283 + if (!this.isAdmin()) { throw ('Installing as Service, requires root'); }
284 +
285 + switch (this.getServiceType())
286 + {
287 + case 'init':
288 + require('fs').copyFileSync(options.servicePath, '/etc/init.d/' + options.name);
289 + console.log('copying ' + options.servicePath);
290 + var m = require('fs').statSync('/etc/init.d/' + options.name).mode;
291 + m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP);
292 + require('fs').chmodSync('/etc/init.d/' + options.name, m);
293 + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
294 + this._update._moduleName = options.name;
295 + this._update.stdout.on('data', function (chunk) { });
296 + this._update.stdin.write('update-rc.d ' + options.name + ' defaults\n');
297 + this._update.stdin.write('exit\n');
298 + //update-rc.d meshagent defaults # creates symlinks for rc.d
299 + //service meshagent start
300 +
301 + this._update.waitExit();
302 +
303 + break;
304 + case 'systemd':
305 + var serviceDescription = options.description ? options.description : 'MeshCentral Agent';
306 + if (!require('fs').existsSync('/usr/local/mesh')) { require('fs').mkdirSync('/usr/local/mesh'); }
307 + require('fs').copyFileSync(options.servicePath, '/usr/local/mesh/' + options.name);
308 + var m = require('fs').statSync('/usr/local/mesh/' + options.name).mode;
309 + m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP);
310 + require('fs').chmodSync('/usr/local/mesh/' + options.name, m);
311 + 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' });
312 + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
313 + this._update._moduleName = options.name;
314 + this._update.stdout.on('data', function (chunk) { });
315 + this._update.stdin.write('systemctl enable ' + options.name + '.service\n');
316 + this._update.stdin.write('exit\n');
317 + this._update.waitExit();
318 + break;
319 + default: // unknown platform service type
320 + break;
321 + }
322 + }
323 + if(process.platform == 'darwin')
324 + {
325 + if (!this.isAdmin()) { throw ('Installing as Service, requires root'); }
326 +
327 + // Mac OS
328 + var stdoutpath = (options.stdout ? ('<key>StandardOutPath</key>\n<string>' + options.stdout + '</string>') : '');
329 + var autoStart = (options.startType == 'AUTO_START' ? '<true/>' : '<false/>');
330 + var params = ' <key>ProgramArguments</key>\n';
331 + params += ' <array>\n';
332 + params += (' <string>/usr/local/mesh_services/' + options.name + '/' + options.name + '</string>\n');
333 + if(options.parameters)
334 + {
335 + for(var itm in options.parameters)
336 + {
337 + params += (' <string>' + options.parameters[itm] + '</string>\n');
338 + }
339 + }
340 + params += ' </array>\n';
341 +
342 + var plist = '<?xml version="1.0" encoding="UTF-8"?>\n';
343 + plist += '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n';
344 + plist += '<plist version="1.0">\n';
345 + plist += ' <dict>\n';
346 + plist += ' <key>Label</key>\n';
347 + plist += (' <string>' + options.name + '</string>\n');
348 + plist += (params + '\n');
349 + plist += ' <key>WorkingDirectory</key>\n';
350 + plist += (' <string>/usr/local/mesh_services/' + options.name + '</string>\n');
351 + plist += (stdoutpath + '\n');
352 + plist += ' <key>RunAtLoad</key>\n';
353 + plist += (autoStart + '\n');
354 + plist += ' </dict>\n';
355 + plist += '</plist>';
356 +
357 + if (!require('fs').existsSync('/usr/local/mesh_services')) { require('fs').mkdirSync('/usr/local/mesh_services'); }
358 + if (!require('fs').existsSync('/Library/LaunchDaemons/' + options.name + '.plist'))
359 + {
360 + if (!require('fs').existsSync('/usr/local/mesh_services/' + options.name)) { require('fs').mkdirSync('/usr/local/mesh_services/' + options.name); }
361 + if (options.binary)
362 + {
363 + require('fs').writeFileSync('/usr/local/mesh_services/' + options.name + '/' + options.name, options.binary);
364 + }
365 + else
366 + {
367 + require('fs').copyFileSync(options.servicePath, '/usr/local/mesh_services/' + options.name + '/' + options.name);
368 + }
369 + require('fs').writeFileSync('/Library/LaunchDaemons/' + options.name + '.plist', plist);
370 + var m = require('fs').statSync('/usr/local/mesh_services/' + options.name + '/' + options.name).mode;
371 + m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP);
372 + require('fs').chmodSync('/usr/local/mesh_services/' + options.name + '/' + options.name, m);
373 + }
374 + else
375 + {
376 + throw ('Service: ' + options.name + ' already exists');
377 + }
378 + }
379 + }
380 + this.uninstallService = function uninstallService(name)
381 + {
382 + if (!this.isAdmin()) { throw ('Uninstalling a service, requires admin'); }
383 +
384 + if (typeof (name) == 'object') { name = name.name; }
385 + if (process.platform == 'win32')
386 + {
387 + var service = this.getService(name);
388 + if (service.status.state == undefined || service.status.state == 'STOPPED')
389 + {
390 + if (this.proxy.DeleteService(service._service) == 0)
391 + {
392 + throw ('Uninstall Service for: ' + name + ', failed with error: ' + this.proxy2.GetLastError());
393 + }
394 + else
395 + {
396 + try
397 + {
398 + require('fs').unlinkSync(this.getServiceFolder() + '\\' + name + '.exe');
399 + }
400 + catch(e)
401 + {
402 + }
403 + }
404 + }
405 + else
406 + {
407 + throw ('Cannot uninstall service: ' + name + ', because it is: ' + service.status.state);
408 + }
409 + }
410 + else if(process.platform == 'linux')
411 + {
412 + switch (this.getServiceType())
413 + {
414 + case 'init':
415 + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
416 + this._update.stdout.on('data', function (chunk) { });
417 + this._update.stdin.write('service ' + name + ' stop\n');
418 + this._update.stdin.write('update-rc.d -f ' + name + ' remove\n');
419 + this._update.stdin.write('exit\n');
420 + this._update.waitExit();
421 + try
422 + {
423 + require('fs').unlinkSync('/etc/init.d/' + name);
424 + console.log(name + ' uninstalled');
425 +
426 + }
427 + catch (e)
428 + {
429 + console.log(name + ' could not be uninstalled', e)
430 + }
431 + break;
432 + case 'systemd':
433 + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
434 + this._update.stdout.on('data', function (chunk) { });
435 + this._update.stdin.write('systemctl stop ' + name + '.service\n');
436 + this._update.stdin.write('systemctl disable ' + name + '.service\n');
437 + this._update.stdin.write('exit\n');
438 + this._update.waitExit();
439 + try
440 + {
441 + require('fs').unlinkSync('/usr/local/mesh/' + name);
442 + require('fs').unlinkSync('/lib/systemd/system/' + name + '.service');
443 + console.log(name + ' uninstalled');
444 + }
445 + catch (e)
446 + {
447 + console.log(name + ' could not be uninstalled', e)
448 + }
449 + break;
450 + default: // unknown platform service type
451 + break;
452 + }
453 + }
454 + else if(process.platform == 'darwin')
455 + {
456 + if (require('fs').existsSync('/Library/LaunchDaemons/' + name + '.plist'))
457 + {
458 + var child = require('child_process').execFile('/bin/sh', ['sh']);
459 + child.stdout.on('data', function (chunk) { });
460 + child.stdin.write('launchctl stop ' + name + '\n');
461 + child.stdin.write('launchctl unload /Library/LaunchDaemons/' + name + '.plist\n');
462 + child.stdin.write('exit\n');
463 + child.waitExit();
464 +
465 + try
466 + {
467 + require('fs').unlinkSync('/usr/local/mesh_services/' + name + '/' + name);
468 + require('fs').unlinkSync('/Library/LaunchDaemons/' + name + '.plist');
469 + }
470 + catch(e)
471 + {
472 + throw ('Error uninstalling service: ' + name + ' => ' + e);
473 + }
474 +
475 + try
476 + {
477 + require('fs').rmdirSync('/usr/local/mesh_services/' + name);
478 + }
479 + catch(e)
480 + {}
481 + }
482 + else
483 + {
484 + throw ('Service: ' + name + ' does not exist');
485 + }
486 + }
487 + }
488 + if(process.platform == 'linux')
489 + {
490 + this.getServiceType = function getServiceType()
491 + {
492 + return (require('process-manager').getProcessInfo(1).Name);
493 + };
494 + }
495 +}
496 +
497 +module.exports = serviceManager;
\ No newline at end of file
agents-new/modules_meshcmd/smbios.js new
+343
@@ -0,0 +1,343 @@
1 +/*
2 +Copyright 2018 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { }
18 +try { Object.defineProperty(String.prototype, "replaceAll", { value: function replaceAll(oldVal, newVal) { return (this.split(oldVal).join(newVal)); } }); } catch (e) { }
19 +
20 +var RSMB = 1381190978;
21 +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' };
22 +var wakeReason = ['Reserved', 'Other', 'Unknown', 'APM Timer', 'Modem Ring', 'LAN', 'Power Switch', 'PCI', 'AC Power'];
23 +
24 +// Fill the left with zeros until the string is of a given length
25 +function zeroLeftPad(str, len)
26 +{
27 + if ((len == null) && (typeof (len) != 'number')) { return null; }
28 + if (str == null) str = ''; // If null, this is to generate zero leftpad string
29 + var zlp = '';
30 + for (var i = 0; i < len - str.length; i++) { zlp += '0'; }
31 + return zlp + str;
32 +}
33 +
34 +function SMBiosTables()
35 +{
36 + this._ObjectID = 'SMBiosTable';
37 + if (process.platform == 'win32') {
38 + this._marshal = require('_GenericMarshal');
39 + this._native = this._marshal.CreateNativeProxy("Kernel32.dll");
40 +
41 + this._native.CreateMethod('EnumSystemFirmwareTables');
42 + this._native.CreateMethod('GetSystemFirmwareTable');
43 + }
44 + if (process.platform == 'linux') {
45 + this._canonicalizeData = function _canonicalizeData(data) {
46 + var lines = data.toString().split('Header and Data:\x0A');
47 + var MemoryStream = require('MemoryStream');
48 + var ms = new MemoryStream();
49 +
50 + for (var i = 1; i < lines.length; ++i) {
51 + var tokens = lines[i].split('Strings:\x0A');
52 + var header = tokens[0].split('\x0A\x0A')[0].replaceAll('\x0A', '').trim().replaceAll(' ', '').replaceAll('\x09', '');
53 + ms.write(Buffer.from(header, 'hex'));
54 + if (tokens.length > 1) {
55 + var strings = tokens[1].split('\x0A\x0A')[0].split('\x0A');
56 + var stringsFinal = [];
57 + for (var strx in strings) {
58 + var tmp = strings[strx].trim().replaceAll(' ', '').replaceAll('\x09', '');
59 + if (!(tmp[0] == '"')) { stringsFinal.push(tmp); }
60 + }
61 + ms.write(Buffer.from(stringsFinal.join(''), 'hex'));
62 + ms.write(Buffer.from('00', 'hex'));
63 + }
64 + else {
65 + ms.write(Buffer.from('0000', 'hex'));
66 + }
67 + }
68 + var retVal = ms.buffer;
69 + retVal.ms = ms;
70 + return (retVal);
71 + };
72 + }
73 + this._parse = function _parse(SMData) {
74 + var ret = {};
75 + var pbyte;
76 + var i = 0
77 + var SMData;
78 + var structcount = 0;
79 +
80 + while (SMData && i < SMData.length)
81 + {
82 + var SMtype = SMData[i];
83 + var SMlength = SMData[i + 1];
84 +
85 + if (!ret[SMtype]) { ret[SMtype] = []; }
86 + ret[SMtype].push(SMData.slice(i + 4, i + SMlength));
87 + if (process.platform == 'win32') { ret[SMtype].peek()._ext = pbyte; }
88 + i += SMlength;
89 +
90 + ret[SMtype].peek()._strings = [];
91 +
92 + while (SMData[i] != 0 && i <= SMData.length)
93 + {
94 + var strstart = i;
95 +
96 + // Start of String, find end of string
97 + while (SMData[i++] != 0 && i <= SMData.length);
98 + try
99 + {
100 + ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim());
101 + }
102 + catch (ee)
103 + {
104 + console.log('oops');
105 + }
106 + }
107 + i += (ret[SMtype].peek()._strings.length == 0) ? 2 : 1;
108 + ++structcount;
109 + //console.log('End of Table[' + SMtype + ']: ' + i);
110 + }
111 + //console.log('Struct Count = ' + structcount);
112 + return (ret);
113 + };
114 + this.get = function get(callback) {
115 + if (process.platform == 'win32') {
116 + var size = this._native.GetSystemFirmwareTable(RSMB, 0, 0, 0).Val;
117 + //console.log('Table Size: ' + size);
118 +
119 + var PtrSize = this._marshal.CreatePointer()._size;
120 + var buffer = this._marshal.CreateVariable(size);
121 + var written = this._native.GetSystemFirmwareTable(RSMB, 0, buffer, size).Val;
122 + //console.log('Written Size: ' + written);
123 +
124 + var rawBuffer = buffer.toBuffer();
125 + var length = buffer.Deref(4, 4).toBuffer().readUInt32LE(0);
126 +
127 + pbyte = buffer.Deref(8, length);
128 + SMData = pbyte.toBuffer();
129 +
130 + if (callback) { callback.apply(this, [this._parse(SMData)]); return; } else { return (this._parse(SMData)); }
131 + }
132 + if (process.platform == 'linux') {
133 + var MemoryStream = require('MemoryStream');
134 + this.child = require('child_process').execFile('/usr/sbin/dmidecode', ['dmidecode', '-u']);
135 + this.child.SMBiosTable = this;
136 + this.child.ms = new MemoryStream();
137 + this.child.ms.callback = callback;
138 + this.child.ms.child = this.child;
139 + this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); });
140 + this.child.on('exit', function () { this.ms.end(); });
141 + this.child.ms.on('end', function () {
142 + //console.log('read ' + this.buffer.length + ' bytes');
143 + if (this.buffer.length < 300) {
144 + //console.log('Not enough permission to read SMBiosTable');
145 + if (this.callback) { this.callback.apply(this.child.SMBiosTable, []); }
146 + }
147 + else {
148 + var SMData = this.child.SMBiosTable._canonicalizeData(this.buffer);
149 + var j = this.child.SMBiosTable._parse(SMData);
150 + if (this.callback) { this.callback.apply(this.child.SMBiosTable, [j]); }
151 + }
152 + });
153 + return;
154 + }
155 + if (callback) { callback.apply(this, [null]); return; } else { return (null); }
156 + };
157 + this.parse = function parse(data) {
158 + var r = {};
159 + try
160 + {
161 + r.processorInfo = this.processorInfo(data);
162 + }
163 + catch(e)
164 + {
165 + }
166 + try
167 + {
168 + r.memoryInfo = this.memoryInfo(data);
169 + }
170 + catch(e)
171 + {
172 + }
173 + try
174 + {
175 + r.systemInfo = this.systemInfo(data);
176 + }
177 + catch(e)
178 + {
179 + }
180 + try
181 + {
182 + r.systemSlots = this.systemInfo(data);
183 + }
184 + catch(e)
185 + {
186 + }
187 + try
188 + {
189 + r.amtInfo = this.amtInfo(data);
190 + }
191 + catch(e)
192 + {
193 + }
194 + return r;
195 + }
196 + this.processorInfo = function processorInfo(data) {
197 + if (!data) { throw ('no data'); }
198 + var ret = [];
199 + var ptype = ['ERROR', 'Other', 'Unknown', 'CPU', 'ALU', 'DSP', 'GPU'];
200 + var statusString = ['Unknown', 'Enabled', 'Disabled by user', 'Disabled by BIOS', 'Idle', 'Reserved', 'Reserved', 'Other'];
201 + var cpuid = 0;
202 + while (data[4] && data[4].length > 0) {
203 + var p = data[4].pop();
204 + var populated = p[20] & 0x40;
205 + var status = p[20] & 0x07
206 + if (populated) {
207 + var j = { _ObjectID: 'SMBiosTables.processorInfo' };
208 + j.Processor = ptype[p[1]];
209 + j.MaxSpeed = p.readUInt16LE(16) + ' Mhz';
210 + if (p[31]) { j.Cores = p[31]; }
211 + if (p[33]) { j.Threads = p[33]; }
212 + j.Populated = 1;
213 + j.Status = statusString[status];
214 + j.Socket = p._strings[p[0] - 1];
215 + j.Manufacturer = p._strings[p[3] - 1];
216 + j.Version = p._strings[p[12] - 1];
217 + ret.push(j);
218 + }
219 + }
220 + return (ret);
221 + };
222 + this.memoryInfo = function memoryInfo(data) {
223 + if (!data) { throw ('no data'); }
224 + var retVal = { _ObjectID: 'SMBiosTables.memoryInfo' };
225 + if (data[16]) {
226 + var m = data[16].peek();
227 + retVal.location = memoryLocation[m[0]];
228 + if ((retVal.maxCapacityKb = m.readUInt32LE(3)) == 0x80000000) {
229 + retVal.maxCapacityKb = 'A really big number';
230 + }
231 + }
232 + return (retVal);
233 + };
234 + this.systemInfo = function systemInfo(data)
235 + {
236 + if (!data) { throw ('no data'); }
237 + var retVal = { _ObjectID: 'SMBiosTables.systemInfo' };
238 + if (data[1])
239 + {
240 + var si = data[1].peek();
241 + var uuid = si.slice(4, 20);
242 +
243 + retVal.uuid = [zeroLeftPad(uuid.readUInt32LE(0).toString(16), 8),
244 + zeroLeftPad(uuid.readUInt16LE(4).toString(16), 4),
245 + zeroLeftPad(uuid.readUInt16LE(6).toString(16), 4),
246 + zeroLeftPad(uuid.readUInt16BE(8).toString(16), 4),
247 + zeroLeftPad(uuid.slice(10).toString('hex').toLowerCase(), 12)].join('-');
248 +
249 + retVal.wakeReason = wakeReason[si[20]];
250 + }
251 + return (retVal);
252 + };
253 + this.systemSlots = function systemSlots(data) {
254 + if (!data) { throw ('no data'); }
255 + var retVal = [];
256 + if (data[9]) {
257 + while (data[9].length > 0) {
258 + var ss = data[9].pop();
259 + retVal.push({ name: ss._strings[ss[0] - 1] });
260 + }
261 + }
262 + return (retVal);
263 + };
264 + this.amtInfo = function amtInfo(data) {
265 + if (!data) { throw ('no data'); }
266 + var retVal = { AMT: false };
267 + if (data[130] && data[130].peek().slice(0, 4).toString() == '$AMT') {
268 + var amt = data[130].peek();
269 + retVal.AMT = amt[4] ? true : false;
270 + if (retVal.AMT) {
271 + retVal.enabled = amt[5] ? true : false;
272 + retVal.storageRedirection = amt[6] ? true : false;
273 + retVal.serialOverLan = amt[7] ? true : false;
274 + retVal.kvm = amt[14] ? true : false;
275 + if (data[131].peek() && data[131].peek().slice(52, 56).toString() == 'vPro') {
276 + var settings = data[131].peek();
277 + if (settings[0] & 0x04) { retVal.TXT = (settings[0] & 0x08) ? true : false; }
278 + if (settings[0] & 0x10) { retVal.VMX = (settings[0] & 0x20) ? true : false; }
279 + retVal.MEBX = settings.readUInt16LE(10).toString() + '.' + settings.readUInt16LE(8).toString() + '.' + settings.readUInt16LE(6).toString() + '.' + settings.readUInt16LE(4).toString();
280 +
281 + var mecap = settings.slice(20, 32);
282 + retVal.ManagementEngine = mecap.readUInt16LE(6).toString() + '.' + mecap.readUInt16LE(4).toString() + '.' + mecap.readUInt16LE(2).toString() + '.' + mecap.readUInt16LE(0).toString();
283 +
284 + //var lan = settings.slice(36, 48);
285 + //console.log(lan.toString('hex'));
286 + //retVal.LAN = (lan.readUInt16LE(10) & 0x03).toString() + '/' + ((lan.readUInt16LE(10) & 0xF8) >> 3).toString();
287 +
288 + //console.log(lan.readUInt16LE(3));
289 + //retVal.WLAN = (lan.readUInt16LE(3) & 0x07).toString() + '/' + ((lan.readUInt16LE(3) & 0xF8) >> 3).toString() + '/' + (lan.readUInt16LE(3) >> 8).toString();
290 + }
291 + }
292 + }
293 + return (retVal);
294 + };
295 + this.smTableTypes = {
296 + 0: 'BIOS information',
297 + 1: 'System information',
298 + 2: 'Baseboard (or Module) information',
299 + 4: 'Processor information',
300 + 5: 'memory controller information',
301 + 6: 'Memory module information',
302 + 7: 'Cache information',
303 + 8: 'Port connector information',
304 + 9: 'System slots',
305 + 10: 'On board devices information',
306 + 11: 'OEM strings',
307 + 12: 'System configuration options',
308 + 13: 'BIOS language information',
309 + 14: 'Group associations',
310 + 15: 'System event log',
311 + 16: 'Physical memory array',
312 + 17: 'Memory device',
313 + 18: '32bit memory error information',
314 + 19: 'Memory array mapped address',
315 + 20: 'Memory device mapped address',
316 + 21: 'Built-in pointing device',
317 + 22: 'Portable battery',
318 + 23: 'System reset',
319 + 24: 'Hardware security',
320 + 25: 'System power controls',
321 + 26: 'Voltage probe',
322 + 27: 'Cooling device',
323 + 28: 'Temperature probe',
324 + 29: 'Electrical current probe',
325 + 30: 'Out-of-band remote access',
326 + 31: 'Boot integrity services (BIS) entry point',
327 + 32: 'System boot information',
328 + 33: '64bit memory error information',
329 + 34: 'Management device',
330 + 35: 'Management device component',
331 + 36: 'Management device threshold data',
332 + 37: 'Memory channel',
333 + 38: 'IPMI device information',
334 + 39: 'System power supply',
335 + 40: 'Additional information',
336 + 41: 'Onboard devices extended information',
337 + 42: 'Management controller host interface',
338 + 126: 'Inactive',
339 + 127: 'End-of-table'
340 + }
341 +}
342 +
343 +module.exports = new SMBiosTables();
\ No newline at end of file
agents-new/modules_meshcmd/user-sessions.js new
+750
@@ -0,0 +1,750 @@
1 +/*
2 +Copyright 2018 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var NOTIFY_FOR_THIS_SESSION = 0;
18 +var NOTIFY_FOR_ALL_SESSIONS = 1;
19 +var WM_WTSSESSION_CHANGE = 0x02B1;
20 +var WM_POWERBROADCAST = 0x218;
21 +var PBT_POWERSETTINGCHANGE = 0x8013;
22 +var PBT_APMSUSPEND = 0x4;
23 +var PBT_APMRESUMESUSPEND = 0x7;
24 +var PBT_APMRESUMEAUTOMATIC = 0x12;
25 +var PBT_APMPOWERSTATUSCHANGE = 0xA;
26 +
27 +var WTS_CONSOLE_CONNECT = (0x1);
28 +var WTS_CONSOLE_DISCONNECT = (0x2);
29 +var WTS_REMOTE_CONNECT = (0x3);
30 +var WTS_REMOTE_DISCONNECT = (0x4);
31 +var WTS_SESSION_LOGON = (0x5);
32 +var WTS_SESSION_LOGOFF = (0x6);
33 +var WTS_SESSION_LOCK = (0x7);
34 +var WTS_SESSION_UNLOCK = (0x8);
35 +var WTS_SESSION_REMOTE_CONTROL = (0x9);
36 +var WTS_SESSION_CREATE = (0xA);
37 +var WTS_SESSION_TERMINATE = (0xB);
38 +
39 +var GUID_ACDC_POWER_SOURCE;
40 +var GUID_BATTERY_PERCENTAGE_REMAINING;
41 +var GUID_CONSOLE_DISPLAY_STATE;
42 +
43 +function UserSessions()
44 +{
45 + this._ObjectID = 'user-sessions';
46 + require('events').EventEmitter.call(this, true)
47 + .createEvent('changed')
48 + .createEvent('locked')
49 + .createEvent('unlocked');
50 +
51 + this.enumerateUsers = function enumerateUsers()
52 + {
53 + var promise = require('promise');
54 + var p = new promise(function (res, rej)
55 + {
56 + this.__resolver = res;
57 + this.__rejector = rej;
58 + });
59 + p.__handler = function __handler(users)
60 + {
61 + p.__resolver(users);
62 + };
63 + try
64 + {
65 + this.Current(p.__handler);
66 + }
67 + catch(e)
68 + {
69 + p.__rejector(e);
70 + }
71 + p.parent = this;
72 + return (p);
73 + }
74 +
75 + if (process.platform == 'win32')
76 + {
77 + this._serviceHooked = false;
78 + this._marshal = require('_GenericMarshal');
79 + this._kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll');
80 + this._kernel32.CreateMethod('GetLastError');
81 +
82 + try
83 + {
84 + this._wts = this._marshal.CreateNativeProxy('Wtsapi32.dll');
85 + this._wts.CreateMethod('WTSEnumerateSessionsA');
86 + this._wts.CreateMethod('WTSQuerySessionInformationA');
87 + this._wts.CreateMethod('WTSRegisterSessionNotification');
88 + this._wts.CreateMethod('WTSUnRegisterSessionNotification');
89 + this._wts.CreateMethod('WTSFreeMemory');
90 + }
91 + catch(exc)
92 + {
93 + }
94 +
95 + this._advapi = this._marshal.CreateNativeProxy('Advapi32.dll');
96 + this._advapi.CreateMethod('AllocateAndInitializeSid');
97 + this._advapi.CreateMethod('CheckTokenMembership');
98 + this._advapi.CreateMethod('FreeSid');
99 +
100 + this._user32 = this._marshal.CreateNativeProxy('user32.dll');
101 + this._user32.CreateMethod({ method: 'RegisterPowerSettingNotification', threadDispatch: 1});
102 + this._user32.CreateMethod('UnregisterPowerSettingNotification');
103 + this._rpcrt = this._marshal.CreateNativeProxy('Rpcrt4.dll');
104 + this._rpcrt.CreateMethod('UuidFromStringA');
105 + this._rpcrt.StringToUUID = function StringToUUID(guid)
106 + {
107 + var retVal = StringToUUID.us._marshal.CreateVariable(16);
108 + if(StringToUUID.us._rpcrt.UuidFromStringA(StringToUUID.us._marshal.CreateVariable(guid), retVal).Val == 0)
109 + {
110 + return (retVal);
111 + }
112 + else
113 + {
114 + throw ('Could not convert string to UUID');
115 + }
116 + }
117 + this._rpcrt.StringToUUID.us = this;
118 +
119 + GUID_ACDC_POWER_SOURCE = this._rpcrt.StringToUUID('5d3e9a59-e9D5-4b00-a6bd-ff34ff516548');
120 + GUID_BATTERY_PERCENTAGE_REMAINING = this._rpcrt.StringToUUID('a7ad8041-b45a-4cae-87a3-eecbb468a9e1');
121 + GUID_CONSOLE_DISPLAY_STATE = this._rpcrt.StringToUUID('6fe69556-704a-47a0-8f24-c28d936fda47');
122 +
123 + this.SessionStates = ['Active', 'Connected', 'ConnectQuery', 'Shadow', 'Disconnected', 'Idle', 'Listening', 'Reset', 'Down', 'Init'];
124 + this.InfoClass =
125 + {
126 + 'WTSInitialProgram': 0,
127 + 'WTSApplicationName': 1,
128 + 'WTSWorkingDirectory': 2,
129 + 'WTSOEMId': 3,
130 + 'WTSSessionId': 4,
131 + 'WTSUserName': 5,
132 + 'WTSWinStationName': 6,
133 + 'WTSDomainName': 7,
134 + 'WTSConnectState': 8,
135 + 'WTSClientBuildNumber': 9,
136 + 'WTSClientName': 10,
137 + 'WTSClientDirectory': 11,
138 + 'WTSClientProductId': 12,
139 + 'WTSClientHardwareId': 13,
140 + 'WTSClientAddress': 14,
141 + 'WTSClientDisplay': 15,
142 + 'WTSClientProtocolType': 16,
143 + 'WTSIdleTime': 17,
144 + 'WTSLogonTime': 18,
145 + 'WTSIncomingBytes': 19,
146 + 'WTSOutgoingBytes': 20,
147 + 'WTSIncomingFrames': 21,
148 + 'WTSOutgoingFrames': 22,
149 + 'WTSClientInfo': 23,
150 + 'WTSSessionInfo': 24,
151 + 'WTSSessionInfoEx': 25,
152 + 'WTSConfigInfo': 26,
153 + 'WTSValidationInfo': 27,
154 + 'WTSSessionAddressV4': 28,
155 + 'WTSIsRemoteSession': 29
156 + };
157 +
158 + this.isRoot = function isRoot()
159 + {
160 + var NTAuthority = this._marshal.CreateVariable(6);
161 + NTAuthority.toBuffer().writeInt8(5, 5);
162 +
163 + var AdministratorsGroup = this._marshal.CreatePointer();
164 + var admin = false;
165 +
166 + if (this._advapi.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0)
167 + {
168 + var member = this._marshal.CreateInteger();
169 + if (this._advapi.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0)
170 + {
171 + if (member.toBuffer().readUInt32LE() != 0) { admin = true; }
172 + }
173 + this._advapi.FreeSid(AdministratorsGroup.Deref());
174 + }
175 + return admin;
176 + }
177 +
178 + this.getSessionAttribute = function getSessionAttribute(sessionId, attr)
179 + {
180 + var buffer = this._marshal.CreatePointer();
181 + var bytesReturned = this._marshal.CreateVariable(4);
182 +
183 + if (this._wts.WTSQuerySessionInformationA(0, sessionId, attr, buffer, bytesReturned).Val == 0)
184 + {
185 + throw ('Error calling WTSQuerySessionInformation: ' + this._kernel32.GetLastError.Val);
186 + }
187 +
188 + var retVal = buffer.Deref().String;
189 +
190 + this._wts.WTSFreeMemory(buffer.Deref());
191 + return (retVal);
192 + };
193 +
194 + this.Current = function Current(cb)
195 + {
196 + var retVal = {};
197 + var pinfo = this._marshal.CreatePointer();
198 + var count = this._marshal.CreateVariable(4);
199 + if (this._wts.WTSEnumerateSessionsA(0, 0, 1, pinfo, count).Val == 0)
200 + {
201 + throw ('Error calling WTSEnumerateSessionsA: ' + this._kernel32.GetLastError().Val);
202 + }
203 +
204 + for (var i = 0; i < count.toBuffer().readUInt32LE() ; ++i)
205 + {
206 + var info = pinfo.Deref().Deref(i * (this._marshal.PointerSize == 4 ? 12 : 24), this._marshal.PointerSize == 4 ? 12 : 24);
207 + var j = { SessionId: info.toBuffer().readUInt32LE() };
208 + j.StationName = info.Deref(this._marshal.PointerSize == 4 ? 4 : 8, this._marshal.PointerSize).Deref().String;
209 + j.State = this.SessionStates[info.Deref(this._marshal.PointerSize == 4 ? 8 : 16, 4).toBuffer().readUInt32LE()];
210 + if (j.State == 'Active') {
211 + j.Username = this.getSessionAttribute(j.SessionId, this.InfoClass.WTSUserName);
212 + j.Domain = this.getSessionAttribute(j.SessionId, this.InfoClass.WTSDomainName);
213 + }
214 + retVal[j.SessionId] = j;
215 + }
216 +
217 + this._wts.WTSFreeMemory(pinfo.Deref());
218 +
219 + Object.defineProperty(retVal, 'Active', { value: showActiveOnly(retVal) });
220 + if (cb) { cb(retVal); }
221 + return (retVal);
222 + };
223 +
224 +
225 + // We need to spin up a message pump, and fetch a window handle
226 + var message_pump = require('win-message-pump');
227 + this._messagepump = new message_pump({ filter: WM_WTSSESSION_CHANGE }); this._messagepump.parent = this;
228 + this._messagepump.on('exit', function (code) { this.parent._wts.WTSUnRegisterSessionNotification(this.parent.hwnd); });
229 + this._messagepump.on('hwnd', function (h)
230 + {
231 + this.parent.hwnd = h;
232 +
233 + // We need to yield, and do this in the next event loop pass, becuase we don't want to call 'RegisterPowerSettingNotification'
234 + // from the messagepump 'thread', because we are actually on the microstack thread, such that the message pump thread, is holding
235 + // on a semaphore for us to return. If we call now, we may deadlock on Windows 7, becuase it will try to notify immediately
236 + this.immediate = setImmediate(function (self)
237 + {
238 + // Now that we have a window handle, we can register it to receive Windows Messages
239 + if (self.parent._wts) { self.parent._wts.WTSRegisterSessionNotification(self.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS); }
240 + self.parent._user32.ACDC_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0);
241 + self.parent._user32.BATT_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0);
242 + self.parent._user32.DISP_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0);
243 + //console.log(self.parent._user32.ACDC_H.Val, self.parent._user32.BATT_H.Val, self.parent._user32.DISP_H.Val);
244 + }, this);
245 + });
246 + this._messagepump.on('message', function (msg)
247 + {
248 + switch(msg.message)
249 + {
250 + case WM_WTSSESSION_CHANGE:
251 + switch(msg.wparam)
252 + {
253 + case WTS_SESSION_LOCK:
254 + this.parent.enumerateUsers().then(function (users)
255 + {
256 + if (users[msg.lparam]) { this.parent.emit('locked', users[msg.lparam]); }
257 + });
258 + break;
259 + case WTS_SESSION_UNLOCK:
260 + this.parent.enumerateUsers().then(function (users)
261 + {
262 + if (users[msg.lparam]) { this.parent.emit('unlocked', users[msg.lparam]); }
263 + });
264 + break;
265 + case WTS_SESSION_LOGON:
266 + case WTS_SESSION_LOGOFF:
267 + this.parent.emit('changed');
268 + break;
269 + }
270 + break;
271 + case WM_POWERBROADCAST:
272 + switch(msg.wparam)
273 + {
274 + default:
275 + console.log('WM_POWERBROADCAST [UNKNOWN wparam]: ' + msg.wparam);
276 + break;
277 + case PBT_APMSUSPEND:
278 + require('power-monitor').emit('sx', 'SLEEP');
279 + break;
280 + case PBT_APMRESUMEAUTOMATIC:
281 + require('power-monitor').emit('sx', 'RESUME_NON_INTERACTIVE');
282 + break;
283 + case PBT_APMRESUMESUSPEND:
284 + require('power-monitor').emit('sx', 'RESUME_INTERACTIVE');
285 + break;
286 + case PBT_APMPOWERSTATUSCHANGE:
287 + require('power-monitor').emit('changed');
288 + break;
289 + case PBT_POWERSETTINGCHANGE:
290 + var lparam = this.parent._marshal.CreatePointer(Buffer.from(msg.lparam_hex, 'hex'));
291 + var data = lparam.Deref(20, lparam.Deref(16, 4).toBuffer().readUInt32LE(0)).toBuffer();
292 + switch(lparam.Deref(0, 16).toBuffer().toString('hex'))
293 + {
294 + case GUID_ACDC_POWER_SOURCE.Deref(0, 16).toBuffer().toString('hex'):
295 + switch(data.readUInt32LE(0))
296 + {
297 + case 0:
298 + require('power-monitor').emit('acdc', 'AC');
299 + break;
300 + case 1:
301 + require('power-monitor').emit('acdc', 'BATTERY');
302 + break;
303 + case 2:
304 + require('power-monitor').emit('acdc', 'HOT');
305 + break;
306 + }
307 + break;
308 + case GUID_BATTERY_PERCENTAGE_REMAINING.Deref(0, 16).toBuffer().toString('hex'):
309 + require('power-monitor').emit('batteryLevel', data.readUInt32LE(0));
310 + break;
311 + case GUID_CONSOLE_DISPLAY_STATE.Deref(0, 16).toBuffer().toString('hex'):
312 + switch(data.readUInt32LE(0))
313 + {
314 + case 0:
315 + require('power-monitor').emit('display', 'OFF');
316 + break;
317 + case 1:
318 + require('power-monitor').emit('display', 'ON');
319 + break;
320 + case 2:
321 + require('power-monitor').emit('display', 'DIMMED');
322 + break;
323 + }
324 + break;
325 + }
326 + break;
327 + }
328 + break;
329 + default:
330 + break;
331 + }
332 + });
333 + }
334 + else if(process.platform == 'linux')
335 + {
336 + var dbus = require('linux-dbus');
337 + this._linuxWatcher = require('fs').watch('/var/run/utmp');
338 + this._linuxWatcher.user_session = this;
339 + this._linuxWatcher.on('change', function (a, b)
340 + {
341 + this.user_session.emit('changed');
342 + });
343 + this._users = function _users()
344 + {
345 + var child = require('child_process').execFile('/bin/sh', ['sh']);
346 + child.stdout.str = '';
347 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
348 + child.stdin.write('awk -F: \'($3 >= 0) {printf "%s:%s\\n", $1, $3}\' /etc/passwd\nexit\n');
349 + child.waitExit();
350 +
351 + var lines = child.stdout.str.split('\n');
352 + var ret = {}, tokens;
353 + for (var ln in lines)
354 + {
355 + tokens = lines[ln].split(':');
356 + if (tokens[0]) { ret[tokens[0]] = tokens[1]; }
357 + }
358 + return (ret);
359 + }
360 + this._uids = function _uids() {
361 + var child = require('child_process').execFile('/bin/sh', ['sh']);
362 + child.stdout.str = '';
363 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
364 + child.stdin.write('awk -F: \'($3 >= 0) {printf "%s:%s\\n", $1, $3}\' /etc/passwd\nexit\n');
365 + child.waitExit();
366 +
367 + var lines = child.stdout.str.split('\n');
368 + var ret = {}, tokens;
369 + for (var ln in lines) {
370 + tokens = lines[ln].split(':');
371 + if (tokens[0]) { ret[tokens[1]] = tokens[0]; }
372 + }
373 + return (ret);
374 + }
375 + this.Self = function Self()
376 + {
377 + var promise = require('promise');
378 + var p = new promise(function (res, rej)
379 + {
380 + this.__resolver = res; this.__rejector = rej;
381 + this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u']);
382 + this.__child.promise = this;
383 + this.__child.stdout._txt = '';
384 + this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); });
385 + this.__child.on('exit', function (code)
386 + {
387 + try
388 + {
389 + parseInt(this.stdout._txt);
390 + }
391 + catch (e)
392 + {
393 + this.promise.__rejector('invalid uid');
394 + return;
395 + }
396 +
397 + var id = parseInt(this.stdout._txt);
398 + this.promise.__resolver(id);
399 + });
400 + });
401 + return (p);
402 + };
403 + this.Current = function Current(cb)
404 + {
405 + var retVal = {};
406 + retVal._ObjectID = 'UserSession'
407 + Object.defineProperty(retVal, '_callback', { value: cb });
408 + Object.defineProperty(retVal, '_child', { value: require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']) });
409 +
410 + retVal._child.Parent = retVal;
411 + retVal._child._txt = '';
412 + retVal._child.on('exit', function (code)
413 + {
414 + var lines = this._txt.split('\n');
415 + var sessions = [];
416 + var users = {};
417 +
418 + for(var i in lines)
419 + {
420 + if (lines[i])
421 + {
422 + var tokens = getTokens(lines[i]);
423 + var s = { Username: tokens[0], SessionId: tokens[1] }
424 + if (tokens[3].includes('still logged in'))
425 + {
426 + s.State = 'Active';
427 + }
428 + else
429 + {
430 + s.LastActive = tokens[3];
431 + }
432 +
433 + sessions.push(s);
434 + }
435 + }
436 + sessions.pop();
437 +
438 +
439 + var usernames = {};
440 + var promises = [];
441 +
442 + for (var i in sessions)
443 + {
444 + if (sessions[i].Username != 'reboot')
445 + {
446 + users[sessions[i].SessionId] = sessions[i];
447 + if(usernames[sessions[i].Username] == null)
448 + {
449 + usernames[sessions[i].Username] = -1;
450 + }
451 + }
452 + }
453 +
454 + try
455 + {
456 + require('promise');
457 + }
458 + catch(e)
459 + {
460 + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
461 + if (this.Parent._callback) { this.Parent._callback.call(this.Parent, users); }
462 + return;
463 + }
464 +
465 + var promise = require('promise');
466 + for (var n in usernames)
467 + {
468 + var p = new promise(function (res, rej)
469 + {
470 + this.__username = n;
471 + this.__resolver = res; this.__rejector = rej;
472 + this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u', n]);
473 + this.__child.promise = this;
474 + this.__child.stdout._txt = '';
475 + this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); });
476 + this.__child.on('exit', function (code)
477 + {
478 + try
479 + {
480 + parseInt(this.stdout._txt);
481 + }
482 + catch(e)
483 + {
484 + this.promise.__rejector('invalid uid');
485 + return;
486 + }
487 +
488 + var id = parseInt(this.stdout._txt);
489 + this.promise.__resolver(id);
490 + });
491 + });
492 + promises.push(p);
493 + }
494 + promise.all(promises).then(function (plist)
495 + {
496 + // Done
497 + var table = {};
498 + for(var i in plist)
499 + {
500 + table[plist[i].__username] = plist[i]._internal.completedArgs[0];
501 + }
502 + for(var i in users)
503 + {
504 + users[i].uid = table[users[i].Username];
505 + }
506 + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
507 + if (retVal._callback) { retVal._callback.call(retVal, users); }
508 + }, function (reason)
509 + {
510 + // Failed
511 + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
512 + if (retVal._callback) { retVal._callback.call(retVal, users); }
513 + });
514 + });
515 + retVal._child.stdout.Parent = retVal._child;
516 + retVal._child.stdout.on('data', function (chunk) { this.Parent._txt += chunk.toString(); });
517 +
518 + return (retVal);
519 + }
520 + this._recheckLoggedInUsers = function _recheckLoggedInUsers()
521 + {
522 + this.enumerateUsers().then(function (u)
523 + {
524 +
525 + if (u.Active.length > 0)
526 + {
527 + // There is already a user logged in, so we can monitor DBUS for lock/unlock
528 + if (this.parent._linux_lock_watcher != null && this.parent._linux_lock_watcher.uid != u.Active[0].uid)
529 + {
530 + delete this.parent._linux_lock_watcher;
531 + }
532 + this.parent._linux_lock_watcher = new dbus(process.env['XDG_CURRENT_DESKTOP'] == 'Unity' ? 'com.ubuntu.Upstart0_6' : 'org.gnome.ScreenSaver', u.Active[0].uid);
533 + this.parent._linux_lock_watcher.user_session = this.parent;
534 + this.parent._linux_lock_watcher.on('signal', function (s)
535 + {
536 + var p = this.user_session.enumerateUsers();
537 + p.signalData = s.data[0];
538 + p.then(function (u)
539 + {
540 + switch (this.signalData)
541 + {
542 + case true:
543 + case 'desktop-lock':
544 + this.parent.emit('locked', u.Active[0]);
545 + break;
546 + case false:
547 + case 'desktop-unlock':
548 + this.parent.emit('unlocked', u.Active[0]);
549 + break;
550 + }
551 + });
552 + });
553 + }
554 + else if (this.parent._linux_lock_watcher != null)
555 + {
556 + delete this.parent._linux_lock_watcher;
557 + }
558 + });
559 +
560 + };
561 + this.on('changed', this._recheckLoggedInUsers); // For linux Lock/Unlock monitoring, we need to watch for LogOn/LogOff, and keep track of the UID.
562 +
563 +
564 + // First step, is to see if there is a user logged in:
565 + this._recheckLoggedInUsers();
566 + }
567 + else if(process.platform == 'darwin')
568 + {
569 + this._users = function ()
570 + {
571 + var child = require('child_process').execFile('/usr/bin/dscl', ['dscl', '.', 'list', '/Users', 'UniqueID']);
572 + child.stdout.str = '';
573 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
574 + child.stdin.write('exit\n');
575 + child.waitExit();
576 +
577 + var lines = child.stdout.str.split('\n');
578 + var tokens, i;
579 + var users = {};
580 +
581 + for (i = 0; i < lines.length; ++i) {
582 + tokens = lines[i].split(' ');
583 + if (tokens[0]) { users[tokens[0]] = tokens[tokens.length - 1]; }
584 + }
585 +
586 + return (users);
587 + }
588 + this._uids = function () {
589 + var child = require('child_process').execFile('/usr/bin/dscl', ['dscl', '.', 'list', '/Users', 'UniqueID']);
590 + child.stdout.str = '';
591 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
592 + child.stdin.write('exit\n');
593 + child.waitExit();
594 +
595 + var lines = child.stdout.str.split('\n');
596 + var tokens, i;
597 + var users = {};
598 +
599 + for (i = 0; i < lines.length; ++i) {
600 + tokens = lines[i].split(' ');
601 + if (tokens[0]) { users[tokens[tokens.length - 1]] = tokens[0]; }
602 + }
603 +
604 + return (users);
605 + }
606 + this._idTable = function()
607 + {
608 + var table = {};
609 + var child = require('child_process').execFile('/usr/bin/id', ['id']);
610 + child.stdout.str = '';
611 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
612 + child.waitExit();
613 +
614 + var lines = child.stdout.str.split('\n')[0].split(' ');
615 + for (var i = 0; i < lines.length; ++i) {
616 + var types = lines[i].split('=');
617 + var tokens = types[1].split(',');
618 + table[types[0]] = {};
619 +
620 + for (var j in tokens) {
621 + var idarr = tokens[j].split('(');
622 + var id = idarr[0];
623 + var name = idarr[1].substring(0, idarr[1].length - 1).trim();
624 + table[types[0]][name] = id;
625 + table[types[0]][id] = name;
626 + }
627 + }
628 + return (table);
629 + }
630 + this.Current = function (cb)
631 + {
632 + var users = {};
633 + var table = this._idTable();
634 + var child = require('child_process').execFile('/usr/bin/last', ['last']);
635 + child.stdout.str = '';
636 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
637 + child.waitExit();
638 +
639 + var lines = child.stdout.str.split('\n');
640 + for (var i = 0; i < lines.length && lines[i].length > 0; ++i)
641 + {
642 + if (!users[lines[i].split(' ')[0]])
643 + {
644 + try
645 + {
646 + 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]] };
647 + }
648 + catch(e)
649 + {}
650 + }
651 + else
652 + {
653 + if(users[lines[i].split(' ')[0]].State != 'Active' && lines[i].split('still logged in').length > 1)
654 + {
655 + users[lines[i].split(' ')[0]].State = 'Active';
656 + }
657 + }
658 + }
659 +
660 + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
661 + if (cb) { cb.call(this, users); }
662 + }
663 + }
664 +
665 + if(process.platform == 'linux' || process.platform == 'darwin')
666 + {
667 + this._self = function _self()
668 + {
669 + var child = require('child_process').execFile('/usr/bin/id', ['id', '-u']);
670 + child.stdout.str = '';
671 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
672 + child.waitExit();
673 + return (parseInt(child.stdout.str));
674 + }
675 + this.isRoot = function isRoot()
676 + {
677 + return (this._self() == 0);
678 + }
679 + this.consoleUid = function consoleUid()
680 + {
681 + var checkstr = process.platform == 'darwin' ? 'console' : ((process.env['DISPLAY'])?process.env['DISPLAY']:':0')
682 + var child = require('child_process').execFile('/bin/sh', ['sh']);
683 + child.stdout.str = '';
684 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
685 + child.stdin.write('who\nexit\n');
686 + child.waitExit();
687 +
688 + var lines = child.stdout.str.split('\n');
689 + var tokens, i, j;
690 + for (i in lines)
691 + {
692 + tokens = lines[i].split(' ');
693 + for (j = 1; j < tokens.length; ++j)
694 + {
695 + if (tokens[j].length > 0)
696 + {
697 + return (parseInt(this._users()[tokens[0]]));
698 + }
699 + }
700 + }
701 +
702 + throw ('nobody logged into console');
703 + }
704 + }
705 +
706 +
707 +}
708 +function showActiveOnly(source)
709 +{
710 + var retVal = [];
711 + var unique = {};
712 + var usernames = [];
713 + var tmp;
714 +
715 + for (var i in source)
716 + {
717 + if (source[i].State == 'Active')
718 + {
719 + retVal.push(source[i]);
720 + tmp = (source[i].Domain ? (source[i].Domain + '\\') : '') + source[i].Username;
721 + if (!unique[tmp]) { unique[tmp] = tmp;}
722 + }
723 + }
724 +
725 + for (var i in unique)
726 + {
727 + usernames.push(i);
728 + }
729 +
730 + Object.defineProperty(retVal, 'usernames', { value: usernames });
731 + return (retVal);
732 +}
733 +function getTokens(str)
734 +{
735 + var columns = [];
736 + var i;
737 +
738 + columns.push(str.substring(0, (i=str.indexOf(' '))));
739 + while (str[++i] == ' ');
740 + columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i)));
741 + while (str[++i] == ' ');
742 + columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i)));
743 + while (str[++i] == ' ');
744 + var status = str.substring(i).trim();
745 + columns.push(status);
746 +
747 + return (columns);
748 +}
749 +
750 +module.exports = new UserSessions();
\ No newline at end of file
agents-new/modules_meshcmd/x/process-manager.js new
+163
@@ -0,0 +1,163 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +
18 +var GM = require('_GenericMarshal');
19 +
20 +// Used on Windows and Linux to get information about running processes
21 +function processManager() {
22 + this._ObjectID = 'process-manager'; // Used for debugging, allows you to get the object type at runtime.
23 +
24 + // Setup the platform specific calls.
25 + switch (process.platform)
26 + {
27 + case 'win32':
28 + this._kernel32 = GM.CreateNativeProxy('kernel32.dll');
29 + this._kernel32.CreateMethod('GetLastError');
30 + this._kernel32.CreateMethod('CreateToolhelp32Snapshot');
31 + this._kernel32.CreateMethod('Process32First');
32 + this._kernel32.CreateMethod('Process32Next');
33 + break;
34 + case 'linux':
35 + case 'darwin':
36 + this._childProcess = require('child_process');
37 + break;
38 + default:
39 + throw (process.platform + ' not supported');
40 + break;
41 + }
42 + this.enumerateProcesses = function enumerateProcesses()
43 + {
44 + var promise = require('promise');
45 + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
46 + this.getProcesses(function (ps, prom) { prom._res(ps); }, ret);
47 + return (ret);
48 + }
49 + // Return a object of: pid -> process information.
50 + this.getProcesses = function getProcesses(callback)
51 + {
52 + switch(process.platform)
53 + {
54 + default:
55 + throw ('Enumerating processes on ' + process.platform + ' not supported');
56 + break;
57 + case 'win32': // Windows processes
58 + var retVal = {};
59 + var h = this._kernel32.CreateToolhelp32Snapshot(2, 0);
60 + var info = GM.CreateVariable(304);
61 + info.toBuffer().writeUInt32LE(304, 0);
62 + var nextProcess = this._kernel32.Process32First(h, info);
63 + while (nextProcess.Val)
64 + {
65 + 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 };
66 + nextProcess = this._kernel32.Process32Next(h, info);
67 + }
68 + if (callback) { callback.apply(this, [retVal]); }
69 + break;
70 + case 'linux': // Linux processes
71 + if (!this._psp) { this._psp = {}; }
72 + var p = this._childProcess.execFile("/bin/ps", ["ps", "-uxa"], { type: this._childProcess.SpawnTypes.TERM });
73 + this._psp[p.pid] = p;
74 + p.Parent = this;
75 + p.ps = '';
76 + p.callback = callback;
77 + p.args = [];
78 + for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); }
79 + p.on('exit', function onGetProcesses()
80 + {
81 + delete this.Parent._psp[this.pid];
82 + var retVal = {}, lines = this.ps.split('\x0D\x0A'), key = {}, keyi = 0;
83 + for (var i in lines)
84 + {
85 + var tokens = lines[i].split(' ');
86 + var tokenList = [];
87 + for(var x in tokens)
88 + {
89 + if (i == 0 && tokens[x]) { key[tokens[x]] = keyi++; }
90 + if (i > 0 && tokens[x]) { tokenList.push(tokens[x]);}
91 + }
92 + if (i > 0) {
93 + if (tokenList[key.PID]) { retVal[tokenList[key.PID]] = { pid: key.PID, user: tokenList[key.USER], cmd: tokenList[key.COMMAND] }; }
94 + }
95 + }
96 + if (this.callback)
97 + {
98 + this.args.unshift(retVal);
99 + this.callback.apply(this.parent, this.args);
100 + }
101 + });
102 + p.stdout.on('data', function (chunk) { this.parent.ps += chunk.toString(); });
103 + break;
104 + case 'darwin':
105 + var promise = require('promise');
106 + var p = new promise(function (res, rej) { this._res = res; this._rej = rej; });
107 + p.pm = this;
108 + p.callback = callback;
109 + p.args = [];
110 + for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); }
111 + p.child = this._childProcess.execFile("/bin/ps", ["ps", "-xa"]);
112 + p.child.promise = p;
113 + p.child.stdout.ps = '';
114 + p.child.stdout.on('data', function (chunk) { this.ps += chunk.toString(); });
115 + p.child.on('exit', function ()
116 + {
117 + var lines = this.stdout.ps.split('\n');
118 + var pidX = lines[0].split('PID')[0].length + 3;
119 + var cmdX = lines[0].split('CMD')[0].length;
120 + var ret = {};
121 + for (var i = 1; i < lines.length; ++i)
122 + {
123 + if (lines[i].length > 0)
124 + {
125 + ret[lines[i].substring(0, pidX).trim()] = { pid: lines[i].substring(0, pidX).trim(), cmd: lines[i].substring(cmdX) };
126 + }
127 + }
128 + this.promise._res(ret);
129 + });
130 + p.then(function (ps)
131 + {
132 + this.args.unshift(ps);
133 + this.callback.apply(this.pm, this.args);
134 + });
135 + break;
136 + }
137 + };
138 +
139 + // Get information about a specific process on Linux
140 + this.getProcessInfo = function getProcessInfo(pid)
141 + {
142 + switch(process.platform)
143 + {
144 + default:
145 + throw ('getProcessInfo() not supported for ' + process.platform);
146 + break;
147 + case 'linux':
148 + var status = require('fs').readFileSync('/proc/' + pid + '/status');
149 + var info = {};
150 + var lines = status.toString().split('\n');
151 + for(var i in lines)
152 + {
153 + var tokens = lines[i].split(':');
154 + if (tokens.length > 1) { tokens[1] = tokens[1].trim(); }
155 + info[tokens[0]] = tokens[1];
156 + }
157 + return (info);
158 + break;
159 + }
160 + };
161 +}
162 +
163 +module.exports = new processManager();
\ No newline at end of file
agents-new/modules_meshcore/amt-lme.js new
+898
@@ -0,0 +1,898 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var MemoryStream = require('MemoryStream');
18 +var lme_id = 0; // Our next channel identifier
19 +var lme_port_offset = 0; // Debug: Set this to "-100" to bind to 16892 & 16893 and IN_ADDRANY. This is for LMS debugging.
20 +var xmlParser = require('amt-xml');
21 +
22 +// Documented in: https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/HTMLDocuments/MPSDocuments/Intel%20AMT%20Port%20Forwarding%20Protocol%20Reference%20Manual.pdf
23 +var APF_DISCONNECT = 1;
24 +var APF_SERVICE_REQUEST = 5;
25 +var APF_SERVICE_ACCEPT = 6;
26 +var APF_USERAUTH_REQUEST = 50;
27 +var APF_USERAUTH_FAILURE = 51;
28 +var APF_USERAUTH_SUCCESS = 52;
29 +var APF_GLOBAL_REQUEST = 80;
30 +var APF_REQUEST_SUCCESS = 81;
31 +var APF_REQUEST_FAILURE = 82;
32 +var APF_CHANNEL_OPEN = 90;
33 +var APF_CHANNEL_OPEN_CONFIRMATION = 91;
34 +var APF_CHANNEL_OPEN_FAILURE = 92;
35 +var APF_CHANNEL_WINDOW_ADJUST = 93;
36 +var APF_CHANNEL_DATA = 94;
37 +var APF_CHANNEL_CLOSE = 97;
38 +var APF_PROTOCOLVERSION = 192;
39 +
40 +
41 +function lme_object() {
42 + this.ourId = ++lme_id;
43 + this.amtId = -1;
44 + this.LME_CHANNEL_STATUS = 'LME_CS_FREE';
45 + this.txWindow = 0;
46 + this.rxWindow = 0;
47 + this.localPort = 0;
48 + this.errorCount = 0;
49 +}
50 +
51 +function stream_bufferedWrite() {
52 + var emitterUtils = require('events').inherits(this);
53 + this.buffer = [];
54 + this._readCheckImmediate = undefined;
55 + this._ObjectID = "bufferedWriteStream";
56 + // Writable Events
57 + emitterUtils.createEvent('close');
58 + emitterUtils.createEvent('drain');
59 + emitterUtils.createEvent('error');
60 + emitterUtils.createEvent('finish');
61 + emitterUtils.createEvent('pipe');
62 + emitterUtils.createEvent('unpipe');
63 +
64 + // Readable Events
65 + emitterUtils.createEvent('readable');
66 + this.isEmpty = function () {
67 + return (this.buffer.length == 0);
68 + };
69 + this.isWaiting = function () {
70 + return (this._readCheckImmediate == undefined);
71 + };
72 + this.write = function (chunk) {
73 + for (var args in arguments) { if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; } }
74 + var tmp = Buffer.alloc(chunk.length);
75 + chunk.copy(tmp);
76 + this.buffer.push({ offset: 0, data: tmp });
77 + this.emit('readable');
78 + return (this.buffer.length == 0 ? true : false);
79 + };
80 + this.read = function () {
81 + var size = arguments.length == 0 ? undefined : arguments[0];
82 + var bytesRead = 0;
83 + var list = [];
84 + while ((size == undefined || bytesRead < size) && this.buffer.length > 0) {
85 + var len = this.buffer[0].data.length - this.buffer[0].offset;
86 + var offset = this.buffer[0].offset;
87 +
88 + if (len > (size - bytesRead)) {
89 + // Only reading a subset
90 + list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead));
91 + this.buffer[0].offset += (size - bytesRead);
92 + bytesRead += (size - bytesRead);
93 + } else {
94 + // Reading the entire thing
95 + list.push(this.buffer[0].data.slice(offset));
96 + bytesRead += len;
97 + this.buffer.shift();
98 + }
99 + }
100 + this._readCheckImmediate = setImmediate(function (buffered) {
101 + buffered._readCheckImmediate = undefined;
102 + if (buffered.buffer.length == 0) {
103 + buffered.emit('drain'); // Drained
104 + } else {
105 + buffered.emit('readable'); // Not drained
106 + }
107 + }, this);
108 + return (Buffer.concat(list));
109 + };
110 +}
111 +
112 +
113 +function lme_heci(options) {
114 + var emitterUtils = require('events').inherits(this);
115 + emitterUtils.createEvent('error');
116 + emitterUtils.createEvent('connect');
117 + emitterUtils.createEvent('notify');
118 + emitterUtils.createEvent('bind');
119 +
120 + if ((options != null) && (options.debug == true)) { lme_port_offset = -100; } // LMS debug mode
121 +
122 + var heci = require('heci');
123 + this.INITIAL_RXWINDOW_SIZE = 4096;
124 +
125 + this._ObjectID = "lme";
126 + this._LME = heci.create();
127 + this._LME._binded = {};
128 + this._LME.LMS = this;
129 + this._LME.on('error', function (e) { this.LMS.emit('error', e); });
130 + this._LME.on('connect', function () {
131 + this.on('data', function (chunk) {
132 + // this = HECI
133 + var cmd = chunk.readUInt8(0);
134 + //console.log('LME Command ' + cmd + ', ' + chunk.length + ' byte(s).');
135 +
136 + switch (cmd) {
137 + default:
138 + console.log('Unhandled LME Command ' + cmd + ', ' + chunk.length + ' byte(s).');
139 + break;
140 + case APF_SERVICE_REQUEST:
141 + var nameLen = chunk.readUInt32BE(1);
142 + var name = chunk.slice(5, nameLen + 5);
143 + //console.log("Service Request for: " + name);
144 + if (name == 'pfwd@amt.intel.com' || name == 'auth@amt.intel.com') {
145 + var outBuffer = Buffer.alloc(5 + nameLen);
146 + outBuffer.writeUInt8(6, 0);
147 + outBuffer.writeUInt32BE(nameLen, 1);
148 + outBuffer.write(name.toString(), 5);
149 + this.write(outBuffer);
150 + //console.log('Answering APF_SERVICE_REQUEST');
151 + } else {
152 + //console.log('UNKNOWN APF_SERVICE_REQUEST');
153 + }
154 + break;
155 + case APF_GLOBAL_REQUEST:
156 + var nameLen = chunk.readUInt32BE(1);
157 + var name = chunk.slice(5, nameLen + 5).toString();
158 +
159 + switch (name) {
160 + case 'tcpip-forward':
161 + var len = chunk.readUInt32BE(nameLen + 6);
162 + var port = chunk.readUInt32BE(nameLen + 10 + len);
163 + //console.log("[" + chunk.length + "/" + len + "] APF_GLOBAL_REQUEST for: " + name + " on port " + port);
164 + if (this[name] == undefined) { this[name] = {}; }
165 + if (this[name][port] != null) { // Close the existing binding
166 + for (var i in this.sockets) {
167 + var channel = this.sockets[i];
168 + if (channel.localPort == port) { this.sockets[i].end(); delete this.sockets[i]; } // Close this socket
169 + }
170 + }
171 + if (this[name][port] == null)
172 + { // Bind a new server socket if not already present
173 + this[name][port] = require('net').createServer();
174 + this[name][port].HECI = this;
175 +
176 + try {
177 + if (lme_port_offset == 0) {
178 + this[name][port].listen({ port: port, host: '127.0.0.1' }); // Normal mode
179 + } else {
180 + this[name][port].listen({ port: (port + lme_port_offset) }); // Debug mode
181 + }
182 + } catch (ex) { console.log('Binding error, LMS port ' + (port + lme_port_offset) + ': ' + ex) } // TODO: We can't bind
183 + this[name][port].on('connection', function (socket) {
184 + //console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort);
185 + this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort - lme_port_offset);
186 + });
187 + this._binded[port] = true;
188 + this.LMS.emit('bind', this._binded);
189 + }
190 + var outBuffer = Buffer.alloc(5);
191 + outBuffer.writeUInt8(81, 0);
192 + outBuffer.writeUInt32BE(port, 1);
193 + this.write(outBuffer);
194 + break;
195 + case 'cancel-tcpip-forward':
196 + var outBuffer = Buffer.alloc(1);
197 + outBuffer.writeUInt8(APF_REQUEST_SUCCESS, 0);
198 + this.write(outBuffer);
199 + break;
200 + case 'udp-send-to@amt.intel.com':
201 + var outBuffer = Buffer.alloc(1);
202 + outBuffer.writeUInt8(APF_REQUEST_FAILURE, 0);
203 + this.write(outBuffer);
204 + break;
205 + default:
206 + //console.log("Unknown APF_GLOBAL_REQUEST for: " + name);
207 + break;
208 + }
209 + break;
210 + case APF_CHANNEL_OPEN_CONFIRMATION:
211 + var rChannel = chunk.readUInt32BE(1);
212 + var sChannel = chunk.readUInt32BE(5);
213 + var wSize = chunk.readUInt32BE(9);
214 + //console.log('rChannel/' + rChannel + ', sChannel/' + sChannel + ', wSize/' + wSize);
215 + if (this.sockets[rChannel] != undefined) {
216 + this.sockets[rChannel].lme.amtId = sChannel;
217 + this.sockets[rChannel].lme.rxWindow = wSize;
218 + this.sockets[rChannel].lme.txWindow = wSize;
219 + this.sockets[rChannel].lme.LME_CHANNEL_STATUS = 'LME_CS_CONNECTED';
220 + //console.log('LME_CS_CONNECTED');
221 + this.sockets[rChannel].bufferedStream = new stream_bufferedWrite();
222 + this.sockets[rChannel].bufferedStream.socket = this.sockets[rChannel];
223 + this.sockets[rChannel].bufferedStream.on('readable', function () {
224 + if (this.socket.lme.txWindow > 0) {
225 + var buffer = this.read(this.socket.lme.txWindow);
226 + var packet = Buffer.alloc(9 + buffer.length);
227 + packet.writeUInt8(APF_CHANNEL_DATA, 0);
228 + packet.writeUInt32BE(this.socket.lme.amtId, 1);
229 + packet.writeUInt32BE(buffer.length, 5);
230 + buffer.copy(packet, 9);
231 + this.socket.lme.txWindow -= buffer.length;
232 + this.socket.HECI.write(packet);
233 + }
234 + });
235 + this.sockets[rChannel].bufferedStream.on('drain', function () {
236 + this.socket.resume();
237 + });
238 + this.sockets[rChannel].on('data', function (chunk) {
239 + if (!this.bufferedStream.write(chunk)) { this.pause(); }
240 + });
241 + this.sockets[rChannel].on('end', function () {
242 + var outBuffer = Buffer.alloc(5);
243 + outBuffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
244 + outBuffer.writeUInt32BE(this.lme.amtId, 1);
245 + this.HECI.write(outBuffer);
246 + });
247 + this.sockets[rChannel].resume();
248 + }
249 +
250 + break;
251 + case APF_PROTOCOLVERSION:
252 + var major = chunk.readUInt32BE(1);
253 + var minor = chunk.readUInt32BE(5);
254 + var reason = chunk.readUInt32BE(9);
255 + var outBuffer = Buffer.alloc(93);
256 + outBuffer.writeUInt8(192, 0);
257 + outBuffer.writeUInt32BE(1, 1);
258 + outBuffer.writeUInt32BE(0, 5);
259 + outBuffer.writeUInt32BE(reason, 9);
260 + //console.log('Answering PROTOCOL_VERSION');
261 + this.write(outBuffer);
262 + break;
263 + case APF_CHANNEL_WINDOW_ADJUST:
264 + var rChannelId = chunk.readUInt32BE(1);
265 + var bytesToAdd = chunk.readUInt32BE(5);
266 + if (this.sockets[rChannelId] != undefined) {
267 + this.sockets[rChannelId].lme.txWindow += bytesToAdd;
268 + if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) {
269 + this.sockets[rChannelId].bufferedStream.emit('readable');
270 + }
271 + } else {
272 + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST');
273 + }
274 + break;
275 + case APF_CHANNEL_DATA:
276 + var rChannelId = chunk.readUInt32BE(1);
277 + var dataLen = chunk.readUInt32BE(5);
278 + var data = chunk.slice(9, 9 + dataLen);
279 + if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) {
280 + this.sockets[rChannelId].pendingBytes.push(data.length);
281 + this.sockets[rChannelId].write(data, function () {
282 + var written = this.pendingBytes.shift();
283 + //console.log('adjust', this.lme.amtId, written);
284 + var outBuffer = Buffer.alloc(9);
285 + outBuffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
286 + outBuffer.writeUInt32BE(this.lme.amtId, 1);
287 + outBuffer.writeUInt32BE(written, 5);
288 + this.HECI.write(outBuffer);
289 + });
290 + } else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) {
291 + var channel = this.insockets[rChannelId];
292 + if (channel.data == null) { channel.data = data.toString(); } else { channel.data += data.toString(); }
293 + channel.rxWindow += dataLen;
294 + //console.log('IN DATA', channel.rxWindow, channel.data.length, dataLen, channel.amtId, data.toString());
295 + var httpData = parseHttp(channel.data);
296 + if ((httpData != null) || (channel.data.length >= 8000)) {
297 + // Parse the WSMAN
298 + var notify = null;
299 + try { notify = xmlParser.ParseWsman(httpData); } catch (e) { }
300 +
301 + // Event the http data
302 + if (notify != null) { this.LMS.emit('notify', notify, channel.options, _lmsNotifyToString(notify), _lmsNotifyToCode(notify)); }
303 +
304 + // Send channel close
305 + var buffer = Buffer.alloc(5);
306 + buffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
307 + buffer.writeUInt32BE(amtId, 1);
308 + this.write(buffer);
309 + } else {
310 + if (channel.rxWindow > 6000) {
311 + // Send window adjust
312 + var buffer = Buffer.alloc(9);
313 + buffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
314 + buffer.writeUInt32BE(channel.amtId, 1);
315 + buffer.writeUInt32BE(channel.rxWindow, 5);
316 + this.write(buffer);
317 + channel.rxWindow = 0;
318 + }
319 + }
320 + } else {
321 + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA');
322 + }
323 + break;
324 + case APF_CHANNEL_OPEN_FAILURE:
325 + var rChannelId = chunk.readUInt32BE(1);
326 + var reasonCode = chunk.readUInt32BE(5);
327 + if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) {
328 + this.sockets[rChannelId].end();
329 + delete this.sockets[rChannelId];
330 + } else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) {
331 + delete this.insockets[rChannelId];
332 + } else {
333 + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_OPEN_FAILURE');
334 + }
335 + break;
336 + case APF_CHANNEL_CLOSE:
337 + var rChannelId = chunk.readUInt32BE(1);
338 + if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) {
339 + this.sockets[rChannelId].end();
340 + var amtId = this.sockets[rChannelId].lme.amtId;
341 + var buffer = Buffer.alloc(5);
342 + delete this.sockets[rChannelId];
343 +
344 + buffer.writeUInt8(APF_CHANNEL_CLOSE, 0); // ????????????????????????????
345 + buffer.writeUInt32BE(amtId, 1);
346 + this.write(buffer);
347 + } else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) {
348 + delete this.insockets[rChannelId];
349 + // Should I send a close back????
350 + } else {
351 + console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE');
352 + }
353 + break;
354 + case APF_CHANNEL_OPEN:
355 + var nameLen = chunk.readUInt32BE(1);
356 + var name = chunk.slice(5, nameLen + 5).toString();
357 + var channelSender = chunk.readUInt32BE(nameLen + 5);
358 + var initialWindowSize = chunk.readUInt32BE(nameLen + 9);
359 + var hostToConnectLen = chunk.readUInt32BE(nameLen + 17);
360 + var hostToConnect = chunk.slice(nameLen + 21, nameLen + 21 + hostToConnectLen).toString();
361 + var portToConnect = chunk.readUInt32BE(nameLen + 21 + hostToConnectLen);
362 + var originatorIpLen = chunk.readUInt32BE(nameLen + 25 + hostToConnectLen);
363 + var originatorIp = chunk.slice(nameLen + 29 + hostToConnectLen, nameLen + 29 + hostToConnectLen + originatorIpLen).toString();
364 + var originatorPort = chunk.readUInt32BE(nameLen + 29 + hostToConnectLen + originatorIpLen);
365 + //console.log('APF_CHANNEL_OPEN', name, channelSender, initialWindowSize, 'From: ' + originatorIp + ':' + originatorPort, 'To: ' + hostToConnect + ':' + portToConnect);
366 +
367 + if (this.insockets == null) { this.insockets = {}; }
368 + var ourId = ++lme_id;
369 + var insocket = new lme_object();
370 + insocket.ourId = ourId;
371 + insocket.amtId = channelSender;
372 + insocket.txWindow = initialWindowSize;
373 + insocket.rxWindow = 0;
374 + insocket.options = { target: hostToConnect, targetPort: portToConnect, source: originatorIp, sourcePort: originatorPort };
375 + this.insockets[ourId] = insocket;
376 +
377 + var buffer = Buffer.alloc(17);
378 + buffer.writeUInt8(APF_CHANNEL_OPEN_CONFIRMATION, 0);
379 + buffer.writeUInt32BE(channelSender, 1); // Intel AMT sender channel
380 + buffer.writeUInt32BE(ourId, 5); // Our receiver channel id
381 + buffer.writeUInt32BE(4000, 9); // Initial Window Size
382 + buffer.writeUInt32BE(0xFFFFFFFF, 13); // Reserved
383 + this.write(buffer);
384 +
385 + /*
386 + var buffer = Buffer.alloc(17);
387 + buffer.writeUInt8(APF_CHANNEL_OPEN_FAILURE, 0);
388 + buffer.writeUInt32BE(channelSender, 1); // Intel AMT sender channel
389 + buffer.writeUInt32BE(2, 5); // Reason code
390 + buffer.writeUInt32BE(0, 9); // Reserved
391 + buffer.writeUInt32BE(0, 13); // Reserved
392 + this.write(buffer);
393 + console.log('Sent APF_CHANNEL_OPEN_FAILURE', channelSender);
394 + */
395 +
396 + break;
397 + }
398 + });
399 + this.LMS.emit('connect');
400 + this.resume();
401 +
402 + });
403 +
404 + this.bindDuplexStream = function (duplexStream, remoteFamily, localPort) {
405 + var socket = duplexStream;
406 + //console.log('New [' + remoteFamily + '] Virtual Connection/' + socket.localPort);
407 + socket.pendingBytes = [];
408 + socket.HECI = this._LME;
409 + socket.LMS = this;
410 + socket.lme = new lme_object();
411 + socket.lme.Socket = socket;
412 + socket.localPort = localPort;
413 + var buffer = new MemoryStream();
414 + buffer.writeUInt8(0x5A);
415 + buffer.writeUInt32BE(15);
416 + buffer.write('forwarded-tcpip');
417 + buffer.writeUInt32BE(socket.lme.ourId);
418 + buffer.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE);
419 + buffer.writeUInt32BE(0xFFFFFFFF);
420 + for (var i = 0; i < 2; ++i) {
421 + if (remoteFamily == 'IPv6') {
422 + buffer.writeUInt32BE(3);
423 + buffer.write('::1');
424 + } else {
425 + buffer.writeUInt32BE(9);
426 + buffer.write('127.0.0.1');
427 + }
428 + buffer.writeUInt32BE(localPort);
429 + }
430 + this._LME.write(buffer.buffer);
431 + if (this._LME.sockets == undefined) { this._LME.sockets = {}; }
432 + this._LME.sockets[socket.lme.ourId] = socket;
433 + socket.pause();
434 + };
435 +
436 + this._LME.connect(heci.GUIDS.LME, { noPipeline: 0 });
437 +}
438 +
439 +function parseHttp(httpData) {
440 + var i = httpData.indexOf('\r\n\r\n');
441 + if ((i == -1) || (httpData.length < (i + 2))) { return null; }
442 + var headers = require('http-headers')(httpData.substring(0, i), true);
443 + var contentLength = parseInt(headers['content-length']);
444 + if (httpData.length >= contentLength + i + 4) { return httpData.substring(i + 4, i + 4 + contentLength); }
445 + return null;
446 +}
447 +
448 +function _lmsNotifyToCode(notify) {
449 + if ((notify == null) || (notify.Body == null) || (notify.Body.MessageID == null)) return null;
450 + var msgid = notify.Body.MessageID;
451 + try { msgid += '-' + notify.Body.MessageArguments[0]; } catch (e) { }
452 + return msgid;
453 +}
454 +
455 +function _lmsNotifyToString(notify) {
456 + if ((notify == null) || (notify.Body == null) || (notify.Body.MessageID == null)) return null;
457 + var msgid = notify.Body.MessageID;
458 + try { msgid += '-' + notify.Body.MessageArguments[0]; } catch (e) { }
459 + if (lmsEvents[msgid]) { return lmsEvents[msgid]; }
460 + return null;
461 +}
462 +
463 +var lmsEvents = {
464 + "iAMT0001": "System Defense Policy %1s triggered.",
465 + "iAMT0002": "Agent Presence Agent %1s not started.",
466 + "iAMT0003": "Agent Presence Agent %1s stopped.",
467 + "iAMT0004": "Agent Presence Agent %1s running.",
468 + "iAMT0005": "Agent Presence Agent %1s expired.",
469 + "iAMT0006": "Agent Presence Agent %1s suspended.",
470 + "iAMT0007": "Host software attempt to disable AMT Network link detected.",
471 + "iAMT0008": "Host software attempt to disable AMT Network link detected -- Host Network link blocked.",
472 + "iAMT0009": "AMT clock or FLASH wear-out protection disabled.",
473 + "iAMT0010": "Intel(R) AMT Network Interface %1s heuristics defense slow threshold trespassed.",
474 + "iAMT0011": "Intel(R) AMT Network Interface %1s heuristics defense fast threshold trespassed.",
475 + "iAMT0012": "Intel(R) AMT Network Interface %1s heuristics defense factory defined threshold trespassed.",
476 + "iAMT0013": "Intel(R) AMT Network Interface %1s heuristics defense Encounter timeout expired.",
477 + "iAMT0014": "General certificate error.",
478 + "iAMT0015": "Certificate expired.",
479 + "iAMT0016": "No trusted root certificate.",
480 + "iAMT0017": "Not configured to work with server certificate.",
481 + "iAMT0018": "Certificate revoked.",
482 + "iAMT0019": "RSA exponent too large.",
483 + "iAMT0020": "RSA modulus too large.",
484 + "iAMT0021": "Unsupported digest.",
485 + "iAMT0022": "Distinguished name too long.",
486 + "iAMT0023": "Key usage missing.",
487 + "iAMT0024": "General SSL handshake error.",
488 + "iAMT0025": "General 802.1x error.",
489 + "iAMT0026": "AMT Diagnostic AlertEAC error - General NAC error.",
490 + "iAMT0027": "AMT Diagnostic AlertEAC error - attempt to get a NAC posture while AMT NAC is disabled.",
491 + "iAMT0028": "AMT Diagnostic AlertEAC error - attempt to get a posture of an unsupported type.",
492 + "iAMT0029": "Audit log storage is 50% full.",
493 + "iAMT0030": "Audit log storage is 75% full.",
494 + "iAMT0031": "Audit log storage is 85% full.",
495 + "iAMT0032": "Audit log storage is 95% full.",
496 + "iAMT0033": "Audit log storage is full.",
497 + "iAMT0034": "Firmware Update Event - Partial.",
498 + "iAMT0035": "Firmware Update Event - Failure.",
499 + "iAMT0036": "Remote connectivity initiated.",
500 + "iAMT0037": "ME Presence event.",
501 + "iAMT0038-0": "AMT is being unprovisioned using BIOS command.",
502 + "iAMT0038-1": "AMT is being unprovisioned using Local MEI command.",
503 + "iAMT0038-2": "AMT is being unprovisioned using Local WS-MAN/SOAP command.",
504 + "iAMT0038-3": "AMT is being unprovisioned using Remote WS-MAN/SOAP command.",
505 + "iAMT0039": "HW Asset Error.",
506 + "iAMT0050": "User Notification Alert - General Notification.",
507 + "iAMT0050-16": "User Notification Alert - Circuit Breaker notification (CB Drop TX filter hit.).",
508 + "iAMT0050-17": "User Notification Alert - Circuit Breaker notification (CB Rate Limit TX filter hit.).",
509 + "iAMT0050-18": "User Notification Alert - Circuit Breaker notification (CB Drop RX filter hit.).",
510 + "iAMT0050-19": "User Notification Alert - Circuit Breaker notification (CB Rate Limit RX filter hit.).",
511 + "iAMT0050-32": "User Notification Alert - EAC notification.",
512 + "iAMT0050-48": "User Notification Alert - Remote diagnostics - (Remote Redirection session started - SOL).",
513 + "iAMT0050-49": "User Notification Alert - Remote diagnostics - (Remote Redirection session stopped - SOL).",
514 + "iAMT0050-50": "User Notification Alert - Remote diagnostics. (Remote Redirection session started - IDE-R).",
515 + "iAMT0050-51": "User Notification Alert - Remote diagnostics. (Remote Redirection session stopped - IDE-R).",
516 + "iAMT0050-66": "User Notification Alert - WLAN notification (Host profile mismatch - Management Interface ignored).",
517 + "iAMT0050-67": "User Notification Alert - WLAN notification (Management device overrides host radio).",
518 + "iAMT0050-68": "User Notification Alert - WLAN notification (Host profile security mismatch).",
519 + "iAMT0050-69": "User Notification Alert - WLAN notification (Management device relinquishes control over host Radio).",
520 + "iAMT0051": "User Notification Alert - SecIo event.",
521 + "iAMT0051-0": "User Notification Alert - SecIo event semaphore at host.",
522 + "iAMT0051-1": "User Notification Alert - semaphore at ME.",
523 + "iAMT0051-2": "User Notification Alert - SecIo event - semaphore timeout.",
524 + "iAMT0052": "User Notification Alert - KVM session event.",
525 + "iAMT0052-0": "User Notification Alert - KVM session requested.",
526 + "iAMT0052-1": "User Notification Alert - KVM session started.",
527 + "iAMT0052-2": "User Notification Alert - KVM session stopped.",
528 + "iAMT0052-3": "User Notification Alert - KVM data channel.",
529 + "iAMT0053": "User Notification Alert - RCS notification.",
530 + "iAMT0053-50": "User Notification Alert - RCS notification (HW button pressed. Connection initiated automatically).",
531 + "iAMT0053-52": "User Notification Alert - RCS notification (HW button pressed. Connection wasn't initiated automatically).",
532 + "iAMT0053-53": "User Notification Alert - RCS notification (Contracts updated).",
533 + "iAMT0054": "User Notification Alert - WLAN notification. Wireless Profile sync enablement state changed.",
534 + "iAMT0055": "User Notification Alert - Provisioning state change notification.",
535 + "iAMT0055-0": "User Notification Alert - Provisioning state change notification - Pre-configuration.",
536 + "iAMT0055-1": "User Notification Alert - Provisioning state change notification - In configuration.",
537 + "iAMT0055-2": "User Notification Alert - Provisioning state change notification - Post-configuration.",
538 + "iAMT0055-3": "User Notification Alert - Provisioning state change notification - Unprovision process has started.",
539 + "iAMT0056": "User Notification Alert - System Defense change notification.",
540 + "iAMT0057": "User Notification Alert - Network State change notification.",
541 + "iAMT0058": "User Notification Alert - Remote Access change notification.",
542 + "iAMT0058-1": "User Notification Alert - Remote Access change notification - tunnel is closed.",
543 + //"iAMT0058-1": "User Notification Alert - Remote Access change notification - tunnel is open.", // TODO
544 + "iAMT0059": "User Notification Alert - KVM enabled event.",
545 + "iAMT0059-0": "User Notification Alert - KVM enabled event - KVM disabled.",
546 + "iAMT0059-1": "User Notification Alert - KVM enabled event - KVM enabled (both from MEBx and PTNI).",
547 + "iAMT0060": "User Notification Alert - SecIO configuration event.",
548 + "iAMT0061": "ME FW reset occurred.",
549 + "iAMT0062": "User Notification Alert - IpSyncEnabled event.",
550 + "iAMT0062-0": "User Notification Alert - IpSyncEnabled event - IpSync disabled.",
551 + "iAMT0062-1": "User Notification Alert - IpSyncEnabled event - IpSync enabled.",
552 + "iAMT0063": "User Notification Alert - HTTP Proxy sync enabled event.",
553 + "iAMT0063-0": "User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync disabled.",
554 + "iAMT0063-1": "User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync enabled.",
555 + "iAMT0064": "User Notification Alert - User Consent event.",
556 + "iAMT0064-1": "User Notification Alert - User Consent event - User Consent granted.",
557 + "iAMT0064-2": "User Notification Alert - User Consent event - User Consent ended.",
558 + "iAMT0067-0": "Graceful Remote Control Operation - Shutdown.",
559 + "iAMT0067-1": "Graceful Remote Control Operation - Reset.",
560 + "iAMT0067-2": "Graceful Remote Control Operation - Hibernate.",
561 + "iAMT0068-0": "Link Protection Notification - No link protection.",
562 + "iAMT0068-1": "Link Protection Notification - Passive link protection.",
563 + "iAMT0068-2": "Link Protection Notification - High link protection.",
564 + "iAMT0069-0": "Local Time Sync Enablement Notification - Local Time Sync Disabled.",
565 + "iAMT0069-1": "Local Time Sync Enablement Notification - Local Time Sync Enabled.",
566 + "iAMT0070": "Host Reset Triggered by WD Expiration Notification.",
567 + "PLAT0004": "The chassis %1s was opened.",
568 + "PLAT0005": "The chassis %1s was closed.",
569 + "PLAT0006": "The drive bay %1s was opened.",
570 + "PLAT0007": "The drive bay %1s was closed.",
571 + "PLAT0008": "The I/O card area %1s was opened.",
572 + "PLAT0009": "The I/O card area %1s was closed.",
573 + "PLAT0010": "The processor area %1s was opened.",
574 + "PLAT0011": "The processor area %1s was closed.",
575 + "PLAT0012": "The LAN %1s has been disconnected.",
576 + "PLAT0013": "The LAN %1s has been connected.",
577 + "PLAT0016": "The permission to insert package %1s has been granted.",
578 + "PLAT0017": "The permission to insert package %1s has been removed.",
579 + "PLAT0018": "The fan card area %1s is open.",
580 + "PLAT0019": "The fan card area %1s is closed.",
581 + "PLAT0022": "The computer system %1s has detected a secure mode violation.",
582 + "PLAT0024": "The computer system %1s has detected a pre-boot user password violation.",
583 + "PLAT0026": "The computer system %1s has detected a pre-boot setup password violation.",
584 + "PLAT0028": "The computer system %1s has detected a network boot password violation.",
585 + "PLAT0030": "The computer system %1s has detected a password violation.",
586 + "PLAT0032": "The management controller %1s has detected an out-of-band password violation.",
587 + "PLAT0034": "The processor %1s has been added.",
588 + "PLAT0035": "The processor %1s has been removed.",
589 + "PLAT0036": "An over-temperature condition has been detected on the processor %1s.",
590 + "PLAT0037": "An over-temperature condition has been removed on the processor %1s.",
591 + "PLAT0038": "The processor %1s is operating in a degraded State.",
592 + "PLAT0039": "The processor %1s is no longer operating in a degraded State.",
593 + "PLAT0040": "The processor %1s has failed.",
594 + "PLAT0042": "The processor %1s has failed.",
595 + "PLAT0044": "The processor %1s has failed.",
596 + "PLAT0046": "The processor %1s has failed.",
597 + "PLAT0048": "The processor %1s has failed.",
598 + "PLAT0060": "The processor %1s has been enabled.",
599 + "PLAT0061": "The processor %1s has been disabled.",
600 + "PLAT0062": "The processor %1s has a configuration mismatch.",
601 + "PLAT0064": "A terminator has been detected on the processor %1s.",
602 + "PLAT0084": "The Power Supply %1s has been added.",
603 + "PLAT0085": "The Power Supply %1s has been removed.",
604 + "PLAT0086": "The Power Supply %1s has failed.",
605 + "PLAT0088": "Failure predicted on power supply %1s.",
606 + "PLAT0096": "The input to power supply %1s has been lost or fallen out of range.",
607 + "PLAT0098": "The power supply %1s is operating in an input state that is out of range.",
608 + "PLAT0099": "The power supply %1s has returned to a normal input state.",
609 + "PLAT0100": "The power supply %1s has lost input.",
610 + "PLAT0104": "The power supply %1s has a configuration mismatch.",
611 + "PLAT0106": "Power supply %1s has been disabled.",
612 + "PLAT0107": "Power supply %1s has been enabled.",
613 + "PLAT0108": "Power supply %1s has been power cycled.",
614 + "PLAT0110": "Power supply %1s has encountered an error during power down.",
615 + "PLAT0112": "Power supply %1s has lost power.",
616 + "PLAT0114": "Soft power control has failed for power supply %1s.",
617 + "PLAT0116": "Power supply %1s has failed.",
618 + "PLAT0118": "Failure predicted on power supply %1s.",
619 + "PLAT0120": "Memory subsystem failure.",
620 + "PLAT0122": "DIMM missing.",
621 + "PLAT0124": "Memory error detected & corrected for DIMM %1s.",
622 + "PLAT0128": "Memory DIMM %1s added.",
623 + "PLAT0129": "Memory DIMM %1s removed.",
624 + "PLAT0130": "Memory DIMM %1s enabled.",
625 + "PLAT0131": "Memory DIMM %1s disabled.",
626 + "PLAT0134": "Memory parity error for DIMM %1s.",
627 + "PLAT0136": "Memory scrub failure for DIMM %1s.",
628 + "PLAT0138": "Memory uncorrectable error detected for DIMM %1s.",
629 + "PLAT0140": "Memory sparing initiated for DIMM %1s.",
630 + "PLAT0141": "Memory sparing concluded for DIMM %1s.",
631 + "PLAT0142": "Memory DIMM %1s Throttled.",
632 + "PLAT0144": "Memory logging limit reached for DIMM %1s.",
633 + "PLAT0145": "Memory logging limit removed for DIMM %1s.",
634 + "PLAT0146": "An over-temperature condition has been detected on the Memory DIMM %1s.",
635 + "PLAT0147": "An over-temperature condition has been removed on the Memory DIMM %1s.",
636 + "PLAT0162": "The drive %1s has been added.",
637 + "PLAT0163": "The drive %1s has been removed.",
638 + "PLAT0164": "The drive %1s has been disabled due to a detected fault.",
639 + "PLAT0167": "The drive %1s has been enabled.",
640 + "PLAT0168": "Failure predicted on drive %1s.",
641 + "PLAT0170": "Hot spare enabled for %1s.",
642 + "PLAT0171": "Hot spare disabled for %1s.",
643 + "PLAT0172": "Consistency check has begun for %1s.",
644 + "PLAT0173": "Consistency check completed for %1s.",
645 + "PLAT0174": "Array %1s is in critical condition.",
646 + "PLAT0176": "Array %1s has failed.",
647 + "PLAT0177": "Array %1s has been restored.",
648 + "PLAT0178": "Rebuild in progress for array %1s.",
649 + "PLAT0179": "Rebuild completed for array %1s.",
650 + "PLAT0180": "Rebuild Aborted for array %1s.",
651 + "PLAT0184": "The system %1s encountered a POST error.",
652 + "PLAT0186": "The system %1s encountered a firmware hang.",
653 + "PLAT0188": "The system %1s encountered firmware progress.",
654 + "PLAT0192": "The log %1s has been disabled.",
655 + "PLAT0193": "The log %1s has been enabled.",
656 + "PLAT0194": "The log %1s has been disabled.",
657 + "PLAT0195": "The log %1s has been enabled.",
658 + "PLAT0196": "The log %1s has been disabled.",
659 + "PLAT0198": "The log %1s has been enabled.",
660 + "PLAT0200": "The log %1s has been cleared.",
661 + "PLAT0202": "The log %1s is full.",
662 + "PLAT0203": "The log %1s is no longer full.",
663 + "PLAT0204": "The log %1s is almost full.",
664 + "PLAT0208": "The log %1s has a configuration error.",
665 + "PLAT0210": "The system %1s has been reconfigured.",
666 + "PLAT0212": "The system %1s has encountered an OEM system boot event.",
667 + "PLAT0214": "The system %1s has encountered an unknown system hardware fault.",
668 + "PLAT0216": "The system %1s has generated an auxiliary log entry.",
669 + "PLAT0218": "The system %1s has executed a PEF action.",
670 + "PLAT0220": "The system %1s has synchronized the system clock.",
671 + "PLAT0222": "A diagnostic interrupt has occurred on system %1s.",
672 + "PLAT0224": "A bus timeout has occurred on system %1s.",
673 + "PLAT0226": "An I/O channel check NMI has occurred on system %1s.",
674 + "PLAT0228": "A software NMI has occurred on system %1s.",
675 + "PLAT0230": "System %1s has recovered from an NMI.",
676 + "PLAT0232": "A PCI PERR has occurred on system %1s.",
677 + "PLAT0234": "A PCI SERR has occurred on system %1s.",
678 + "PLAT0236": "An EISA fail safe timeout occurred on system %1s.",
679 + "PLAT0238": "A correctable bus error has occurred on system %1s.",
680 + "PLAT0240": "An uncorrectable bus error has occurred on system %1s.",
681 + "PLAT0242": "A fatal NMI error has occurred on system %1s.",
682 + "PLAT0244": "A fatal bus error has occurred on system %1s.",
683 + "PLAT0246": "A bus on system %1s is operating in a degraded state.",
684 + "PLAT0247": "A bus on system %1s is no longer operating in a degraded state.",
685 + "PLAT0248": "The power button %1s has been pressed.",
686 + "PLAT0249": "The power button %1s has been released.",
687 + "PLAT0250": "The sleep button %1s has been pressed.",
688 + "PLAT0251": "The sleep button %1s has been released.",
689 + "PLAT0252": "The reset button %1s has been pressed.",
690 + "PLAT0253": "The reset button %1s has been released.",
691 + "PLAT0254": "The latch to %1s has been opened.",
692 + "PLAT0255": "The latch to %1s has been closed.",
693 + "PLAT0256": "The service request %1s has been enabled.",
694 + "PLAT0257": "The service request %1s has been completed.",
695 + "PLAT0258": "Power control of system %1s has failed.",
696 + "PLAT0262": "The network port %1s has been connected.",
697 + "PLAT0263": "The network port %1s has been disconnected.",
698 + "PLAT0266": "The connector %1s has encountered a configuration error.",
699 + "PLAT0267": "The connector %1s configuration error has been repaired.",
700 + "PLAT0272": "Power on for system %1s.",
701 + "PLAT0274": "Power cycle hard requested for system %1s.",
702 + "PLAT0276": "Power cycle soft requested for system %1s.",
703 + "PLAT0278": "PXE boot requested for system %1s.",
704 + "PLAT0280": "Diagnostics boot requested for system %1s.",
705 + "PLAT0282": "System restart requested for system %1s.",
706 + "PLAT0284": "System restart begun for system %1s.",
707 + "PLAT0286": "No bootable media available for system %1s.",
708 + "PLAT0288": "Non-bootable media selected for system %1s.",
709 + "PLAT0290": "PXE server not found for system %1s.",
710 + "PLAT0292": "User timeout on boot for system %1s.",
711 + "PLAT0296": "System %1s boot from floppy initiated.",
712 + "PLAT0298": "System %1s boot from local drive initiated.",
713 + "PLAT0300": "System %1s boot from PXE on network port initiated.",
714 + "PLAT0302": "System %1s boot diagnostics initiated.",
715 + "PLAT0304": "System %1s boot from CD initiated.",
716 + "PLAT0306": "System %1s boot from ROM initiated.",
717 + "PLAT0312": "System %1s boot initiated.",
718 + "PLAT0320": "Critical stop during OS load on system %1s.",
719 + "PLAT0322": "Run-time critical stop on system %1s.",
720 + "PLAT0324": "OS graceful stop on system %1s.",
721 + "PLAT0326": "OS graceful shutdown begun on system %1s.",
722 + "PLAT0327": "OS graceful shutdown completed on system %1s.",
723 + "PLAT0328": "Agent not responding on system %1s.",
724 + "PLAT0329": "Agent has begun responding on system %1s.",
725 + "PLAT0330": "Fault in slot on system %1s.",
726 + "PLAT0331": "Fault condition removed on system %1s.",
727 + "PLAT0332": "Identifying slot on system %1s.",
728 + "PLAT0333": "Identify stopped on slot for system %1s.",
729 + "PLAT0334": "Package installed in slot for system %1s.",
730 + "PLAT0336": "Slot empty system %1s.",
731 + "PLAT0338": "Slot in system %1s is ready for installation.",
732 + "PLAT0340": "Slot in system %1s is ready for removal.",
733 + "PLAT0342": "Power is off on slot of system %1s.",
734 + "PLAT0344": "Power is on for slot of system %1s.",
735 + "PLAT0346": "Removal requested for slot of system %1s.",
736 + "PLAT0348": "Interlock activated on slot of system %1s.",
737 + "PLAT0349": "Interlock de-asserted on slot of system %1s.",
738 + "PLAT0350": "Slot disabled on system %1s.",
739 + "PLAT0351": "Slot enabled on system %1s.",
740 + "PLAT0352": "Slot of system %1s holds spare.",
741 + "PLAT0353": "Slot of system %1s no longer holds spare.",
742 + "PLAT0354": "Computer system %1s enabled.",
743 + "PLAT0356": "Computer system %1s is in sleep - light mode.",
744 + "PLAT0358": "Computer system %1s is in hibernate.",
745 + "PLAT0360": "Computer system %1s is in standby.",
746 + "PLAT0362": "Computer system %1s is in soft off mode.",
747 + "PLAT0364": "Computer system %1s is in hard off mode.",
748 + "PLAT0366": "Computer system %1s is sleeping.",
749 + "PLAT0368": "Watchdog timer expired for %1s.",
750 + "PLAT0370": "Reboot of system initiated by watchdog %1s.",
751 + "PLAT0372": "Powering off system initiated by watchdog %1s.",
752 + "PLAT0374": "Power cycle of system initiated by watchdog %1s.",
753 + "PLAT0376": "Watchdog timer interrupt occurred for %1s.",
754 + "PLAT0378": "A page alert has been generated for system %1s.",
755 + "PLAT0380": "A LAN alert has been generated for system %1s.",
756 + "PLAT0382": "An event trap has been generated for system %1s.",
757 + "PLAT0384": "An SNMP trap has been generated for system %1s.",
758 + "PLAT0390": "%1s detected as present.",
759 + "PLAT0392": "%1s detected as absent.",
760 + "PLAT0394": "%1s has been disabled.",
761 + "PLAT0395": "%1s has been enabled.",
762 + "PLAT0396": "Heartbeat lost for LAN %1s.",
763 + "PLAT0397": "Heartbeat detected for LAN %1s.",
764 + "PLAT0398": "Sensor %1s is unavailable or degraded on management system.",
765 + "PLAT0399": "Sensor %1s has returned to normal on management system.",
766 + "PLAT0400": "Controller %1s is unavailable or degraded on management system.",
767 + "PLAT0401": "Controller %1s has returned to normal on management system.",
768 + "PLAT0402": "Management system %1s is off-line.",
769 + "PLAT0404": "Management system %1s is disabled.",
770 + "PLAT0405": "Management system %1s is enabled.",
771 + "PLAT0406": "Sensor %1s has failed on management system.",
772 + "PLAT0408": "FRU %1s has failed on management system.",
773 + "PLAT0424": "The battery %1s is critically low.",
774 + "PLAT0427": "The battery %1s is no longer critically low.",
775 + "PLAT0430": "The battery %1s has been removed from unit.",
776 + "PLAT0431": "The battery %1s has been added.",
777 + "PLAT0432": "The battery %1s has failed.",
778 + "PLAT0434": "Session audit is deactivated on system %1s.",
779 + "PLAT0435": "Session audit is activated on system %1s.",
780 + "PLAT0436": "A hardware change occurred on system %1s.",
781 + "PLAT0438": "A firmware or software change occurred on system %1s.",
782 + "PLAT0440": "A hardware incompatibility was detected on system %1s.",
783 + "PLAT0442": "A firmware or software incompatibility was detected on system %1s.",
784 + "PLAT0444": "Invalid or unsupported hardware was detected on system %1s.",
785 + "PLAT0446": "Invalid or unsupported firmware or software was detected on system %1s.",
786 + "PLAT0448": "A successful hardware change was detected on system %1s.",
787 + "PLAT0450": "A successful software or firmware change was detected on system %1s.",
788 + "PLAT0464": "FRU %1s not installed on system.",
789 + "PLAT0465": "FRU %1s installed on system.",
790 + "PLAT0466": "Activation requested for FRU %1s on system.",
791 + "PLAT0467": "FRU %1s on system is active.",
792 + "PLAT0468": "Activation in progress for FRU %1s on system.",
793 + "PLAT0470": "Deactivation request for FRU %1s on system.",
794 + "PLAT0471": "FRU %1s on system is in standby or \"hot spare\" state.",
795 + "PLAT0472": "Deactivation in progress for FRU %1s on system.",
796 + "PLAT0474": "Communication lost with FRU %1s on system.",
797 + "PLAT0476": "Numeric sensor %1s going low (lower non-critical).",
798 + "PLAT0478": "Numeric sensor %1s going high (lower non-critical).",
799 + "PLAT0480": "Numeric sensor %1s going low (lower critical).",
800 + "PLAT0482": "Numeric sensor %1s going high (lower critical).",
801 + "PLAT0484": "Numeric sensor %1s going low (lower non-recoverable).",
802 + "PLAT0486": "Numeric sensor %1s going high (lower non-critical).",
803 + "PLAT0488": "Numeric sensor %1s going low (upper non-critical).",
804 + "PLAT0490": "Numeric sensor %1s going high (upper non-critical).",
805 + "PLAT0492": "Numeric sensor %1s going low (upper critical).",
806 + "PLAT0494": "Numeric sensor %1s going high (upper critical).",
807 + "PLAT0496": "Numeric sensor %1s going low (upper non-recoverable).",
808 + "PLAT0498": "Numeric sensor %1s going high (upper non-recoverable).",
809 + "PLAT0500": "Sensor %1s has transitioned to idle.",
810 + "PLAT0502": "Sensor %1s has transitioned to active.",
811 + "PLAT0504": "Sensor %1s has transitioned to busy.",
812 + "PLAT0508": "Sensor %1s has asserted.",
813 + "PLAT0509": "Sensor %1s has de-asserted.",
814 + "PLAT0510": "Sensor %1s is asserting predictive failure.",
815 + "PLAT0511": "Sensor %1s is de-asserting predictive failure.",
816 + "PLAT0512": "Sensor %1s has indicated limit exceeded.",
817 + "PLAT0513": "Sensor %1s has indicated limit no longer exceeded.",
818 + "PLAT0514": "Sensor %1s has indicated performance met.",
819 + "PLAT0516": "Sensor %1s has indicated performance lags.",
820 + "PLAT0518": "Sensor %1s has transitioned to normal state.",
821 + "PLAT0520": "Sensor %1s has transitioned from normal to non-critical state.",
822 + "PLAT0522": "Sensor %1s has transitioned to critical from a less severe state.",
823 + "PLAT0524": "Sensor %1s has transitioned to non-recoverable from a less severe state.",
824 + "PLAT0526": "Sensor %1s has transitioned to non-critical from a more severe state.",
825 + "PLAT0528": "Sensor %1s has transitioned to critical from a non-recoverable state.",
826 + "PLAT0530": "Sensor %1s has transitioned to non-recoverable.",
827 + "PLAT0532": "Sensor %1s indicates a monitor state.",
828 + "PLAT0534": "Sensor %1s has an informational state.",
829 + "PLAT0536": "Device %1s has been added.",
830 + "PLAT0537": "Device %1s has been removed from unit.",
831 + "PLAT0538": "Device %1s has been enabled.",
832 + "PLAT0539": "Device %1s has been disabled.",
833 + "PLAT0540": "Sensor %1s has indicated a running state.",
834 + "PLAT0544": "Sensor %1s has indicated a power off state.",
835 + "PLAT0546": "Sensor %1s has indicated an on-line state.",
836 + "PLAT0548": "Sensor %1s has indicated an off-line state.",
837 + "PLAT0550": "Sensor %1s has indicated an off-duty state.",
838 + "PLAT0552": "Sensor %1s has indicated a degraded state.",
839 + "PLAT0554": "Sensor %1s has indicated a power save state.",
840 + "PLAT0556": "Sensor %1s has indicated an install error.",
841 + "PLAT0558": "Redundancy %1s has been lost.",
842 + "PLAT0560": "Redundancy %1s has been reduced.",
843 + "PLAT0561": "Redundancy %1s has been restored.",
844 + "PLAT0562": "%1s has transitioned to a D0 power state.",
845 + "PLAT0564": "%1s has transitioned to a D1 power state.",
846 + "PLAT0566": "%1s has transitioned to a D2 power state.",
847 + "PLAT0568": "%1s has transitioned to a D3 power state.",
848 + "PLAT0720": "The System %1s encountered firmware progress - memory initialization entry.",
849 + "PLAT0721": "The System %1s encountered firmware progress - memory initialization exit.",
850 + "PLAT0722": "The System %1s encountered firmware progress - hard drive initialization entry.",
851 + "PLAT0723": "The System %1s encountered firmware progress - hard drive initialization exit.",
852 + "PLAT0724": "The System %1s encountered firmware progress - user authentication.",
853 + "PLAT0728": "The System %1s encountered firmware progress - USR resource configuration entry.",
854 + "PLAT0729": "The System %1s encountered firmware progress - USR resource configuration exit.",
855 + "PLAT0730": "The System %1s encountered firmware progress - PCI recource configuration entry.",
856 + "PLAT0731": "The System %1s encountered firmware progress - PCI recource configuration exit.",
857 + "PLAT0732": "The System %1s encountered firmware progress - Option ROM initialization entry.",
858 + "PLAT0733": "The System %1s encountered firmware progress - Option ROM initialization entry exit.",
859 + "PLAT0734": "The System %1s encountered firmware progress -video initialization entry entry.",
860 + "PLAT0735": "The System %1s encountered firmware progress - video initialization entry exit.",
861 + "PLAT0736": "The System %1s encountered firmware progress - cache initialization entry.",
862 + "PLAT0737": "The System %1s encountered firmware progress - cache initialization exit.",
863 + "PLAT0738": "The System %1s encountered firmware progress - keyboard controller initialization entry.",
864 + "PLAT0739": "The System %1s encountered firmware progress - keyboard controller initialization exit.",
865 + "PLAT0740": "The System %1s encountered firmware progress - motherboard initialization entry.",
866 + "PLAT0741": "The System %1s encountered firmware progress - motherboard initialization exit.",
867 + "PLAT0742": "The System %1s encountered firmware progress - floppy disk initialization entry.",
868 + "PLAT0743": "The System %1s encountered firmware progress - floppy disk initialization exit.",
869 + "PLAT0744": "The System %1s encountered firmware progress - keyboard test entry.",
870 + "PLAT0745": "The System %1s encountered firmware progress - keyboard test exit.",
871 + "PLAT0746": "The System %1s encountered firmware progress - pointing device test entry.",
872 + "PLAT0747": "The System %1s encountered firmware progress - pointing device test exit.",
873 + "PLAT0750": "The System %1s encountered firmware progress - dock enable entry.",
874 + "PLAT0751": "The System %1s encountered firmware progress - dock enable exit.",
875 + "PLAT0752": "The System %1s encountered firmware progress - dock disable entry.",
876 + "PLAT0753": "The System %1s encountered firmware progress - dock disable exit.",
877 + "PLAT0760": "The System %1s encountered firmware progress - start OS boot process.",
878 + "PLAT0762": "The System %1s encountered firmware progress - call OS wake vector.",
879 + "PLAT0764": "The System %1s encountered firmware progress - unrecoverable keyboard failure.",
880 + "PLAT0766": "The System %1s encountered firmware progress - no video device detected.",
881 + "PLAT0768": "The System %1s encountered firmware progress - SMART alert detected on drive.",
882 + "PLAT0770": "The System %1s encountered firmware progress - unrecoverable boot device failure.",
883 + "PLAT0789": "Corrupt BIOS detected.",
884 + "PLAT0790": "The System %1s encountered PCI configuration failure.",
885 + "PLAT0791": "The System %1s encountered a video subsystem failure.",
886 + "PLAT0792": "The System %1s encountered a storage subsystem failure.",
887 + "PLAT0793": "The System %1s encountered a USB subsystem failure.",
888 + "PLAT0794": "The System %1s has detected no memory in the system.",
889 + "PLAT0795": "The System %1s encountered a motherboard failure.",
890 + "PLAT0796": "The System %1s encountered a memory Regulator Voltage Bad.",
891 + "PLAT0797": "%1s PCI reset is not deasserting.",
892 + "PLAT0798": "%1s Non-Motherboard Regulator Failure.",
893 + "PLAT0799": "%1s Power Supply Cable failure.",
894 + "PLAT0800": "%1s Motherboard regulator failure.",
895 + "PLAT0801": "%1s System component compatibility mismatch."
896 +}
897 +
898 +module.exports = lme_heci;
agents-new/modules_meshcore/amt-manage.js new
+649
@@ -0,0 +1,649 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +/**
18 +* @fileoverview Intel(r) AMT Management
19 +* @author Ylian Saint-Hilaire
20 +* @version v0.1.0
21 +*/
22 +
23 +/**
24 + * Construct a AmtStackCreateService object, this ia the main Intel AMT communication stack.
25 + * @constructor
26 + */
27 +function AmtManager(agent, db, isdebug) {
28 + var sendConsole = function (msg) { agent.SendCommand({ "action": "msg", "type": "console", "value": msg }); }
29 + var debug = function (msg) { if (isdebug) { sendConsole('amt-manager: ' + msg + '<br />'); } }
30 + var amtMei = null, amtMeiState = 0;
31 + var amtLms = null, amtLmsState = 0;
32 + var amtGetVersionResult = null;
33 + var oswsstack = null;
34 + var osamtstack = null;
35 + var amtpolicy = null;
36 + var obj = this;
37 + obj.state = 0;
38 + obj.lmsstate = 0;
39 + obj.onStateChange = null;
40 + obj.setDebug = function (x) { isdebug = x; }
41 +
42 + // Set current Intel AMT activation policy
43 + obj.setPolicy = function (policy) {
44 + if (JSON.stringify(amtpolicy) != JSON.stringify(policy)) {
45 + amtpolicy = policy;
46 + if (applyPolicyTimer == null) { obj.applyPolicy(); }
47 + }
48 + }
49 +
50 + // Try to load up the MEI module
51 + var rebindToMeiRetrys = 0;
52 + obj.reset = function () {
53 + ++rebindToMeiRetrys;
54 + amtMei = null, amtMeiState = 0, amtLms = null, amtLmsState = 0, obj.state = 0, obj.lmsstate = 0;
55 + //debug('Binding to MEI');
56 + try {
57 + var amtMeiLib = require('amt-mei');
58 + amtMei = new amtMeiLib();
59 + amtMei.on('error', function (e) { debug('MEI error'); amtMei = null; amtMeiState = -1; obj.state = -1; obj.onStateChange(amtMeiState); });
60 + amtMei.getVersion(function (result) {
61 + if (result == null) {
62 + amtMeiState = -1;
63 + obj.state = -1;
64 + if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); }
65 + if (rebindToMeiRetrys < 10) { setTimeout(obj.reset, 10000); }
66 + } else {
67 + amtGetVersionResult = result;
68 + amtMeiState = 2;
69 + obj.state = 2;
70 + rebindToMeiRetrys = 0;
71 + if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); }
72 + //debug('MEI binded');
73 + obj.lmsreset();
74 + }
75 + });
76 + } catch (ex) { debug('MEI exception: ' + ex); amtMei = null; amtMeiState = -1; obj.state = -1; }
77 + }
78 +
79 + // Get Intel AMT information using MEI
80 + var amtMeiTmpState = null;
81 + obj.getAmtInfo = function(func) {
82 + if ((amtMei == null) || (amtMeiState < 2)) { if (func != null) { func(null); } return; }
83 + try {
84 + amtMeiTmpState = { Flags: 0 }; // Flags: 1=EHBC, 2=CCM, 4=ACM
85 + amtMei.getProtocolVersion(function (result) { if (result != null) { amtMeiTmpState.MeiVersion = result; } });
86 + amtMei.getVersion(function (result) { if (result) { amtMeiTmpState.Versions = {}; for (var version in result.Versions) { amtMeiTmpState.Versions[result.Versions[version].Description] = result.Versions[version].Version; } } });
87 + amtMei.getProvisioningMode(function (result) { if (result) { amtMeiTmpState.ProvisioningMode = result.mode; } });
88 + amtMei.getProvisioningState(function (result) { if (result) { amtMeiTmpState.ProvisioningState = result.state; } });
89 + amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } });
90 + 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
91 + //amtMei.getMACAddresses(function (result) { if (result) { amtMeiTmpState.mac = result; } });
92 + amtMei.getLanInterfaceSettings(0, function (result) { if (result) { amtMeiTmpState.net0 = result; } });
93 + amtMei.getLanInterfaceSettings(1, function (result) { if (result) { amtMeiTmpState.net1 = result; } });
94 + amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { amtMeiTmpState.UUID = result.uuid; } });
95 + amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } if (func != null) { func(amtMeiTmpState); } });
96 + } catch (e) { if (func != null) { func(null); } return; }
97 + }
98 +
99 + // Called on MicroLMS Intel AMT user notification
100 + var handleAmtNotification = function(notifyMsg) {
101 + if ((notifyMsg == null) || (notifyMsg.Body == null) || (notifyMsg.Body.MessageID == null) || (notifyMsg.Body.MessageArguments == null)) return null;
102 + var amtMessage = notifyMsg.Body.MessageID, amtMessageArg = notifyMsg.Body.MessageArguments[0], notify = null;
103 +
104 + switch (amtMessage) {
105 + case 'iAMT0050': { if (amtMessageArg == '48') { notify = 'Intel&reg; AMT Serial-over-LAN connected'; } else if (amtMessageArg == '49') { notify = 'Intel&reg; AMT Serial-over-LAN disconnected'; } break; } // SOL
106 + case 'iAMT0052': { if (amtMessageArg == '1') { notify = 'Intel&reg; AMT KVM connected'; } else if (amtMessageArg == '2') { notify = 'Intel&reg; AMT KVM disconnected'; } break; } // KVM
107 + default: { break; }
108 + }
109 +
110 + // Sent to the entire group, no sessionid or userid specified.
111 + if (notify != null) { agent.SendCommand({ "action": "msg", "type": "notify", "value": notify, "tag": "general" }); }
112 + }
113 +
114 + // Launch LMS
115 + obj.lmsreset = function () {
116 + //debug('Binding to LMS');
117 + var amtLms = null, amtLmsState = 0;
118 + obj.lmsstate = 0;
119 + try {
120 + var lme_heci = require('amt-lme');
121 + amtLmsState = 1;
122 + obj.lmsstate = 1;
123 + amtLms = new lme_heci();
124 + amtLms.on('error', function (e) { amtLmsState = 0; obj.lmsstate = 0; amtLms = null; debug('LMS error'); setupMeiOsAdmin(1); });
125 + amtLms.on('connect', function () { amtLmsState = 2; obj.lmsstate = 2; debug('LMS connected'); setupMeiOsAdmin(2); });
126 + //amtLms.on('bind', function (map) { });
127 + amtLms.on('notify', function (data, options, str, code) {
128 + //debug('LMS notify');
129 + if (code == 'iAMT0052-3') {
130 + kvmGetData();
131 + } else {
132 + //if (str != null) { debug('Intel AMT LMS: ' + str); }
133 + handleAmtNotification(data);
134 + }
135 + });
136 + } catch (e) { amtLmsState = -1; obj.lmsstate = -1; amtLms = null; }
137 + }
138 +
139 +
140 + //
141 + // KVM Data Channel
142 + //
143 +
144 + var setupMeiOsAdmin = function (state) {
145 + //debug('Setup MEI OS Admin');
146 + if ((amtMei == null) || (amtMeiState < 2) || (amtGetVersionResult == null)) { return; } // If there is no MEI, don't bother with obj.
147 + amtMei.getLocalSystemAccount(function (x) {
148 + if (x == null) return;
149 + //debug('getLocalSystemAccount ' + JSON.stringify(x));
150 + var transport = require('amt-wsman-duk');
151 + var wsman = require('amt-wsman');
152 + var amt = require('amt');
153 + oswsstack = new wsman(transport, '127.0.0.1', 16992, x.user, x.pass, false);
154 + osamtstack = new amt(oswsstack);
155 + //if (func) { func(state); }
156 +
157 + // We got the $$OsAdmin account setup.
158 + amtMeiState = 3;
159 + obj.state = 3;
160 + if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); }
161 + if (applyPolicyTimer == null) { obj.applyPolicy(); }
162 +
163 + //var AllWsman = "CIM_SoftwareIdentity,IPS_SecIOService,IPS_ScreenSettingData,IPS_ProvisioningRecordLog,IPS_HostBasedSetupService,IPS_HostIPSettings,IPS_IPv6PortSettings".split(',');
164 + //osamtstack.BatchEnum(null, AllWsman, startLmsWsmanResponse, null, true);
165 + //*************************************
166 + // Setup KVM data channel if this is Intel AMT 12 or above
167 + var amtver = null;
168 + try { for (var i in amtGetVersionResult.Versions) { if (amtGetVersionResult.Versions[i].Description == 'AMT') amtver = parseInt(amtGetVersionResult.Versions[i].Version.split('.')[0]); } } catch (e) { }
169 + if ((amtver != null) && (amtver >= 12)) {
170 + debug('KVM data channel setup');
171 + kvmGetData('skip'); // Clear any previous data, this is a dummy read to about handling old data.
172 + obj.kvmTempTimer = setInterval(function () { kvmGetData(); }, 2000); // Start polling for KVM data.
173 + kvmSetData(JSON.stringify({ action: 'restart', ver: 1 })); // Send a restart command to advise the console if present that MicroLMS just started.
174 + }
175 + });
176 + }
177 +
178 + var kvmGetData = function (tag) {
179 + osamtstack.IPS_KVMRedirectionSettingData_DataChannelRead(obj.kvmDataGetResponse, tag);
180 + }
181 +
182 + var kvmDataGetResponse = function (stack, name, response, status, tag) {
183 + if ((tag != 'skip') && (status == 200) && (response.Body.ReturnValue == 0)) {
184 + var val = null;
185 + try { val = Buffer.from(response.Body.DataMessage, 'base64').toString(); } catch (e) { return }
186 + if (val != null) { obj.kvmProcessData(response.Body.RealmsBitmap, response.Body.MessageId, val); }
187 + }
188 + }
189 +
190 + var webRtcDesktop = null;
191 + var kvmProcessData = function (realms, messageId, val) {
192 + var data = null;
193 + try { data = JSON.parse(val) } catch (e) { }
194 + if ((data != null) && (data.action)) {
195 + if (data.action == 'present') { kvmSetData(JSON.stringify({ action: 'present', ver: 1, platform: process.platform })); }
196 + if (data.action == 'offer') {
197 + webRtcDesktop = {};
198 + var rtc = require('ILibWebRTC');
199 + webRtcDesktop.webrtc = rtc.createConnection();
200 + webRtcDesktop.webrtc.on('connected', function () { });
201 + webRtcDesktop.webrtc.on('disconnected', function () { obj.webRtcCleanUp(); });
202 + webRtcDesktop.webrtc.on('dataChannel', function (rtcchannel) {
203 + webRtcDesktop.rtcchannel = rtcchannel;
204 + webRtcDesktop.kvm = mesh.getRemoteDesktopStream();
205 + webRtcDesktop.kvm.pipe(webRtcDesktop.rtcchannel, { dataTypeSkip: 1, end: false });
206 + webRtcDesktop.rtcchannel.on('end', function () { obj.webRtcCleanUp(); });
207 + webRtcDesktop.rtcchannel.on('data', function (x) { obj.kvmCtrlData(this, x); });
208 + webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm, { dataTypeSkip: 1, end: false });
209 + //webRtcDesktop.kvm.on('end', function () { debug('WebRTC DataChannel closed2'); obj.webRtcCleanUp(); });
210 + //webRtcDesktop.rtcchannel.on('data', function (data) { debug('WebRTC data: ' + data); });
211 + });
212 + kvmSetData(JSON.stringify({ action: 'answer', ver: 1, sdp: webRtcDesktop.webrtc.setOffer(data.sdp) }));
213 + }
214 + }
215 + }
216 +
217 + // Process KVM control channel data
218 + var kvmCtrlData = function (channel, cmd) {
219 + if (cmd.length > 0 && cmd.charCodeAt(0) != 123) {
220 + // This is upload data
221 + if (obj.fileupload != null) {
222 + cmd = Buffer.from(cmd, 'base64');
223 + var header = cmd.readUInt32BE(0);
224 + if ((header == 0x01000000) || (header == 0x01000001)) {
225 + fs.writeSync(obj.fileupload.fp, cmd.slice(4));
226 + channel.write({ action: 'upload', sub: 'ack', reqid: obj.fileupload.reqid });
227 + if (header == 0x01000001) { fs.closeSync(obj.fileupload.fp); obj.fileupload = null; } // Close the file
228 + }
229 + }
230 + return;
231 + }
232 + debug('KVM Ctrl Data: ' + cmd);
233 + //sendConsoleText('KVM Ctrl Data: ' + cmd);
234 +
235 + try { cmd = JSON.parse(cmd); } catch (ex) { debug('Invalid JSON: ' + cmd); return; }
236 + if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
237 + switch (cmd.action) {
238 + case 'ping': {
239 + // This is a keep alive
240 + channel.write({ action: 'pong' });
241 + break;
242 + }
243 + case 'lock': {
244 + // Lock the current user out of the desktop
245 + 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 }); }
246 + break;
247 + }
248 + case 'ls': {
249 + /*
250 + // Close the watcher if required
251 + var samepath = ((obj.httprequest.watcher != undefined) && (cmd.path == obj.httprequest.watcher.path));
252 + if ((obj.httprequest.watcher != undefined) && (samepath == false)) {
253 + //console.log('Closing watcher: ' + obj.httprequest.watcher.path);
254 + //obj.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!!
255 + delete obj.httprequest.watcher;
256 + }
257 + */
258 +
259 + // Send the folder content to the browser
260 + var response = getDirectoryInfo(cmd.path);
261 + if (cmd.reqid != undefined) { response.reqid = cmd.reqid; }
262 + channel.write(response);
263 +
264 + /*
265 + // Start the directory watcher
266 + if ((cmd.path != '') && (samepath == false)) {
267 + var watcher = fs.watch(cmd.path, onFileWatcher);
268 + watcher.tunnel = obj.httprequest;
269 + watcher.path = cmd.path;
270 + obj.httprequest.watcher = watcher;
271 + //console.log('Starting watcher: ' + obj.httprequest.watcher.path);
272 + }
273 + */
274 + break;
275 + }
276 + case 'mkdir': {
277 + // Create a new empty folder
278 + fs.mkdirSync(cmd.path);
279 + break;
280 + }
281 + case 'rm': {
282 + // Remove many files or folders
283 + for (var i in cmd.delfiles) {
284 + var fullpath = path.join(cmd.path, cmd.delfiles[i]);
285 + try { fs.unlinkSync(fullpath); } catch (e) { debug(e); }
286 + }
287 + break;
288 + }
289 + case 'rename': {
290 + // Rename a file or folder
291 + try { fs.renameSync(path.join(cmd.path, cmd.oldname), path.join(cmd.path, cmd.newname)); } catch (e) { debug(e); }
292 + break;
293 + }
294 + case 'download': {
295 + // Download a file, to browser
296 + var sendNextBlock = 0;
297 + if (cmd.sub == 'start') { // Setup the download
298 + if (obj.filedownload != null) { channel.write({ action: 'download', sub: 'cancel', id: obj.filedownload.id }); delete obj.filedownload; }
299 + obj.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
300 + 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; }
301 + if (obj.filedownload) { channel.write({ action: 'download', sub: 'start', id: cmd.id }); }
302 + } else if ((obj.filedownload != null) && (cmd.id == obj.filedownload.id)) { // Download commands
303 + if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete obj.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; }
304 + }
305 + // Send the next download block(s)
306 + while (sendNextBlock > 0) {
307 + sendNextBlock--;
308 + var buf = Buffer.alloc(4096);
309 + var len = fs.readSync(obj.filedownload.f, buf, 4, 4092, null);
310 + obj.filedownload.ptr += len;
311 + if (len < 4092) { buf.writeInt32BE(0x01000001, 0); fs.closeSync(obj.filedownload.f); delete obj.filedownload; sendNextBlock = 0; } else { buf.writeInt32BE(0x01000000, 0); }
312 + channel.write(buf.slice(0, len + 4).toString('base64')); // Write as Base64
313 + }
314 + break;
315 + }
316 + case 'upload': {
317 + // Upload a file, from browser
318 + if (cmd.sub == 'start') { // Start the upload
319 + if (obj.fileupload != null) { fs.closeSync(obj.fileupload.fp); }
320 + if (!cmd.path || !cmd.name) break;
321 + obj.fileupload = { reqid: cmd.reqid };
322 + var filepath = path.join(cmd.path, cmd.name);
323 + try { obj.fileupload.fp = fs.openSync(filepath, 'wbN'); } catch (e) { }
324 + 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 }); }
325 + }
326 + else if (cmd.sub == 'cancel') { // Stop the upload
327 + if (obj.fileupload != null) { fs.closeSync(obj.fileupload.fp); obj.fileupload = null; }
328 + }
329 + break;
330 + }
331 + case 'copy': {
332 + // Copy a bunch of files from scpath to dspath
333 + for (var i in cmd.names) {
334 + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
335 + if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
336 + }
337 + break;
338 + }
339 + case 'move': {
340 + // Move a bunch of files from scpath to dspath
341 + for (var i in cmd.names) {
342 + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
343 + if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
344 + }
345 + break;
346 + }
347 + default: {
348 + debug('Invalid KVM command: ' + cmd);
349 + break;
350 + }
351 + }
352 + }
353 +
354 + var webRtcCleanUp = function () {
355 + debug('webRtcCleanUp');
356 + if (webRtcDesktop == null) return;
357 + if (webRtcDesktop.rtcchannel) {
358 + try { webRtcDesktop.rtcchannel.close(); } catch (e) { }
359 + try { webRtcDesktop.rtcchannel.removeAllListeners('data'); } catch (e) { }
360 + try { webRtcDesktop.rtcchannel.removeAllListeners('end'); } catch (e) { }
361 + delete webRtcDesktop.rtcchannel;
362 + }
363 + if (webRtcDesktop.webrtc) {
364 + try { webRtcDesktop.webrtc.close(); } catch (e) { }
365 + try { webRtcDesktop.webrtc.removeAllListeners('connected'); } catch (e) { }
366 + try { webRtcDesktop.webrtc.removeAllListeners('disconnected'); } catch (e) { }
367 + try { webRtcDesktop.webrtc.removeAllListeners('dataChannel'); } catch (e) { }
368 + delete webRtcDesktop.webrtc;
369 + }
370 + if (webRtcDesktop.kvm) {
371 + try { webRtcDesktop.kvm.end(); } catch (e) { }
372 + delete webRtcDesktop.kvm;
373 + }
374 + webRtcDesktop = null;
375 + }
376 +
377 + var kvmSetData = function (x) {
378 + osamtstack.IPS_KVMRedirectionSettingData_DataChannelWrite(Buffer.from(x).toString('base64'), function () { });
379 + }
380 +
381 + // Delete a directory with a files and directories within it
382 + var deleteFolderRecursive = function(path, rec) {
383 + if (fs.existsSync(path)) {
384 + if (rec == true) {
385 + fs.readdirSync(obj.path.join(path, '*')).forEach(function (file, index) {
386 + var curPath = obj.path.join(path, file);
387 + if (fs.statSync(curPath).isDirectory()) { // recurse
388 + deleteFolderRecursive(curPath, true);
389 + } else { // delete file
390 + fs.unlinkSync(curPath);
391 + }
392 + });
393 + }
394 + fs.unlinkSync(path);
395 + }
396 + };
397 +
398 + // Polyfill path.join
399 + var path = {
400 + join: function () {
401 + var x = [];
402 + for (var i in arguments) {
403 + var w = arguments[i];
404 + if (w != null) {
405 + while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
406 + if (i != 0) { while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } }
407 + x.push(w);
408 + }
409 + }
410 + if (x.length == 0) return '/';
411 + return x.join('/');
412 + }
413 + };
414 +
415 + function md5hex(str) { return require('MD5Stream').create().syncHash(str).toString('hex'); }
416 +
417 + //
418 + // Deactivate Intel AMT CCM
419 + //
420 +
421 + // 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.
422 + obj.deactivateCCM = function() {
423 + amtMei.unprovision(1, function (status) {
424 + if (status == 0) {
425 + debug('Success deactivating Intel AMT CCM.');
426 + agent.SendCommand({ "action": "coreinfo", "intelamt": { "state": 0, "flags": 0 } });
427 + applyPolicyTimer = setTimeout(obj.applyPolicy, 8000);
428 + } else {
429 + debug('Intel AMT CCM deactivation error: ' + status);
430 + }
431 + });
432 + }
433 +
434 + //
435 + // Activate Intel AMT to CCM
436 + //
437 +
438 + function makePass(length) {
439 + var text = "", possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
440 + for (var i = 0; i < length; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); }
441 + return text;
442 + }
443 +
444 + obj.activeToCCM = function (adminpass) {
445 + if ((adminpass == null) || (adminpass == '')) { adminpass = 'P@0s' + makePass(23); }
446 + intelAmtAdminPass = adminpass;
447 + //debug('Trying to get local account info...');
448 + amtMei.getLocalSystemAccount(function (x) {
449 + if ((x != null) && x.user && x.pass) {
450 + //debug('Intel AMT local account info: User=' + x.user + ', Pass=' + x.pass + '.');
451 + var transport = require('amt-wsman-duk');
452 + var wsman = require('amt-wsman');
453 + var amt = require('amt');
454 + oswsstack = new wsman(transport, '127.0.0.1', 16992, x.user, x.pass, false);
455 + osamtstack = new amt(oswsstack);
456 + //debug('Trying to get Intel AMT activation information...');
457 + osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], activeToCCMEx2, adminpass);
458 + } else {
459 + debug('Unable to get $$OsAdmin password.');
460 + }
461 + });
462 + }
463 +
464 + var activeToCCMEx2 = function(stack, name, responses, status, adminpass) {
465 + if (status != 200) { debug('Failed to fetch activation information, status ' + status); }
466 + else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { debug('Client control mode activation not allowed'); }
467 + else { stack.IPS_HostBasedSetupService_Setup(2, md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + adminpass).substring(0, 32), null, null, null, null, activeToCCMEx3); }
468 + }
469 +
470 + var activeToCCMEx3 = function(stack, name, responses, status) {
471 + if (status != 200) { debug('Failed to activate, status ' + status); }
472 + else if (responses.Body.ReturnValue != 0) { debug('Client control mode activation failed: ' + responses.Body.ReturnValueStr); }
473 + else {
474 + debug('Intel AMT CCM activation success.');
475 + db.Put('amtCCMPass', intelAmtAdminPass);
476 + agent.SendCommand({ "action": "coreinfo", "intelamt": { "state": 2, "flags": 2, "user": "admin", "pass": intelAmtAdminPass } });
477 + }
478 + applyPolicyTimer = setTimeout(obj.applyPolicy, 8000);
479 + }
480 +
481 + obj.start = function () {
482 + // Try to load Intel AMT policy
483 + var amtPolicy = null;
484 + try { amtPolicy = JSON.parse(db.Get('amtPolicy')); } catch (ex) { debug('Exception loading amtPolicy'); }
485 + //if (amtPolicy == null) { debug('no amtPolicy'); } else { debug('Loaded amtPolicy: ' + JSON.stringify(amtPolicy)); }
486 + try { intelAmtAdminPass = db.Get('amtCCMPass'); } catch (ex) { }
487 + if (typeof intelAmtAdminPass != 'string') { intelAmtAdminPass = null; }
488 + obj.reset();
489 + }
490 +
491 + // Apply Intel AMT policy
492 + var intelAmtAdminPass, wsstack, amtstack, applyPolicyTimer, policyWsmanRetry = 0;
493 + obj.applyPolicy = function () {
494 + applyPolicyTimer = null;
495 + if ((amtMeiState != 3) || (typeof amtpolicy != 'object') || (typeof amtpolicy.type != 'number') || (amtpolicy.type == 0)) return;
496 + if ((amtpolicy.password != null) && (amtpolicy.password != '')) { intelAmtAdminPass = amtpolicy.password; }
497 + obj.getAmtInfo(function (meinfo) {
498 + if ((amtpolicy.type == 1) && (meinfo.ProvisioningState == 2) && ((meinfo.Flags & 2) != 0)) {
499 + // CCM Deactivation Policy.
500 + wsstack = null;
501 + amtstack = null;
502 + obj.deactivateCCM();
503 + } else if ((amtpolicy.type == 2) && (meinfo.ProvisioningState == 0)) {
504 + // CCM Activation Policy
505 + wsstack = null;
506 + amtstack = null;
507 + if ((amtpolicy.password == null) || (amtpolicy.password == '')) { intelAmtAdminPass = null; }
508 + obj.activeToCCM(intelAmtAdminPass);
509 + } else if ((amtpolicy.type == 2) && (meinfo.ProvisioningState == 2) && (intelAmtAdminPass != null) && ((meinfo.Flags & 2) != 0)) {
510 + // Perform password test
511 + var transport = require('amt-wsman-duk');
512 + var wsman = require('amt-wsman');
513 + var amt = require('amt');
514 + wsstack = new wsman(transport, '127.0.0.1', 16992, 'admin', intelAmtAdminPass, false);
515 + amtstack = new amt(wsstack);
516 + var wsmanQuery = ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService', '*AMT_RedirectionService', '*CIM_KVMRedirectionSAP', 'AMT_PublicKeyCertificate', '*AMT_EnvironmentDetectionSettingData'];
517 + if (amtpolicy.cirasetup == 2) { wsmanQuery.push("AMT_ManagementPresenceRemoteSAP", "AMT_RemoteAccessCredentialContext", "AMT_RemoteAccessPolicyAppliesToMPS", "AMT_RemoteAccessPolicyRule", "*AMT_UserInitiatedConnectionService", "AMT_MPSUsernamePassword"); }
518 + try { amtstack.BatchEnum(null, wsmanQuery, wsmanPassTestResponse); } catch (ex) { debug(ex); }
519 + } else {
520 + // Other possible cases...
521 + }
522 + });
523 + }
524 +
525 + function wsmanPassTestResponse(stack, name, responses, status) {
526 + if (status != 200) {
527 + if (status == 401) {
528 + if (amtpolicy.badpass == 1) { obj.deactivateCCM(); } // Incorrect password, reactivate
529 + } else {
530 + if (++policyWsmanRetry < 20) {
531 + if (policyWsmanRetry == 10) { debug('WSMAN fault, MEI Reset'); obj.reset(); }
532 + var wsmanQuery = ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService', '*AMT_RedirectionService', '*CIM_KVMRedirectionSAP', 'AMT_PublicKeyCertificate', '*AMT_EnvironmentDetectionSettingData'];
533 + if (amtpolicy.cirasetup == 2) { wsmanQuery.push("AMT_ManagementPresenceRemoteSAP", "AMT_RemoteAccessCredentialContext", "AMT_RemoteAccessPolicyAppliesToMPS", "AMT_RemoteAccessPolicyRule", "*AMT_UserInitiatedConnectionService", "AMT_MPSUsernamePassword"); }
534 + try { amtstack.BatchEnum(null, wsmanQuery, wsmanPassTestResponse); } catch (ex) { debug(ex); }
535 + } else {
536 + debug('WSMAN fault, status=' + status);
537 + policyWsmanRetry = 0;
538 + }
539 + }
540 + } else {
541 + policyWsmanRetry = 0;
542 + var s = {};
543 + s.redir = (responses['AMT_RedirectionService'].response["ListenerEnabled"] == true);
544 + s.sol = ((responses['AMT_RedirectionService'].response["EnabledState"] & 2) != 0);
545 + s.ider = ((responses['AMT_RedirectionService'].response["EnabledState"] & 1) != 0);
546 + 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);
547 +
548 + // Enable Ping and RMCP if disabled
549 + if ((responses['AMT_GeneralSettings'].response['PingResponseEnabled'] != true) || (responses['AMT_GeneralSettings'].response['RmcpPingResponseEnabled'] != true)) {
550 + responses['AMT_GeneralSettings'].response['PingResponseEnabled'] = true;
551 + responses['AMT_GeneralSettings'].response['RmcpPingResponseEnabled'] = true;
552 + amtstack.Put('AMT_GeneralSettings', responses['AMT_GeneralSettings'].response, function (stack, name, response, status) { if (status != 200) { debug("Enable PING PUT Error " + status); } }, 0, 1)
553 + }
554 +
555 + // Enable redirection port, SOL and IDER if needed
556 + if ((s.redir == false) || (s.sol == false) || (s.ider == false)) {
557 + var r = responses['AMT_RedirectionService'].response;
558 + r["ListenerEnabled"] = true; // Turn on the redirection port
559 + r["EnabledState"] = 32768 + 1 + 2; // Turn on IDER (1) and SOL (2)
560 + amtstack.AMT_RedirectionService_RequestStateChange(r["EnabledState"], function (stack, name, response, status) { if (status != 200) { debug("Enable Redirection EXEC Error " + status); } });
561 + }
562 +
563 + // Enable KVM if needed
564 + if ((responses['CIM_KVMRedirectionSAP'] != null) && (s.kvm == false)) {
565 + amtstack.CIM_KVMRedirectionSAP_RequestStateChange(2, 0,
566 + function (stack, name, response, status) {
567 + if (status != 200) { messagebox("Error", "KVMRedirectionSAP, RequestStateChange Error " + status); return; }
568 + amtstack.Put("AMT_RedirectionService", r, function (stack, name, response, status) { if (status != 200) { debug("Enable KVM PUT Error " + status); } }, 0, 1)
569 + }
570 + );
571 + }
572 +
573 + // Check if the MeshCentral root certificate is present
574 + if (typeof amtpolicy.rootcert == 'string') {
575 + var rootFound = false, xxCertificates = responses["AMT_PublicKeyCertificate"].responses;
576 + for (var i in xxCertificates) { if ((xxCertificates[i]["X509Certificate"] == amtpolicy.rootcert) && (xxCertificates[i]["TrustedRootCertficate"] == true)) { rootFound = true; } }
577 + if (rootFound == false) { amtstack.AMT_PublicKeyManagementService_AddTrustedRootCertificate(amtpolicy.rootcert, function (stack, name, response, status) { if (status != 200) { debug("Add root cert EXEC Error " + status); } }); }
578 + }
579 +
580 + // If CIRA needs to be setup
581 + if ((amtpolicy.cirasetup == 2) && (amtpolicy.ciraserver != null)) {
582 + var serverFound = false, xxCiraServers = responses["AMT_ManagementPresenceRemoteSAP"].responses;
583 + for (var i in xxCiraServers) { if ((xxCiraServers[i].AccessInfo == amtpolicy.ciraserver.name) && (xxCiraServers[i].Port == amtpolicy.ciraserver.port)) { serverFound = xxCiraServers[i].Name; } }
584 + if (serverFound == false) {
585 + // TODO: Remove all CIRA activation policies.
586 + // amtstack.Delete('AMT_RemoteAccessPolicyRule', { 'PolicyRuleName': name }, editMpsPolicyOk2);
587 + // TODO: Remove all other MPS servers.
588 +
589 + // Add our MPS server
590 + 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) {
591 + if (status != 200) {
592 + debug("Add MPS server EXEC Error " + status);
593 + } else {
594 + serverFound = false;
595 + var x = response.Body.MpServer.ReferenceParameters.SelectorSet.Selector;
596 + for (var i in x) { if (x[i]['@Name'] == 'Name') { serverFound = x[i]['Value']; } }
597 + if (serverFound != false) { checkCiraTriggerPolicy(responses, serverFound); }
598 + }
599 + });
600 + } else {
601 + checkCiraTriggerPolicy(responses, serverFound);
602 + }
603 + } else if (amtpolicy.cirasetup == 1) {
604 + // This call will clear environement detection if needed.
605 + checkEnvironmentDetection(responses);
606 + }
607 + }
608 + }
609 +
610 + function checkCiraTriggerPolicy(responses, serverInstanceName) {
611 + // Check CIRA activation policy
612 + var server1 = '<Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</Address><ReferenceParameters xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing"><ResourceURI xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">http://intel.com/wbem/wscim/1/amt-schema/1/AMT_ManagementPresenceRemoteSAP</ResourceURI><SelectorSet xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"><Selector Name="Name">' + serverInstanceName + '</Selector></SelectorSet></ReferenceParameters>';
613 + amtstack.AMT_RemoteAccessService_AddRemoteAccessPolicyRule(2, 0, 'AAAAAAAAAAo=', [server1], null, function (stack, name, response, status) {
614 + if (status != 200) {
615 + debug("Add AddRemoteAccessPolicyRule Error " + status);
616 + } else {
617 + //debug('AMT_RemoteAccessService_AddRemoteAccessPolicyRule Response:' + JSON.stringify(response));
618 + checkEnvironmentDetection(responses);
619 + }
620 + });
621 + }
622 +
623 + // Check environement detection. This will set or clear the environement detection strings as needed.
624 + function checkEnvironmentDetection(responses) {
625 + var t2 = [];
626 + if ((amtpolicy.ciraserver != null) && (amtpolicy.ciraserver.home != null)) { t2 = amtpolicy.ciraserver.home; }
627 + var t = responses["AMT_EnvironmentDetectionSettingData"].response;
628 + t['DetectionStrings'] = MakeToArray(t['DetectionStrings']);
629 + if (CompareStrArrays(t['DetectionStrings'], t2) == false) {
630 + t['DetectionStrings'] = t2;
631 + amtstack.Put('AMT_EnvironmentDetectionSettingData', t, function (stack, name, response, status) { if (status != 200) { debug("Put AMT_EnvironmentDetectionSettingData Error " + status); } }, 0, 1);
632 + }
633 + }
634 +
635 + // Imperfect compare of two string arrays.
636 + function CompareStrArrays(arr1, arr2) {
637 + if (arr1 == arr2) return true;
638 + if (arr1 == null) { arr1 = []; }
639 + if (arr2 == null) { arr2 = []; }
640 + if (arr1.length != arr2.length) return false;
641 + for (var i in arr1) { if (arr2.indexOf(arr1[i]) == -1) return false; }
642 + return true;
643 + }
644 +
645 + function MakeToArray(v) { if (!v || v == null || typeof v == "object") return v; return [v]; };
646 +
647 +}
648 +
649 +module.exports = AmtManager;
agents-new/modules_meshcore/amt-mei.js new
+418
@@ -0,0 +1,418 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var Q = require('queue');
18 +function amt_heci() {
19 + var emitterUtils = require('events').inherits(this);
20 + emitterUtils.createEvent('error');
21 +
22 + var heci = require('heci');
23 + var sendConsole = function (msg) { require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": msg }); }
24 +
25 + this._ObjectID = "pthi";
26 + this._rq = new Q();
27 + this._setupPTHI = function _setupPTHI()
28 + {
29 + this._amt = heci.create();
30 + this._amt.BiosVersionLen = 65;
31 + this._amt.UnicodeStringLen = 20;
32 +
33 + this._amt.Parent = this;
34 + this._amt.on('error', function _amtOnError(e)
35 + {
36 + if(this.Parent._rq.isEmpty())
37 + {
38 + this.Parent.emit('error', e); // No pending requests, so propagate the error up
39 + }
40 + else
41 + {
42 + // There is a pending request, so fail the pending request
43 + var user = this.Parent._rq.deQueue();
44 + var params = user.optional;
45 + var callback = user.func;
46 + params.unshift({ Status: -1 }); // Relay an error
47 + callback.apply(this.Parent, params);
48 +
49 + if(!this.Parent._rq.isEmpty())
50 + {
51 + // There are still more pending requests, so try to re-helpconnect MEI
52 + this.connect(heci.GUIDS.AMT, { noPipeline: 1 });
53 + }
54 + }
55 + });
56 + this._amt.on('connect', function _amtOnConnect()
57 + {
58 + this.on('data', function _amtOnData(chunk)
59 + {
60 + //console.log("Received: " + chunk.length + " bytes");
61 + var header = this.Parent.getCommand(chunk);
62 + //console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
63 +
64 + var user = this.Parent._rq.deQueue();
65 + var params = user.optional;
66 + var callback = user.func;
67 +
68 + params.unshift(header);
69 + callback.apply(this.Parent, params);
70 +
71 + if(this.Parent._rq.isEmpty())
72 + {
73 + // No More Requests, we can close PTHI
74 + this.Parent._amt.disconnect();
75 + this.Parent._amt = null;
76 + }
77 + else
78 + {
79 + // Send the next request
80 + this.write(this.Parent._rq.peekQueue().send);
81 + }
82 + });
83 +
84 + // Start sending requests
85 + this.write(this.Parent._rq.peekQueue().send);
86 + });
87 + };
88 + function trim(x) { var y = x.indexOf('\0'); if (y >= 0) { return x.substring(0, y); } else { return x; } }
89 + this.getCommand = function getCommand(chunk) {
90 + var command = chunk.length == 0 ? (this._rq.peekQueue().cmd | 0x800000) : chunk.readUInt32LE(4);
91 + 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 };
92 + return (ret);
93 + };
94 +
95 + this.sendCommand = function sendCommand()
96 + {
97 + if (arguments.length < 3 || typeof (arguments[0]) != 'number' || typeof (arguments[1]) != 'object' || typeof (arguments[2]) != 'function') { throw ('invalid parameters'); }
98 + var args = [];
99 + for (var i = 3; i < arguments.length; ++i) { args.push(arguments[i]); }
100 +
101 + var header = Buffer.from('010100000000000000000000', 'hex');
102 + header.writeUInt32LE(arguments[0] | 0x04000000, 4);
103 + header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8);
104 + this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args , send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]]))});
105 +
106 + if(!this._amt)
107 + {
108 + this._setupPTHI();
109 + this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
110 + }
111 + }
112 +
113 + this.getVersion = function getVersion(callback) {
114 + var optional = [];
115 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
116 + this.sendCommand(26, null, function (header, fn, opt) {
117 + if (header.Status == 0) {
118 + var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, this._amt.BiosVersionLen).toString(), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4);
119 + for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen) ; ++i) {
120 + 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() };
121 + v = v.slice(4 + (2 * this._amt.UnicodeStringLen));
122 + }
123 + if (val.BiosVersion.indexOf('\0') > 0) { val.BiosVersion = val.BiosVersion.substring(0, val.BiosVersion.indexOf('\0')); }
124 + opt.unshift(val);
125 + } else {
126 + opt.unshift(null);
127 + }
128 + fn.apply(this, opt);
129 + }, callback, optional);
130 + };
131 +
132 + // Fill the left with zeros until the string is of a given length
133 + function zeroLeftPad(str, len) {
134 + if ((len == null) && (typeof (len) != 'number')) { return null; }
135 + if (str == null) str = ''; // If null, this is to generate zero leftpad string
136 + var zlp = '';
137 + for (var i = 0; i < len - str.length; i++) { zlp += '0'; }
138 + return zlp + str;
139 + }
140 +
141 + this.getUuid = function getUuid(callback) {
142 + var optional = [];
143 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
144 + this.sendCommand(0x5c, null, function (header, fn, opt) {
145 + if (header.Status == 0) {
146 + var result = {};
147 + result.uuid = [zeroLeftPad(header.Data.readUInt32LE(0).toString(16), 8),
148 + zeroLeftPad(header.Data.readUInt16LE(4).toString(16), 4),
149 + zeroLeftPad(header.Data.readUInt16LE(6).toString(16), 4),
150 + zeroLeftPad(header.Data.readUInt16BE(8).toString(16), 4),
151 + zeroLeftPad(header.Data.slice(10).toString('hex').toLowerCase(), 12)].join('-');
152 + opt.unshift(result);
153 + } else {
154 + opt.unshift(null);
155 + }
156 + fn.apply(this, opt);
157 + }, callback, optional);
158 + };
159 +
160 + this.getProvisioningState = function getProvisioningState(callback) {
161 + var optional = [];
162 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
163 + this.sendCommand(17, null, function (header, fn, opt) {
164 + if (header.Status == 0) {
165 + var result = {};
166 + result.state = header.Data.readUInt32LE(0);
167 + if (result.state < 3) { result.stateStr = ["PRE", "IN", "POST"][result.state]; }
168 + opt.unshift(result);
169 + } else {
170 + opt.unshift(null);
171 + }
172 + fn.apply(this, opt);
173 + }, callback, optional);
174 + };
175 + this.getProvisioningMode = function getProvisioningMode(callback) {
176 + var optional = [];
177 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
178 + this.sendCommand(8, null, function (header, fn, opt) {
179 + if (header.Status == 0) {
180 + var result = {};
181 + result.mode = header.Data.readUInt32LE(0);
182 + if (result.mode < 4) { result.modeStr = ["NONE", "ENTERPRISE", "SMALL_BUSINESS", "REMOTE_ASSISTANCE"][result.mode]; }
183 + result.legacy = header.Data.readUInt32LE(4) == 0 ? false : true;
184 + opt.unshift(result);
185 + } else {
186 + opt.unshift(null);
187 + }
188 + fn.apply(this, opt);
189 + }, callback, optional);
190 + };
191 + this.getEHBCState = function getEHBCState(callback) {
192 + var optional = [];
193 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
194 + this.sendCommand(132, null, function (header, fn, opt) {
195 + if (header.Status == 0) {
196 + opt.unshift({ EHBC: header.Data.readUInt32LE(0) != 0 });
197 + } else {
198 + opt.unshift(null);
199 + }
200 + fn.apply(this, opt);
201 + }, callback, optional);
202 + };
203 + this.getControlMode = function getControlMode(callback) {
204 + var optional = [];
205 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
206 + this.sendCommand(107, null, function (header, fn, opt) {
207 + if (header.Status == 0) {
208 + var result = {};
209 + result.controlMode = header.Data.readUInt32LE(0);
210 + if (result.controlMode < 3) { result.controlModeStr = ["NONE_RPAT", "CLIENT", "ADMIN", "REMOTE_ASSISTANCE"][result.controlMode]; }
211 + opt.unshift(result);
212 + } else {
213 + opt.unshift(null);
214 + }
215 + fn.apply(this, opt);
216 + }, callback, optional);
217 + };
218 + this.getMACAddresses = function getMACAddresses(callback) {
219 + var optional = [];
220 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
221 + this.sendCommand(37, null, function (header, fn, opt) {
222 + if (header.Status == 0) {
223 + opt.unshift({ DedicatedMAC: header.Data.slice(0, 6).toString('hex:'), HostMAC: header.Data.slice(6, 12).toString('hex:') });
224 + } else { opt.unshift({ DedicatedMAC: null, HostMAC: null }); }
225 + fn.apply(this, opt);
226 + }, callback, optional);
227 + };
228 + this.getDnsSuffix = function getDnsSuffix(callback) {
229 + var optional = [];
230 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
231 + this.sendCommand(54, null, function (header, fn, opt) {
232 + if (header.Status == 0) {
233 + var resultLen = header.Data.readUInt16LE(0);
234 + if (resultLen > 0) { opt.unshift(header.Data.slice(2, 2 + resultLen).toString()); } else { opt.unshift(null); }
235 + } else {
236 + opt.unshift(null);
237 + }
238 + fn.apply(this, opt);
239 + }, callback, optional);
240 + };
241 + this.getHashHandles = function getHashHandles(callback) {
242 + var optional = [];
243 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
244 + this.sendCommand(0x2C, null, function (header, fn, opt) {
245 + var result = [];
246 + if (header.Status == 0) {
247 + var resultLen = header.Data.readUInt32LE(0);
248 + for (var i = 0; i < resultLen; ++i) {
249 + result.push(header.Data.readUInt32LE(4 + (4 * i)));
250 + }
251 + }
252 + opt.unshift(result);
253 + fn.apply(this, opt);
254 + }, callback, optional);
255 + };
256 + this.getCertHashEntry = function getCertHashEntry(handle, callback) {
257 + var optional = [];
258 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
259 +
260 + var data = Buffer.alloc(4);
261 + data.writeUInt32LE(handle, 0);
262 +
263 + this.sendCommand(0x2D, data, function (header, fn, opt) {
264 + if (header.Status == 0) {
265 + var result = {};
266 + result.isDefault = header.Data.readUInt32LE(0);
267 + result.isActive = header.Data.readUInt32LE(4);
268 + result.hashAlgorithm = header.Data.readUInt8(72);
269 + if (result.hashAlgorithm < 4) {
270 + result.hashAlgorithmStr = ["MD5", "SHA1", "SHA256", "SHA512"][result.hashAlgorithm];
271 + result.hashAlgorithmSize = [16, 20, 32, 64][result.hashAlgorithm];
272 + result.certificateHash = header.Data.slice(8, 8 + result.hashAlgorithmSize).toString('hex');
273 + }
274 + result.name = header.Data.slice(73 + 2, 73 + 2 + header.Data.readUInt16LE(73)).toString();
275 + opt.unshift(result);
276 + } else {
277 + opt.unshift(null);
278 + }
279 + fn.apply(this, opt);
280 + }, callback, optional);
281 + };
282 + this.getCertHashEntries = function getCertHashEntries(callback) {
283 + var optional = [];
284 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
285 +
286 + this.getHashHandles(function (handles, fn, opt) {
287 + var entries = [];
288 + this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
289 + }, callback, optional);
290 + };
291 +
292 + this._getHashEntrySink = function _getHashEntrySink(result, fn, opt, entries, handles) {
293 + entries.push(result);
294 + if (handles.length > 0) {
295 + this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
296 + } else {
297 + opt.unshift(entries);
298 + fn.apply(this, opt);
299 + }
300 + }
301 + this.getLocalSystemAccount = function getLocalSystemAccount(callback) {
302 + var optional = [];
303 + for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
304 + this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt)
305 + {
306 + if (header.Status == 0 && header.Data.length == 68)
307 + {
308 + opt.unshift({ user: trim(header.Data.slice(0, 33).toString()), pass: trim(header.Data.slice(33, 67).toString()), raw: header.Data });
309 + }
310 + else
311 + {
312 + opt.unshift(null);
313 + }
314 + fn.apply(this, opt);
315 + }, callback, optional);
316 + }
317 + this.getLanInterfaceSettings = function getLanInterfaceSettings(index, callback)
318 + {
319 + var optional = [];
320 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
321 + var ifx = Buffer.alloc(4);
322 + ifx.writeUInt32LE(index);
323 + this.sendCommand(0x48, ifx, function onGetLanInterfaceSettings(header, fn, opt)
324 + {
325 + if(header.Status == 0)
326 + {
327 + var info = {};
328 + info.enabled = header.Data.readUInt32LE(0);
329 + info.dhcpEnabled = header.Data.readUInt32LE(8);
330 + switch(header.Data[12])
331 + {
332 + case 1:
333 + info.dhcpMode = 'ACTIVE'
334 + break;
335 + case 2:
336 + info.dhcpMode = 'PASSIVE'
337 + break;
338 + default:
339 + info.dhcpMode = 'UNKNOWN';
340 + break;
341 + }
342 + info.mac = header.Data.slice(14).toString('hex:');
343 +
344 + var addr = header.Data.readUInt32LE(4);
345 + info.address = ((addr >> 24) & 255) + '.' + ((addr >> 16) & 255) + '.' + ((addr >> 8) & 255) + '.' + (addr & 255);
346 + opt.unshift(info);
347 + fn.apply(this, opt);
348 + }
349 + else
350 + {
351 + opt.unshift(null);
352 + fn.apply(this, opt);
353 + }
354 + }, callback, optional);
355 +
356 + };
357 + this.unprovision = function unprovision(mode, callback) {
358 + var optional = [];
359 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
360 + var data = Buffer.alloc(4);
361 + data.writeUInt32LE(mode, 0);
362 + this.sendCommand(16, data, function (header, fn, opt) {
363 + opt.unshift(header.Status);
364 + fn.apply(this, opt);
365 + }, callback, optional);
366 + }
367 + this.startConfiguration = function startConfiguration() {
368 + var optional = [];
369 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
370 + this.sendCommand(0x29, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
371 + }
372 + this.stopConfiguration = function stopConfiguration() {
373 + var optional = [];
374 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
375 + this.sendCommand(0x5E, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
376 + }
377 + this.openUserInitiatedConnection = function openUserInitiatedConnection() {
378 + var optional = [];
379 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
380 + this.sendCommand(0x44, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
381 + }
382 + this.closeUserInitiatedConnection = function closeUnserInitiatedConnected() {
383 + var optional = [];
384 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
385 + this.sendCommand(0x45, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
386 + }
387 + this.getRemoteAccessConnectionStatus = function getRemoteAccessConnectionStatus() {
388 + var optional = [];
389 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
390 + this.sendCommand(0x46, data, function (header, fn, opt) {
391 + if (header.Status == 0) {
392 + var hostname = v.slice(14, header.Data.readUInt16LE(12) + 14).toString()
393 + 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 });
394 + } else {
395 + opt.unshift({ status: header.Status });
396 + }
397 + fn.apply(this, opt);
398 + }, callback, optional);
399 + }
400 + this.getProtocolVersion = function getProtocolVersion(callback) {
401 + var optional = [];
402 + for (var i = 1; i < arguments.length; ++i) { opt.push(arguments[i]); }
403 +
404 + heci.doIoctl(heci.IOCTL.HECI_VERSION, Buffer.alloc(5), Buffer.alloc(5), function (status, buffer, self, fn, opt) {
405 + if (status == 0) {
406 + var result = buffer.readUInt8(0).toString() + '.' + buffer.readUInt8(1).toString() + '.' + buffer.readUInt8(2).toString() + '.' + buffer.readUInt16BE(3).toString();
407 + opt.unshift(result);
408 + fn.apply(self, opt);
409 + }
410 + else {
411 + opt.unshift(null);
412 + fn.apply(self, opt);
413 + }
414 + }, this, callback, optional);
415 + }
416 +}
417 +
418 +module.exports = amt_heci;
\ No newline at end of file
agents-new/modules_meshcore/amt-scanner.js new
+105
@@ -0,0 +1,105 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +/**
18 +* @description Meshcentral Intel AMT Local Scanner
19 +* @author Ylian Saint-Hilaire & Joko Sastriawan
20 +* @version v0.0.1
21 +*/
22 +
23 +// Construct a Intel AMT Scanner object
24 +
25 +function AMTScanner() {
26 + var emitterUtils = require('events').inherits(this);
27 + emitterUtils.createEvent('found');
28 +
29 + this.dgram = require('dgram');
30 +
31 + this.buildRmcpPing = function (tag) {
32 + var packet = Buffer.from('06000006000011BE80000000', 'hex');
33 + packet[9] = tag;
34 + return packet;
35 + };
36 +
37 + this.parseRmcpPacket = function (server, data, rinfo, func) {
38 + if (data == null || data.length < 20) return;
39 + var res = {};
40 + if (((data[12] == 0) || (data[13] != 0) || (data[14] != 1) || (data[15] != 0x57)) && (data[21] & 32)) {
41 + res.servertag = data[9];
42 + res.minorVersion = data[18] & 0x0F;
43 + res.majorVersion = (data[18] >> 4) & 0x0F;
44 + res.provisioningState = data[19] & 0x03; // Pre = 0, In = 1, Post = 2
45 +
46 + var openPort = (data[16] * 256) + data[17];
47 + var dualPorts = ((data[19] & 0x04) != 0) ? true : false;
48 + res.openPorts = [openPort];
49 + res.address = rinfo.address;
50 + if (dualPorts == true) { res.openPorts = [16992, 16993]; }
51 + if (func !== undefined) {
52 + func(server, res);
53 + }
54 + }
55 + }
56 +
57 + this.parseIPv4Range = function (range) {
58 + if (range == undefined || range == null) return null;
59 + var x = range.split('-');
60 + if (x.length == 2) { return { min: this.parseIpv4Addr(x[0]), max: this.parseIpv4Addr(x[1]) }; }
61 + x = range.split('/');
62 + if (x.length == 2) {
63 + var ip = this.parseIpv4Addr(x[0]), masknum = parseInt(x[1]), mask = 0;
64 + if (masknum <= 16 || masknum > 32) return null;
65 + masknum = 32 - masknum;
66 + for (var i = 0; i < masknum; i++) { mask = (mask << 1); mask++; }
67 + return { min: ip & (0xFFFFFFFF - mask), max: (ip & (0xFFFFFFFF - mask)) + mask };
68 + }
69 + x = this.parseIpv4Addr(range);
70 + if (x == null) return null;
71 + return { min: x, max: x };
72 + };
73 +
74 + // Parse IP address. Takes a
75 + this.parseIpv4Addr = function (addr) {
76 + var x = addr.split('.');
77 + if (x.length == 4) { return (parseInt(x[0]) << 24) + (parseInt(x[1]) << 16) + (parseInt(x[2]) << 8) + (parseInt(x[3]) << 0); }
78 + return null;
79 + }
80 +
81 + // IP address number to string
82 + this.IPv4NumToStr = function (num) {
83 + return ((num >> 24) & 0xFF) + '.' + ((num >> 16) & 0xFF) + '.' + ((num >> 8) & 0xFF) + '.' + (num & 0xFF);
84 + }
85 +
86 + this.scan = function (rangestr, timeout) {
87 + var iprange = this.parseIPv4Range(rangestr);
88 + var rmcp = this.buildRmcpPing(0);
89 + var server = this.dgram.createSocket({ type: 'udp4' });
90 + server.parent = this;
91 + server.scanResults = [];
92 + server.on('error', function (err) { console.log('Error:' + err); });
93 + server.on('message', function (msg, rinfo) { if (rinfo.size > 4) { this.parent.parseRmcpPacket(this, msg, rinfo, function (s, res) { s.scanResults.push(res); }) }; });
94 + server.on('listening', function () { for (var i = iprange.min; i <= iprange.max; i++) { server.send(rmcp, 623, server.parent.IPv4NumToStr(i)); } });
95 + server.bind({ address: '0.0.0.0', port: 0, exclusive: true });
96 + var tmout = setTimeout(function cb() {
97 + //console.log("Server closed");
98 + server.close();
99 + server.parent.emit('found', server.scanResults);
100 + delete server;
101 + }, timeout);
102 + };
103 +}
104 +
105 +module.exports = AMTScanner;
agents-new/modules_meshcore/amt-wsman-duk.js new
+147
@@ -0,0 +1,147 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +/**
18 +* @description WSMAN communication using duktape http
19 +* @author Ylian Saint-Hilaire
20 +* @version v0.2.0c
21 +*/
22 +
23 +// Construct a WSMAN communication object
24 +function CreateWsmanComm(/*host, port, user, pass, tls, extra*/)
25 +{
26 + var obj = {};
27 + obj.PendingAjax = []; // List of pending AJAX calls. When one frees up, another will start.
28 + obj.ActiveAjaxCount = 0; // Number of currently active AJAX calls
29 + obj.MaxActiveAjaxCount = 1; // Maximum number of activate AJAX calls at the same time.
30 + obj.FailAllError = 0; // Set this to non-zero to fail all AJAX calls with that error status, 999 causes responses to be silent.
31 + obj.digest = null;
32 + obj.RequestCount = 0;
33 +
34 + if (arguments.length == 1 && typeof(arguments[0] == 'object'))
35 + {
36 + obj.host = arguments[0].host;
37 + obj.port = arguments[0].port;
38 + obj.authToken = arguments[0].authToken;
39 + obj.tls = arguments[0].tls;
40 + }
41 + else
42 + {
43 + obj.host = arguments[0];
44 + obj.port = arguments[1];
45 + obj.user = arguments[2];
46 + obj.pass = arguments[3];
47 + obj.tls = arguments[4];
48 + }
49 +
50 +
51 + // Private method
52 + // pri = priority, if set to 1, the call is high priority and put on top of the stack.
53 + obj.PerformAjax = function (postdata, callback, tag, pri, url, action) {
54 + if ((obj.ActiveAjaxCount == 0 || ((obj.ActiveAjaxCount < obj.MaxActiveAjaxCount) && (obj.challengeParams != null))) && obj.PendingAjax.length == 0) {
55 + // There are no pending AJAX calls, perform the call now.
56 + obj.PerformAjaxEx(postdata, callback, tag, url, action);
57 + } else {
58 + // If this is a high priority call, put this call in front of the array, otherwise put it in the back.
59 + if (pri == 1) { obj.PendingAjax.unshift([postdata, callback, tag, url, action]); } else { obj.PendingAjax.push([postdata, callback, tag, url, action]); }
60 + }
61 + }
62 +
63 + // Private method
64 + obj.PerformNextAjax = function () {
65 + if (obj.ActiveAjaxCount >= obj.MaxActiveAjaxCount || obj.PendingAjax.length == 0) return;
66 + var x = obj.PendingAjax.shift();
67 + obj.PerformAjaxEx(x[0], x[1], x[2], x[3], x[4]);
68 + obj.PerformNextAjax();
69 + }
70 +
71 + // Private method
72 + obj.PerformAjaxEx = function (postdata, callback, tag, url, action) {
73 + if (obj.FailAllError != 0) { if (obj.FailAllError != 999) { obj.gotNextMessagesError({ status: obj.FailAllError }, 'error', null, [postdata, callback, tag]); } return; }
74 + if (!postdata) postdata = "";
75 + //console.log("SEND: " + postdata); // DEBUG
76 +
77 + // We are in a DukTape environement
78 + if (obj.digest == null)
79 + {
80 + if (obj.authToken)
81 + {
82 + obj.digest = require('http-digest').create({ authToken: obj.authToken });
83 + }
84 + else
85 + {
86 + obj.digest = require('http-digest').create(obj.user, obj.pass);
87 + }
88 + obj.digest.http = require('http');
89 + }
90 + 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)); } };
91 +
92 + var req = obj.digest.request(request);
93 + //console.log('Request ' + (obj.RequestCount++));
94 +
95 + req.on('error', function (e) { obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); });
96 + req.on('response', function (response) {
97 + //console.log('Response: ' + response.statusCode);
98 + if (response.statusCode != 200) {
99 + //console.log('ERR:' + JSON.stringify(response));
100 + obj.gotNextMessagesError({ status: response.statusCode }, 'error', null, [postdata, callback, tag]);
101 + } else {
102 + response.acc = '';
103 + response.on('data', function (data2) { this.acc += data2; });
104 + response.on('end', function () { obj.gotNextMessages(response.acc, 'success', { status: response.statusCode }, [postdata, callback, tag]); });
105 + }
106 + });
107 +
108 + // Send POST body, this work with binary.
109 + req.end(postdata);
110 +
111 + obj.ActiveAjaxCount++;
112 + return req;
113 + }
114 +
115 + // AJAX specific private method
116 + obj.pendingAjaxCall = [];
117 +
118 + // Private method
119 + obj.gotNextMessages = function (data, status, request, callArgs) {
120 + obj.ActiveAjaxCount--;
121 + if (obj.FailAllError == 999) return;
122 + //console.log("RECV: " + data); // DEBUG
123 + if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
124 + if (request.status != 200) { callArgs[1](null, request.status, callArgs[2]); return; }
125 + callArgs[1](data, 200, callArgs[2]);
126 + obj.PerformNextAjax();
127 + }
128 +
129 + // Private method
130 + obj.gotNextMessagesError = function (request, status, errorThrown, callArgs) {
131 + obj.ActiveAjaxCount--;
132 + if (obj.FailAllError == 999) return;
133 + if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
134 + //if (status != 200) { console.log("ERROR, status=" + status + "\r\n\r\nreq=" + callArgs[0]); } // Debug: Display the request & response if something did not work.
135 + if (obj.FailAllError != 999) { callArgs[1]({ Header: { HttpError: request.status } }, request.status, callArgs[2]); }
136 + obj.PerformNextAjax();
137 + }
138 +
139 + // Cancel all pending queries with given status
140 + obj.CancelAllQueries = function (s) {
141 + while (obj.PendingAjax.length > 0) { var x = obj.PendingAjax.shift(); x[1](null, s, x[2]); }
142 + }
143 +
144 + return obj;
145 +}
146 +
147 +module.exports = CreateWsmanComm;
agents-new/modules_meshcore/amt-wsman.js new
+211
@@ -0,0 +1,211 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +/**
18 +* @description Intel(r) AMT WSMAN Stack
19 +* @author Ylian Saint-Hilaire
20 +* @version v0.2.0
21 +*/
22 +
23 +// Construct a MeshServer object
24 +function WsmanStackCreateService(/*CreateWsmanComm, host, port, user, pass, tls, extra*/)
25 +{
26 + var obj = {_ObjectID: 'WSMAN'};
27 + //obj.onDebugMessage = null; // Set to a function if you want to get debug messages.
28 + obj.NextMessageId = 1; // Next message number, used to label WSMAN calls.
29 + obj.Address = '/wsman';
30 + obj.xmlParser = require('amt-xml');
31 +
32 + if (arguments.length == 1 && typeof (arguments[0] == 'object'))
33 + {
34 + var CreateWsmanComm = arguments[0].transport;
35 + if (CreateWsmanComm) { obj.comm = new CreateWsmanComm(arguments[0]); }
36 + }
37 + else
38 + {
39 + var CreateWsmanComm = arguments[0];
40 + if (CreateWsmanComm) { obj.comm = new CreateWsmanComm(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]); }
41 + }
42 +
43 + obj.PerformAjax = function PerformAjax(postdata, callback, tag, pri, namespaces) {
44 + if (namespaces == null) namespaces = '';
45 + obj.comm.PerformAjax('<?xml version=\"1.0\" encoding=\"utf-8\"?><Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns=\"http://www.w3.org/2003/05/soap-envelope\" ' + namespaces + '><Header><a:Action>' + postdata, function (data, status, tag) {
46 + if (status != 200) { callback(obj, null, { Header: { HttpError: status } }, status, tag); return; }
47 + var wsresponse = obj.xmlParser.ParseWsman(data);
48 + if (!wsresponse || wsresponse == null) { callback(obj, null, { Header: { HttpError: status } }, 601, tag); } else { callback(obj, wsresponse.Header["ResourceURI"], wsresponse, 200, tag); }
49 + }, tag, pri);
50 + }
51 +
52 + // Private method
53 + //obj.Debug = function (msg) { /*console.log(msg);*/ }
54 +
55 + // Cancel all pending queries with given status
56 + obj.CancelAllQueries = function CancelAllQueries(s) { obj.comm.CancelAllQueries(s); }
57 +
58 + // Get the last element of a URI string
59 + obj.GetNameFromUrl = function (resuri) {
60 + var x = resuri.lastIndexOf("/");
61 + return (x == -1)?resuri:resuri.substring(x + 1);
62 + }
63 +
64 + // Perform a WSMAN Subscribe operation
65 + obj.ExecSubscribe = function ExecSubscribe(resuri, delivery, url, callback, tag, pri, selectors, opaque, user, pass) {
66 + var digest = "", digest2 = "", opaque = "";
67 + if (user != null && pass != null) { digest = '<t:IssuedTokens xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:se="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><t:RequestSecurityTokenResponse><t:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</t:TokenType><t:RequestedSecurityToken><se:UsernameToken><se:Username>' + user + '</se:Username><se:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText">' + pass + '</se:Password></se:UsernameToken></t:RequestedSecurityToken></t:RequestSecurityTokenResponse></t:IssuedTokens>'; digest2 = '<w:Auth Profile="http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/http/digest"/>'; }
68 + if (opaque != null) { opaque = '<a:ReferenceParameters><m:arg>' + opaque + '</m:arg></a:ReferenceParameters>'; }
69 + if (delivery == 'PushWithAck') { delivery = 'dmtf.org/wbem/wsman/1/wsman/PushWithAck'; } else if (delivery == 'Push') { delivery = 'xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push'; }
70 + var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + digest + '</Header><Body><e:Subscribe><e:Delivery Mode="http://schemas.' + delivery + '"><e:NotifyTo><a:Address>' + url + '</a:Address>' + opaque + '</e:NotifyTo>' + digest2 + '</e:Delivery></e:Subscribe>';
71 + obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:m="http://x.com"');
72 + }
73 +
74 + // Perform a WSMAN UnSubscribe operation
75 + obj.ExecUnSubscribe = function ExecUnSubscribe(resuri, callback, tag, pri, selectors) {
76 + var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + '</Header><Body><e:Unsubscribe/>';
77 + obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"');
78 + }
79 +
80 + // Perform a WSMAN PUT operation
81 + obj.ExecPut = function ExecPut(resuri, putobj, callback, tag, pri, selectors) {
82 + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Put</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + '</Header><Body>' + _PutObjToBodyXml(resuri, putobj);
83 + obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri);
84 + }
85 +
86 + // Perform a WSMAN CREATE operation
87 + obj.ExecCreate = function ExecCreate(resuri, putobj, callback, tag, pri, selectors) {
88 + var objname = obj.GetNameFromUrl(resuri);
89 + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><g:" + objname + " xmlns:g=\"" + resuri + "\">";
90 + for (var n in putobj) { data += "<g:" + n + ">" + putobj[n] + "</g:" + n + ">" }
91 + obj.PerformAjax(data + "</g:" + objname + "></Body></Envelope>", callback, tag, pri);
92 + }
93 +
94 + // Perform a WSMAN DELETE operation
95 + obj.ExecDelete = function ExecDelete(resuri, putobj, callback, tag, pri) {
96 + var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(putobj) + "</Header><Body /></Envelope>";
97 + obj.PerformAjax(data, callback, tag, pri);
98 + }
99 +
100 + // Perform a WSMAN GET operation
101 + obj.ExecGet = function ExecGet(resuri, callback, tag, pri) {
102 + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body /></Envelope>", callback, tag, pri);
103 + }
104 +
105 + // Perform a WSMAN method call operation
106 + obj.ExecMethod = function ExecMethod(resuri, method, args, callback, tag, pri, selectors) {
107 + var argsxml = "";
108 + for (var i in args) { if (args[i] != null) { if (Array.isArray(args[i])) { for (var x in args[i]) { argsxml += "<r:" + i + ">" + args[i][x] + "</r:" + i + ">"; } } else { argsxml += "<r:" + i + ">" + args[i] + "</r:" + i + ">"; } } }
109 + obj.ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors);
110 + }
111 +
112 + // Perform a WSMAN method call operation. The arguments are already formatted in XML.
113 + obj.ExecMethodXml = function ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors) {
114 + obj.PerformAjax(resuri + "/" + method + "</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><r:" + method + '_INPUT' + " xmlns:r=\"" + resuri + "\">" + argsxml + "</r:" + method + "_INPUT></Body></Envelope>", callback, tag, pri);
115 + }
116 +
117 + // Perform a WSMAN ENUM operation
118 + obj.ExecEnum = function ExecEnum(resuri, callback, tag, pri) {
119 + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Enumerate xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\" /></Body></Envelope>", callback, tag, pri);
120 + }
121 +
122 + // Perform a WSMAN PULL operation
123 + obj.ExecPull = function ExecPull(resuri, enumctx, callback, tag, pri) {
124 + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\"><EnumerationContext>" + enumctx + "</EnumerationContext><MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters></Pull></Body></Envelope>", callback, tag, pri);
125 + }
126 +
127 + function _PutObjToBodyXml(resuri, putObj) {
128 + if (!resuri || putObj == null) return '';
129 + var objname = obj.GetNameFromUrl(resuri);
130 + var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';
131 +
132 + for (var prop in putObj) {
133 + if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue;
134 + if (putObj[prop] == null || typeof putObj[prop] === 'function') continue;
135 + if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) {
136 + result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>';
137 + var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector'];
138 + if (Array.isArray(selectorArray)) {
139 + for (var i=0; i< selectorArray.length; i++) {
140 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
141 + }
142 + }
143 + else {
144 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
145 + }
146 + result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>';
147 + }
148 + else {
149 + if (Array.isArray(putObj[prop])) {
150 + for (var i = 0; i < putObj[prop].length; i++) {
151 + result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>';
152 + }
153 + } else {
154 + result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>';
155 + }
156 + }
157 + }
158 +
159 + result += '</r:' + objname + '>';
160 + return result;
161 + }
162 +
163 + /*
164 + convert
165 + { @Name: 'InstanceID', @AttrName: 'Attribute Value'}
166 + into
167 + ' Name="InstanceID" AttrName="Attribute Value" '
168 + */
169 + function _ObjectToXmlAttributes(objWithAttributes) {
170 + if(!objWithAttributes) return '';
171 + var result = ' ';
172 + for (var propName in objWithAttributes) {
173 + if (!objWithAttributes.hasOwnProperty(propName) || propName.indexOf('@') !== 0) continue;
174 + result += propName.substring(1) + '="' + objWithAttributes[propName] + '" ';
175 + }
176 + return result;
177 + }
178 +
179 + function _PutObjToSelectorsXml(selectorSet) {
180 + if (!selectorSet) return '';
181 + if (typeof selectorSet == 'string') return selectorSet;
182 + if (selectorSet['InstanceID']) return "<w:SelectorSet><w:Selector Name=\"InstanceID\">" + selectorSet['InstanceID'] + "</w:Selector></w:SelectorSet>";
183 + var result = '<w:SelectorSet>';
184 + for(var propName in selectorSet) {
185 + if (!selectorSet.hasOwnProperty(propName)) continue;
186 + result += '<w:Selector Name="' + propName + '">';
187 + if (selectorSet[propName]['ReferenceParameters']) {
188 + result += '<a:EndpointReference>';
189 + result += '<a:Address>' + selectorSet[propName]['Address'] + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + selectorSet[propName]['ReferenceParameters']['ResourceURI'] + '</w:ResourceURI><w:SelectorSet>';
190 + var selectorArray = selectorSet[propName]['ReferenceParameters']['SelectorSet']['Selector'];
191 + if (Array.isArray(selectorArray)) {
192 + for (var i = 0; i < selectorArray.length; i++) {
193 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
194 + }
195 + } else {
196 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
197 + }
198 + result += '</w:SelectorSet></a:ReferenceParameters></a:EndpointReference>';
199 + } else {
200 + result += selectorSet[propName];
201 + }
202 + result += '</w:Selector>';
203 + }
204 + result += '</w:SelectorSet>';
205 + return result;
206 + }
207 +
208 + return obj;
209 +}
210 +
211 +module.exports = WsmanStackCreateService;
agents-new/modules_meshcore/amt-xml.js new
+185
@@ -0,0 +1,185 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { }
18 +
19 +
20 +// Parse XML and return JSON
21 +module.exports.ParseWsman = function (xml) {
22 + try {
23 + if (!xml.childNodes) xml = _turnToXml(xml);
24 + var r = { Header: {} }, header = xml.getElementsByTagName("Header")[0], t;
25 + if (!header) header = xml.getElementsByTagName("a:Header")[0];
26 + if (!header) return null;
27 + for (var i = 0; i < header.childNodes.length; i++) {
28 + var child = header.childNodes[i];
29 + r.Header[child.localName] = child.textContent;
30 + }
31 + var body = xml.getElementsByTagName("Body")[0];
32 + if (!body) body = xml.getElementsByTagName("a:Body")[0];
33 + if (!body) return null;
34 + if (body.childNodes.length > 0) {
35 + t = body.childNodes[0].localName;
36 + if (t.indexOf("_OUTPUT") == t.length - 7) { t = t.substring(0, t.length - 7); }
37 + r.Header['Method'] = t;
38 + r.Body = _ParseWsmanRec(body.childNodes[0]);
39 + }
40 + return r;
41 + } catch (e) {
42 + console.error("Unable to parse XML: " + xml, e);
43 + return null;
44 + }
45 +}
46 +
47 +// Private method
48 +function _ParseWsmanRec(node) {
49 + var data, r = {};
50 + for (var i = 0; i < node.childNodes.length; i++) {
51 + var child = node.childNodes[i];
52 + if ((child.childElementCount == null) || (child.childElementCount == 0)) { data = child.textContent; } else { data = _ParseWsmanRec(child); }
53 + if (data == 'true') data = true; // Convert 'true' into true
54 + if (data == 'false') data = false; // Convert 'false' into false
55 + if ((parseInt(data) + '') === data) data = parseInt(data); // Convert integers
56 +
57 + var childObj = data;
58 + if ((child.attributes != null) && (child.attributes.length > 0)) {
59 + childObj = { 'Value': data };
60 + for (var j = 0; j < child.attributes.length; j++) {
61 + childObj['@' + child.attributes[j].name] = child.attributes[j].value;
62 + }
63 + }
64 +
65 + if (r[child.localName] instanceof Array) { r[child.localName].push(childObj); }
66 + else if (r[child.localName] == null) { r[child.localName] = childObj; }
67 + else { r[child.localName] = [r[child.localName], childObj]; }
68 + }
69 + return r;
70 +}
71 +
72 +function _PutObjToBodyXml(resuri, putObj) {
73 + if (!resuri || putObj == null) return '';
74 + var objname = obj.GetNameFromUrl(resuri);
75 + var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';
76 +
77 + for (var prop in putObj) {
78 + if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue;
79 + if (putObj[prop] == null || typeof putObj[prop] === 'function') continue;
80 + if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) {
81 + result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>';
82 + var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector'];
83 + if (Array.isArray(selectorArray)) {
84 + for (var i = 0; i < selectorArray.length; i++) {
85 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
86 + }
87 + }
88 + else {
89 + result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
90 + }
91 + result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>';
92 + }
93 + else {
94 + if (Array.isArray(putObj[prop])) {
95 + for (var i = 0; i < putObj[prop].length; i++) {
96 + result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>';
97 + }
98 + } else {
99 + result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>';
100 + }
101 + }
102 + }
103 +
104 + result += '</r:' + objname + '>';
105 + return result;
106 +}
107 +
108 +// This is a drop-in replacement to _turnToXml() that works without xml parser dependency.
109 +function _treeBuilder() {
110 + this.tree = [];
111 + this.push = function (element) { this.tree.push(element); };
112 + 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); };
113 + this.peek = function () { return (this.tree.peek()); }
114 + 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; } } } } }
115 + 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; }
116 +}
117 +function _turnToXml(text) { if (text == null) return null; return ({ childNodes: [_turnToXmlRec(text)], getElementsByTagName: _getElementsByTagName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS }); }
118 +function _getElementsByTagNameNS(ns, name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name && (node.namespace == ns || ns == '*')) { ret.push(node); } }); return ret; }
119 +function _getElementsByTagName(name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name) { ret.push(node); } }); return ret; }
120 +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); }
121 +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); }
122 +function _xmlTraverseAllRec(nodes, func) { for (var i in nodes) { func(nodes[i]); if (nodes[i].childNodes) { _xmlTraverseAllRec(nodes[i].childNodes, func); } } }
123 +function _turnToXmlRec(text) {
124 + var elementStack = new _treeBuilder(), lastElement = null, x1 = text.split('<'), ret = [], element = null, currentElementName = null;
125 + for (var i in x1) {
126 + var x2 = x1[i].split('>'), x3 = x2[0].split(' '), elementName = x3[0];
127 + if ((elementName.length > 0) && (elementName[0] != '?')) {
128 + if (elementName[0] != '/') {
129 + var attributes = [], localName, localname2 = elementName.split(' ')[0].split(':'), localName = (localname2.length > 1) ? localname2[1] : localname2[0];
130 + Object.defineProperty(attributes, "get",
131 + {
132 + value: function () {
133 + if (arguments.length == 1) {
134 + for (var a in this) { if (this[a].name == arguments[0]) { return (this[a]); } }
135 + }
136 + else if (arguments.length == 2) {
137 + for (var a in this) { if (this[a].name == arguments[1] && (arguments[0] == '*' || this[a].namespace == arguments[0])) { return (this[a]); } }
138 + }
139 + else {
140 + throw ('attributes.get(): Invalid number of parameters');
141 + }
142 + }
143 + });
144 + elementStack.push({ name: elementName, localName: localName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS, getChildElementsByTagNameNS: _getChildElementsByTagNameNS, attributes: attributes, childNodes: [], nsTable: {} });
145 + // Parse Attributes
146 + if (x3.length > 0) {
147 + var skip = false;
148 + for (var j in x3) {
149 + if (x3[j] == '/') {
150 + // This is an empty Element
151 + elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
152 + elementStack.peek().textContent = '';
153 + lastElement = elementStack.pop();
154 + skip = true;
155 + break;
156 + }
157 + var k = x3[j].indexOf('=');
158 + if (k > 0) {
159 + var attrName = x3[j].substring(0, k);
160 + var attrValue = x3[j].substring(k + 2, x3[j].length - 1);
161 + var attrNS = elementStack.getNamespace('*');
162 +
163 + if (attrName == 'xmlns') {
164 + elementStack.addNamespace('*', attrValue);
165 + attrNS = attrValue;
166 + } else if (attrName.startsWith('xmlns:')) {
167 + elementStack.addNamespace(attrName.substring(6), attrValue);
168 + } else {
169 + var ax = attrName.split(':');
170 + if (ax.length == 2) { attrName = ax[1]; attrNS = elementStack.getNamespace(ax[0]); }
171 + }
172 + var x = { name: attrName, value: attrValue }
173 + if (attrNS != null) x.namespace = attrNS;
174 + elementStack.peek().attributes.push(x);
175 + }
176 + }
177 + if (skip) { continue; }
178 + }
179 + elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
180 + if (x2[1]) { elementStack.peek().textContent = x2[1]; }
181 + } else { lastElement = elementStack.pop(); }
182 + }
183 + }
184 + return lastElement;
185 +}
agents-new/modules_meshcore/amt.js new
+1017
@@ -0,0 +1,1017 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +/**
18 +* @fileoverview Intel(r) AMT Communication StackXX
19 +* @author Ylian Saint-Hilaire
20 +* @version v0.2.0b
21 +*/
22 +
23 +/**
24 + * Construct a AmtStackCreateService object, this ia the main Intel AMT communication stack.
25 + * @constructor
26 + */
27 +function AmtStackCreateService(wsmanStack) {
28 + var obj = new Object();
29 + obj._ObjectID = 'AMT'
30 + obj.wsman = wsmanStack;
31 + 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/"];
32 + obj.PendingEnums = [];
33 + obj.PendingBatchOperations = 0;
34 + obj.ActiveEnumsCount = 0;
35 + obj.MaxActiveEnumsCount = 1; // Maximum number of enumerations that can be done at the same time.
36 + obj.onProcessChanged = null;
37 + var _MaxProcess = 0;
38 + var _LastProcess = 0;
39 +
40 + // Return the number of pending actions
41 + obj.GetPendingActions = function () { return (obj.PendingEnums.length * 2) + (obj.ActiveEnumsCount) + obj.wsman.comm.PendingAjax.length + obj.wsman.comm.ActiveAjaxCount + obj.PendingBatchOperations; }
42 +
43 + // Private Method, Update the current processing status, this gives the application an idea of what progress is being done by the WSMAN stack
44 + function _up() {
45 + var x = obj.GetPendingActions();
46 + if (_MaxProcess < x) _MaxProcess = x;
47 + if (obj.onProcessChanged != null && _LastProcess != x) {
48 + //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);
49 + _LastProcess = x;
50 + obj.onProcessChanged(x, _MaxProcess);
51 + }
52 + if (x == 0) _MaxProcess = 0;
53 + }
54 +
55 + // Perform a WSMAN "SUBSCRIBE" operation.
56 + 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(); }
57 +
58 + // Perform a WSMAN "UNSUBSCRIBE" operation.
59 + 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(); }
60 +
61 + // Perform a WSMAN "GET" operation.
62 + 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(); }
63 +
64 + // Perform a WSMAN "PUT" operation.
65 + 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(); }
66 +
67 + // Perform a WSMAN "CREATE" operation.
68 + 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(); }
69 +
70 + // Perform a WSMAN "DELETE" operation.
71 + 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(); }
72 +
73 + // Perform a WSMAN method call operation.
74 + 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(); }
75 +
76 + // Perform a WSMAN method call operation.
77 + 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(); }
78 +
79 + // Perform a WSMAN "ENUMERATE" operation.
80 + obj.Enum = function Enum(name, callback, tag, pri) {
81 + if (obj.ActiveEnumsCount < obj.MaxActiveEnumsCount) {
82 + obj.ActiveEnumsCount++; obj.wsman.ExecEnum(obj.CompleteName(name), function (ws, resuri, response, xstatus, tag0) { _up(); _EnumStartSink(name, response, callback, resuri, xstatus, tag0); }, tag, pri);
83 + } else {
84 + obj.PendingEnums.push([name, callback, tag, pri]);
85 + }
86 + _up();
87 + }
88 +
89 + // Private method
90 + function _EnumStartSink(name, response, callback, resuri, status, tag, pri) {
91 + if (status != 200) { callback.call(obj, obj, name, null, status, tag); _EnumDoNext(1); return; }
92 + if (response == null || response.Header["Method"] != "EnumerateResponse" || !response.Body["EnumerationContext"]) { callback.call(obj, obj, name, null, 603, tag); _EnumDoNext(1); return; }
93 + var enumctx = response.Body["EnumerationContext"];
94 + obj.wsman.ExecPull(resuri, enumctx, function (ws, resuri, response, xstatus) { _EnumContinueSink(name, response, callback, resuri, [], xstatus, tag, pri); });
95 + }
96 +
97 + // Private method
98 + function _EnumContinueSink(name, response, callback, resuri, items, status, tag, pri) {
99 + if (status != 200) { callback.call(obj, obj, name, null, status, tag); _EnumDoNext(1); return; }
100 + if (response == null || response.Header["Method"] != "PullResponse") { callback.call(obj, obj, name, null, 604, tag); _EnumDoNext(1); return; }
101 + for (var i in response.Body["Items"]) {
102 + if (response.Body["Items"][i] instanceof Array) {
103 + for (var j in response.Body["Items"][i]) { items.push(response.Body["Items"][i][j]); }
104 + } else {
105 + items.push(response.Body["Items"][i]);
106 + }
107 + }
108 + if (response.Body["EnumerationContext"]) {
109 + var enumctx = response.Body["EnumerationContext"];
110 + obj.wsman.ExecPull(resuri, enumctx, function (ws, resuri, response, xstatus) { _EnumContinueSink(name, response, callback, resuri, items, xstatus, tag, 1); });
111 + } else {
112 + _EnumDoNext(1);
113 + callback.call(obj, obj, name, items, status, tag);
114 + _up();
115 + }
116 + }
117 +
118 + // Private method
119 + function _EnumDoNext(dec) {
120 + obj.ActiveEnumsCount -= dec;
121 + if (obj.ActiveEnumsCount >= obj.MaxActiveEnumsCount || obj.PendingEnums.length == 0) return;
122 + var x = obj.PendingEnums.shift();
123 + obj.Enum(x[0], x[1], x[2]);
124 + _EnumDoNext(0);
125 + }
126 +
127 + // Perform a batch of WSMAN "ENUM" operations.
128 + obj.BatchEnum = function (batchname, names, callback, tag, continueOnError, pri) {
129 + obj.PendingBatchOperations += (names.length * 2);
130 + _BatchNextEnum(batchname, Clone(names), callback, tag, {}, continueOnError, pri); _up();
131 + }
132 +
133 + function Clone(v) { return JSON.parse(JSON.stringify(v)); }
134 +
135 + // Request each enum in the batch, stopping if something does not return status 200
136 + function _BatchNextEnum(batchname, names, callback, tag, results, continueOnError, pri) {
137 + obj.PendingBatchOperations -= 2;
138 + var n = names.shift(), f = obj.Enum;
139 + 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.
140 + //console.log((f == obj.Get?'Get ':'Enum ') + n);
141 + // Perform a GET/ENUM action
142 + f(n, function (stack, name, responses, status, tag0) {
143 + tag0[2][name] = { response: (responses==null?null:responses.Body), responses: responses, status: status };
144 + 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); }
145 + else { _up(); _BatchNextEnum(batchname, names, callback, tag, tag0[2], pri); }
146 + }, [batchname, names, results], pri);
147 + _up();
148 + }
149 +
150 + // Perform a batch of WSMAN "GET" operations.
151 + obj.BatchGet = function (batchname, names, callback, tag, pri) {
152 + _FetchNext({ name: batchname, names: names, callback: callback, current: 0, responses: {}, tag: tag, pri: pri }); _up();
153 + }
154 +
155 + // Private method
156 + function _FetchNext(batch) {
157 + if (batch.names.length <= batch.current) {
158 + batch.callback.call(obj, obj, batch.name, batch.responses, 200, batch.tag);
159 + } else {
160 + obj.wsman.ExecGet(obj.CompleteName(batch.names[batch.current]), function (ws, resuri, response, xstatus) { _Fetched(batch, response, xstatus); }, batch.pri);
161 + batch.current++;
162 + }
163 + _up();
164 + }
165 +
166 + // Private method
167 + function _Fetched(batch, response, status) {
168 + if (response == null || status != 200) {
169 + batch.callback.call(obj, obj, batch.name, null, status, batch.tag);
170 + } else {
171 + batch.responses[response.Header["Method"]] = response;
172 + _FetchNext(batch);
173 + }
174 + }
175 +
176 + // Private method
177 + obj.CompleteName = function(name) {
178 + if (name.indexOf("AMT_") == 0) return obj.pfx[0] + name;
179 + if (name.indexOf("CIM_") == 0) return obj.pfx[1] + name;
180 + if (name.indexOf("IPS_") == 0) return obj.pfx[2] + name;
181 + }
182 +
183 + obj.CompleteExecResponse = function (resp) {
184 + if (resp && resp != null && resp.Body && (resp.Body["ReturnValue"] != undefined)) { resp.Body.ReturnValueStr = obj.AmtStatusToStr(resp.Body["ReturnValue"]); }
185 + return resp;
186 + }
187 +
188 + obj.RequestPowerStateChange = function (PowerState, callback_func) {
189 + obj.CIM_PowerManagementService_RequestPowerStateChange(PowerState, "<Address xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><ResourceURI xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystem</ResourceURI><SelectorSet xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\"><Selector Name=\"CreationClassName\">CIM_ComputerSystem</Selector><Selector Name=\"Name\">ManagedSystem</Selector></SelectorSet></ReferenceParameters>", null, null, callback_func);
190 + }
191 +
192 + obj.SetBootConfigRole = function (Role, callback_func) {
193 + obj.CIM_BootService_SetBootConfigRole("<Address xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><ResourceURI xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_BootConfigSetting</ResourceURI><SelectorSet xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\"><Selector Name=\"InstanceID\">Intel(r) AMT: Boot Configuration 0</Selector></SelectorSet></ReferenceParameters>", Role, callback_func);
194 + }
195 +
196 + // Cancel all pending queries with given status
197 + obj.CancelAllQueries = function (s) {
198 + obj.wsman.CancelAllQueries(s);
199 + }
200 +
201 + // Auto generated methods
202 + obj.AMT_AgentPresenceWatchdog_RegisterAgent = function (callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "RegisterAgent", {}, callback_func, tag, pri, selectors); }
203 + obj.AMT_AgentPresenceWatchdog_AssertPresence = function (SequenceNumber, callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func, tag, pri, selectors); }
204 + obj.AMT_AgentPresenceWatchdog_AssertShutdown = function (SequenceNumber, callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func, tag, pri, selectors); }
205 + 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); }
206 + obj.AMT_AgentPresenceWatchdog_DeleteAllActions = function (callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "DeleteAllActions", {}, callback_func, tag, pri, selectors); }
207 + obj.AMT_AgentPresenceWatchdogAction_GetActionEac = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdogAction", "GetActionEac", {}, callback_func); }
208 + obj.AMT_AgentPresenceWatchdogVA_RegisterAgent = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "RegisterAgent", {}, callback_func); }
209 + obj.AMT_AgentPresenceWatchdogVA_AssertPresence = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func); }
210 + obj.AMT_AgentPresenceWatchdogVA_AssertShutdown = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func); }
211 + 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); }
212 + obj.AMT_AgentPresenceWatchdogVA_DeleteAllActions = function (_method_dummy, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "DeleteAllActions", { "_method_dummy": _method_dummy }, callback_func); }
213 + obj.AMT_AlarmClockService_AddAlarm = function AlarmClockService_AddAlarm(alarmInstance, callback_func)
214 + {
215 + var id = alarmInstance.InstanceID;
216 + var nm = alarmInstance.ElementName;
217 + var start = alarmInstance.StartTime.Datetime;
218 + var interval = alarmInstance.Interval ? alarmInstance.Interval.Datetime : undefined;
219 + var doc = alarmInstance.DeleteOnCompletion;
220 + var tpl = "<d:AlarmTemplate xmlns:d=\"http://intel.com/wbem/wscim/1/amt-schema/1/AMT_AlarmClockService\" xmlns:s=\"http://intel.com/wbem/wscim/1/ips-schema/1/IPS_AlarmClockOccurrence\"><s:InstanceID>" + id + "</s:InstanceID><s:ElementName>" + nm + "</s:ElementName><s:StartTime><p:Datetime xmlns:p=\"http://schemas.dmtf.org/wbem/wscim/1/common\">" + start + "</p:Datetime></s:StartTime>" + ((interval!=undefined)?("<s:Interval><p:Interval xmlns:p=\"http://schemas.dmtf.org/wbem/wscim/1/common\">" + interval + "</p:Interval></s:Interval>"):"") + "<s:DeleteOnCompletion>" + doc + "</s:DeleteOnCompletion></d:AlarmTemplate>"
221 + obj.wsman.ExecMethodXml(obj.CompleteName("AMT_AlarmClockService"), "AddAlarm", tpl, callback_func);
222 + };
223 + obj.AMT_AuditLog_ClearLog = function (callback_func) { obj.Exec("AMT_AuditLog", "ClearLog", {}, callback_func); }
224 + obj.AMT_AuditLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_AuditLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
225 + obj.AMT_AuditLog_ReadRecords = function (StartIndex, callback_func, tag) { obj.Exec("AMT_AuditLog", "ReadRecords", { "StartIndex": StartIndex }, callback_func, tag); }
226 + obj.AMT_AuditLog_SetAuditLock = function (LockTimeoutInSeconds, Flag, Handle, callback_func) { obj.Exec("AMT_AuditLog", "SetAuditLock", { "LockTimeoutInSeconds": LockTimeoutInSeconds, "Flag": Flag, "Handle": Handle }, callback_func); }
227 + obj.AMT_AuditLog_ExportAuditLogSignature = function (SigningMechanism, callback_func) { obj.Exec("AMT_AuditLog", "ExportAuditLogSignature", { "SigningMechanism": SigningMechanism }, callback_func); }
228 + 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); }
229 + 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); }
230 + 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); }
231 + 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); }
232 + obj.AMT_AuthorizationService_EnumerateUserAclEntries = function (StartIndex, callback_func) { obj.Exec("AMT_AuthorizationService", "EnumerateUserAclEntries", { "StartIndex": StartIndex }, callback_func); }
233 + obj.AMT_AuthorizationService_GetUserAclEntryEx = function (Handle, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "GetUserAclEntryEx", { "Handle": Handle }, callback_func, tag); }
234 + 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); }
235 + obj.AMT_AuthorizationService_RemoveUserAclEntry = function (Handle, callback_func) { obj.Exec("AMT_AuthorizationService", "RemoveUserAclEntry", { "Handle": Handle }, callback_func); }
236 + obj.AMT_AuthorizationService_SetAdminAclEntryEx = function (Username, DigestPassword, callback_func) { obj.Exec("AMT_AuthorizationService", "SetAdminAclEntryEx", { "Username": Username, "DigestPassword": DigestPassword }, callback_func); }
237 + obj.AMT_AuthorizationService_GetAdminAclEntry = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminAclEntry", {}, callback_func); }
238 + obj.AMT_AuthorizationService_GetAdminAclEntryStatus = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminAclEntryStatus", {}, callback_func); }
239 + obj.AMT_AuthorizationService_GetAdminNetAclEntryStatus = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminNetAclEntryStatus", {}, callback_func); }
240 + obj.AMT_AuthorizationService_SetAclEnabledState = function (Handle, Enabled, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "SetAclEnabledState", { "Handle": Handle, "Enabled": Enabled }, callback_func, tag); }
241 + obj.AMT_AuthorizationService_GetAclEnabledState = function (Handle, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "GetAclEnabledState", { "Handle": Handle }, callback_func, tag); }
242 + obj.AMT_EndpointAccessControlService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
243 + obj.AMT_EndpointAccessControlService_GetPosture = function (PostureType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetPosture", { "PostureType": PostureType }, callback_func); }
244 + obj.AMT_EndpointAccessControlService_GetPostureHash = function (PostureType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetPostureHash", { "PostureType": PostureType }, callback_func); }
245 + obj.AMT_EndpointAccessControlService_UpdatePostureState = function (UpdateType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "UpdatePostureState", { "UpdateType": UpdateType }, callback_func); }
246 + obj.AMT_EndpointAccessControlService_GetEacOptions = function (callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetEacOptions", {}, callback_func); }
247 + obj.AMT_EndpointAccessControlService_SetEacOptions = function (EacVendors, PostureHashAlgorithm, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "SetEacOptions", { "EacVendors": EacVendors, "PostureHashAlgorithm": PostureHashAlgorithm }, callback_func); }
248 + obj.AMT_EnvironmentDetectionSettingData_SetSystemDefensePolicy = function (Policy, callback_func) { obj.Exec("AMT_EnvironmentDetectionSettingData", "SetSystemDefensePolicy", { "Policy": Policy }, callback_func); }
249 + obj.AMT_EnvironmentDetectionSettingData_EnableVpnRouting = function (Enable, callback_func) { obj.Exec("AMT_EnvironmentDetectionSettingData", "EnableVpnRouting", { "Enable": Enable }, callback_func); }
250 + obj.AMT_EthernetPortSettings_SetLinkPreference = function (LinkPreference, Timeout, callback_func) { obj.Exec("AMT_EthernetPortSettings", "SetLinkPreference", { "LinkPreference": LinkPreference, "Timeout": Timeout }, callback_func); }
251 + obj.AMT_HeuristicPacketFilterStatistics_ResetSelectedStats = function (SelectedStatistics, callback_func) { obj.Exec("AMT_HeuristicPacketFilterStatistics", "ResetSelectedStats", { "SelectedStatistics": SelectedStatistics }, callback_func); }
252 + obj.AMT_KerberosSettingData_GetCredentialCacheState = function (callback_func) { obj.Exec("AMT_KerberosSettingData", "GetCredentialCacheState", {}, callback_func); }
253 + obj.AMT_KerberosSettingData_SetCredentialCacheState = function (Enable, callback_func) { obj.Exec("AMT_KerberosSettingData", "SetCredentialCacheState", { "Enable": Enable }, callback_func); }
254 + obj.AMT_MessageLog_CancelIteration = function (IterationIdentifier, callback_func) { obj.Exec("AMT_MessageLog", "CancelIteration", { "IterationIdentifier": IterationIdentifier }, callback_func); }
255 + obj.AMT_MessageLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_MessageLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
256 + obj.AMT_MessageLog_ClearLog = function (callback_func) { obj.Exec("AMT_MessageLog", "ClearLog", { }, callback_func); }
257 + obj.AMT_MessageLog_GetRecords = function (IterationIdentifier, MaxReadRecords, callback_func, tag) { obj.Exec("AMT_MessageLog", "GetRecords", { "IterationIdentifier": IterationIdentifier, "MaxReadRecords": MaxReadRecords }, callback_func, tag); }
258 + obj.AMT_MessageLog_GetRecord = function (IterationIdentifier, PositionToNext, callback_func) { obj.Exec("AMT_MessageLog", "GetRecord", { "IterationIdentifier": IterationIdentifier, "PositionToNext": PositionToNext }, callback_func); }
259 + obj.AMT_MessageLog_PositionAtRecord = function (IterationIdentifier, MoveAbsolute, RecordNumber, callback_func) { obj.Exec("AMT_MessageLog", "PositionAtRecord", { "IterationIdentifier": IterationIdentifier, "MoveAbsolute": MoveAbsolute, "RecordNumber": RecordNumber }, callback_func); }
260 + obj.AMT_MessageLog_PositionToFirstRecord = function (callback_func, tag) { obj.Exec("AMT_MessageLog", "PositionToFirstRecord", {}, callback_func, tag); }
261 + obj.AMT_MessageLog_FreezeLog = function (Freeze, callback_func) { obj.Exec("AMT_MessageLog", "FreezeLog", { "Freeze": Freeze }, callback_func); }
262 + obj.AMT_PublicKeyManagementService_AddCRL = function (Url, SerialNumbers, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddCRL", { "Url": Url, "SerialNumbers": SerialNumbers }, callback_func); }
263 + obj.AMT_PublicKeyManagementService_ResetCRLList = function (_method_dummy, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "ResetCRLList", { "_method_dummy": _method_dummy }, callback_func); }
264 + obj.AMT_PublicKeyManagementService_AddCertificate = function (CertificateBlob, callback_func, tag) { obj.Exec("AMT_PublicKeyManagementService", "AddCertificate", { "CertificateBlob": CertificateBlob }, callback_func, tag); }
265 + obj.AMT_PublicKeyManagementService_AddTrustedRootCertificate = function (CertificateBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddTrustedRootCertificate", { "CertificateBlob": CertificateBlob }, callback_func); }
266 + obj.AMT_PublicKeyManagementService_AddKey = function (KeyBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddKey", { "KeyBlob": KeyBlob }, callback_func); }
267 + obj.AMT_PublicKeyManagementService_GeneratePKCS10Request = function (KeyPair, DNName, Usage, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GeneratePKCS10Request", { "KeyPair": KeyPair, "DNName": DNName, "Usage": Usage }, callback_func); }
268 + obj.AMT_PublicKeyManagementService_GeneratePKCS10RequestEx = function (KeyPair, SigningAlgorithm, NullSignedCertificateRequest, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GeneratePKCS10RequestEx", { "KeyPair": KeyPair, "SigningAlgorithm": SigningAlgorithm, "NullSignedCertificateRequest": NullSignedCertificateRequest }, callback_func); }
269 + obj.AMT_PublicKeyManagementService_GenerateKeyPair = function (KeyAlgorithm, KeyLength, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GenerateKeyPair", { "KeyAlgorithm": KeyAlgorithm, "KeyLength": KeyLength }, callback_func); }
270 + obj.AMT_RedirectionService_RequestStateChange = function (RequestedState, callback_func) { obj.Exec("AMT_RedirectionService", "RequestStateChange", { "RequestedState": RequestedState }, callback_func); }
271 + obj.AMT_RedirectionService_TerminateSession = function (SessionType, callback_func) { obj.Exec("AMT_RedirectionService", "TerminateSession", { "SessionType": SessionType }, callback_func); }
272 + 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); }
273 + 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); }
274 + obj.AMT_RemoteAccessService_CloseRemoteAccessConnection = function (_method_dummy, callback_func) { obj.Exec("AMT_RemoteAccessService", "CloseRemoteAccessConnection", { "_method_dummy": _method_dummy }, callback_func); }
275 + obj.AMT_SetupAndConfigurationService_CommitChanges = function (_method_dummy, callback_func, tag) { obj.Exec("AMT_SetupAndConfigurationService", "CommitChanges", { "_method_dummy": _method_dummy }, callback_func, tag); }
276 + obj.AMT_SetupAndConfigurationService_Unprovision = function (ProvisioningMode, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "Unprovision", { "ProvisioningMode": ProvisioningMode }, callback_func); }
277 + obj.AMT_SetupAndConfigurationService_PartialUnprovision = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "PartialUnprovision", { "_method_dummy": _method_dummy }, callback_func); }
278 + obj.AMT_SetupAndConfigurationService_ResetFlashWearOutProtection = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "ResetFlashWearOutProtection", { "_method_dummy": _method_dummy }, callback_func); }
279 + obj.AMT_SetupAndConfigurationService_ExtendProvisioningPeriod = function (Duration, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "ExtendProvisioningPeriod", { "Duration": Duration }, callback_func); }
280 + obj.AMT_SetupAndConfigurationService_SetMEBxPassword = function (Password, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "SetMEBxPassword", { "Password": Password }, callback_func); }
281 + obj.AMT_SetupAndConfigurationService_SetTLSPSK = function (PID, PPS, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "SetTLSPSK", { "PID": PID, "PPS": PPS }, callback_func); }
282 + obj.AMT_SetupAndConfigurationService_GetProvisioningAuditRecord = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetProvisioningAuditRecord", {}, callback_func); }
283 + obj.AMT_SetupAndConfigurationService_GetUuid = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetUuid", {}, callback_func); }
284 + obj.AMT_SetupAndConfigurationService_GetUnprovisionBlockingComponents = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetUnprovisionBlockingComponents", {}, callback_func); }
285 + obj.AMT_SetupAndConfigurationService_GetProvisioningAuditRecordV2 = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetProvisioningAuditRecordV2", {}, callback_func); }
286 + obj.AMT_SystemDefensePolicy_GetTimeout = function (callback_func) { obj.Exec("AMT_SystemDefensePolicy", "GetTimeout", {}, callback_func); }
287 + obj.AMT_SystemDefensePolicy_SetTimeout = function (Timeout, callback_func) { obj.Exec("AMT_SystemDefensePolicy", "SetTimeout", { "Timeout": Timeout }, callback_func); }
288 + 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); }
289 + obj.AMT_SystemPowerScheme_SetPowerScheme = function (callback_func, schemeInstanceId, tag) { obj.Exec("AMT_SystemPowerScheme", "SetPowerScheme", {}, callback_func, tag, 0, { "InstanceID": schemeInstanceId }); }
290 + obj.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch = function (callback_func, tag) { obj.Exec("AMT_TimeSynchronizationService", "GetLowAccuracyTimeSynch", {}, callback_func, tag); }
291 + 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); }
292 + obj.AMT_TLSCredentialContext_Create = function AMT_TLSCredentialContext_Create(ElementInContext, ElementProvidingContext, callback_func, tag) { obj.Create("AMT_TLSCredentialContext", { "ElementInContext": ElementInContext, "ElementProvidingContext": ElementProvidingContext }, callback_func, tag); }
293 + obj.AMT_UserInitiatedConnectionService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_UserInitiatedConnectionService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
294 + obj.AMT_WebUIService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func, tag) { obj.Exec("AMT_WebUIService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func, tag); }
295 + 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); }
296 + 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); }
297 + obj.AMT_WiFiPortConfigurationService_DeleteAllITProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllITProfiles", { "_method_dummy": _method_dummy }, callback_func); }
298 + obj.AMT_WiFiPortConfigurationService_DeleteAllUserProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllUserProfiles", { "_method_dummy": _method_dummy }, callback_func); }
299 + obj.CIM_Account_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Account", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
300 + obj.CIM_AccountManagementService_CreateAccount = function (System, AccountTemplate, callback_func) { obj.Exec("CIM_AccountManagementService", "CreateAccount", { "System": System, "AccountTemplate": AccountTemplate }, callback_func); }
301 + obj.CIM_BootConfigSetting_ChangeBootOrder = function (Source, callback_func) { obj.Exec("CIM_BootConfigSetting", "ChangeBootOrder", { "Source": Source }, callback_func); }
302 + obj.CIM_BootService_SetBootConfigRole = function (BootConfigSetting, Role, callback_func) { obj.Exec("CIM_BootService", "SetBootConfigRole", { "BootConfigSetting": BootConfigSetting, "Role": Role }, callback_func, 0, 1); }
303 + obj.CIM_Card_ConnectorPower = function (Connector, PoweredOn, callback_func) { obj.Exec("CIM_Card", "ConnectorPower", { "Connector": Connector, "PoweredOn": PoweredOn }, callback_func); }
304 + obj.CIM_Card_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_Card", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
305 + obj.CIM_Chassis_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_Chassis", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
306 + obj.CIM_Fan_SetSpeed = function (DesiredSpeed, callback_func) { obj.Exec("CIM_Fan", "SetSpeed", { "DesiredSpeed": DesiredSpeed }, callback_func); }
307 + obj.CIM_KVMRedirectionSAP_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_KVMRedirectionSAP", "RequestStateChange", { "RequestedState": RequestedState/*, "TimeoutPeriod": TimeoutPeriod */}, callback_func); }
308 + obj.CIM_MediaAccessDevice_LockMedia = function (Lock, callback_func) { obj.Exec("CIM_MediaAccessDevice", "LockMedia", { "Lock": Lock }, callback_func); }
309 + obj.CIM_MediaAccessDevice_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_MediaAccessDevice", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
310 + obj.CIM_MediaAccessDevice_Reset = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "Reset", {}, callback_func); }
311 + obj.CIM_MediaAccessDevice_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_MediaAccessDevice", "EnableDevice", { "Enabled": Enabled }, callback_func); }
312 + obj.CIM_MediaAccessDevice_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_MediaAccessDevice", "OnlineDevice", { "Online": Online }, callback_func); }
313 + obj.CIM_MediaAccessDevice_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_MediaAccessDevice", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
314 + obj.CIM_MediaAccessDevice_SaveProperties = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "SaveProperties", {}, callback_func); }
315 + obj.CIM_MediaAccessDevice_RestoreProperties = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "RestoreProperties", {}, callback_func); }
316 + obj.CIM_MediaAccessDevice_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_MediaAccessDevice", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
317 + obj.CIM_PhysicalFrame_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_PhysicalFrame", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
318 + obj.CIM_PhysicalPackage_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_PhysicalPackage", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
319 + 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); }
320 + obj.CIM_PowerSupply_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_PowerSupply", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
321 + obj.CIM_PowerSupply_Reset = function (callback_func) { obj.Exec("CIM_PowerSupply", "Reset", {}, callback_func); }
322 + obj.CIM_PowerSupply_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_PowerSupply", "EnableDevice", { "Enabled": Enabled }, callback_func); }
323 + obj.CIM_PowerSupply_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_PowerSupply", "OnlineDevice", { "Online": Online }, callback_func); }
324 + obj.CIM_PowerSupply_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_PowerSupply", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
325 + obj.CIM_PowerSupply_SaveProperties = function (callback_func) { obj.Exec("CIM_PowerSupply", "SaveProperties", {}, callback_func); }
326 + obj.CIM_PowerSupply_RestoreProperties = function (callback_func) { obj.Exec("CIM_PowerSupply", "RestoreProperties", {}, callback_func); }
327 + obj.CIM_PowerSupply_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_PowerSupply", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
328 + obj.CIM_Processor_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Processor", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
329 + obj.CIM_Processor_Reset = function (callback_func) { obj.Exec("CIM_Processor", "Reset", {}, callback_func); }
330 + obj.CIM_Processor_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Processor", "EnableDevice", { "Enabled": Enabled }, callback_func); }
331 + obj.CIM_Processor_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Processor", "OnlineDevice", { "Online": Online }, callback_func); }
332 + obj.CIM_Processor_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Processor", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
333 + obj.CIM_Processor_SaveProperties = function (callback_func) { obj.Exec("CIM_Processor", "SaveProperties", {}, callback_func); }
334 + obj.CIM_Processor_RestoreProperties = function (callback_func) { obj.Exec("CIM_Processor", "RestoreProperties", {}, callback_func); }
335 + obj.CIM_Processor_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Processor", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
336 + obj.CIM_RecordLog_ClearLog = function (callback_func) { obj.Exec("CIM_RecordLog", "ClearLog", {}, callback_func); }
337 + obj.CIM_RecordLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_RecordLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
338 + obj.CIM_RedirectionService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_RedirectionService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
339 + obj.CIM_Sensor_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Sensor", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
340 + obj.CIM_Sensor_Reset = function (callback_func) { obj.Exec("CIM_Sensor", "Reset", {}, callback_func); }
341 + obj.CIM_Sensor_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Sensor", "EnableDevice", { "Enabled": Enabled }, callback_func); }
342 + obj.CIM_Sensor_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Sensor", "OnlineDevice", { "Online": Online }, callback_func); }
343 + obj.CIM_Sensor_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Sensor", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
344 + obj.CIM_Sensor_SaveProperties = function (callback_func) { obj.Exec("CIM_Sensor", "SaveProperties", {}, callback_func); }
345 + obj.CIM_Sensor_RestoreProperties = function (callback_func) { obj.Exec("CIM_Sensor", "RestoreProperties", {}, callback_func); }
346 + obj.CIM_Sensor_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Sensor", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
347 + obj.CIM_StatisticalData_ResetSelectedStats = function (SelectedStatistics, callback_func) { obj.Exec("CIM_StatisticalData", "ResetSelectedStats", { "SelectedStatistics": SelectedStatistics }, callback_func); }
348 + obj.CIM_Watchdog_KeepAlive = function (callback_func) { obj.Exec("CIM_Watchdog", "KeepAlive", {}, callback_func); }
349 + obj.CIM_Watchdog_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Watchdog", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
350 + obj.CIM_Watchdog_Reset = function (callback_func) { obj.Exec("CIM_Watchdog", "Reset", {}, callback_func); }
351 + obj.CIM_Watchdog_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Watchdog", "EnableDevice", { "Enabled": Enabled }, callback_func); }
352 + obj.CIM_Watchdog_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Watchdog", "OnlineDevice", { "Online": Online }, callback_func); }
353 + obj.CIM_Watchdog_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Watchdog", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
354 + obj.CIM_Watchdog_SaveProperties = function (callback_func) { obj.Exec("CIM_Watchdog", "SaveProperties", {}, callback_func); }
355 + obj.CIM_Watchdog_RestoreProperties = function (callback_func) { obj.Exec("CIM_Watchdog", "RestoreProperties", {}, callback_func); }
356 + obj.CIM_Watchdog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Watchdog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
357 + obj.CIM_WiFiPort_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_WiFiPort", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
358 + obj.CIM_WiFiPort_Reset = function (callback_func) { obj.Exec("CIM_WiFiPort", "Reset", {}, callback_func); }
359 + obj.CIM_WiFiPort_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_WiFiPort", "EnableDevice", { "Enabled": Enabled }, callback_func); }
360 + obj.CIM_WiFiPort_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_WiFiPort", "OnlineDevice", { "Online": Online }, callback_func); }
361 + obj.CIM_WiFiPort_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_WiFiPort", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
362 + obj.CIM_WiFiPort_SaveProperties = function (callback_func) { obj.Exec("CIM_WiFiPort", "SaveProperties", {}, callback_func); }
363 + obj.CIM_WiFiPort_RestoreProperties = function (callback_func) { obj.Exec("CIM_WiFiPort", "RestoreProperties", {}, callback_func); }
364 + obj.CIM_WiFiPort_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_WiFiPort", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
365 + 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); }
366 + obj.IPS_HostBasedSetupService_AddNextCertInChain = function (NextCertificate, IsLeafCertificate, IsRootCertificate, callback_func) { obj.Exec("IPS_HostBasedSetupService", "AddNextCertInChain", { "NextCertificate": NextCertificate, "IsLeafCertificate": IsLeafCertificate, "IsRootCertificate": IsRootCertificate }, callback_func); }
367 + 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); }
368 + obj.IPS_HostBasedSetupService_UpgradeClientToAdmin = function (McNonce, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "UpgradeClientToAdmin", { "McNonce": McNonce, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); }
369 + obj.IPS_HostBasedSetupService_DisableClientControlMode = function (_method_dummy, callback_func) { obj.Exec("IPS_HostBasedSetupService", "DisableClientControlMode", { "_method_dummy": _method_dummy }, callback_func); }
370 + obj.IPS_KVMRedirectionSettingData_TerminateSession = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "TerminateSession", {}, callback_func); }
371 + obj.IPS_KVMRedirectionSettingData_DataChannelRead = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelRead", {}, callback_func); }
372 + obj.IPS_KVMRedirectionSettingData_DataChannelWrite = function (Data, callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelWrite", { "DataMessage": Data }, callback_func); }
373 + obj.IPS_OptInService_StartOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "StartOptIn", {}, callback_func); }
374 + obj.IPS_OptInService_CancelOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "CancelOptIn", {}, callback_func); }
375 + obj.IPS_OptInService_SendOptInCode = function (OptInCode, callback_func) { obj.Exec("IPS_OptInService", "SendOptInCode", { "OptInCode": OptInCode }, callback_func); }
376 + obj.IPS_OptInService_StartService = function (callback_func) { obj.Exec("IPS_OptInService", "StartService", {}, callback_func); }
377 + obj.IPS_OptInService_StopService = function (callback_func) { obj.Exec("IPS_OptInService", "StopService", {}, callback_func); }
378 + obj.IPS_OptInService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_OptInService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
379 + obj.IPS_ProvisioningRecordLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_ProvisioningRecordLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
380 + obj.IPS_ProvisioningRecordLog_ClearLog = function (_method_dummy, callback_func) { obj.Exec("IPS_ProvisioningRecordLog", "ClearLog", { "_method_dummy": _method_dummy }, callback_func); }
381 + obj.IPS_SecIOService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_SecIOService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
382 +
383 + obj.AmtStatusToStr = function (code) { if (obj.AmtStatusCodes[code]) return obj.AmtStatusCodes[code]; else return "UNKNOWN_ERROR" }
384 + obj.AmtStatusCodes = {
385 + 0x0000: "SUCCESS",
386 + 0x0001: "INTERNAL_ERROR",
387 + 0x0002: "NOT_READY",
388 + 0x0003: "INVALID_PT_MODE",
389 + 0x0004: "INVALID_MESSAGE_LENGTH",
390 + 0x0005: "TABLE_FINGERPRINT_NOT_AVAILABLE",
391 + 0x0006: "INTEGRITY_CHECK_FAILED",
392 + 0x0007: "UNSUPPORTED_ISVS_VERSION",
393 + 0x0008: "APPLICATION_NOT_REGISTERED",
394 + 0x0009: "INVALID_REGISTRATION_DATA",
395 + 0x000A: "APPLICATION_DOES_NOT_EXIST",
396 + 0x000B: "NOT_ENOUGH_STORAGE",
397 + 0x000C: "INVALID_NAME",
398 + 0x000D: "BLOCK_DOES_NOT_EXIST",
399 + 0x000E: "INVALID_BYTE_OFFSET",
400 + 0x000F: "INVALID_BYTE_COUNT",
401 + 0x0010: "NOT_PERMITTED",
402 + 0x0011: "NOT_OWNER",
403 + 0x0012: "BLOCK_LOCKED_BY_OTHER",
404 + 0x0013: "BLOCK_NOT_LOCKED",
405 + 0x0014: "INVALID_GROUP_PERMISSIONS",
406 + 0x0015: "GROUP_DOES_NOT_EXIST",
407 + 0x0016: "INVALID_MEMBER_COUNT",
408 + 0x0017: "MAX_LIMIT_REACHED",
409 + 0x0018: "INVALID_AUTH_TYPE",
410 + 0x0019: "AUTHENTICATION_FAILED",
411 + 0x001A: "INVALID_DHCP_MODE",
412 + 0x001B: "INVALID_IP_ADDRESS",
413 + 0x001C: "INVALID_DOMAIN_NAME",
414 + 0x001D: "UNSUPPORTED_VERSION",
415 + 0x001E: "REQUEST_UNEXPECTED",
416 + 0x001F: "INVALID_TABLE_TYPE",
417 + 0x0020: "INVALID_PROVISIONING_STATE",
418 + 0x0021: "UNSUPPORTED_OBJECT",
419 + 0x0022: "INVALID_TIME",
420 + 0x0023: "INVALID_INDEX",
421 + 0x0024: "INVALID_PARAMETER",
422 + 0x0025: "INVALID_NETMASK",
423 + 0x0026: "FLASH_WRITE_LIMIT_EXCEEDED",
424 + 0x0027: "INVALID_IMAGE_LENGTH",
425 + 0x0028: "INVALID_IMAGE_SIGNATURE",
426 + 0x0029: "PROPOSE_ANOTHER_VERSION",
427 + 0x002A: "INVALID_PID_FORMAT",
428 + 0x002B: "INVALID_PPS_FORMAT",
429 + 0x002C: "BIST_COMMAND_BLOCKED",
430 + 0x002D: "CONNECTION_FAILED",
431 + 0x002E: "CONNECTION_TOO_MANY",
432 + 0x002F: "RNG_GENERATION_IN_PROGRESS",
433 + 0x0030: "RNG_NOT_READY",
434 + 0x0031: "CERTIFICATE_NOT_READY",
435 + 0x0400: "DISABLED_BY_POLICY",
436 + 0x0800: "NETWORK_IF_ERROR_BASE",
437 + 0x0801: "UNSUPPORTED_OEM_NUMBER",
438 + 0x0802: "UNSUPPORTED_BOOT_OPTION",
439 + 0x0803: "INVALID_COMMAND",
440 + 0x0804: "INVALID_SPECIAL_COMMAND",
441 + 0x0805: "INVALID_HANDLE",
442 + 0x0806: "INVALID_PASSWORD",
443 + 0x0807: "INVALID_REALM",
444 + 0x0808: "STORAGE_ACL_ENTRY_IN_USE",
445 + 0x0809: "DATA_MISSING",
446 + 0x080A: "DUPLICATE",
447 + 0x080B: "EVENTLOG_FROZEN",
448 + 0x080C: "PKI_MISSING_KEYS",
449 + 0x080D: "PKI_GENERATING_KEYS",
450 + 0x080E: "INVALID_KEY",
451 + 0x080F: "INVALID_CERT",
452 + 0x0810: "CERT_KEY_NOT_MATCH",
453 + 0x0811: "MAX_KERB_DOMAIN_REACHED",
454 + 0x0812: "UNSUPPORTED",
455 + 0x0813: "INVALID_PRIORITY",
456 + 0x0814: "NOT_FOUND",
457 + 0x0815: "INVALID_CREDENTIALS",
458 + 0x0816: "INVALID_PASSPHRASE",
459 + 0x0818: "NO_ASSOCIATION",
460 + 0x081B: "AUDIT_FAIL",
461 + 0x081C: "BLOCKING_COMPONENT",
462 + 0x0821: "USER_CONSENT_REQUIRED",
463 + 0x1000: "APP_INTERNAL_ERROR",
464 + 0x1001: "NOT_INITIALIZED",
465 + 0x1002: "LIB_VERSION_UNSUPPORTED",
466 + 0x1003: "INVALID_PARAM",
467 + 0x1004: "RESOURCES",
468 + 0x1005: "HARDWARE_ACCESS_ERROR",
469 + 0x1006: "REQUESTOR_NOT_REGISTERED",
470 + 0x1007: "NETWORK_ERROR",
471 + 0x1008: "PARAM_BUFFER_TOO_SHORT",
472 + 0x1009: "COM_NOT_INITIALIZED_IN_THREAD",
473 + 0x100A: "URL_REQUIRED"
474 + }
475 +
476 + //
477 + // Methods used for getting the event log
478 + //
479 +
480 + obj.GetMessageLog = function (func, tag) {
481 + obj.AMT_MessageLog_PositionToFirstRecord(_GetMessageLog0, [func, tag, []]);
482 + }
483 + function _GetMessageLog0(stack, name, responses, status, tag) {
484 + if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; }
485 + obj.AMT_MessageLog_GetRecords(responses.Body["IterationIdentifier"], 390, _GetMessageLog1, tag);
486 + }
487 + function _GetMessageLog1(stack, name, responses, status, tag) {
488 + if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; }
489 + var i, j, x, e, AmtMessages = tag[2], t = new Date(), TimeStamp, ra = responses.Body["RecordArray"];
490 + if (typeof ra === 'string') { responses.Body["RecordArray"] = [responses.Body["RecordArray"]]; }
491 +
492 + for (i in ra) {
493 + e = Buffer.from(ra[i], 'base64');
494 + if (e != null) {
495 + TimeStamp = ReadIntX(e, 0);
496 + if ((TimeStamp > 0) && (TimeStamp < 0xFFFFFFFF)) {
497 + 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) };
498 + for (j = 13; j < 21; j++) { x['EventData'].push(e[j]); }
499 + x['EntityStr'] = _SystemEntityTypes[x['Entity']];
500 + x['Desc'] = _GetEventDetailStr(x['EventSensorType'], x['EventOffset'], x['EventData'], x['Entity']);
501 + if (!x['EntityStr']) x['EntityStr'] = "Unknown";
502 + AmtMessages.push(x);
503 + }
504 + }
505 + }
506 +
507 + 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]); }
508 + }
509 +
510 + 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('|');
511 + 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('|');
512 + 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('|');
513 + 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('|');
514 + 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('|');
515 + obj.WatchdogCurrentStates = { 1: 'Not Started', 2: 'Stopped', 4: 'Running', 8: 'Expired', 16: 'Suspended' };
516 +
517 + function _GetEventDetailStr(eventSensorType, eventOffset, eventDataField, entity) {
518 +
519 + if (eventSensorType == 15)
520 + {
521 + if (eventDataField[0] == 235) return "Invalid Data";
522 + if (eventOffset == 0) return _SystemFirmwareError[eventDataField[1]];
523 + return _SystemFirmwareProgress[eventDataField[1]];
524 + }
525 +
526 + if (eventSensorType == 18 && eventDataField[0] == 170) // System watchdog event
527 + {
528 + 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]];
529 + }
530 +
531 + //if (eventSensorType == 5 && eventOffset == 0) // System chassis
532 + //{
533 + // return "Case intrusion";
534 + //}
535 +
536 + //if (eventSensorType == 192 && eventOffset == 0 && eventDataField[0] == 170 && eventDataField[1] == 48)
537 + //{
538 + // if (eventDataField[2] == 0) return "A remote Serial Over LAN session was established.";
539 + // if (eventDataField[2] == 1) return "Remote Serial Over LAN session finished. User control was restored.";
540 + // if (eventDataField[2] == 2) return "A remote IDE-Redirection session was established.";
541 + // if (eventDataField[2] == 3) return "Remote IDE-Redirection session finished. User control was restored.";
542 + //}
543 +
544 + //if (eventSensorType == 36)
545 + //{
546 + // long handle = ((long)(eventDataField[1]) << 24) + ((long)(eventDataField[2]) << 16) + ((long)(eventDataField[3]) << 8) + (long)(eventDataField[4]);
547 + // string nic = string.Format("#{0}", eventDataField[0]);
548 + // if (eventDataField[0] == 0xAA) nic = "wired"; // TODO: Add wireless *****
549 + // //if (eventDataField[0] == 0xAA) nic = "wireless";
550 +
551 + // if (handle == 4294967293) { return string.Format("All received packet filter was matched on {0} interface.", nic); }
552 + // if (handle == 4294967292) { return string.Format("All outbound packet filter was matched on {0} interface.", nic); }
553 + // if (handle == 4294967290) { return string.Format("Spoofed packet filter was matched on {0} interface.", nic); }
554 + // return string.Format("Filter {0} was matched on {1} interface.", handle, nic);
555 + //}
556 +
557 + //if (eventSensorType == 192)
558 + //{
559 + // if (eventDataField[2] == 0) return "Security policy invoked. Some or all network traffic (TX) was stopped.";
560 + // if (eventDataField[2] == 2) return "Security policy invoked. Some or all network traffic (RX) was stopped.";
561 + // return "Security policy invoked.";
562 + //}
563 +
564 + //if (eventSensorType == 193)
565 + //{
566 + // if (eventDataField[0] == 0xAA && eventDataField[1] == 0x30 && eventDataField[2] == 0x00 && eventDataField[3] == 0x00) { return "User request for remote connection."; }
567 + // 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 }
568 + // if (eventDataField[0] == 0xAA && eventDataField[1] == 0x20 && eventDataField[2] == 0x04 && eventDataField[3] == 0x00) { return "Certificate revoked. "; }
569 + //}
570 +
571 + if (eventSensorType == 6) return "Authentication failed " + (eventDataField[1] + (eventDataField[2] << 8)) + " times. The system may be under attack.";
572 + if (eventSensorType == 30) return "No bootable media";
573 + if (eventSensorType == 32) return "Operating system lockup or power interrupt";
574 + if (eventSensorType == 35) return "System boot failure";
575 + if (eventSensorType == 37) return "System firmware started (at least one CPU is properly executing).";
576 + return "Unknown Sensor Type #" + eventSensorType;
577 + }
578 +
579 +// ###BEGIN###{AuditLog}
580 +
581 + // Useful link: https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Fsecurityadminevents.htm
582 +
583 + var _AmtAuditStringTable =
584 + {
585 + 16: 'Security Admin',
586 + 17: 'RCO',
587 + 18: 'Redirection Manager',
588 + 19: 'Firmware Update Manager',
589 + 20: 'Security Audit Log',
590 + 21: 'Network Time',
591 + 22: 'Network Administration',
592 + 23: 'Storage Administration',
593 + 24: 'Event Manager',
594 + 25: 'Circuit Breaker Manager',
595 + 26: 'Agent Presence Manager',
596 + 27: 'Wireless Configuration',
597 + 28: 'EAC',
598 + 29: 'KVM',
599 + 30: 'User Opt-In Events',
600 + 32: 'Screen Blanking',
601 + 33: 'Watchdog Events',
602 + 1600: 'Provisioning Started',
603 + 1601: 'Provisioning Completed',
604 + 1602: 'ACL Entry Added',
605 + 1603: 'ACL Entry Modified',
606 + 1604: 'ACL Entry Removed',
607 + 1605: 'ACL Access with Invalid Credentials',
608 + 1606: 'ACL Entry State',
609 + 1607: 'TLS State Changed',
610 + 1608: 'TLS Server Certificate Set',
611 + 1609: 'TLS Server Certificate Remove',
612 + 1610: 'TLS Trusted Root Certificate Added',
613 + 1611: 'TLS Trusted Root Certificate Removed',
614 + 1612: 'TLS Preshared Key Set',
615 + 1613: 'Kerberos Settings Modified',
616 + 1614: 'Kerberos Master Key Modified',
617 + 1615: 'Flash Wear out Counters Reset',
618 + 1616: 'Power Package Modified',
619 + 1617: 'Set Realm Authentication Mode',
620 + 1618: 'Upgrade Client to Admin Control Mode',
621 + 1619: 'Unprovisioning Started',
622 + 1700: 'Performed Power Up',
623 + 1701: 'Performed Power Down',
624 + 1702: 'Performed Power Cycle',
625 + 1703: 'Performed Reset',
626 + 1704: 'Set Boot Options',
627 + 1800: 'IDER Session Opened',
628 + 1801: 'IDER Session Closed',
629 + 1802: 'IDER Enabled',
630 + 1803: 'IDER Disabled',
631 + 1804: 'SoL Session Opened',
632 + 1805: 'SoL Session Closed',
633 + 1806: 'SoL Enabled',
634 + 1807: 'SoL Disabled',
635 + 1808: 'KVM Session Started',
636 + 1809: 'KVM Session Ended',
637 + 1810: 'KVM Enabled',
638 + 1811: 'KVM Disabled',
639 + 1812: 'VNC Password Failed 3 Times',
640 + 1900: 'Firmware Updated',
641 + 1901: 'Firmware Update Failed',
642 + 2000: 'Security Audit Log Cleared',
643 + 2001: 'Security Audit Policy Modified',
644 + 2002: 'Security Audit Log Disabled',
645 + 2003: 'Security Audit Log Enabled',
646 + 2004: 'Security Audit Log Exported',
647 + 2005: 'Security Audit Log Recovered',
648 + 2100: 'Intel(R) ME Time Set',
649 + 2200: 'TCPIP Parameters Set',
650 + 2201: 'Host Name Set',
651 + 2202: 'Domain Name Set',
652 + 2203: 'VLAN Parameters Set',
653 + 2204: 'Link Policy Set',
654 + 2205: 'IPv6 Parameters Set',
655 + 2300: 'Global Storage Attributes Set',
656 + 2301: 'Storage EACL Modified',
657 + 2302: 'Storage FPACL Modified',
658 + 2303: 'Storage Write Operation',
659 + 2400: 'Alert Subscribed',
660 + 2401: 'Alert Unsubscribed',
661 + 2402: 'Event Log Cleared',
662 + 2403: 'Event Log Frozen',
663 + 2500: 'CB Filter Added',
664 + 2501: 'CB Filter Removed',
665 + 2502: 'CB Policy Added',
666 + 2503: 'CB Policy Removed',
667 + 2504: 'CB Default Policy Set',
668 + 2505: 'CB Heuristics Option Set',
669 + 2506: 'CB Heuristics State Cleared',
670 + 2600: 'Agent Watchdog Added',
671 + 2601: 'Agent Watchdog Removed',
672 + 2602: 'Agent Watchdog Action Set',
673 + 2700: 'Wireless Profile Added',
674 + 2701: 'Wireless Profile Removed',
675 + 2702: 'Wireless Profile Updated',
676 + 2800: 'EAC Posture Signer SET',
677 + 2801: 'EAC Enabled',
678 + 2802: 'EAC Disabled',
679 + 2803: 'EAC Posture State',
680 + 2804: 'EAC Set Options',
681 + 2900: 'KVM Opt-in Enabled',
682 + 2901: 'KVM Opt-in Disabled',
683 + 2902: 'KVM Password Changed',
684 + 2903: 'KVM Consent Succeeded',
685 + 2904: 'KVM Consent Failed',
686 + 3000: 'Opt-In Policy Change',
687 + 3001: 'Send Consent Code Event',
688 + 3002: 'Start Opt-In Blocked Event'
689 + }
690 +
691 + // Return human readable extended audit log data
692 + // TODO: Just put some of them here, but many more still need to be added, helpful link here:
693 + // https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Fsecurityadminevents.htm
694 + obj.GetAuditLogExtendedDataStr = function (id, data) {
695 + if ((id == 1602 || id == 1604) && data[0] == 0) { return bufToArray(data).splice(2, 2 + data[1]).toString(); } // ACL Entry Added/Removed (Digest)
696 + if (id == 1603) { if (data[1] == 0) { return bufToArray(data).splice(3).toString(); } return null; } // ACL Entry Modified
697 + if (id == 1605) { return ["Invalid ME access", "Invalid MEBx access"][data[0]]; } // ACL Access with Invalid Credentials
698 + if (id == 1606) { var r = ["Disabled", "Enabled"][data[0]]; if (data[1] == 0) { r += ", " + data[3]; } return r; } // ACL Entry State
699 + if (id == 1607) { return "Remote " + ["NoAuth", "ServerAuth", "MutualAuth"][data[0]] + ", Local " + ["NoAuth", "ServerAuth", "MutualAuth"][data[1]]; } // TLS State Changed
700 + if (id == 1617) { return obj.RealmNames[ReadInt(data, 0)] + ", " + ["NoAuth", "Auth", "Disabled"][data[4]]; } // Set Realm Authentication Mode
701 + if (id == 1619) { return ["BIOS", "MEBx", "Local MEI", "Local WSMAN", "Remote WSAMN"][data[0]]; } // Intel AMT Unprovisioning Started
702 + 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
703 + if (id == 2100) { var t4 = new Date(); t4.setTime(ReadInt(data, 0) * 1000 + (new Date().getTimezoneOffset() * 60000)); return t4.toLocaleString(); } // Intel AMT Time Set
704 + if (id == 3000) { return "From " + ["None", "KVM", "All"][data[0]] + " to " + ["None", "KVM", "All"][data[1]]; } // Opt-In Policy Change
705 + if (id == 3001) { return ["Success", "Failed 3 times"][data[0]]; } // Send Consent Code Event
706 + return null;
707 + }
708 +
709 + obj.GetAuditLog = function (func) {
710 + obj.AMT_AuditLog_ReadRecords(1, _GetAuditLog0, [func, []]);
711 + }
712 +
713 + function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; }
714 + function ReadShort(v, p) { return (v[p] << 8) + v[p + 1]; }
715 + 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.
716 + function ReadIntX(v, p) { return (v[p + 3] * 0x1000000) + (v[p + 2] << 16) + (v[p + 1] << 8) + v[p]; }
717 + function btoa(x) { return Buffer.from(x).toString('base64'); }
718 + function atob(x) { var z = null; try { z = Buffer.from(x, 'base64').toString(); } catch (e) { console.log(e); } return z; }
719 + function bufToArray(buf) { var r = []; for (var i in buf) { r.push(buf[i]); } return r; }
720 +
721 + function _GetAuditLog0(stack, name, responses, status, tag) {
722 + if (status != 200) { tag[0](obj, [], status); return; }
723 + var ptr, i, e, es, x, r = tag[1], t = new Date(), TimeStamp;
724 +
725 + if (responses.Body['RecordsReturned'] > 0) {
726 + responses.Body['EventRecords'] = MakeToArray(responses.Body['EventRecords']);
727 +
728 + for (i in responses.Body['EventRecords']) {
729 + e = null;
730 + try {
731 + es = atob(responses.Body['EventRecords'][i]);
732 + e = Buffer.from(es);
733 + } catch (ex) {
734 + console.log(ex + " " + responses.Body['EventRecords'][i])
735 + }
736 +
737 + x = { 'AuditAppID': ReadShort(e, 0), 'EventID': ReadShort(e, 2), 'InitiatorType': e[4] };
738 + x['AuditApp'] = _AmtAuditStringTable[x['AuditAppID']];
739 + x['Event'] = _AmtAuditStringTable[(x['AuditAppID'] * 100) + x['EventID']];
740 + if (!x['Event']) x['Event'] = '#' + x['EventID'];
741 +
742 + // Read and process the initiator
743 + if (x['InitiatorType'] == 0) {
744 + // HTTP digest
745 + var userlen = e[5];
746 + x['Initiator'] = e.slice(6, 6 + userlen).toString();
747 + ptr = 6 + userlen;
748 + }
749 + if (x['InitiatorType'] == 1) {
750 + // Kerberos
751 + x['KerberosUserInDomain'] = ReadInt(e, 5);
752 + var userlen = e[9];
753 + x['Initiator'] = GetSidString(e.slice(10, 10 + userlen));
754 + ptr = 10 + userlen;
755 + }
756 + if (x['InitiatorType'] == 2) {
757 + // Local
758 + x['Initiator'] = 'Local';
759 + ptr = 5;
760 + }
761 + if (x['InitiatorType'] == 3) {
762 + // KVM Default Port
763 + x['Initiator'] = 'KVM Default Port';
764 + ptr = 5;
765 + }
766 +
767 + // Read timestamp
768 + TimeStamp = ReadInt(e, ptr);
769 + x['Time'] = new Date((TimeStamp + (t.getTimezoneOffset() * 60)) * 1000);
770 + ptr += 4;
771 +
772 + // Read network access
773 + x['MCLocationType'] = e[ptr++];
774 + var netlen = e[ptr++];
775 +
776 + x['NetAddress'] = e.slice(ptr, ptr + netlen).toString();
777 +
778 + // Read extended data
779 + ptr += netlen;
780 + var exlen = e[ptr++];
781 + x['Ex'] = e.slice(ptr, ptr + exlen);
782 + x['ExStr'] = obj.GetAuditLogExtendedDataStr((x['AuditAppID'] * 100) + x['EventID'], x['Ex']);
783 + r.push(x);
784 + }
785 + }
786 + if (responses.Body['TotalRecordCount'] > r.length) {
787 + obj.AMT_AuditLog_ReadRecords(r.length + 1, _GetAuditLog0, [tag[0], r]);
788 + } else {
789 + tag[0](obj, r, status);
790 + }
791 + }
792 +
793 + // ###END###{AuditLog}
794 +
795 + /*
796 + // ###BEGIN###{Certificates}
797 +
798 + // Forge MD5
799 + function hex_md5(str) { return forge.md.md5.create().update(str).digest().toHex(); }
800 +
801 + // ###END###{Certificates}
802 +
803 + // ###BEGIN###{!Certificates}
804 +
805 + // TinyMD5 from https://github.com/jbt/js-crypto
806 +
807 + // Perform MD5 setup
808 + var md5_k = [];
809 + for (var i = 0; i < 64;) { md5_k[i] = 0 | (Math.abs(Math.sin(++i)) * 4294967296); }
810 +
811 + // Perform MD5 on raw string and return hex
812 + function hex_md5(str) {
813 + var b, c, d, j,
814 + x = [],
815 + str2 = unescape(encodeURI(str)),
816 + a = str2.length,
817 + h = [b = 1732584193, c = -271733879, ~b, ~c],
818 + i = 0;
819 +
820 + for (; i <= a;) x[i >> 2] |= (str2.charCodeAt(i) || 128) << 8 * (i++ % 4);
821 +
822 + x[str = (a + 8 >> 6) * 16 + 14] = a * 8;
823 + i = 0;
824 +
825 + for (; i < str; i += 16) {
826 + a = h; j = 0;
827 + for (; j < 64;) {
828 + a = [
829 + d = a[3],
830 + ((b = a[1] | 0) +
831 + ((d = (
832 + (a[0] +
833 + [
834 + b & (c = a[2]) | ~b & d,
835 + d & b | ~d & c,
836 + b ^ c ^ d,
837 + c ^ (b | ~d)
838 + ][a = j >> 4]
839 + ) +
840 + (md5_k[j] +
841 + (x[[
842 + j,
843 + 5 * j + 1,
844 + 3 * j + 5,
845 + 7 * j
846 + ][a] % 16 + i] | 0)
847 + )
848 + )) << (a = [
849 + 7, 12, 17, 22,
850 + 5, 9, 14, 20,
851 + 4, 11, 16, 23,
852 + 6, 10, 15, 21
853 + ][4 * a + j++ % 4]) | d >>> 32 - a)
854 + ),
855 + b,
856 + c
857 + ];
858 + }
859 + for (j = 4; j;) h[--j] = h[j] + a[j];
860 + }
861 +
862 + str = '';
863 + for (; j < 32;) str += ((h[j >> 3] >> ((1 ^ j++ & 7) * 4)) & 15).toString(16);
864 + return str;
865 + }
866 +
867 + // ###END###{!Certificates}
868 +
869 + // Perform MD5 on raw string and return raw string result
870 + function rstr_md5(str) { return hex2rstr(hex_md5(str)); }
871 + */
872 + /*
873 + Convert arguments into selector set and body XML. Used by AMT_WiFiPortConfigurationService_UpdateWiFiSettings.
874 + args = {
875 + "WiFiEndpoint": {
876 + __parameterType: 'reference',
877 + __resourceUri: 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpoint',
878 + Name: 'WiFi Endpoint 0'
879 + },
880 + "WiFiEndpointSettingsInput":
881 + {
882 + __parameterType: 'instance',
883 + __namespace: 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpointSettings',
884 + ElementName: document.querySelector('#editProfile-profileName').value,
885 + InstanceID: 'Intel(r) AMT:WiFi Endpoint Settings ' + document.querySelector('#editProfile-profileName').value,
886 + AuthenticationMethod: document.querySelector('#editProfile-networkAuthentication').value,
887 + //BSSType: 3, // Intel(r) AMT supports only infrastructure networks
888 + EncryptionMethod: document.querySelector('#editProfile-encryption').value,
889 + SSID: document.querySelector('#editProfile-networkName').value,
890 + Priority: 100,
891 + PSKPassPhrase: document.querySelector('#editProfile-passPhrase').value
892 + },
893 + "IEEE8021xSettingsInput": null,
894 + "ClientCredential": null,
895 + "CACredential": null
896 + },
897 + */
898 + function execArgumentsToXml(args) {
899 + if (args === undefined || args === null) return null;
900 +
901 + var result = '';
902 + for (var argName in args) {
903 + var arg = args[argName];
904 + if (!arg) continue;
905 + if (arg['__parameterType'] === 'reference') result += referenceToXml(argName, arg);
906 + else result += instanceToXml(argName, arg);
907 + //if(arg['__isInstance']) result += instanceToXml(argName, arg);
908 + }
909 + return result;
910 + }
911 +
912 + /**
913 + * Convert JavaScript object into XML
914 +
915 + <r:WiFiEndpointSettingsInput xmlns:q="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpointSettings">
916 + <q:ElementName>Wireless-Profile-Admin</q:ElementName>
917 + <q:InstanceID>Intel(r) AMT:WiFi Endpoint Settings Wireless-Profile-Admin</q:InstanceID>
918 + <q:AuthenticationMethod>6</q:AuthenticationMethod>
919 + <q:EncryptionMethod>4</q:EncryptionMethod>
920 + <q:Priority>100</q:Priority>
921 + <q:PSKPassPhrase>P@ssw0rd</q:PSKPassPhrase>
922 + </r:WiFiEndpointSettingsInput>
923 + */
924 + function instanceToXml(instanceName, inInstance) {
925 + if (inInstance === undefined || inInstance === null) return null;
926 +
927 + var hasNamespace = !!inInstance['__namespace'];
928 + var startTag = hasNamespace ? '<q:' : '<';
929 + var endTag = hasNamespace ? '</q:' : '</';
930 + var namespaceDef = hasNamespace ? (' xmlns:q="' + inInstance['__namespace'] + '"') : '';
931 + var result = '<r:' + instanceName + namespaceDef + '>';
932 + for (var prop in inInstance) {
933 + if (!inInstance.hasOwnProperty(prop) || prop.indexOf('__') === 0) continue;
934 +
935 + if (typeof inInstance[prop] === 'function' || Array.isArray(inInstance[prop])) continue;
936 +
937 + if (typeof inInstance[prop] === 'object') {
938 + //result += startTag + prop +'>' + instanceToXml('prop', inInstance[prop]) + endTag + prop +'>';
939 + console.error('only convert one level down...');
940 + }
941 + else {
942 + result += startTag + prop + '>' + inInstance[prop].toString() + endTag + prop + '>';
943 + }
944 + }
945 + result += '</r:' + instanceName + '>';
946 + return result;
947 + }
948 +
949 +
950 + /**
951 + * Convert a selector set into XML. Expect no nesting.
952 + * {
953 + * selectorName : selectorValue,
954 + * selectorName : selectorValue,
955 + * ... ...
956 + * }
957 +
958 + <r:WiFiEndpoint>
959 + <a:Address>http://192.168.1.103:16992/wsman</a:Address>
960 + <a:ReferenceParameters>
961 + <w:ResourceURI>http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpoint</w:ResourceURI>
962 + <w:SelectorSet>
963 + <w:Selector Name="Name">WiFi Endpoint 0</w:Selector>
964 + </w:SelectorSet>
965 + </a:ReferenceParameters>
966 + </r:WiFiEndpoint>
967 +
968 + */
969 + function referenceToXml(referenceName, inReference) {
970 + if (inReference === undefined || inReference === null) return null;
971 +
972 + var result = '<r:' + referenceName + '><a:Address>/wsman</a:Address><a:ReferenceParameters><w:ResourceURI>' + inReference['__resourceUri'] + '</w:ResourceURI><w:SelectorSet>';
973 + for (var selectorName in inReference) {
974 + if (!inReference.hasOwnProperty(selectorName) || selectorName.indexOf('__') === 0) continue;
975 +
976 + if (typeof inReference[selectorName] === 'function' ||
977 + typeof inReference[selectorName] === 'object' ||
978 + Array.isArray(inReference[selectorName]))
979 + continue;
980 +
981 + result += '<w:Selector Name="' + selectorName + '">' + inReference[selectorName].toString() + '</w:Selector>';
982 + }
983 +
984 + result += '</w:SelectorSet></a:ReferenceParameters></r:' + referenceName + '>';
985 + return result;
986 + }
987 +
988 + // Convert a byte array of SID into string
989 + function GetSidString(sid) {
990 + var r = "S-" + sid.charCodeAt(0) + "-" + sid.charCodeAt(7);
991 + for (var i = 2; i < (sid.length / 4); i++) r += "-" + ReadIntX(sid, i * 4);
992 + return r;
993 + }
994 +
995 + // Convert a SID readable string into bytes
996 + function GetSidByteArray(sidString) {
997 + if (!sidString || sidString == null) return null;
998 + var sidParts = sidString.split('-');
999 +
1000 + // Make sure the SID has at least 4 parts and starts with 'S'
1001 + if (sidParts.length < 4 || (sidParts[0] != 's' && sidParts[0] != 'S')) return null;
1002 +
1003 + // Check that each part of the SID is really an integer
1004 + for (var i = 1; i < sidParts.length; i++) { var y = parseInt(sidParts[i]); if (y != sidParts[i]) return null; sidParts[i] = y; }
1005 +
1006 + // 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.
1007 + var r = String.fromCharCode(sidParts[1]) + String.fromCharCode(sidParts.length - 3) + ShortToStr(Math.floor(sidParts[2] / Math.pow(2, 32))) + IntToStr((sidParts[2]) & 0xFFFF);
1008 +
1009 + // the rest are in 32 bit in little endian
1010 + for (var i = 3; i < sidParts.length; i++) r += IntToStrX(sidParts[i]);
1011 + return r;
1012 + }
1013 +
1014 + return obj;
1015 +}
1016 +
1017 +module.exports = AmtStackCreateService;
agents-new/modules_meshcore/linux-dbus.js new
+128
@@ -0,0 +1,128 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { }
18 +
19 +
20 +
21 +function dbus(address, uid)
22 +{
23 + this._ObjectID = 'linux-dbus';
24 + require('events').EventEmitter.call(this, true)
25 + .createEvent('signal');
26 + Object.defineProperty(this, "uid", { value: uid });
27 + this._child = require('child_process').execFile("/bin/sh", ["sh"], { type: require('child_process').SpawnTypes.TERM, uid: uid == null ? -1 : uid });
28 + this._child.stdin.write('dbus-monitor --session "type=\'signal\', interface=\'' + address + '\'" | ( while read X; do echo "$X"; done )\n');
29 + this._child.stdout.dbus = this;
30 + this._child.stdout.on('data', function (chunk)
31 + {
32 + // Parse DBUS Data
33 + if (!this.ready) { this.ready = true; return; }
34 +
35 + var lines = [];
36 + var tokens = chunk.toString().split('\r\n');
37 + for (var i in tokens)
38 + {
39 + if (tokens[i] == '')
40 + {
41 + // End of record
42 + this.dbus.preParseRecords(lines);
43 + lines = [];
44 + }
45 + else
46 + {
47 + lines.push(tokens[i]);
48 + }
49 + }
50 + });
51 + this.preParseRecords = function (lines)
52 + {
53 + var record = [];
54 + for (var i in lines)
55 + {
56 + if(lines[i].startsWith('signal '))
57 + {
58 + if(record.length>0)
59 + {
60 + this.parseRecords(record);
61 + }
62 + record = [];
63 + }
64 + record.push(lines[i]);
65 + }
66 + if (record.length > 0)
67 + {
68 + this.parseRecords(record);
69 + }
70 + }
71 + this.parseRecords = function (lines)
72 + {
73 + if (lines[0].startsWith('signal '))
74 + {
75 + var signal = {};
76 + var sigtokens = lines[0].split(' ');
77 + sigtokens.shift();
78 +
79 + for (var i in sigtokens) {
80 + var sigitems = sigtokens[i].split('=');
81 + if (sigitems.length == 2) {
82 + signal[sigitems[0]] = sigitems[1];
83 + }
84 + }
85 +
86 + lines.shift();
87 + signal.data = lines;
88 +
89 + this.parseSignal(signal);
90 + }
91 + }
92 + this.parseSignal = function(signal)
93 + {
94 + var data = signal.data;
95 + signal.data = [];
96 +
97 + for(var i=0; i<data.length; ++i)
98 + {
99 + if (data[i].startsWith('array '))
100 + {
101 + signal.data.push([]);
102 + for(i=i+1; i<data.length; ++i)
103 + {
104 + this.parseSignal2(data[i], signal.data.peek());
105 + }
106 + }
107 + else
108 + {
109 + this.parseSignal2(data[i], signal.data);
110 + }
111 + }
112 +
113 + this.emit('signal', signal);
114 + }
115 + this.parseSignal2 = function (inputStr, outArray)
116 + {
117 + if(inputStr.startsWith('string '))
118 + {
119 + outArray.push(JSON.parse(inputStr.slice(7)));
120 + }
121 + else if(inputStr.startsWith('boolean '))
122 + {
123 + outArray.push(JSON.parse(inputStr.slice(8)));
124 + }
125 + }
126 +}
127 +
128 +module.exports = dbus;
agents-new/modules_meshcore/monitor-border.js new
+335
@@ -0,0 +1,335 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var red = 0xFF;
18 +var yellow = 0xFFFF;
19 +var GXxor = 0x6; // src XOR dst
20 +var GXclear = 0x0;
21 +var ExposureMask = (1 << 15);
22 +
23 +function windows_monitorborder()
24 +{
25 + this._ObjectID = 'monitor-info';
26 + var info = require('monitor-info');
27 + var gm = require('_GenericMarshal');
28 + var user32 = gm.CreateNativeProxy('user32.dll');
29 +
30 + info.monitors = [];
31 + user32.CreateMethod('GetDC');
32 + user32.CreateMethod('ReleaseDC');
33 + user32.CreateMethod('FillRect');
34 + user32.CreateMethod('InvalidateRect');
35 +
36 + var gdi32 = gm.CreateNativeProxy('gdi32.dll');
37 + gdi32.CreateMethod('CreateSolidBrush');
38 +
39 + var redBrush = gdi32.CreateSolidBrush(red);
40 + var yellowBrush = gdi32.CreateSolidBrush(yellow);
41 +
42 + require('events').EventEmitter.call(this);
43 + this.on('~', function () { this.Stop(); });
44 +
45 + this.Stop = function Stop()
46 + {
47 + info.redInterval = null;
48 +
49 + var drawRect = gm.CreateVariable(16);
50 + var drawRectBuffer = drawRect.toBuffer();
51 +
52 + for (var i in info.monitors)
53 + {
54 + // Top
55 + drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
56 + drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
57 + drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left), 8);
58 + drawRectBuffer.writeInt32LE(info.monitors[i].bottom - info.monitors[i].top, 12);
59 + user32.InvalidateRect(0, drawRect, 0);
60 + }
61 + }
62 +
63 + this.Start = function Start()
64 + {
65 + info.getInfo().then(function (mon)
66 + {
67 + var drawRect = gm.CreateVariable(16);
68 +
69 + info.monitors = mon;
70 + info.dc = user32.GetDC(0);
71 + info.state = 0;
72 +
73 + info.redInterval = setInterval(function ()
74 + {
75 + info.state = (info.state + 1) % 8;
76 +
77 + var drawRectBuffer = drawRect.toBuffer();
78 + for(var i in info.monitors)
79 + {
80 + drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
81 + drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
82 + drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left)/2, 8);
83 + drawRectBuffer.writeInt32LE(5, 12);
84 + user32.FillRect(info.dc, drawRect, (info.state == 0 || info.state == 4) ? yellowBrush : redBrush);
85 + drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 0);
86 + drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
87 + drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
88 + drawRectBuffer.writeInt32LE(5, 12);
89 + user32.FillRect(info.dc, drawRect, (info.state == 1 || info.state == 5) ? yellowBrush : redBrush);
90 +
91 +
92 + drawRectBuffer.writeInt32LE(info.monitors[i].right - 5, 0);
93 + drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
94 + drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
95 + drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top)/2, 12);
96 + user32.FillRect(info.dc, drawRect, (info.state == 2 || info.state == 6) ? yellowBrush : redBrush);
97 + drawRectBuffer.writeInt32LE(info.monitors[i].right - 5, 0);
98 + drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 4);
99 + drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
100 + drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
101 + user32.FillRect(info.dc, drawRect, (info.state == 3 || info.state == 7) ? yellowBrush : redBrush);
102 +
103 +
104 + drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 0);
105 + drawRectBuffer.writeInt32LE(info.monitors[i].bottom - 5, 4);
106 + drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
107 + drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
108 + user32.FillRect(info.dc, drawRect, (info.state == 4 || info.state == 0) ? yellowBrush : redBrush);
109 + drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
110 + drawRectBuffer.writeInt32LE(info.monitors[i].bottom - 5, 4);
111 + drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 8);
112 + drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
113 + user32.FillRect(info.dc, drawRect, (info.state == 5 || info.state == 1) ? yellowBrush : redBrush);
114 +
115 +
116 + drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
117 + drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 4);
118 + drawRectBuffer.writeInt32LE(info.monitors[i].left + 5, 8);
119 + drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
120 + user32.FillRect(info.dc, drawRect, (info.state == 6 || info.state == 2) ? yellowBrush : redBrush);
121 + drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
122 + drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
123 + drawRectBuffer.writeInt32LE(info.monitors[i].left + 5, 8);
124 + drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 12);
125 + user32.FillRect(info.dc, drawRect, (info.state == 7 || info.state == 3) ? yellowBrush : redBrush);
126 + }
127 + }, 450);
128 + });
129 + }
130 +}
131 +
132 +function linux_monitorborder()
133 +{
134 + var self = this;
135 + this.displays = [];
136 + this._ObjectID = 'monitor-info';
137 + this._info = require('monitor-info');
138 + this._isUnity = this._info.isUnity();
139 +
140 + console.log('isUnity = ' + this._isUnity);
141 +
142 + require('events').EventEmitter.call(this);
143 + this.on('~', function () { this.Stop(); });
144 +
145 + this.Stop = function Stop()
146 + {
147 + this._timeout = null;
148 + if(!this._isUnity)
149 + {
150 + for(var i=0; i < this.displays.length; ++i)
151 + {
152 + if(this.displays[i].GC1 && this.displays[i].rootWindow)
153 + {
154 + self._info._X11.XSetFunction(self.displays[i].display, self.displays[i].GC1, GXclear);
155 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, self.displays[i].right, 0);
156 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right, 0, self.displays[i].right, self.displays[i].bottom);
157 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, self.displays[i].bottom, self.displays[i].right, self.displays[i].bottom);
158 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, 0, self.displays[i].bottom);
159 +
160 + this._info._X11.XFlush(this.displays[i].display);
161 + }
162 + }
163 + }
164 + }
165 + this.Start = function Start()
166 + {
167 + this._info.getInfo().then(function (mon)
168 + {
169 + self.displays = mon;
170 + console.log(mon.length + ' displays');
171 + for(var i = 0; i<mon.length; ++i)
172 + {
173 + console.log('Width: ' + mon[i].right + ', Height: ' + mon[i].bottom);
174 + mon[i].rootWindow = self._info._X11.XRootWindow(mon[i].display, mon[i].screenId);
175 +
176 + if (self._isUnity)
177 + {
178 + // We are unity, so we have to fake the borders with borderless windows
179 + var white = self._info._X11.XWhitePixel(mon[i].display, mon[i].screenId).Val;
180 +
181 + // Top
182 + mon[i].window_top = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, 0, 0, mon[i].right, 5, 0, white, white);
183 + mon[i].window_top.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_top, 0, 0);
184 + self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_top.gc, 10, 0, 1, 1);
185 + self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_top.gc, 1);
186 + self._info.unDecorateWindow(mon[i].display, mon[i].window_top);
187 + self._info.setWindowSizeHints(mon[i].display, mon[i].window_top, 0, 0, mon[i].right, 5);
188 +
189 + // Right
190 + mon[i].window_right = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, mon[i].right - 5, 0, 5, mon[i].bottom, 0, white, white);
191 + mon[i].window_right.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_right, 0, 0);
192 + self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_right.gc, 10, 0, 1, 1);
193 + self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_right.gc, 1);
194 + self._info.unDecorateWindow(mon[i].display, mon[i].window_right);
195 + self._info.setWindowSizeHints(mon[i].display, mon[i].window_right, mon[i].right - 5, 0, 5, mon[i].bottom);
196 +
197 + // Left
198 + mon[i].window_left = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, 0, 0, 5, mon[i].bottom, 0, white, white);
199 + mon[i].window_left.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_left, 0, 0);
200 + self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_left.gc, 10, 0, 1, 1);
201 + self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_left.gc, 1);
202 + self._info.unDecorateWindow(mon[i].display, mon[i].window_left);
203 + self._info.setWindowSizeHints(mon[i].display, mon[i].window_left, 0, 0, 5, mon[i].bottom);
204 +
205 + // Bottom
206 + mon[i].window_bottom = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, 0, mon[i].bottom - 5, mon[i].right, 5, 0, white, white);
207 + mon[i].window_bottom.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_bottom, 0, 0);
208 + self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_bottom.gc, 10, 0, 1, 1);
209 + self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_bottom.gc, 1);
210 + self._info.unDecorateWindow(mon[i].display, mon[i].window_bottom);
211 + self._info.setWindowSizeHints(mon[i].display, mon[i].window_bottom, 0, mon[i].bottom - 5, mon[i].right, 5);
212 +
213 + self._info._X11.XMapWindow(mon[i].display, mon[i].window_top);
214 + self._info._X11.XMapWindow(mon[i].display, mon[i].window_right);
215 + self._info._X11.XMapWindow(mon[i].display, mon[i].window_left);
216 + self._info._X11.XMapWindow(mon[i].display, mon[i].window_bottom);
217 +
218 + self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_top);
219 + self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_top);
220 + self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_right);
221 + self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_right);
222 + self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_left);
223 + self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_left);
224 + self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_bottom);
225 + self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_bottom);
226 +
227 + self._info._X11.XFlush(mon[i].display);
228 + mon[i].borderState = 0;
229 + }
230 + else
231 + {
232 + // If we aren't unity, then we can just draw
233 + mon[i].GC1 = self._info._X11.XCreateGC(mon[i].display, mon[i].rootWindow, 0, 0);
234 + mon[i].borderState = 0;
235 +
236 + self._info._X11.XSetForeground(mon[i].display, mon[i].GC1, self._info._X11.XWhitePixel(mon[i].display, mon[i].screenId).Val); // White
237 + self._info._X11.XSetLineAttributes(mon[i].display, mon[i].GC1, 10, 0, 1, 1);
238 + self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].GC1, 1);
239 + }
240 + }
241 + self._info._XEvent = self._info._gm.CreateVariable(192);
242 + self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 250);
243 + });
244 + }
245 +
246 + this.timeoutHandler = function()
247 + {
248 + for (var i = 0; i < self.displays.length; ++i) {
249 + self.displays[i].borderState = (self.displays[i].borderState + 1) % 8;
250 +
251 + // Top
252 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 0 || self.displays[i].borderState == 4) ? 0xffff00 : 0xff0000);
253 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, self.displays[i].right / 2, 0);
254 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 1 || self.displays[i].borderState == 5) ? 0xffff00 : 0xff0000);
255 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right / 2, 0, self.displays[i].right, 0);
256 +
257 + // Right
258 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 2 || self.displays[i].borderState == 6) ? 0xffff00 : 0xff0000);
259 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right, 0, self.displays[i].right, self.displays[i].bottom / 2);
260 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 3 || self.displays[i].borderState == 7) ? 0xffff00 : 0xff0000);
261 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right, self.displays[i].bottom / 2, self.displays[i].right, self.displays[i].bottom);
262 +
263 + // Bottom
264 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 5 || self.displays[i].borderState == 1) ? 0xffff00 : 0xff0000);
265 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, self.displays[i].bottom, self.displays[i].right / 2, self.displays[i].bottom);
266 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 4 || self.displays[i].borderState == 0) ? 0xffff00 : 0xff0000);
267 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right / 2, self.displays[i].bottom, self.displays[i].right, self.displays[i].bottom);
268 +
269 + // Left
270 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 7 || self.displays[i].borderState == 3) ? 0xffff00 : 0xff0000);
271 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, 0, self.displays[i].bottom / 2);
272 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 6 || self.displays[i].borderState == 2) ? 0xffff00 : 0xff0000);
273 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, self.displays[i].bottom / 2, 0, self.displays[i].bottom);
274 +
275 +
276 + self._info._X11.XFlush(self.displays[i].display);
277 + }
278 + self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 400);
279 + }
280 + this.unity_drawBorder = function unity_drawBorder()
281 + {
282 + for (var i = 0; i < self.displays.length; ++i)
283 + {
284 + self.displays[i].borderState = (self.displays[i].borderState + 1) % 8;
285 +
286 + // Top
287 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_top.gc, (self.displays[i].borderState == 0 || self.displays[i].borderState == 4) ? 0xffff00 : 0xff0000);
288 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_top, self.displays[i].window_top.gc, 0, 0, self.displays[i].right / 2, 0);
289 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_top.gc, (self.displays[i].borderState == 1 || self.displays[i].borderState == 5) ? 0xffff00 : 0xff0000);
290 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_top, self.displays[i].window_top.gc, self.displays[i].right / 2, 0, self.displays[i].right, 0);
291 + self._info._X11.XFlush(self.displays[i].display);
292 +
293 + // Right
294 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_right.gc, (self.displays[i].borderState == 2 || self.displays[i].borderState == 6) ? 0xffff00 : 0xff0000);
295 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_right, self.displays[i].window_right.gc, 0, 0, 0, self.displays[i].bottom / 2);
296 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_right.gc, (self.displays[i].borderState == 3 || self.displays[i].borderState == 7) ? 0xffff00 : 0xff0000);
297 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_right, self.displays[i].window_right.gc, 0, self.displays[i].bottom / 2, 0, self.displays[i].bottom);
298 + self._info._X11.XFlush(self.displays[i].display);
299 +
300 + // Bottom
301 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_bottom.gc, (self.displays[i].borderState == 5 || self.displays[i].borderState == 1) ? 0xffff00 : 0xff0000);
302 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_bottom, self.displays[i].window_bottom.gc, 0, 0, self.displays[i].right / 2, 0);
303 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_bottom.gc, (self.displays[i].borderState == 4 || self.displays[i].borderState == 0) ? 0xffff00 : 0xff0000);
304 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_bottom, self.displays[i].window_bottom.gc, self.displays[i].right / 2, 0, self.displays[i].right, 0);
305 + self._info._X11.XFlush(self.displays[i].display);
306 +
307 + // Left
308 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_left.gc, (self.displays[i].borderState == 7 || self.displays[i].borderState == 3) ? 0xffff00 : 0xff0000);
309 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_left, self.displays[i].window_left.gc, 0, 0, 0, self.displays[i].bottom / 2);
310 + self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_left.gc, (self.displays[i].borderState == 6 || self.displays[i].borderState == 2) ? 0xffff00 : 0xff0000);
311 + self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_left, self.displays[i].window_left.gc, 0, self.displays[i].bottom / 2, 0, self.displays[i].bottom);
312 + self._info._X11.XFlush(self.displays[i].display);
313 + }
314 + self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 400);
315 + }
316 +}
317 +
318 +switch(process.platform)
319 +{
320 + case 'win32':
321 + module.exports = new windows_monitorborder();
322 + break;
323 + case 'linux':
324 + module.exports = new linux_monitorborder();
325 + break;
326 + default:
327 + break;
328 +}
329 +
330 +
331 +
332 +
333 +
334 +
335 +
agents-new/modules_meshcore/power-monitor.js new
+34
@@ -0,0 +1,34 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +function powerMonitor()
18 +{
19 + this._ObjectID = 'power-monitor';
20 + require('events').EventEmitter.call(this, true)
21 + .createEvent('changed')
22 + .createEvent('sx')
23 + .createEvent('batteryLevel')
24 + .createEvent('acdc')
25 + .createEvent('display');
26 +
27 + this._i = setImmediate(function (self)
28 + {
29 + require('user-sessions'); // This is needed because this is where the Windows Messages are processed for these events
30 + delete self._i;
31 + }, this);
32 +}
33 +
34 +module.exports = new powerMonitor();
\ No newline at end of file
agents-new/modules_meshcore/smbios.js new
+343
@@ -0,0 +1,343 @@
1 +/*
2 +Copyright 2018 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { }
18 +try { Object.defineProperty(String.prototype, "replaceAll", { value: function replaceAll(oldVal, newVal) { return (this.split(oldVal).join(newVal)); } }); } catch (e) { }
19 +
20 +var RSMB = 1381190978;
21 +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' };
22 +var wakeReason = ['Reserved', 'Other', 'Unknown', 'APM Timer', 'Modem Ring', 'LAN', 'Power Switch', 'PCI', 'AC Power'];
23 +
24 +// Fill the left with zeros until the string is of a given length
25 +function zeroLeftPad(str, len)
26 +{
27 + if ((len == null) && (typeof (len) != 'number')) { return null; }
28 + if (str == null) str = ''; // If null, this is to generate zero leftpad string
29 + var zlp = '';
30 + for (var i = 0; i < len - str.length; i++) { zlp += '0'; }
31 + return zlp + str;
32 +}
33 +
34 +function SMBiosTables()
35 +{
36 + this._ObjectID = 'SMBiosTable';
37 + if (process.platform == 'win32') {
38 + this._marshal = require('_GenericMarshal');
39 + this._native = this._marshal.CreateNativeProxy("Kernel32.dll");
40 +
41 + this._native.CreateMethod('EnumSystemFirmwareTables');
42 + this._native.CreateMethod('GetSystemFirmwareTable');
43 + }
44 + if (process.platform == 'linux') {
45 + this._canonicalizeData = function _canonicalizeData(data) {
46 + var lines = data.toString().split('Header and Data:\x0A');
47 + var MemoryStream = require('MemoryStream');
48 + var ms = new MemoryStream();
49 +
50 + for (var i = 1; i < lines.length; ++i) {
51 + var tokens = lines[i].split('Strings:\x0A');
52 + var header = tokens[0].split('\x0A\x0A')[0].replaceAll('\x0A', '').trim().replaceAll(' ', '').replaceAll('\x09', '');
53 + ms.write(Buffer.from(header, 'hex'));
54 + if (tokens.length > 1) {
55 + var strings = tokens[1].split('\x0A\x0A')[0].split('\x0A');
56 + var stringsFinal = [];
57 + for (var strx in strings) {
58 + var tmp = strings[strx].trim().replaceAll(' ', '').replaceAll('\x09', '');
59 + if (!(tmp[0] == '"')) { stringsFinal.push(tmp); }
60 + }
61 + ms.write(Buffer.from(stringsFinal.join(''), 'hex'));
62 + ms.write(Buffer.from('00', 'hex'));
63 + }
64 + else {
65 + ms.write(Buffer.from('0000', 'hex'));
66 + }
67 + }
68 + var retVal = ms.buffer;
69 + retVal.ms = ms;
70 + return (retVal);
71 + };
72 + }
73 + this._parse = function _parse(SMData) {
74 + var ret = {};
75 + var pbyte;
76 + var i = 0
77 + var SMData;
78 + var structcount = 0;
79 +
80 + while (SMData && i < SMData.length)
81 + {
82 + var SMtype = SMData[i];
83 + var SMlength = SMData[i + 1];
84 +
85 + if (!ret[SMtype]) { ret[SMtype] = []; }
86 + ret[SMtype].push(SMData.slice(i + 4, i + SMlength));
87 + if (process.platform == 'win32') { ret[SMtype].peek()._ext = pbyte; }
88 + i += SMlength;
89 +
90 + ret[SMtype].peek()._strings = [];
91 +
92 + while (SMData[i] != 0 && i <= SMData.length)
93 + {
94 + var strstart = i;
95 +
96 + // Start of String, find end of string
97 + while (SMData[i++] != 0 && i <= SMData.length);
98 + try
99 + {
100 + ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim());
101 + }
102 + catch (ee)
103 + {
104 + console.log('oops');
105 + }
106 + }
107 + i += (ret[SMtype].peek()._strings.length == 0) ? 2 : 1;
108 + ++structcount;
109 + //console.log('End of Table[' + SMtype + ']: ' + i);
110 + }
111 + //console.log('Struct Count = ' + structcount);
112 + return (ret);
113 + };
114 + this.get = function get(callback) {
115 + if (process.platform == 'win32') {
116 + var size = this._native.GetSystemFirmwareTable(RSMB, 0, 0, 0).Val;
117 + //console.log('Table Size: ' + size);
118 +
119 + var PtrSize = this._marshal.CreatePointer()._size;
120 + var buffer = this._marshal.CreateVariable(size);
121 + var written = this._native.GetSystemFirmwareTable(RSMB, 0, buffer, size).Val;
122 + //console.log('Written Size: ' + written);
123 +
124 + var rawBuffer = buffer.toBuffer();
125 + var length = buffer.Deref(4, 4).toBuffer().readUInt32LE(0);
126 +
127 + pbyte = buffer.Deref(8, length);
128 + SMData = pbyte.toBuffer();
129 +
130 + if (callback) { callback.apply(this, [this._parse(SMData)]); return; } else { return (this._parse(SMData)); }
131 + }
132 + if (process.platform == 'linux') {
133 + var MemoryStream = require('MemoryStream');
134 + this.child = require('child_process').execFile('/usr/sbin/dmidecode', ['dmidecode', '-u']);
135 + this.child.SMBiosTable = this;
136 + this.child.ms = new MemoryStream();
137 + this.child.ms.callback = callback;
138 + this.child.ms.child = this.child;
139 + this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); });
140 + this.child.on('exit', function () { this.ms.end(); });
141 + this.child.ms.on('end', function () {
142 + //console.log('read ' + this.buffer.length + ' bytes');
143 + if (this.buffer.length < 300) {
144 + //console.log('Not enough permission to read SMBiosTable');
145 + if (this.callback) { this.callback.apply(this.child.SMBiosTable, []); }
146 + }
147 + else {
148 + var SMData = this.child.SMBiosTable._canonicalizeData(this.buffer);
149 + var j = this.child.SMBiosTable._parse(SMData);
150 + if (this.callback) { this.callback.apply(this.child.SMBiosTable, [j]); }
151 + }
152 + });
153 + return;
154 + }
155 + if (callback) { callback.apply(this, [null]); return; } else { return (null); }
156 + };
157 + this.parse = function parse(data) {
158 + var r = {};
159 + try
160 + {
161 + r.processorInfo = this.processorInfo(data);
162 + }
163 + catch(e)
164 + {
165 + }
166 + try
167 + {
168 + r.memoryInfo = this.memoryInfo(data);
169 + }
170 + catch(e)
171 + {
172 + }
173 + try
174 + {
175 + r.systemInfo = this.systemInfo(data);
176 + }
177 + catch(e)
178 + {
179 + }
180 + try
181 + {
182 + r.systemSlots = this.systemInfo(data);
183 + }
184 + catch(e)
185 + {
186 + }
187 + try
188 + {
189 + r.amtInfo = this.amtInfo(data);
190 + }
191 + catch(e)
192 + {
193 + }
194 + return r;
195 + }
196 + this.processorInfo = function processorInfo(data) {
197 + if (!data) { throw ('no data'); }
198 + var ret = [];
199 + var ptype = ['ERROR', 'Other', 'Unknown', 'CPU', 'ALU', 'DSP', 'GPU'];
200 + var statusString = ['Unknown', 'Enabled', 'Disabled by user', 'Disabled by BIOS', 'Idle', 'Reserved', 'Reserved', 'Other'];
201 + var cpuid = 0;
202 + while (data[4] && data[4].length > 0) {
203 + var p = data[4].pop();
204 + var populated = p[20] & 0x40;
205 + var status = p[20] & 0x07
206 + if (populated) {
207 + var j = { _ObjectID: 'SMBiosTables.processorInfo' };
208 + j.Processor = ptype[p[1]];
209 + j.MaxSpeed = p.readUInt16LE(16) + ' Mhz';
210 + if (p[31]) { j.Cores = p[31]; }
211 + if (p[33]) { j.Threads = p[33]; }
212 + j.Populated = 1;
213 + j.Status = statusString[status];
214 + j.Socket = p._strings[p[0] - 1];
215 + j.Manufacturer = p._strings[p[3] - 1];
216 + j.Version = p._strings[p[12] - 1];
217 + ret.push(j);
218 + }
219 + }
220 + return (ret);
221 + };
222 + this.memoryInfo = function memoryInfo(data) {
223 + if (!data) { throw ('no data'); }
224 + var retVal = { _ObjectID: 'SMBiosTables.memoryInfo' };
225 + if (data[16]) {
226 + var m = data[16].peek();
227 + retVal.location = memoryLocation[m[0]];
228 + if ((retVal.maxCapacityKb = m.readUInt32LE(3)) == 0x80000000) {
229 + retVal.maxCapacityKb = 'A really big number';
230 + }
231 + }
232 + return (retVal);
233 + };
234 + this.systemInfo = function systemInfo(data)
235 + {
236 + if (!data) { throw ('no data'); }
237 + var retVal = { _ObjectID: 'SMBiosTables.systemInfo' };
238 + if (data[1])
239 + {
240 + var si = data[1].peek();
241 + var uuid = si.slice(4, 20);
242 +
243 + retVal.uuid = [zeroLeftPad(uuid.readUInt32LE(0).toString(16), 8),
244 + zeroLeftPad(uuid.readUInt16LE(4).toString(16), 4),
245 + zeroLeftPad(uuid.readUInt16LE(6).toString(16), 4),
246 + zeroLeftPad(uuid.readUInt16BE(8).toString(16), 4),
247 + zeroLeftPad(uuid.slice(10).toString('hex').toLowerCase(), 12)].join('-');
248 +
249 + retVal.wakeReason = wakeReason[si[20]];
250 + }
251 + return (retVal);
252 + };
253 + this.systemSlots = function systemSlots(data) {
254 + if (!data) { throw ('no data'); }
255 + var retVal = [];
256 + if (data[9]) {
257 + while (data[9].length > 0) {
258 + var ss = data[9].pop();
259 + retVal.push({ name: ss._strings[ss[0] - 1] });
260 + }
261 + }
262 + return (retVal);
263 + };
264 + this.amtInfo = function amtInfo(data) {
265 + if (!data) { throw ('no data'); }
266 + var retVal = { AMT: false };
267 + if (data[130] && data[130].peek().slice(0, 4).toString() == '$AMT') {
268 + var amt = data[130].peek();
269 + retVal.AMT = amt[4] ? true : false;
270 + if (retVal.AMT) {
271 + retVal.enabled = amt[5] ? true : false;
272 + retVal.storageRedirection = amt[6] ? true : false;
273 + retVal.serialOverLan = amt[7] ? true : false;
274 + retVal.kvm = amt[14] ? true : false;
275 + if (data[131].peek() && data[131].peek().slice(52, 56).toString() == 'vPro') {
276 + var settings = data[131].peek();
277 + if (settings[0] & 0x04) { retVal.TXT = (settings[0] & 0x08) ? true : false; }
278 + if (settings[0] & 0x10) { retVal.VMX = (settings[0] & 0x20) ? true : false; }
279 + retVal.MEBX = settings.readUInt16LE(10).toString() + '.' + settings.readUInt16LE(8).toString() + '.' + settings.readUInt16LE(6).toString() + '.' + settings.readUInt16LE(4).toString();
280 +
281 + var mecap = settings.slice(20, 32);
282 + retVal.ManagementEngine = mecap.readUInt16LE(6).toString() + '.' + mecap.readUInt16LE(4).toString() + '.' + mecap.readUInt16LE(2).toString() + '.' + mecap.readUInt16LE(0).toString();
283 +
284 + //var lan = settings.slice(36, 48);
285 + //console.log(lan.toString('hex'));
286 + //retVal.LAN = (lan.readUInt16LE(10) & 0x03).toString() + '/' + ((lan.readUInt16LE(10) & 0xF8) >> 3).toString();
287 +
288 + //console.log(lan.readUInt16LE(3));
289 + //retVal.WLAN = (lan.readUInt16LE(3) & 0x07).toString() + '/' + ((lan.readUInt16LE(3) & 0xF8) >> 3).toString() + '/' + (lan.readUInt16LE(3) >> 8).toString();
290 + }
291 + }
292 + }
293 + return (retVal);
294 + };
295 + this.smTableTypes = {
296 + 0: 'BIOS information',
297 + 1: 'System information',
298 + 2: 'Baseboard (or Module) information',
299 + 4: 'Processor information',
300 + 5: 'memory controller information',
301 + 6: 'Memory module information',
302 + 7: 'Cache information',
303 + 8: 'Port connector information',
304 + 9: 'System slots',
305 + 10: 'On board devices information',
306 + 11: 'OEM strings',
307 + 12: 'System configuration options',
308 + 13: 'BIOS language information',
309 + 14: 'Group associations',
310 + 15: 'System event log',
311 + 16: 'Physical memory array',
312 + 17: 'Memory device',
313 + 18: '32bit memory error information',
314 + 19: 'Memory array mapped address',
315 + 20: 'Memory device mapped address',
316 + 21: 'Built-in pointing device',
317 + 22: 'Portable battery',
318 + 23: 'System reset',
319 + 24: 'Hardware security',
320 + 25: 'System power controls',
321 + 26: 'Voltage probe',
322 + 27: 'Cooling device',
323 + 28: 'Temperature probe',
324 + 29: 'Electrical current probe',
325 + 30: 'Out-of-band remote access',
326 + 31: 'Boot integrity services (BIS) entry point',
327 + 32: 'System boot information',
328 + 33: '64bit memory error information',
329 + 34: 'Management device',
330 + 35: 'Management device component',
331 + 36: 'Management device threshold data',
332 + 37: 'Memory channel',
333 + 38: 'IPMI device information',
334 + 39: 'System power supply',
335 + 40: 'Additional information',
336 + 41: 'Onboard devices extended information',
337 + 42: 'Management controller host interface',
338 + 126: 'Inactive',
339 + 127: 'End-of-table'
340 + }
341 +}
342 +
343 +module.exports = new SMBiosTables();
\ No newline at end of file
agents-new/modules_meshcore/toaster.js new
+125
@@ -0,0 +1,125 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var toasters = {};
18 +
19 +function Toaster()
20 +{
21 + this._ObjectID = 'toaster';
22 + this.Toast = function Toast(title, caption)
23 + {
24 + var retVal = {};
25 + var emitter = require('events').inherits(retVal);
26 + emitter.createEvent('Dismissed');
27 +
28 + retVal.title = title;
29 + retVal.caption = caption;
30 +
31 + if (process.platform == 'win32')
32 + {
33 + emitter.createEvent('Clicked');
34 +
35 + var session = require('user-sessions').Current();
36 + for (var i in session) {
37 + console.log(session[i]);
38 + }
39 + try {
40 + console.log('Attempting Toast Mechanism 1');
41 + retVal._child = require('ScriptContainer').Create({ processIsolation: true, sessionId: session.Active[0].SessionId });
42 + }
43 + catch (e) {
44 + console.log(e);
45 + console.log('Attempting Toast Mechanism 2');
46 + retVal._child = require('ScriptContainer').Create({ processIsolation: true });
47 + }
48 + retVal._child.parent = retVal;
49 +
50 + retVal._child.on('exit', function (code) { this.parent.emit('Dismissed'); delete this.parent._child; });
51 + retVal._child.addModule('win-console', getJSModule('win-console'));
52 + retVal._child.addModule('win-message-pump', getJSModule('win-message-pump'));
53 +
54 + var str = "\
55 + try{\
56 + var toast = require('win-console');\
57 + var balloon = toast.SetTrayIcon({ szInfo: '" + caption + "', szInfoTitle: '" + title + "', balloonOnly: true });\
58 + balloon.on('ToastDismissed', function(){process.exit();});\
59 + }\
60 + catch(e)\
61 + {\
62 + require('ScriptContainer').send(e);\
63 + }\
64 + require('ScriptContainer').send('done');\
65 + ";
66 + retVal._child.ExecuteString(str);
67 + toasters[retVal._hashCode()] = retVal;
68 + retVal.on('Dismissed', function () { delete toasters[this._hashCode()]; });
69 + console.log('Returning');
70 + return (retVal);
71 + }
72 + else
73 + {
74 + if(!require('fs').existsSync('/usr/bin/notify-send'))
75 + {
76 + throw ('Toast not supported on this platform');
77 + }
78 + Object.defineProperty(retVal, '_sessions', {
79 + value: require('user-sessions').Current(function onCurrentSession(sessions)
80 + {
81 + this._cchild = require('child_process').execFile('/usr/bin/whoami', ['whoami'], { type: require('child_process').SpawnTypes.TERM });
82 + this._cchild.stdout.on('data', function (chunk)
83 + {
84 + if (chunk.toString().split('\r\n')[0] == 'root')
85 + {
86 + if (sessions[':0'].State != 'Connected' && sessions[':0'].State != 'Active')
87 + {
88 + // No logged in user owns the display
89 + this.parent.parent.Parent.emit('Dismissed');
90 + return;
91 + }
92 +
93 + // We root, so we need to direct to DISPLAY=:0
94 + this.parent.parent._notify = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
95 + 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');
96 + this.parent.parent._notify.stdin.write('exit\n');
97 + this.parent.parent._notify.stdout.on('data', function (chunk) { });
98 + }
99 + else
100 + {
101 + // We ain't root, so that means we can just call send-notify directly
102 + 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 });
103 + this.parent.parent._notify.stdout.on('data', function (chunk) { });
104 + }
105 +
106 + // NOTIFY-SEND has a bug where timeouts don't work, so the default is 10 seconds
107 + this.parent.parent.Parent._timeout = setTimeout(function onFakeDismissed(obj)
108 + {
109 + obj.emit('Dismissed');
110 + }, 10000, this.parent.parent.Parent);
111 + });
112 + this._cchild.parent = this;
113 + })
114 + });
115 + retVal._sessions.Parent = retVal;
116 +
117 + toasters[retVal._hashCode()] = retVal;
118 + retVal.on('Dismissed', function () { delete toasters[this._hashCode()]; });
119 +
120 + return (retVal);
121 + }
122 + };
123 +}
124 +
125 +module.exports = new Toaster();
\ No newline at end of file
agents-new/modules_meshcore/wifi-scanner-windows.js new
+170
@@ -0,0 +1,170 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +function _Scan()
18 +{
19 + var wlanInterfaces = this.Marshal.CreatePointer();
20 + this.Native.WlanEnumInterfaces(this.Handle, 0, wlanInterfaces);
21 +
22 + var count = wlanInterfaces.Deref().Deref(0, 4).toBuffer().readUInt32LE(0);
23 +
24 + var info = wlanInterfaces.Deref().Deref(8, 532);
25 + var iname = info.Deref(16, 512).AnsiString;
26 +
27 + var istate;
28 + switch (info.Deref(528, 4).toBuffer().readUInt32LE(0))
29 + {
30 + case 0:
31 + istate = "NOT READY";
32 + break;
33 + case 1:
34 + istate = "CONNECTED";
35 + break;
36 + case 2:
37 + istate = "AD-HOC";
38 + break;
39 + case 3:
40 + istate = "DISCONNECTING";
41 + break;
42 + case 4:
43 + istate = "DISCONNECTED";
44 + break;
45 + case 5:
46 + istate = "ASSOCIATING";
47 + break;
48 + case 6:
49 + istate = "DISCOVERING";
50 + break;
51 + case 7:
52 + istate = "AUTHENTICATING";
53 + break;
54 + default:
55 + istate = "UNKNOWN";
56 + break;
57 + }
58 +
59 + var iguid = info.Deref(0, 16);
60 + if (this.Native.WlanScan(this.Handle, iguid, 0, 0, 0).Val == 0)
61 + {
62 + return (true);
63 + }
64 + else
65 + {
66 + return (false);
67 + }
68 +}
69 +
70 +function AccessPoint(_ssid, _bssid, _rssi, _lq)
71 +{
72 + this.ssid = _ssid;
73 + this.bssid = _bssid;
74 + this.rssi = _rssi;
75 + this.lq = _lq;
76 +}
77 +AccessPoint.prototype.toString = function()
78 +{
79 + return (this.ssid + " [" + this.bssid + "]: " + this.lq);
80 +}
81 +
82 +function OnNotify(NotificationData)
83 +{
84 + var NotificationSource = NotificationData.Deref(0, 4).toBuffer().readUInt32LE(0);
85 + var NotificationCode = NotificationData.Deref(4, 4).toBuffer().readUInt32LE(0);
86 + var dataGuid = NotificationData.Deref(8, 16);
87 +
88 + if ((NotificationSource & 0X00000008) && (NotificationCode == 7))
89 + {
90 + var bss = this.Parent.Marshal.CreatePointer();
91 + var result = this.Parent.Native.GetBSSList(this.Parent.Handle, dataGuid, 0, 3, 0, 0, bss).Val;
92 + if (result == 0)
93 + {
94 + var totalSize = bss.Deref().Deref(0, 4).toBuffer().readUInt32LE(0);
95 + var numItems = bss.Deref().Deref(4, 4).toBuffer().readUInt32LE(0);
96 + for (i = 0; i < numItems; ++i)
97 + {
98 + var item = bss.Deref().Deref(8 + (360 * i), 360);
99 + var ssid = item.Deref(4, 32).String.trim();
100 + var bssid = item.Deref(40, 6).HexString2;
101 + var rssi = item.Deref(56, 4).toBuffer().readUInt32LE(0);
102 + var lq = item.Deref(60, 4).toBuffer().readUInt32LE(0);
103 +
104 + this.Parent.emit('Scan', new AccessPoint(ssid, bssid, rssi, lq));
105 + }
106 + }
107 +
108 + }
109 +}
110 +
111 +function Wireless()
112 +{
113 + var emitterUtils = require('events').inherits(this);
114 +
115 + this.Marshal = require('_GenericMarshal');
116 + this.Native = this.Marshal.CreateNativeProxy("wlanapi.dll");
117 + this.Native.CreateMethod("WlanOpenHandle");
118 + this.Native.CreateMethod("WlanGetNetworkBssList", "GetBSSList");
119 + this.Native.CreateMethod("WlanRegisterNotification");
120 + this.Native.CreateMethod("WlanEnumInterfaces");
121 + this.Native.CreateMethod("WlanScan");
122 + this.Native.CreateMethod("WlanQueryInterface");
123 +
124 + var negotiated = this.Marshal.CreatePointer();
125 + var h = this.Marshal.CreatePointer();
126 +
127 + this.Native.WlanOpenHandle(2, 0, negotiated, h);
128 + this.Handle = h.Deref();
129 +
130 + this._NOTIFY_PROXY_OBJECT = this.Marshal.CreateCallbackProxy(OnNotify, 2);
131 + this._NOTIFY_PROXY_OBJECT.Parent = this;
132 + var PrevSource = this.Marshal.CreatePointer();
133 + var result = this.Native.WlanRegisterNotification(this.Handle, 0X0000FFFF, 0, this._NOTIFY_PROXY_OBJECT.Callback, this._NOTIFY_PROXY_OBJECT.State, 0, PrevSource);
134 +
135 + emitterUtils.createEvent('Scan');
136 + emitterUtils.addMethod('Scan', _Scan);
137 +
138 + this.GetConnectedNetwork = function ()
139 + {
140 + var interfaces = this.Marshal.CreatePointer();
141 +
142 + console.log('Success = ' + this.Native.WlanEnumInterfaces(this.Handle, 0, interfaces).Val);
143 + var count = interfaces.Deref().Deref(0, 4).toBuffer().readUInt32LE(0);
144 + var info = interfaces.Deref().Deref(8, 532);
145 + var iname = info.Deref(16, 512).AnsiString;
146 + var istate = info.Deref(528, 4).toBuffer().readUInt32LE(0);
147 + if(info.Deref(528, 4).toBuffer().readUInt32LE(0) == 1) // CONNECTED
148 + {
149 + var dataSize = this.Marshal.CreatePointer();
150 + var pData = this.Marshal.CreatePointer();
151 + var valueType = this.Marshal.CreatePointer();
152 + var iguid = info.Deref(0, 16);
153 + var retVal = this.Native.WlanQueryInterface(this.Handle, iguid, 7, 0, dataSize, pData, valueType).Val;
154 + if (retVal == 0)
155 + {
156 + var associatedSSID = pData.Deref().Deref(524, 32).String;
157 + var bssid = pData.Deref().Deref(560, 6).HexString;
158 + var lq = pData.Deref().Deref(576, 4).toBuffer().readUInt32LE(0);
159 +
160 + return (new AccessPoint(associatedSSID, bssid, 0, lq));
161 + }
162 + }
163 + throw ("GetConnectedNetworks: FAILED (not associated to a network)");
164 + };
165 +
166 +
167 + return (this);
168 +}
169 +
170 +module.exports = new Wireless();
agents-new/modules_meshcore/wifi-scanner.js new
+127
@@ -0,0 +1,127 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var MemoryStream = require('MemoryStream');
18 +var WindowsChildScript = 'var parent = require("ScriptContainer");var Wireless = require("wifi-scanner-windows");Wireless.on("Scan", function (ap) { parent.send(ap); });Wireless.Scan();';
19 +
20 +
21 +function AccessPoint(_ssid, _bssid, _lq)
22 +{
23 + this.ssid = _ssid;
24 + this.bssid = _bssid;
25 + this.lq = _lq;
26 +}
27 +AccessPoint.prototype.toString = function ()
28 +{
29 + return ("[" + this.bssid + "]: " + this.ssid + " (" + this.lq + ")");
30 + //return (this.ssid + " [" + this.bssid + "]: " + this.lq);
31 +}
32 +
33 +function WiFiScanner()
34 +{
35 + var emitterUtils = require('events').inherits(this);
36 + emitterUtils.createEvent('accessPoint');
37 +
38 + this.hasWireless = function ()
39 + {
40 + var retVal = false;
41 + var interfaces = require('os').networkInterfaces();
42 + for (var name in interfaces)
43 + {
44 + if (interfaces[name][0].type == 'wireless') { retVal = true; break; }
45 + }
46 + return (retVal);
47 + };
48 +
49 + this.Scan = function ()
50 + {
51 + if (process.platform == 'win32')
52 + {
53 + this.master = require('ScriptContainer').Create(15, ContainerPermissions.DEFAULT);
54 + this.master.parent = this;
55 + this.master.on('data', function (j) { this.parent.emit('accessPoint', new AccessPoint(j.ssid, j.bssid, j.lq)); });
56 +
57 + this.master.addModule('wifi-scanner-windows', getJSModule('wifi-scanner-windows'));
58 + this.master.ExecuteString(WindowsChildScript);
59 + }
60 + else if (process.platform == 'linux')
61 + {
62 + // Need to get the wireless interface name
63 + var interfaces = require('os').networkInterfaces();
64 + var wlan = null;
65 + for (var i in interfaces)
66 + {
67 + if (interfaces[i][0].type == 'wireless')
68 + {
69 + wlan = i;
70 + break;
71 + }
72 + }
73 + if (wlan != null)
74 + {
75 + this.child = require('child_process').execFile('/sbin/iwlist', ['iwlist', wlan, 'scan']);
76 + this.child.parent = this;
77 + this.child.ms = new MemoryStream();
78 + this.child.ms.parent = this.child;
79 + this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); });
80 + this.child.on('exit', function () { this.ms.end(); });
81 + this.child.ms.on('end', function ()
82 + {
83 + var str = this.buffer.toString();
84 + tokens = str.split(' - Address: ');
85 + for (var block in tokens)
86 + {
87 + if (block == 0) continue;
88 + var ln = tokens[block].split('\n');
89 + var _bssid = ln[0];
90 + var _lq;
91 + var _ssid;
92 +
93 + for (var lnblock in ln)
94 + {
95 + lnblock = ln[lnblock].trim();
96 + lnblock = lnblock.trim();
97 + if (lnblock.startsWith('ESSID:'))
98 + {
99 + _ssid = lnblock.slice(7, lnblock.length - 1);
100 + if (_ssid == '<hidden>') { _ssid = ''; }
101 + }
102 + if (lnblock.startsWith('Signal level='))
103 + {
104 + _lq = lnblock.slice(13,lnblock.length-4);
105 + }
106 + else if (lnblock.startsWith('Quality='))
107 + {
108 + _lq = lnblock.slice(8, 10);
109 + var scale = lnblock.slice(11, 13);
110 + }
111 + }
112 + this.parent.parent.emit('accessPoint', new AccessPoint(_ssid, _bssid, _lq));
113 + }
114 + });
115 + }
116 + }
117 + }
118 +}
119 +
120 +module.exports = WiFiScanner;
121 +
122 +
123 +
124 +
125 +
126 +
127 +
agents-new/modules_meshcore/win-console.js new
+164
@@ -0,0 +1,164 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var TrayIconFlags =
18 + {
19 + NIF_MESSAGE: 0x00000001,
20 + NIF_ICON: 0x00000002,
21 + NIF_TIP: 0x00000004,
22 + NIF_STATE: 0x00000008,
23 + NIF_INFO: 0x00000010,
24 + NIF_GUID: 0x00000020,
25 + NIF_REALTIME: 0x00000040,
26 + NIF_SHOWTIP: 0x00000080,
27 +
28 + NIM_ADD: 0x00000000,
29 + NIM_MODIFY: 0x00000001,
30 + NIM_DELETE: 0x00000002,
31 + NIM_SETFOCUS: 0x00000003,
32 + NIM_SETVERSION: 0x00000004
33 + };
34 +var NOTIFYICON_VERSION_4 = 4;
35 +var MessageTypes = { WM_APP: 0x8000, WM_USER: 0x0400 };
36 +function WindowsConsole()
37 +{
38 + if (process.platform == 'win32')
39 + {
40 + this._ObjectID = 'win-console';
41 + this._Marshal = require('_GenericMarshal');
42 + this._kernel32 = this._Marshal.CreateNativeProxy("kernel32.dll");
43 + this._user32 = this._Marshal.CreateNativeProxy("user32.dll");
44 + this._kernel32.CreateMethod("GetConsoleWindow");
45 + this._kernel32.CreateMethod('GetCurrentThread');
46 + this._user32.CreateMethod("ShowWindow");
47 + this._user32.CreateMethod("LoadImageA");
48 + this._user32.CreateMethod({ method: 'GetMessageA', threadDispatch: 1 });
49 + this._shell32 = this._Marshal.CreateNativeProxy('Shell32.dll');
50 + this._shell32.CreateMethod('Shell_NotifyIconA');
51 +
52 + this._handle = this._kernel32.GetConsoleWindow();
53 + this.minimize = function () {
54 + this._user32.ShowWindow(this._handle, 6);
55 + };
56 + this.restore = function () {
57 + this._user32.ShowWindow(this._handle, 9);
58 + };
59 + this.hide = function () {
60 + this._user32.ShowWindow(this._handle, 0);
61 + };
62 + this.show = function () {
63 + this._user32.ShowWindow(this._handle, 5);
64 + };
65 +
66 +
67 + this._loadicon = function (imagePath) {
68 + var h = this._user32.LoadImageA(0, this._Marshal.CreateVariable(imagePath), 1, 0, 0, 0x00000010 | 0x00008000 | 0x00000040); // LR_LOADFROMFILE | LR_SHARED | LR_DEFAULTSIZE
69 + return (h);
70 + };
71 +
72 + this.SetTrayIcon = function SetTrayIcon(options)
73 + {
74 + var data = this._Marshal.CreateVariable(this._Marshal.PointerSize == 4 ? 508 : 528);
75 + //console.log('struct size = ' + data._size);
76 + //console.log('TryIcon, WM_MESSAGE filter = ' + options.filter);
77 + data.toBuffer().writeUInt32LE(data._size, 0);
78 +
79 + var trayType = TrayIconFlags.NIF_TIP | TrayIconFlags.NIF_MESSAGE
80 + options.filter = MessageTypes.WM_APP + 1;
81 + data.Deref(this._Marshal.PointerSize == 4 ? 16 : 24, 4).toBuffer().writeUInt32LE(options.filter);
82 +
83 + if (!options.noBalloon) { trayType |= TrayIconFlags.NIF_INFO; }
84 +
85 + if (options.icon)
86 + {
87 + trayType |= TrayIconFlags.NIF_ICON;
88 + var hIcon = data.Deref(this._Marshal.PointerSize == 4 ? 20 : 32, this._Marshal.PointerSize);
89 + options.icon.pointerBuffer().copy(hIcon.toBuffer());
90 + }
91 +
92 + data.Deref(this._Marshal.PointerSize * 2, 4).toBuffer().writeUInt32LE(1);
93 + data.Deref(this._Marshal.PointerSize == 4 ? 12 : 20, 4).toBuffer().writeUInt32LE(trayType);
94 + data.Deref(this._Marshal.PointerSize == 4 ? 416 : 432, 4).toBuffer().writeUInt32LE(NOTIFYICON_VERSION_4);
95 +
96 + var szTip = data.Deref(this._Marshal.PointerSize == 4 ? 24 : 40, 128);
97 + var szInfo = data.Deref(this._Marshal.PointerSize == 4 ? 160 : 176, 256);
98 + var szInfoTitle = data.Deref(this._Marshal.PointerSize == 4 ? 420 : 436, 64);
99 +
100 + if (options.szTip) { Buffer.from(options.szTip).copy(szTip.toBuffer()); }
101 + if (options.szInfo) { Buffer.from(options.szInfo).copy(szInfo.toBuffer()); }
102 + if (options.szInfoTitle) { Buffer.from(options.szInfoTitle).copy(szInfoTitle.toBuffer()); }
103 +
104 +
105 + var MessagePump = require('win-message-pump');
106 + retVal = { _ObjectID: 'WindowsConsole.TrayIcon', MessagePump: new MessagePump(options) };
107 + var retValEvents = require('events').inherits(retVal);
108 + retValEvents.createEvent('ToastClicked');
109 + retValEvents.createEvent('IconHover');
110 + retValEvents.createEvent('ToastDismissed');
111 + retVal.Options = options;
112 + retVal.MessagePump.TrayIcon = retVal;
113 + retVal.MessagePump.NotifyData = data;
114 + retVal.MessagePump.WindowsConsole = this;
115 + retVal.MessagePump.on('exit', function onExit(code) { console.log('Pump Exited'); if (this.TrayIcon) { this.TrayIcon.remove(); } });
116 + retVal.MessagePump.on('hwnd', function onHwnd(h)
117 + {
118 + //console.log('Got HWND');
119 + options.hwnd = h;
120 + h.pointerBuffer().copy(this.NotifyData.Deref(this.WindowsConsole._Marshal.PointerSize, this.WindowsConsole._Marshal.PointerSize).toBuffer());
121 +
122 + if(this.WindowsConsole._shell32.Shell_NotifyIconA(TrayIconFlags.NIM_ADD, this.NotifyData).Val == 0)
123 + {
124 + // Something went wrong
125 + }
126 + });
127 + retVal.MessagePump.on('message', function onWindowsMessage(msg)
128 + {
129 + if(msg.message == this.TrayIcon.Options.filter)
130 + {
131 + var handled = false;
132 + if (msg.wparam == 1 && msg.lparam == 1029)
133 + {
134 + this.TrayIcon.emit('ToastClicked');
135 + handled = true;
136 + }
137 + if (msg.wparam == 1 && msg.lparam == 512)
138 + {
139 + this.TrayIcon.emit('IconHover');
140 + handled = true;
141 + }
142 + if (this.TrayIcon.Options.balloonOnly && msg.wparam == 1 && (msg.lparam == 1028 || msg.lparam == 1029))
143 + {
144 + this.TrayIcon.emit('ToastDismissed');
145 + this.TrayIcon.remove();
146 + handled = true;
147 + }
148 + if (!handled) { console.log(msg); }
149 + }
150 + });
151 + retVal.remove = function remove()
152 + {
153 + this.MessagePump.WindowsConsole._shell32.Shell_NotifyIconA(TrayIconFlags.NIM_DELETE, this.MessagePump.NotifyData);
154 + this.MessagePump.stop();
155 + delete this.MessagePump.TrayIcon;
156 + delete this.MessagePump;
157 + };
158 + return (retVal);
159 +
160 + };
161 + }
162 +}
163 +
164 +module.exports = new WindowsConsole();
\ No newline at end of file
agents-new/modules_meshcore/win-terminal.js new
+507
@@ -0,0 +1,507 @@
1 +/*
2 +Copyright 2018 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var promise = require('promise');
18 +var duplex = require('stream').Duplex;
19 +
20 +var SW_HIDE = 0;
21 +var SW_MINIMIZE = 6;
22 +var STARTF_USESHOWWINDOW = 0x1;
23 +var STD_INPUT_HANDLE = -10;
24 +var STD_OUTPUT_HANDLE = -11;
25 +var EVENT_CONSOLE_CARET = 0x4001;
26 +var EVENT_CONSOLE_END_APPLICATION = 0x4007;
27 +var WINEVENT_OUTOFCONTEXT = 0x000;
28 +var WINEVENT_SKIPOWNPROCESS = 0x0002;
29 +var CREATE_NEW_PROCESS_GROUP = 0x200;
30 +var EVENT_CONSOLE_UPDATE_REGION = 0x4002;
31 +var EVENT_CONSOLE_UPDATE_SIMPLE = 0x4003;
32 +var EVENT_CONSOLE_UPDATE_SCROLL = 0x4004;
33 +var EVENT_CONSOLE_LAYOUT = 0x4005;
34 +var EVENT_CONSOLE_START_APPLICATION = 0x4006;
35 +var KEY_EVENT = 0x1;
36 +var MAPVK_VK_TO_VSC = 0;
37 +var WM_QUIT = 0x12;
38 +
39 +var GM = require('_GenericMarshal');
40 +var si = GM.CreateVariable(GM.PointerSize == 4 ? 68 : 104);
41 +var pi = GM.CreateVariable(GM.PointerSize == 4 ? 16 : 24);
42 +
43 +si.Deref(0, 4).toBuffer().writeUInt32LE(GM.PointerSize == 4 ? 68 : 104); // si.cb
44 +si.Deref(GM.PointerSize == 4 ? 48 : 64, 2).toBuffer().writeUInt16LE(SW_HIDE | SW_MINIMIZE); // si.wShowWindow
45 +si.Deref(GM.PointerSize == 4 ? 44 : 60, 4).toBuffer().writeUInt32LE(STARTF_USESHOWWINDOW); // si.dwFlags;
46 +
47 +var MSG = GM.CreateVariable(GM.PointerSize == 4 ? 28 : 48);
48 +
49 +function windows_terminal() {
50 + this._ObjectID = 'windows_terminal';
51 + this._user32 = GM.CreateNativeProxy('User32.dll');
52 + this._user32.CreateMethod('DispatchMessageA');
53 + this._user32.CreateMethod('GetMessageA');
54 + this._user32.CreateMethod('MapVirtualKeyA');
55 + this._user32.CreateMethod('PostThreadMessageA');
56 + this._user32.CreateMethod('SetWinEventHook');
57 + this._user32.CreateMethod('ShowWindow');
58 + this._user32.CreateMethod('TranslateMessage');
59 + this._user32.CreateMethod('UnhookWinEvent');
60 + this._user32.CreateMethod('VkKeyScanA');
61 + this._user32.terminal = this;
62 +
63 + this._kernel32 = GM.CreateNativeProxy('Kernel32.dll');
64 + this._kernel32.CreateMethod('AllocConsole');
65 + this._kernel32.CreateMethod('CreateProcessA');
66 + this._kernel32.CreateMethod('CloseHandle');
67 + this._kernel32.CreateMethod('FillConsoleOutputAttribute');
68 + this._kernel32.CreateMethod('FillConsoleOutputCharacterA');
69 + this._kernel32.CreateMethod('GetConsoleScreenBufferInfo');
70 + this._kernel32.CreateMethod('GetConsoleWindow');
71 + this._kernel32.CreateMethod('GetLastError');
72 + this._kernel32.CreateMethod('GetStdHandle');
73 + this._kernel32.CreateMethod('GetThreadId');
74 + this._kernel32.CreateMethod('ReadConsoleOutputA');
75 + this._kernel32.CreateMethod('SetConsoleCursorPosition');
76 + this._kernel32.CreateMethod('SetConsoleScreenBufferSize');
77 + this._kernel32.CreateMethod('SetConsoleWindowInfo');
78 + this._kernel32.CreateMethod('TerminateProcess');
79 + this._kernel32.CreateMethod('WaitForSingleObject');
80 + this._kernel32.CreateMethod('WriteConsoleInputA');
81 +
82 + var currentX = 0;
83 + var currentY = 0;
84 +
85 + this._scrx = 0;
86 + this._scry = 0;
87 +
88 + this.SendCursorUpdate = function () {
89 + var newCsbi = GM.CreateVariable(22);
90 +
91 + if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, newCsbi).Val == 0) { return; }
92 + if (newCsbi.Deref(4, 2).toBuffer().readUInt16LE() != this.currentX || newCsbi.Deref(6, 2).toBuffer().readUInt16LE() != this.currentY) {
93 + //wchar_t mywbuf[512];
94 + //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);
95 + //OutputDebugString(mywbuf);
96 +
97 + //m_viewOffset = newCsbi.srWindow.Top;
98 + //WriteMoveCursor((SerialAgent *)this->sa, (char)(newCsbi.dwCursorPosition.Y - m_viewOffset), (char)(newCsbi.dwCursorPosition.X - m_viewOffset));
99 + //LowStackSendData((SerialAgent *)(this->sa), "", 0);
100 +
101 + this.currentX = newCsbi.Deref(4, 2).toBuffer().readUInt16LE();
102 + this.currentY = newCsbi.Deref(6, 2).toBuffer().readUInt16LE();
103 + }
104 + }
105 +
106 + this.ClearScreen = function () {
107 + var CONSOLE_SCREEN_BUFFER_INFO = GM.CreateVariable(22);
108 + if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, CONSOLE_SCREEN_BUFFER_INFO).Val == 0) { return; }
109 +
110 + var coordScreen = GM.CreateVariable(4);
111 + var dwConSize = CONSOLE_SCREEN_BUFFER_INFO.Deref(0, 2).toBuffer().readUInt16LE(0) * CONSOLE_SCREEN_BUFFER_INFO.Deref(2, 2).toBuffer().readUInt16LE(0);
112 + var cCharsWritten = GM.CreateVariable(4);
113 +
114 + // Fill the entire screen with blanks.
115 + if (this._kernel32.FillConsoleOutputCharacterA(this._stdoutput, 32, dwConSize, coordScreen.Deref(0, 4).toBuffer().readUInt32LE(), cCharsWritten).Val == 0) { return; }
116 +
117 + // Get the current text attribute.
118 + if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, CONSOLE_SCREEN_BUFFER_INFO).Val == 0) { return; }
119 +
120 + // Set the buffer's attributes accordingly.
121 + 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; }
122 +
123 + // Put the cursor at its home coordinates.
124 + this._kernel32.SetConsoleCursorPosition(this._stdoutput, coordScreen.Deref(0, 4).toBuffer().readUInt32LE());
125 +
126 + // Put the window to top-left.
127 + var rect = GM.CreateVariable(8);
128 + var srWindow = CONSOLE_SCREEN_BUFFER_INFO.Deref(10, 8).toBuffer();
129 + rect.Deref(4, 2).toBuffer().writeUInt16LE(srWindow.readUInt16LE(4) - srWindow.readUInt16LE(0));
130 + rect.Deref(6, 2).toBuffer().writeUInt16LE(srWindow.readUInt16LE(6) - srWindow.readUInt16LE(2));
131 +
132 + this._kernel32.SetConsoleWindowInfo(this._stdoutput, 1, rect);
133 + }
134 +
135 + this.Start = function Start(CONSOLE_SCREEN_WIDTH, CONSOLE_SCREEN_HEIGHT)
136 + {
137 + this.stopping = null;
138 + if (this._kernel32.GetConsoleWindow().Val == 0) {
139 + if (this._kernel32.AllocConsole().Val == 0) {
140 + throw ('AllocConsole failed with: ' + this._kernel32.GetLastError().Val);
141 + }
142 + }
143 +
144 + this._stdinput = this._kernel32.GetStdHandle(STD_INPUT_HANDLE);
145 + this._stdoutput = this._kernel32.GetStdHandle(STD_OUTPUT_HANDLE);
146 + this._connected = false;
147 + var coordScreen = GM.CreateVariable(4);
148 + coordScreen.Deref(0, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_WIDTH);
149 + coordScreen.Deref(2, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_HEIGHT);
150 +
151 + var rect = GM.CreateVariable(8);
152 + rect.Deref(4, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_WIDTH - 1);
153 + rect.Deref(6, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_HEIGHT - 1);
154 +
155 + if (this._kernel32.SetConsoleWindowInfo(this._stdoutput, 1, rect).Val == 0) {
156 + throw ('Failed to set Console Screen Size');
157 + }
158 + if (this._kernel32.SetConsoleScreenBufferSize(this._stdoutput, coordScreen.Deref(0, 4).toBuffer().readUInt32LE()).Val == 0) {
159 + throw ('Failed to set Console Buffer Size');
160 + }
161 +
162 + // Hide the console window
163 + this._user32.ShowWindow(this._kernel32.GetConsoleWindow().Val, SW_HIDE);
164 +
165 + this.ClearScreen();
166 + this._hookThread().then(function () {
167 + // Hook Ready
168 + this.terminal.StartCommand();
169 + }, console.log);
170 + this._stream = new duplex({
171 + 'write': function (chunk, flush) {
172 + if (!this.terminal.connected) {
173 + //console.log('_write: ' + chunk);
174 + if (!this._promise.chunk) {
175 + this._promise.chunk = [];
176 + }
177 + if (typeof (chunk) == 'string') {
178 + this._promise.chunk.push(chunk);
179 + } else {
180 + this._promise.chunk.push(Buffer.alloc(chunk.length));
181 + chunk.copy(this._promise.chunk.peek());
182 + }
183 + this._promise.chunk.peek().flush = flush;
184 + this._promise.then(function () {
185 + var buf;
186 + while (this.chunk.length > 0) {
187 + buf = this.chunk.shift();
188 + this.terminal._WriteBuffer(buf);
189 + buf.flush();
190 + }
191 + });
192 + }
193 + else {
194 + //console.log('writeNOW: ' + chunk);
195 + this.terminal._WriteBuffer(chunk);
196 + flush();
197 + }
198 + return (true);
199 + },
200 + 'final': function (flush) {
201 + var p = this.terminal._stop();
202 + p.__flush = flush;
203 + p.then(function () { this.__flush(); });
204 + }
205 + });
206 + this._stream.terminal = this;
207 + this._stream._promise = new promise(function (res, rej) { this._res = res; this._rej = rej; });
208 + this._stream._promise.terminal = this;
209 + return (this._stream);
210 + };
211 + this._stop = function () {
212 + if (this.stopping) { return (this.stopping); }
213 + //console.log('Stopping Terminal...');
214 + this._ConsoleWinEventProc.removeAllListeners('GlobalCallback');
215 + this.stopping = new promise(function (res, rej) { this._res = res; this._rej = rej; });
216 +
217 + var threadID = this._kernel32.GetThreadId(this._user32.SetWinEventHook.async.thread()).Val;
218 + this._user32.PostThreadMessageA(threadID, WM_QUIT, 0, 0);
219 + this._stream.emit('end');
220 + return (this.stopping);
221 + }
222 +
223 + this._hookThread = function () {
224 + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
225 + ret.terminal = this;
226 + this._ConsoleWinEventProc = GM.GetGenericGlobalCallback(7);
227 + this._ConsoleWinEventProc.terminal = this;
228 + var p = this._user32.SetWinEventHook.async(EVENT_CONSOLE_CARET, EVENT_CONSOLE_END_APPLICATION, 0, this._ConsoleWinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
229 + p.ready = ret;
230 + p.terminal = this;
231 + p.then(function (hwinEventHook) {
232 + if (hwinEventHook.Val == 0) {
233 + this.ready._rej('Error calling SetWinEventHook');
234 + } else {
235 + this.terminal.hwinEventHook = hwinEventHook;
236 + this.ready._res();
237 + this.terminal._GetMessage();
238 + }
239 + });
240 +
241 + this._ConsoleWinEventProc.on('GlobalCallback', function (hhook, dwEvent, hwnd, idObject, idChild, idEventThread, swmsEventTime) {
242 + if (!this.terminal.hwinEventHook || this.terminal.hwinEventHook.Val != hhook.Val) { return; }
243 + var buffer = null;
244 +
245 + switch (dwEvent.Val) {
246 + case EVENT_CONSOLE_CARET:
247 + break;
248 + case EVENT_CONSOLE_UPDATE_REGION:
249 + if (!this.terminal.connected) {
250 + this.terminal.connected = true;
251 + this.terminal._stream._promise._res();
252 + }
253 + if (this.terminal._scrollTimer == null) {
254 + buffer = this.terminal._GetScreenBuffer(LOWORD(idObject.Val), HIWORD(idObject.Val), LOWORD(idChild.Val), HIWORD(idChild.Val));
255 + //console.log('UPDATE REGION: [Left: ' + LOWORD(idObject.Val) + ' Top: ' + HIWORD(idObject.Val) + ' Right: ' + LOWORD(idChild.Val) + ' Bottom: ' + HIWORD(idChild.Val) + ']');
256 + this.terminal._SendDataBuffer(buffer);
257 + }
258 + break;
259 + case EVENT_CONSOLE_UPDATE_SIMPLE:
260 + //console.log('UPDATE SIMPLE: [X: ' + LOWORD(idObject.Val) + ' Y: ' + HIWORD(idObject.Val) + ' Char: ' + LOWORD(idChild.Val) + ' Attr: ' + HIWORD(idChild.Val) + ']');
261 + 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) };
262 + this.terminal._SendDataBuffer(simplebuffer);
263 + break;
264 + case EVENT_CONSOLE_UPDATE_SCROLL:
265 + //console.log('UPDATE SCROLL: [dx: ' + idObject.Val + ' dy: ' + idChild.Val + ']');
266 + this.terminal._SendScroll(idObject.Val, idChild.Val);
267 + break;
268 + case EVENT_CONSOLE_LAYOUT:
269 + //console.log('CONSOLE_LAYOUT');
270 + //snprintf( Buf, 512, "Event Console LAYOUT!\r\n");
271 + //SendLayout();
272 + break;
273 + case EVENT_CONSOLE_START_APPLICATION:
274 + //console.log('START APPLICATION: [PID: ' + idObject.Val + ' CID: ' + idChild.Val + ']');
275 + //snprintf( Buf, 512, "Event Console START APPLICATION!\r\nProcess ID: %d - Child ID: %d\r\n\r\n", (int)idObject, (int)idChild);
276 + //SendConsoleEvent(dwEvent, idObject, idChild);
277 + break;
278 + case EVENT_CONSOLE_END_APPLICATION:
279 + if (idObject.Val == this.terminal._hProcessID)
280 + {
281 + //console.log('END APPLICATION: [PID: ' + idObject.Val + ' CID: ' + idChild.Val + ']');
282 + this.terminal._hProcess = null;
283 + this.terminal._stop().then(function () { console.log('STOPPED'); });
284 + }
285 + break;
286 + default:
287 + //snprintf(Buf, 512, "unknown console event.\r\n");
288 + console.log('Unknown event: ' + dwEvent.Val);
289 + break;
290 + }
291 +
292 + //mbstowcs_s(&l, wBuf, Buf, 512);
293 + //OutputDebugString(wBuf);
294 +
295 + });
296 + return (ret);
297 + }
298 +
299 + this._GetMessage = function () {
300 + if (this._user32.abort) { console.log('aborting loop'); return; }
301 + this._user32.GetMessageA.async(this._user32.SetWinEventHook.async, MSG, 0, 0, 0).then(function (ret) {
302 + //console.log('GetMessage Response');
303 + if (ret.Val != 0) {
304 + if (ret.Val == -1) {
305 + // handle the error and possibly exit
306 + } else {
307 + //console.log('TranslateMessage');
308 + this.nativeProxy._user32.TranslateMessage.async(this.nativeProxy.user32.SetWinEventHook.async, MSG).then(function () {
309 + //console.log('DispatchMessage');
310 + this.nativeProxy._user32.DispatchMessageA.async(this.nativeProxy.user32.SetWinEventHook.async, MSG).then(function () {
311 + this.nativeProxy.terminal._GetMessage();
312 + }, console.log);
313 + }, console.log);
314 + }
315 + } else
316 + {
317 + this.nativeProxy.UnhookWinEvent.async(this.nativeProxy.terminal._user32.SetWinEventHook.async, this.nativeProxy.terminal.hwinEventHook)
318 + .then(function ()
319 + {
320 + if (this.nativeProxy.terminal._hProcess == null) { return; }
321 +
322 + this.nativeProxy.terminal.stopping._res();
323 + if (this.nativeProxy.terminal._kernel32.TerminateProcess(this.nativeProxy.terminal._hProcess, 1067).Val == 0) {
324 + var e = this.nativeProxy.terminal._kernel32.GetLastError().Val;
325 + console.log('Unable to kill Terminal Process, error: ' + e);
326 + }
327 + this.nativeProxy.terminal.stopping = null;
328 + }, function (err)
329 + {
330 + console.log('REJECTED_UnhookWinEvent: ' + err);
331 + });
332 + }
333 + }, function (err) {
334 + // Get Message Failed
335 + console.log('REJECTED_GETMessage: ' + err);
336 + });
337 + }
338 + this._WriteBuffer = function (buf) {
339 + for (var i = 0; i < buf.length; ++i) {
340 + if (typeof (buf) == 'string') {
341 + this._WriteCharacter(buf.charCodeAt(i), false);
342 + } else {
343 + this._WriteCharacter(buf[i], false);
344 + }
345 + }
346 + }
347 + this._WriteCharacter = function (key, bControlKey) {
348 + var rec = GM.CreateVariable(20);
349 + rec.Deref(0, 2).toBuffer().writeUInt16LE(KEY_EVENT); // rec.EventType
350 + rec.Deref(4, 4).toBuffer().writeUInt16LE(1); // rec.Event.KeyEvent.bKeyDown
351 + rec.Deref(16, 4).toBuffer().writeUInt32LE(bControlKey); // rec.Event.KeyEvent.dwControlKeyState
352 + rec.Deref(14, 1).toBuffer()[0] = key; // rec.Event.KeyEvent.uChar.AsciiChar
353 + rec.Deref(8, 2).toBuffer().writeUInt16LE(1); // rec.Event.KeyEvent.wRepeatCount
354 + rec.Deref(10, 2).toBuffer().writeUInt16LE(this._user32.VkKeyScanA(key).Val); // rec.Event.KeyEvent.wVirtualKeyCode
355 + rec.Deref(12, 2).toBuffer().writeUInt16LE(this._user32.MapVirtualKeyA(this._user32.VkKeyScanA(key).Val, MAPVK_VK_TO_VSC).Val);
356 +
357 + var dwWritten = GM.CreateVariable(4);
358 + if (this._kernel32.WriteConsoleInputA(this._stdinput, rec, 1, dwWritten).Val == 0) { return (false); }
359 +
360 + rec.Deref(4, 4).toBuffer().writeUInt16LE(0); // rec.Event.KeyEvent.bKeyDown
361 + return (this._kernel32.WriteConsoleInputA(this._stdinput, rec, 1, dwWritten).Val != 0);
362 + }
363 +
364 + // Get the current visible screen buffer
365 + this._GetScreenBuffer = function (sx, sy, ex, ey) {
366 + var info = GM.CreateVariable(22);
367 + if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, info).Val == 0) { throw ('Error getting screen buffer info'); }
368 +
369 + var nWidth = info.Deref(14, 2).toBuffer().readUInt16LE() - info.Deref(10, 2).toBuffer().readUInt16LE() + 1;
370 + var nHeight = info.Deref(16, 2).toBuffer().readUInt16LE() - info.Deref(12, 2).toBuffer().readUInt16LE() + 1;
371 +
372 + if (arguments[3] == null) {
373 + // Use Default Parameters
374 + sx = 0;
375 + sy = 0;
376 + ex = nWidth - 1;
377 + ey = nHeight - 1;
378 + } else {
379 + if (this._scrx != 0) { sx += this._scrx; ex += this._scrx; }
380 + if (this._scry != 0) { sy += this._scry; ey += this._scry; }
381 + this._scrx = this._scry = 0;
382 + }
383 +
384 + var nBuffer = GM.CreateVariable((ex - sx + 1) * (ey - sy + 1) * 4);
385 + var size = GM.CreateVariable(4);
386 + size.Deref(0, 2).toBuffer().writeUInt16LE(ex - sx + 1, 0);
387 + size.Deref(2, 2).toBuffer().writeUInt16LE(ey - sy + 1, 0);
388 +
389 + var startCoord = GM.CreateVariable(4);
390 + startCoord.Deref(0, 2).toBuffer().writeUInt16LE(0, 0);
391 + startCoord.Deref(2, 2).toBuffer().writeUInt16LE(0, 0);
392 +
393 + var region = GM.CreateVariable(8);
394 + region.buffer = region.toBuffer();
395 + region.buffer.writeUInt16LE(sx, 0);
396 + region.buffer.writeUInt16LE(sy, 2);
397 + region.buffer.writeUInt16LE(ex, 4);
398 + region.buffer.writeUInt16LE(ey, 6);
399 +
400 + if (this._kernel32.ReadConsoleOutputA(this._stdoutput, nBuffer, size.Deref(0, 4).toBuffer().readUInt32LE(), startCoord.Deref(0, 4).toBuffer().readUInt32LE(), region).Val == 0) {
401 + throw ('Unable to read Console Output');
402 + }
403 +
404 + // Lets convert the buffer into something simpler
405 + //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 };
406 +
407 + var retVal = { data: [], attributes: [], width: ex - sx + 1, height: ey - sy + 1, x: sx, y: sy };
408 + var x, y, line, ifo, tmp, lineWidth = ex - sx + 1;
409 +
410 + for (y = 0; y <= (ey - sy) ; ++y) {
411 + retVal.data.push(Buffer.alloc(lineWidth));
412 + retVal.attributes.push(Buffer.alloc(lineWidth));
413 +
414 + line = nBuffer.Deref(y * lineWidth * 4, lineWidth * 4).toBuffer();
415 + for (x = 0; x < lineWidth; ++x) {
416 + retVal.data.peek()[x] = line[x * 4];
417 + retVal.attributes.peek()[x] = line[2 + (x * 4)];
418 + }
419 + }
420 +
421 + return (retVal);
422 + }
423 +
424 + this._SendDataBuffer = function (data) {
425 + // { data, attributes, width, height, x, y }
426 +
427 + var dy, line, attr;
428 + for (dy = 0; dy < data.height; ++dy) {
429 + line = data.data[dy];
430 + attr = data.attributes[dy];
431 + line.s = line.toString();
432 +
433 + //line = data.data.slice(data.width * dy, (data.width * dy) + data.width);
434 + //attr = data.attributes.slice(data.width * dy, (data.width * dy) + data.width);
435 + this._stream.push(TranslateLine(data.x + 1, data.y + dy + 1, line, attr));
436 + }
437 + }
438 +
439 + this._SendScroll = function _SendScroll(dx, dy) {
440 + if (this._scrollTimer) { return; }
441 +
442 + var info = GM.CreateVariable(22);
443 + if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, info).Val == 0) { throw ('Error getting screen buffer info'); }
444 +
445 + var nWidth = info.Deref(14, 2).toBuffer().readUInt16LE() - info.Deref(10, 2).toBuffer().readUInt16LE() + 1;
446 + var nHeight = info.Deref(16, 2).toBuffer().readUInt16LE() - info.Deref(12, 2).toBuffer().readUInt16LE() + 1;
447 +
448 + this._stream.push(GetEsc('H', [nHeight - 1, 0]));
449 + for (var i = 0; i > nHeight; ++i) { this._stream.push(Buffer.from('\r\n')); }
450 +
451 + var buffer = this._GetScreenBuffer(0, 0, nWidth - 1, nHeight - 1);
452 + this._SendDataBuffer(buffer);
453 +
454 + this._scrollTimer = setTimeout(function (self, nw, nh) {
455 + var buffer = self._GetScreenBuffer(0, 0, nw - 1, nh - 1);
456 + self._SendDataBuffer(buffer);
457 + self._scrollTimer = null;
458 + }, 250, this, nWidth, nHeight);
459 + }
460 +
461 + this.StartCommand = function StartCommand() {
462 + 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) {
463 + console.log('Error Spawning CMD');
464 + return;
465 + }
466 +
467 + this._kernel32.CloseHandle(pi.Deref(GM.PointerSize, GM.PointerSize).Deref()); // pi.hThread
468 + this._hProcess = pi.Deref(0, GM.PointerSize).Deref(); // pi.hProcess
469 + this._hProcessID = pi.Deref(GM.PointerSize == 4 ? 8 : 16, 4).toBuffer().readUInt32LE(); // pi.dwProcessId
470 + //console.log('Ready => hProcess: ' + this._hProcess._ptr + ' PID: ' + this._hProcessID);
471 + }
472 +}
473 +
474 +function LOWORD(val) { return (val & 0xFFFF); }
475 +function HIWORD(val) { return ((val >> 16) & 0xFFFF); }
476 +function GetEsc(op, args) { return (Buffer.from('\x1B[' + args.join(';') + op)); }
477 +function MeshConsole(msg) { require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": JSON.stringify(msg) }); }
478 +function TranslateLine(x, y, data, attributes) {
479 + var i, fcolor, bcolor, rcolor, fbright, bbright, lastAttr, fc, bc, rc, fb, bb, esc = [], output = [GetEsc('H', [y, x])];
480 + if (typeof attributes == 'number') { attributes = [ attributes ]; } // If we get a single attribute, turn it into an array.
481 +
482 + for (i = 0; i < data.length; i++) {
483 + if (lastAttr != attributes[i]) { // To boost performance, if the attribute is the same as the last one, skip this entire part.
484 + fc = (attributes[i] & 0x0007);
485 + fc = ((fc & 0x0001) << 2) + (fc & 0x0002) + ((fc & 0x0004) >> 2); // Foreground color
486 + bc = (attributes[i] & 0x0070) >> 4;
487 + bc = ((bc & 0x0001) << 2) + (bc & 0x0002) + ((bc & 0x0004) >> 2); // Background color
488 + rc = (attributes[i] & 0x4000); // Reverse color set
489 + fb = (attributes[i] & 0x0008) >> 3; // Bright foreground set
490 + bb = (attributes[i] & 0x0080); // Bright background set
491 +
492 + 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
493 + if (fc != fcolor) { esc.push(fc + 30); fcolor = fc; } // Set the foreground color if needed
494 + if (bc != bcolor) { esc.push(bc + 40); bcolor = bc; } // Set the background color if needed
495 + if (fb != fbright) { esc.push(2 - fb); fbright = fb; } // Set the bright foreground color if needed
496 + if (bb != bbright) { if (bb == 0) { esc.push(bcolor + 40); } else { esc.push(bcolor + 100); bbright = bb; } } // Set bright Background color if needed
497 +
498 + if (esc.length > 0) { output.push(GetEsc('m', esc)); esc = []; }
499 + lastAttr = attributes[i];
500 + }
501 + output.push(Buffer.from(String.fromCharCode(data[i])));
502 + }
503 +
504 + return Buffer.concat(output);
505 +}
506 +
507 +module.exports = new windows_terminal();
\ No newline at end of file
agents-new/modules_meshcore/x/clipboard.js new
+178
@@ -0,0 +1,178 @@
1 +/*
2 +Copyright 2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var promise = require('promise');
18 +
19 +function nativeAddModule(name)
20 +{
21 + var value = getJSModule(name);
22 + var ret = "duk_peval_string_noresult(ctx, \"addModule('" + name + "', Buffer.from('" + Buffer.from(value).toString('base64') + "', 'base64').toString());\");";
23 + module.exports(ret);
24 +}
25 +
26 +function lin_readtext()
27 +{
28 + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
29 + try
30 + {
31 + require('monitor-info')
32 + }
33 + catch(exc)
34 + {
35 + ret._rej(exc);
36 + return (ret);
37 + }
38 +
39 + var X11 = require('monitor-info')._X11;
40 + if (!X11)
41 + {
42 + ret._rej('X11 required for Clipboard Manipulation');
43 + }
44 + else
45 + {
46 + var SelectionNotify = 31;
47 + var AnyPropertyType = 0;
48 + var GM = require('monitor-info')._gm;
49 +
50 + ret._getInfoPromise = require('monitor-info').getInfo();
51 + ret._getInfoPromise._masterPromise = ret;
52 + ret._getInfoPromise.then(function (mon)
53 + {
54 + if (mon.length > 0)
55 + {
56 + var white = X11.XWhitePixel(mon[0].display, mon[0].screenId).Val;
57 +
58 + this._masterPromise.CLIPID = X11.XInternAtom(mon[0].display, GM.CreateVariable('CLIPBOARD'), 0);
59 + this._masterPromise.FMTID = X11.XInternAtom(mon[0].display, GM.CreateVariable('UTF8_STRING'), 0);
60 + this._masterPromise.PROPID = X11.XInternAtom(mon[0].display, GM.CreateVariable('XSEL_DATA'), 0);
61 + this._masterPromise.INCRID = X11.XInternAtom(mon[0].display, GM.CreateVariable('INCR'), 0);
62 + this._masterPromise.ROOTWIN = X11.XRootWindow(mon[0].display, mon[0].screenId);
63 + this._masterPromise.FAKEWIN = X11.XCreateSimpleWindow(mon[0].display, this._masterPromise.ROOTWIN, 0, 0, mon[0].right, 5, 0, white, white);
64 +
65 + X11.XSync(mon[0].display, 0);
66 + X11.XConvertSelection(mon[0].display, this._masterPromise.CLIPID, this._masterPromise.FMTID, this._masterPromise.PROPID, this._masterPromise.FAKEWIN, 0);
67 + X11.XSync(mon[0].display, 0);
68 +
69 + this._masterPromise.DescriptorEvent = require('DescriptorEvents').addDescriptor(X11.XConnectionNumber(mon[0].display).Val, { readset: true });
70 + this._masterPromise.DescriptorEvent._masterPromise = this._masterPromise;
71 + this._masterPromise.DescriptorEvent._display = mon[0].display;
72 + this._masterPromise.DescriptorEvent.on('readset', function (fd)
73 + {
74 + var XE = GM.CreateVariable(1024);
75 + while (X11.XPending(this._display).Val)
76 + {
77 + X11.XNextEventSync(this._display, XE);
78 + if(XE.Deref(0, 4).toBuffer().readUInt32LE() == SelectionNotify)
79 + {
80 + var id = GM.CreatePointer();
81 + var bits = GM.CreatePointer();
82 + var sz = GM.CreatePointer();
83 + var tail = GM.CreatePointer();
84 + var result = GM.CreatePointer();
85 +
86 + X11.XGetWindowProperty(this._display, this._masterPromise.FAKEWIN, this._masterPromise.PROPID, 0, 65535, 0, AnyPropertyType, id, bits, sz, tail, result);
87 + this._masterPromise._res(result.Deref().String);
88 + X11.XFree(result.Deref());
89 + X11.XDestroyWindow(this._display, this._masterPromise.FAKEWIN);
90 +
91 + this.removeDescriptor(fd);
92 + break;
93 + }
94 + }
95 + });
96 + }
97 + });
98 + }
99 + return (ret);
100 +}
101 +function lin_copytext()
102 +{
103 +}
104 +
105 +function win_readtext()
106 +{
107 + var ret = '';
108 + var CF_TEXT = 1;
109 + var GM = require('_GenericMarshal');
110 + var user32 = GM.CreateNativeProxy('user32.dll');
111 + var kernel32 = GM.CreateNativeProxy('kernel32.dll');
112 + kernel32.CreateMethod('GlobalAlloc');
113 + kernel32.CreateMethod('GlobalLock');
114 + kernel32.CreateMethod('GlobalUnlock');
115 + user32.CreateMethod('OpenClipboard');
116 + user32.CreateMethod('CloseClipboard');
117 + user32.CreateMethod('GetClipboardData');
118 +
119 + user32.OpenClipboard(0);
120 + var h = user32.GetClipboardData(CF_TEXT);
121 + if(h.Val!=0)
122 + {
123 + var hbuffer = kernel32.GlobalLock(h);
124 + ret = hbuffer.String;
125 + kernel32.GlobalUnlock(h);
126 + }
127 + user32.CloseClipboard();
128 +
129 + var p = new promise(function (res, rej) { this._res = res; this._rej = rej; });
130 + p._res(ret);
131 + return (p);
132 +}
133 +
134 +function win_copytext(txt)
135 +{
136 + var GMEM_MOVEABLE = 0x0002;
137 + var CF_TEXT = 1;
138 +
139 + var GM = require('_GenericMarshal');
140 + var user32 = GM.CreateNativeProxy('user32.dll');
141 + var kernel32 = GM.CreateNativeProxy('kernel32.dll');
142 + kernel32.CreateMethod('GlobalAlloc');
143 + kernel32.CreateMethod('GlobalLock');
144 + kernel32.CreateMethod('GlobalUnlock');
145 + user32.CreateMethod('OpenClipboard');
146 + user32.CreateMethod('EmptyClipboard');
147 + user32.CreateMethod('CloseClipboard');
148 + user32.CreateMethod('SetClipboardData');
149 +
150 + var h = kernel32.GlobalAlloc(GMEM_MOVEABLE, txt.length + 2);
151 + h.autoFree(false);
152 + var hbuffer = kernel32.GlobalLock(h);
153 + hbuffer.autoFree(false);
154 + var tmp = Buffer.alloc(txt.length + 1);
155 + Buffer.from(txt).copy(tmp);
156 + tmp.copy(hbuffer.Deref(0, txt.length + 1).toBuffer());
157 + kernel32.GlobalUnlock(h);
158 +
159 + user32.OpenClipboard(0);
160 + user32.EmptyClipboard();
161 + user32.SetClipboardData(CF_TEXT, h);
162 + user32.CloseClipboard();
163 +}
164 +
165 +switch(process.platform)
166 +{
167 + case 'win32':
168 + module.exports = win_copytext;
169 + module.exports.read = win_readtext;
170 + break;
171 + case 'linux':
172 + module.exports = lin_copytext;
173 + module.exports.read = lin_readtext;
174 + break;
175 + case 'darwin':
176 + break;
177 +}
178 +module.exports.nativeAddModule = nativeAddModule;
\ No newline at end of file
agents-new/modules_meshcore/x/monitor-info.js new
+313
@@ -0,0 +1,313 @@
1 +/*
2 +Copyright 2018 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var promise = require('promise');
18 +var PPosition = 4;
19 +var PSize = 8;
20 +var _NET_WM_STATE_REMOVE = 0; // remove/unset property
21 +var _NET_WM_STATE_ADD = 1; // add/set property
22 +var _NET_WM_STATE_TOGGLE = 2; // toggle property
23 +var SubstructureRedirectMask = (1 << 20);
24 +var SubstructureNotifyMask = (1 << 19);
25 +
26 +function getLibInfo(libname)
27 +{
28 + if (process.platform != 'linux') { throw ('Only supported on linux'); }
29 +
30 + var child = require('child_process').execFile('/bin/sh', ['sh']);
31 + child.stdout.str = '';
32 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
33 + child.stdin.write("ldconfig -p | grep '" + libname + ".so.'\nexit\n");
34 + child.waitExit();
35 +
36 + var v = [];
37 + var lines = child.stdout.str.split('\n');
38 + for (var i in lines) {
39 + if (lines[i]) {
40 + var info = lines[i].split('=>');
41 + var pth = info[1].trim();
42 + var libinfo = info[0].trim().split(' ');
43 + var lib = libinfo[0];
44 + var plat = libinfo[1].substring(1, libinfo[1].length - 1).split(',');
45 +
46 + if (lib.startsWith(libname + '.so.')) {
47 + v.push({ lib: lib, path: pth, info: plat });
48 + }
49 + }
50 + }
51 + return (v);
52 +}
53 +
54 +function monitorinfo()
55 +{
56 + this._ObjectID = 'monitor-info';
57 + this._gm = require('_GenericMarshal');
58 +
59 + if (process.platform == 'win32')
60 + {
61 + this._user32 = this._gm.CreateNativeProxy('user32.dll');
62 + this._user32.CreateMethod('EnumDisplayMonitors');
63 + this._kernel32 = this._gm.CreateNativeProxy('kernel32.dll');
64 + this._kernel32.CreateMethod('GetLastError');
65 +
66 + this.getInfo = function getInfo()
67 + {
68 + var info = this;
69 + return (new promise(function (resolver, rejector) {
70 + this._monitorinfo = { resolver: resolver, rejector: rejector, self: info, callback: info._gm.GetGenericGlobalCallback(4) };
71 + this._monitorinfo.callback.info = this._monitorinfo;
72 + this._monitorinfo.dwData = info._gm.ObjectToPtr(this._monitorinfo);
73 +
74 + this._monitorinfo.callback.results = [];
75 + this._monitorinfo.callback.on('GlobalCallback', function OnMonitorInfo(hmon, hdc, r, user) {
76 + if (this.ObjectToPtr_Verify(this.info, user)) {
77 + var rb = r.Deref(0, 16).toBuffer();
78 + this.results.push({ left: rb.readInt32LE(0), top: rb.readInt32LE(4), right: rb.readInt32LE(8), bottom: rb.readInt32LE(12) });
79 +
80 + var r = this.info.self._gm.CreateInteger();
81 + r.Val = 1;
82 + return (r);
83 + }
84 + });
85 +
86 + if (info._user32.EnumDisplayMonitors(0, 0, this._monitorinfo.callback, this._monitorinfo.dwData).Val == 0) {
87 + rejector('LastError=' + info._kernel32.GetLastError().Val);
88 + return;
89 + }
90 + else {
91 + resolver(this._monitorinfo.callback.results);
92 + }
93 +
94 + }));
95 + }
96 + }
97 + else if(process.platform == 'linux')
98 + {
99 + // First thing we need to do, is determine where the X11 libraries are
100 + var askOS = false;
101 + try
102 + {
103 + if (require('user-sessions').isRoot()) { askOS = true; }
104 + }
105 + catch (e)
106 + { }
107 +
108 + if (askOS)
109 + {
110 + // Sufficient access rights to use ldconfig
111 + var x11info = getLibInfo('libX11');
112 + var xtstinfo = getLibInfo('libXtst');
113 + var xextinfo = getLibInfo('libXext');
114 + var ix;
115 +
116 + for(ix in x11info)
117 + {
118 + try
119 + {
120 + this._gm.CreateNativeProxy(x11info[ix].path);
121 + Object.defineProperty(this, 'Location_X11LIB', { value: x11info[ix].path });
122 + break;
123 + }
124 + catch(ex)
125 + {
126 + }
127 + }
128 + for (ix in xtstinfo)
129 + {
130 + try
131 + {
132 + this._gm.CreateNativeProxy(xtstinfo[ix].path);
133 + Object.defineProperty(this, 'Location_X11TST', { value: xtstinfo[ix].path });
134 + break;
135 + }
136 + catch (ex)
137 + {
138 + }
139 + }
140 + for (ix in xextinfo)
141 + {
142 + try
143 + {
144 + this._gm.CreateNativeProxy(xextinfo[ix].path);
145 + Object.defineProperty(this, 'Location_X11EXT', { value: xextinfo[ix].path });
146 + break;
147 + }
148 + catch (ex)
149 + {
150 + }
151 + }
152 + }
153 + else
154 + {
155 + // Not enough access rights to use ldconfig, so manually search
156 + var fs = require('fs');
157 + var files = fs.readdirSync('/usr/lib');
158 + var files2;
159 +
160 + for (var i in files) {
161 + try {
162 + if (files[i].split('libX11.so.').length > 1 && files[i].split('.').length == 3) {
163 + Object.defineProperty(this, 'Location_X11LIB', { value: '/usr/lib/' + files[i] });
164 + }
165 + if (files[i].split('libXtst.so.').length > 1 && files[i].split('.').length == 3) {
166 + Object.defineProperty(this, 'Location_X11TST', { value: '/usr/lib/' + files[i] });
167 + }
168 + if (files[i].split('libXext.so.').length > 1 && files[i].split('.').length == 3) {
169 + Object.defineProperty(this, 'Location_X11EXT', { value: '/usr/lib/' + files[i] });
170 + }
171 +
172 + if (files[i].split('-linux-').length > 1) {
173 + files2 = fs.readdirSync('/usr/lib/' + files[i]);
174 + for (j in files2) {
175 + if (files2[j].split('libX11.so.').length > 1 && files2[j].split('.').length == 3) {
176 + Object.defineProperty(this, 'Location_X11LIB', { value: '/usr/lib/' + files[i] + '/' + files2[j] });
177 + }
178 + if (files2[j].split('libXtst.so.').length > 1 && files2[j].split('.').length == 3) {
179 + Object.defineProperty(this, 'Location_X11TST', { value: '/usr/lib/' + files[i] + '/' + files2[j] });
180 + }
181 + if (files2[j].split('libXext.so.').length > 1 && files2[j].split('.').length == 3) {
182 + Object.defineProperty(this, 'Location_X11EXT', { value: '/usr/lib/' + files[i] + '/' + files2[j] });
183 + }
184 + }
185 + }
186 + } catch (ex) { }
187 + }
188 + }
189 + Object.defineProperty(this, 'kvm_x11_support', { value: (this.Location_X11LIB && this.Location_X11TST && this.Location_X11EXT)?true:false });
190 +
191 + if (this.Location_X11LIB)
192 + {
193 + this._X11 = this._gm.CreateNativeProxy(this.Location_X11LIB);
194 + this._X11.CreateMethod('XChangeProperty');
195 + this._X11.CreateMethod('XCloseDisplay');
196 + this._X11.CreateMethod('XConnectionNumber');
197 + this._X11.CreateMethod('XConvertSelection');
198 + this._X11.CreateMethod('XCreateGC');
199 + this._X11.CreateMethod('XCreateWindow');
200 + this._X11.CreateMethod('XCreateSimpleWindow');
201 + this._X11.CreateMethod('XDefaultColormap');
202 + this._X11.CreateMethod('XDefaultScreen');
203 + this._X11.CreateMethod('XDestroyWindow');
204 + this._X11.CreateMethod('XDrawLine');
205 + this._X11.CreateMethod('XDisplayHeight');
206 + this._X11.CreateMethod('XDisplayWidth');
207 + this._X11.CreateMethod('XFetchName');
208 + this._X11.CreateMethod('XFlush');
209 + this._X11.CreateMethod('XFree');
210 + this._X11.CreateMethod('XCreateGC');
211 + this._X11.CreateMethod('XGetWindowProperty');
212 + this._X11.CreateMethod('XInternAtom');
213 + this._X11.CreateMethod('XMapWindow');
214 + this._X11.CreateMethod({ method: 'XNextEvent', threadDispatch: true });
215 + this._X11.CreateMethod({ method: 'XNextEvent', newName: 'XNextEventSync' });
216 + this._X11.CreateMethod('XOpenDisplay');
217 + this._X11.CreateMethod('XPending');
218 + this._X11.CreateMethod('XRootWindow');
219 + this._X11.CreateMethod('XSelectInput');
220 + this._X11.CreateMethod('XScreenCount');
221 + this._X11.CreateMethod('XScreenOfDisplay');
222 + this._X11.CreateMethod('XSelectInput');
223 + this._X11.CreateMethod('XSendEvent');
224 + this._X11.CreateMethod('XSetForeground');
225 + this._X11.CreateMethod('XSetFunction');
226 + this._X11.CreateMethod('XSetLineAttributes');
227 + this._X11.CreateMethod('XSetNormalHints');
228 + this._X11.CreateMethod('XSetSubwindowMode');
229 + this._X11.CreateMethod('XSync');
230 + this._X11.CreateMethod('XBlackPixel');
231 + this._X11.CreateMethod('XWhitePixel');
232 + }
233 +
234 + this.isUnity = function isUnity()
235 + {
236 + return (process.env['XDG_CURRENT_DESKTOP'] == 'Unity');
237 + }
238 +
239 + this.unDecorateWindow = function unDecorateWindow(display, window)
240 + {
241 + var MwmHints = this._gm.CreateVariable(40);
242 + var mwmHintsProperty = this._X11.XInternAtom(display, this._gm.CreateVariable('_MOTIF_WM_HINTS'), 0);
243 + MwmHints.Deref(0, 4).toBuffer().writeUInt32LE(1 << 1);
244 + this._X11.XChangeProperty(display, window, mwmHintsProperty, mwmHintsProperty, 32, 0, MwmHints, 5);
245 + }
246 + this.setWindowSizeHints = function setWindowSizeHints(display, window, x, y, width, height)
247 + {
248 + var sizeHints = this._gm.CreateVariable(80);
249 + sizeHints.Deref(0, 4).toBuffer().writeUInt32LE(PPosition | PSize);
250 + sizeHints.Deref(8, 4).toBuffer().writeUInt32LE(x);
251 + sizeHints.Deref(12, 4).toBuffer().writeUInt32LE(y);
252 + sizeHints.Deref(16, 4).toBuffer().writeUInt32LE(width);
253 + sizeHints.Deref(20, 4).toBuffer().writeUInt32LE(height);
254 + this._X11.XSetNormalHints(display, window, sizeHints);
255 + }
256 + this.setAlwaysOnTop = function setAlwaysOnTop(display, rootWindow, window)
257 + {
258 + var wmNetWmState = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE'), 1);
259 + var wmStateAbove = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE_ABOVE'), 1);
260 +
261 + var xclient = this._gm.CreateVariable(96);
262 + xclient.Deref(0, 4).toBuffer().writeUInt32LE(33); // ClientMessage type
263 + xclient.Deref(48, 4).toBuffer().writeUInt32LE(32); // Format 32
264 + wmNetWmState.pointerBuffer().copy(xclient.Deref(40, 8).toBuffer()); // message_type
265 + xclient.Deref(56, 8).toBuffer().writeUInt32LE(_NET_WM_STATE_ADD); // data.l[0]
266 + wmStateAbove.pointerBuffer().copy(xclient.Deref(64, 8).toBuffer()); // data.l[1]
267 +
268 + window.pointerBuffer().copy(xclient.Deref(32, 8).toBuffer()); // window
269 + this._X11.XSendEvent(display, rootWindow, 0, SubstructureRedirectMask | SubstructureNotifyMask, xclient);
270 + }
271 + this.hideWindowIcon = function hideWindowIcon(display, rootWindow, window)
272 + {
273 + var wmNetWmState = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE'), 1);
274 + var wmStateSkip = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE_SKIP_TASKBAR'), 1);
275 +
276 + var xclient = this._gm.CreateVariable(96);
277 + xclient.Deref(0, 4).toBuffer().writeUInt32LE(33); // ClientMessage type
278 + xclient.Deref(48, 4).toBuffer().writeUInt32LE(32); // Format 32
279 + wmNetWmState.pointerBuffer().copy(xclient.Deref(40, 8).toBuffer()); // message_type
280 + xclient.Deref(56, 8).toBuffer().writeUInt32LE(_NET_WM_STATE_ADD); // data.l[0]
281 + wmStateSkip.pointerBuffer().copy(xclient.Deref(64, 8).toBuffer()); // data.l[1]
282 +
283 + window.pointerBuffer().copy(xclient.Deref(32, 8).toBuffer()); // window
284 + this._X11.XSendEvent(display, rootWindow, 0, SubstructureRedirectMask | SubstructureNotifyMask, xclient);
285 + }
286 +
287 + this.getInfo = function getInfo()
288 + {
289 + var info = this;
290 + return (new promise(function (resolver, rejector)
291 + {
292 + var display = info._X11.XOpenDisplay(info._gm.CreateVariable(':0'));
293 + var screenCount = info._X11.XScreenCount(display).Val;
294 + var ret = [];
295 + for(var i=0;i<screenCount;++i)
296 + {
297 + var screen = info._X11.XScreenOfDisplay(display, i);
298 + ret.push({ left: 0, top: 0, right: info._X11.XDisplayWidth(display, i).Val, bottom: info._X11.XDisplayHeight(display, i).Val, screen: screen, screenId: i, display: display });
299 + }
300 + resolver(ret);
301 + }));
302 + }
303 + }
304 + else
305 + {
306 + throw (process.platform + ' not supported');
307 + }
308 +}
309 +
310 +module.exports = new monitorinfo();
311 +
312 +
313 +
agents-new/modules_meshcore/x/process-manager.js new
+163
@@ -0,0 +1,163 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +
18 +var GM = require('_GenericMarshal');
19 +
20 +// Used on Windows and Linux to get information about running processes
21 +function processManager() {
22 + this._ObjectID = 'process-manager'; // Used for debugging, allows you to get the object type at runtime.
23 +
24 + // Setup the platform specific calls.
25 + switch (process.platform)
26 + {
27 + case 'win32':
28 + this._kernel32 = GM.CreateNativeProxy('kernel32.dll');
29 + this._kernel32.CreateMethod('GetLastError');
30 + this._kernel32.CreateMethod('CreateToolhelp32Snapshot');
31 + this._kernel32.CreateMethod('Process32First');
32 + this._kernel32.CreateMethod('Process32Next');
33 + break;
34 + case 'linux':
35 + case 'darwin':
36 + this._childProcess = require('child_process');
37 + break;
38 + default:
39 + throw (process.platform + ' not supported');
40 + break;
41 + }
42 + this.enumerateProcesses = function enumerateProcesses()
43 + {
44 + var promise = require('promise');
45 + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
46 + this.getProcesses(function (ps, prom) { prom._res(ps); }, ret);
47 + return (ret);
48 + }
49 + // Return a object of: pid -> process information.
50 + this.getProcesses = function getProcesses(callback)
51 + {
52 + switch(process.platform)
53 + {
54 + default:
55 + throw ('Enumerating processes on ' + process.platform + ' not supported');
56 + break;
57 + case 'win32': // Windows processes
58 + var retVal = {};
59 + var h = this._kernel32.CreateToolhelp32Snapshot(2, 0);
60 + var info = GM.CreateVariable(304);
61 + info.toBuffer().writeUInt32LE(304, 0);
62 + var nextProcess = this._kernel32.Process32First(h, info);
63 + while (nextProcess.Val)
64 + {
65 + 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 };
66 + nextProcess = this._kernel32.Process32Next(h, info);
67 + }
68 + if (callback) { callback.apply(this, [retVal]); }
69 + break;
70 + case 'linux': // Linux processes
71 + if (!this._psp) { this._psp = {}; }
72 + var p = this._childProcess.execFile("/bin/ps", ["ps", "-uxa"], { type: this._childProcess.SpawnTypes.TERM });
73 + this._psp[p.pid] = p;
74 + p.Parent = this;
75 + p.ps = '';
76 + p.callback = callback;
77 + p.args = [];
78 + for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); }
79 + p.on('exit', function onGetProcesses()
80 + {
81 + delete this.Parent._psp[this.pid];
82 + var retVal = {}, lines = this.ps.split('\x0D\x0A'), key = {}, keyi = 0;
83 + for (var i in lines)
84 + {
85 + var tokens = lines[i].split(' ');
86 + var tokenList = [];
87 + for(var x in tokens)
88 + {
89 + if (i == 0 && tokens[x]) { key[tokens[x]] = keyi++; }
90 + if (i > 0 && tokens[x]) { tokenList.push(tokens[x]);}
91 + }
92 + if (i > 0) {
93 + if (tokenList[key.PID]) { retVal[tokenList[key.PID]] = { pid: key.PID, user: tokenList[key.USER], cmd: tokenList[key.COMMAND] }; }
94 + }
95 + }
96 + if (this.callback)
97 + {
98 + this.args.unshift(retVal);
99 + this.callback.apply(this.parent, this.args);
100 + }
101 + });
102 + p.stdout.on('data', function (chunk) { this.parent.ps += chunk.toString(); });
103 + break;
104 + case 'darwin':
105 + var promise = require('promise');
106 + var p = new promise(function (res, rej) { this._res = res; this._rej = rej; });
107 + p.pm = this;
108 + p.callback = callback;
109 + p.args = [];
110 + for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); }
111 + p.child = this._childProcess.execFile("/bin/ps", ["ps", "-xa"]);
112 + p.child.promise = p;
113 + p.child.stdout.ps = '';
114 + p.child.stdout.on('data', function (chunk) { this.ps += chunk.toString(); });
115 + p.child.on('exit', function ()
116 + {
117 + var lines = this.stdout.ps.split('\n');
118 + var pidX = lines[0].split('PID')[0].length + 3;
119 + var cmdX = lines[0].split('CMD')[0].length;
120 + var ret = {};
121 + for (var i = 1; i < lines.length; ++i)
122 + {
123 + if (lines[i].length > 0)
124 + {
125 + ret[lines[i].substring(0, pidX).trim()] = { pid: lines[i].substring(0, pidX).trim(), cmd: lines[i].substring(cmdX) };
126 + }
127 + }
128 + this.promise._res(ret);
129 + });
130 + p.then(function (ps)
131 + {
132 + this.args.unshift(ps);
133 + this.callback.apply(this.pm, this.args);
134 + });
135 + break;
136 + }
137 + };
138 +
139 + // Get information about a specific process on Linux
140 + this.getProcessInfo = function getProcessInfo(pid)
141 + {
142 + switch(process.platform)
143 + {
144 + default:
145 + throw ('getProcessInfo() not supported for ' + process.platform);
146 + break;
147 + case 'linux':
148 + var status = require('fs').readFileSync('/proc/' + pid + '/status');
149 + var info = {};
150 + var lines = status.toString().split('\n');
151 + for(var i in lines)
152 + {
153 + var tokens = lines[i].split(':');
154 + if (tokens.length > 1) { tokens[1] = tokens[1].trim(); }
155 + info[tokens[0]] = tokens[1];
156 + }
157 + return (info);
158 + break;
159 + }
160 + };
161 +}
162 +
163 +module.exports = new processManager();
\ No newline at end of file
agents-new/modules_meshcore/x/service-manager.js new
+497
@@ -0,0 +1,497 @@
1 +/*
2 +Copyright 2018 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +function parseServiceStatus(token)
18 +{
19 + var j = {};
20 + var serviceType = token.Deref(0, 4).IntVal;
21 + j.isFileSystemDriver = ((serviceType & 0x00000002) == 0x00000002);
22 + j.isKernelDriver = ((serviceType & 0x00000001) == 0x00000001);
23 + j.isSharedProcess = ((serviceType & 0x00000020) == 0x00000020);
24 + j.isOwnProcess = ((serviceType & 0x00000010) == 0x00000010);
25 + j.isInteractive = ((serviceType & 0x00000100) == 0x00000100);
26 + switch (token.Deref((1 * 4), 4).toBuffer().readUInt32LE())
27 + {
28 + case 0x00000005:
29 + j.state = 'CONTINUE_PENDING';
30 + break;
31 + case 0x00000006:
32 + j.state = 'PAUSE_PENDING';
33 + break;
34 + case 0x00000007:
35 + j.state = 'PAUSED';
36 + break;
37 + case 0x00000004:
38 + j.state = 'RUNNING';
39 + break;
40 + case 0x00000002:
41 + j.state = 'START_PENDING';
42 + break;
43 + case 0x00000003:
44 + j.state = 'STOP_PENDING';
45 + break;
46 + case 0x00000001:
47 + j.state = 'STOPPED';
48 + break;
49 + }
50 + var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE();
51 + j.controlsAccepted = [];
52 + if ((controlsAccepted & 0x00000010) == 0x00000010)
53 + {
54 + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDADD');
55 + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDREMOVE');
56 + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDENABLE');
57 + j.controlsAccepted.push('SERVICE_CONTROL_NETBINDDISABLE');
58 + }
59 + if ((controlsAccepted & 0x00000008) == 0x00000008) { j.controlsAccepted.push('SERVICE_CONTROL_PARAMCHANGE'); }
60 + if ((controlsAccepted & 0x00000002) == 0x00000002) { j.controlsAccepted.push('SERVICE_CONTROL_PAUSE'); j.controlsAccepted.push('SERVICE_CONTROL_CONTINUE'); }
61 + if ((controlsAccepted & 0x00000100) == 0x00000100) { j.controlsAccepted.push('SERVICE_CONTROL_PRESHUTDOWN'); }
62 + if ((controlsAccepted & 0x00000004) == 0x00000004) { j.controlsAccepted.push('SERVICE_CONTROL_SHUTDOWN'); }
63 + if ((controlsAccepted & 0x00000001) == 0x00000001) { j.controlsAccepted.push('SERVICE_CONTROL_STOP'); }
64 + if ((controlsAccepted & 0x00000020) == 0x00000020) { j.controlsAccepted.push('SERVICE_CONTROL_HARDWAREPROFILECHANGE'); }
65 + if ((controlsAccepted & 0x00000040) == 0x00000040) { j.controlsAccepted.push('SERVICE_CONTROL_POWEREVENT'); }
66 + if ((controlsAccepted & 0x00000080) == 0x00000080) { j.controlsAccepted.push('SERVICE_CONTROL_SESSIONCHANGE'); }
67 + j.pid = token.Deref((7 * 4), 4).toBuffer().readUInt32LE();
68 + return (j);
69 +}
70 +
71 +function serviceManager()
72 +{
73 + this._ObjectID = 'service-manager';
74 + if (process.platform == 'win32')
75 + {
76 + this.GM = require('_GenericMarshal');
77 + this.proxy = this.GM.CreateNativeProxy('Advapi32.dll');
78 + this.proxy.CreateMethod('OpenSCManagerA');
79 + this.proxy.CreateMethod('EnumServicesStatusExA');
80 + this.proxy.CreateMethod('OpenServiceA');
81 + this.proxy.CreateMethod('QueryServiceStatusEx');
82 + this.proxy.CreateMethod('ControlService');
83 + this.proxy.CreateMethod('StartServiceA');
84 + this.proxy.CreateMethod('CloseServiceHandle');
85 + this.proxy.CreateMethod('CreateServiceA');
86 + this.proxy.CreateMethod('ChangeServiceConfig2A');
87 + this.proxy.CreateMethod('DeleteService');
88 + this.proxy.CreateMethod('AllocateAndInitializeSid');
89 + this.proxy.CreateMethod('CheckTokenMembership');
90 + this.proxy.CreateMethod('FreeSid');
91 +
92 + this.proxy2 = this.GM.CreateNativeProxy('Kernel32.dll');
93 + this.proxy2.CreateMethod('GetLastError');
94 +
95 + this.isAdmin = function isAdmin() {
96 + var NTAuthority = this.GM.CreateVariable(6);
97 + NTAuthority.toBuffer().writeInt8(5, 5);
98 + var AdministratorsGroup = this.GM.CreatePointer();
99 + var admin = false;
100 +
101 + if (this.proxy.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0)
102 + {
103 + var member = this.GM.CreateInteger();
104 + if (this.proxy.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0)
105 + {
106 + if (member.toBuffer().readUInt32LE() != 0) { admin = true; }
107 + }
108 + this.proxy.FreeSid(AdministratorsGroup.Deref());
109 + }
110 + return admin;
111 + };
112 + this.getProgramFolder = function getProgramFolder()
113 + {
114 + if (require('os').arch() == 'x64')
115 + {
116 + // 64 bit Windows
117 + if (this.GM.PointerSize == 4)
118 + {
119 + return process.env['ProgramFiles(x86)']; // 32 Bit App
120 + }
121 + return process.env['ProgramFiles']; // 64 bit App
122 + }
123 +
124 + // 32 bit Windows
125 + return process.env['ProgramFiles'];
126 + };
127 + this.getServiceFolder = function getServiceFolder() { return this.getProgramFolder() + '\\mesh'; };
128 +
129 + this.enumerateService = function () {
130 + var machineName = this.GM.CreatePointer();
131 + var dbName = this.GM.CreatePointer();
132 + var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0001 | 0x0004);
133 +
134 + var bytesNeeded = this.GM.CreatePointer();
135 + var servicesReturned = this.GM.CreatePointer();
136 + var resumeHandle = this.GM.CreatePointer();
137 + //var services = this.proxy.CreateVariable(262144);
138 + var success = this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, 0x00, 0x00, bytesNeeded, servicesReturned, resumeHandle, 0x00);
139 + if (bytesNeeded.IntVal <= 0) {
140 + throw ('error enumerating services');
141 + }
142 + var sz = bytesNeeded.IntVal;
143 + var services = this.GM.CreateVariable(sz);
144 + this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, services, sz, bytesNeeded, servicesReturned, resumeHandle, 0x00);
145 + console.log("servicesReturned", servicesReturned.IntVal);
146 +
147 + var ptrSize = dbName._size;
148 + var blockSize = 36 + (2 * ptrSize);
149 + blockSize += ((ptrSize - (blockSize % ptrSize)) % ptrSize);
150 + var retVal = [];
151 + for (var i = 0; i < servicesReturned.IntVal; ++i) {
152 + var token = services.Deref(i * blockSize, blockSize);
153 + var j = {};
154 + j.name = token.Deref(0, ptrSize).Deref().String;
155 + j.displayName = token.Deref(ptrSize, ptrSize).Deref().String;
156 + j.status = parseServiceStatus(token.Deref(2 * ptrSize, 36));
157 + retVal.push(j);
158 + }
159 + this.proxy.CloseServiceHandle(handle);
160 + return (retVal);
161 + }
162 + this.getService = function (name) {
163 + var serviceName = this.GM.CreateVariable(name);
164 + var ptr = this.GM.CreatePointer();
165 + var bytesNeeded = this.GM.CreateVariable(ptr._size);
166 + var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0001 | 0x0004 | 0x0020 | 0x0010);
167 + if (handle.Val == 0) { throw ('could not open ServiceManager'); }
168 + var h = this.proxy.OpenServiceA(handle, serviceName, 0x0004 | 0x0020 | 0x0010 | 0x00010000);
169 + if (h.Val != 0) {
170 + var success = this.proxy.QueryServiceStatusEx(h, 0, 0, 0, bytesNeeded);
171 + var status = this.GM.CreateVariable(bytesNeeded.toBuffer().readUInt32LE());
172 + success = this.proxy.QueryServiceStatusEx(h, 0, status, status._size, bytesNeeded);
173 + if (success != 0) {
174 + retVal = {};
175 + retVal.status = parseServiceStatus(status);
176 + retVal._scm = handle;
177 + retVal._service = h;
178 + retVal._GM = this.GM;
179 + retVal._proxy = this.proxy;
180 + require('events').inherits(retVal);
181 + retVal.on('~', function () { this._proxy.CloseServiceHandle(this); this._proxy.CloseServiceHandle(this._scm); });
182 + retVal.name = name;
183 + retVal.stop = function () {
184 + if (this.status.state == 'RUNNING') {
185 + var newstate = this._GM.CreateVariable(36);
186 + var success = this._proxy.ControlService(this._service, 0x00000001, newstate);
187 + if (success == 0) {
188 + throw (this.name + '.stop() failed');
189 + }
190 + }
191 + else {
192 + throw ('cannot call ' + this.name + '.stop(), when current state is: ' + this.status.state);
193 + }
194 + }
195 + retVal.start = function () {
196 + if (this.status.state == 'STOPPED') {
197 + var success = this._proxy.StartServiceA(this._service, 0, 0);
198 + if (success == 0) {
199 + throw (this.name + '.start() failed');
200 + }
201 + }
202 + else {
203 + throw ('cannot call ' + this.name + '.start(), when current state is: ' + this.status.state);
204 + }
205 + }
206 + return (retVal);
207 + }
208 + else {
209 +
210 + }
211 + }
212 +
213 + this.proxy.CloseServiceHandle(handle);
214 + throw ('could not find service: ' + name);
215 + }
216 + }
217 + else
218 + {
219 + this.isAdmin = function isAdmin()
220 + {
221 + return (require('user-sessions').isRoot());
222 + }
223 + }
224 + this.installService = function installService(options)
225 + {
226 + if (process.platform == 'win32')
227 + {
228 + if (!this.isAdmin()) { throw ('Installing as Service, requires admin'); }
229 +
230 + // Before we start, we need to copy the binary to the right place
231 + var folder = this.getServiceFolder();
232 + if (!require('fs').existsSync(folder)) { require('fs').mkdirSync(folder); }
233 + require('fs').copyFileSync(options.servicePath, folder + '\\' + options.name + '.exe');
234 + options.servicePath = folder + '\\' + options.name + '.exe';
235 +
236 + var servicePath = this.GM.CreateVariable('"' + options.servicePath + '"');
237 + var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0002);
238 + if (handle.Val == 0) { throw ('error opening SCManager'); }
239 + var serviceName = this.GM.CreateVariable(options.name);
240 + var displayName = this.GM.CreateVariable(options.name);
241 + var allAccess = 0x000F01FF;
242 + var serviceType;
243 +
244 +
245 + switch (options.startType) {
246 + case 'BOOT_START':
247 + serviceType = 0x00;
248 + break;
249 + case 'SYSTEM_START':
250 + serviceType = 0x01;
251 + break;
252 + case 'AUTO_START':
253 + serviceType = 0x02;
254 + break;
255 + case 'DEMAND_START':
256 + serviceType = 0x03;
257 + break;
258 + default:
259 + serviceType = 0x04; // Disabled
260 + break;
261 + }
262 +
263 + var h = this.proxy.CreateServiceA(handle, serviceName, displayName, allAccess, 0x10 | 0x100, serviceType, 0, servicePath, 0, 0, 0, 0, 0);
264 + if (h.Val == 0) { this.proxy.CloseServiceHandle(handle); throw ('Error Creating Service: ' + this.proxy2.GetLastError().Val); }
265 + if (options.description) {
266 + console.log(options.description);
267 +
268 + var dscPtr = this.GM.CreatePointer();
269 + dscPtr.Val = this.GM.CreateVariable(options.description);
270 +
271 + if (this.proxy.ChangeServiceConfig2A(h, 1, dscPtr) == 0) {
272 + this.proxy.CloseServiceHandle(h);
273 + this.proxy.CloseServiceHandle(handle);
274 + throw ('Unable to set description');
275 + }
276 + }
277 + this.proxy.CloseServiceHandle(h);
278 + this.proxy.CloseServiceHandle(handle);
279 + return (this.getService(options.name));
280 + }
281 + if(process.platform == 'linux')
282 + {
283 + if (!this.isAdmin()) { throw ('Installing as Service, requires root'); }
284 +
285 + switch (this.getServiceType())
286 + {
287 + case 'init':
288 + require('fs').copyFileSync(options.servicePath, '/etc/init.d/' + options.name);
289 + console.log('copying ' + options.servicePath);
290 + var m = require('fs').statSync('/etc/init.d/' + options.name).mode;
291 + m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP);
292 + require('fs').chmodSync('/etc/init.d/' + options.name, m);
293 + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
294 + this._update._moduleName = options.name;
295 + this._update.stdout.on('data', function (chunk) { });
296 + this._update.stdin.write('update-rc.d ' + options.name + ' defaults\n');
297 + this._update.stdin.write('exit\n');
298 + //update-rc.d meshagent defaults # creates symlinks for rc.d
299 + //service meshagent start
300 +
301 + this._update.waitExit();
302 +
303 + break;
304 + case 'systemd':
305 + var serviceDescription = options.description ? options.description : 'MeshCentral Agent';
306 + if (!require('fs').existsSync('/usr/local/mesh')) { require('fs').mkdirSync('/usr/local/mesh'); }
307 + require('fs').copyFileSync(options.servicePath, '/usr/local/mesh/' + options.name);
308 + var m = require('fs').statSync('/usr/local/mesh/' + options.name).mode;
309 + m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP);
310 + require('fs').chmodSync('/usr/local/mesh/' + options.name, m);
311 + 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' });
312 + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
313 + this._update._moduleName = options.name;
314 + this._update.stdout.on('data', function (chunk) { });
315 + this._update.stdin.write('systemctl enable ' + options.name + '.service\n');
316 + this._update.stdin.write('exit\n');
317 + this._update.waitExit();
318 + break;
319 + default: // unknown platform service type
320 + break;
321 + }
322 + }
323 + if(process.platform == 'darwin')
324 + {
325 + if (!this.isAdmin()) { throw ('Installing as Service, requires root'); }
326 +
327 + // Mac OS
328 + var stdoutpath = (options.stdout ? ('<key>StandardOutPath</key>\n<string>' + options.stdout + '</string>') : '');
329 + var autoStart = (options.startType == 'AUTO_START' ? '<true/>' : '<false/>');
330 + var params = ' <key>ProgramArguments</key>\n';
331 + params += ' <array>\n';
332 + params += (' <string>/usr/local/mesh_services/' + options.name + '/' + options.name + '</string>\n');
333 + if(options.parameters)
334 + {
335 + for(var itm in options.parameters)
336 + {
337 + params += (' <string>' + options.parameters[itm] + '</string>\n');
338 + }
339 + }
340 + params += ' </array>\n';
341 +
342 + var plist = '<?xml version="1.0" encoding="UTF-8"?>\n';
343 + plist += '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n';
344 + plist += '<plist version="1.0">\n';
345 + plist += ' <dict>\n';
346 + plist += ' <key>Label</key>\n';
347 + plist += (' <string>' + options.name + '</string>\n');
348 + plist += (params + '\n');
349 + plist += ' <key>WorkingDirectory</key>\n';
350 + plist += (' <string>/usr/local/mesh_services/' + options.name + '</string>\n');
351 + plist += (stdoutpath + '\n');
352 + plist += ' <key>RunAtLoad</key>\n';
353 + plist += (autoStart + '\n');
354 + plist += ' </dict>\n';
355 + plist += '</plist>';
356 +
357 + if (!require('fs').existsSync('/usr/local/mesh_services')) { require('fs').mkdirSync('/usr/local/mesh_services'); }
358 + if (!require('fs').existsSync('/Library/LaunchDaemons/' + options.name + '.plist'))
359 + {
360 + if (!require('fs').existsSync('/usr/local/mesh_services/' + options.name)) { require('fs').mkdirSync('/usr/local/mesh_services/' + options.name); }
361 + if (options.binary)
362 + {
363 + require('fs').writeFileSync('/usr/local/mesh_services/' + options.name + '/' + options.name, options.binary);
364 + }
365 + else
366 + {
367 + require('fs').copyFileSync(options.servicePath, '/usr/local/mesh_services/' + options.name + '/' + options.name);
368 + }
369 + require('fs').writeFileSync('/Library/LaunchDaemons/' + options.name + '.plist', plist);
370 + var m = require('fs').statSync('/usr/local/mesh_services/' + options.name + '/' + options.name).mode;
371 + m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP);
372 + require('fs').chmodSync('/usr/local/mesh_services/' + options.name + '/' + options.name, m);
373 + }
374 + else
375 + {
376 + throw ('Service: ' + options.name + ' already exists');
377 + }
378 + }
379 + }
380 + this.uninstallService = function uninstallService(name)
381 + {
382 + if (!this.isAdmin()) { throw ('Uninstalling a service, requires admin'); }
383 +
384 + if (typeof (name) == 'object') { name = name.name; }
385 + if (process.platform == 'win32')
386 + {
387 + var service = this.getService(name);
388 + if (service.status.state == undefined || service.status.state == 'STOPPED')
389 + {
390 + if (this.proxy.DeleteService(service._service) == 0)
391 + {
392 + throw ('Uninstall Service for: ' + name + ', failed with error: ' + this.proxy2.GetLastError());
393 + }
394 + else
395 + {
396 + try
397 + {
398 + require('fs').unlinkSync(this.getServiceFolder() + '\\' + name + '.exe');
399 + }
400 + catch(e)
401 + {
402 + }
403 + }
404 + }
405 + else
406 + {
407 + throw ('Cannot uninstall service: ' + name + ', because it is: ' + service.status.state);
408 + }
409 + }
410 + else if(process.platform == 'linux')
411 + {
412 + switch (this.getServiceType())
413 + {
414 + case 'init':
415 + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
416 + this._update.stdout.on('data', function (chunk) { });
417 + this._update.stdin.write('service ' + name + ' stop\n');
418 + this._update.stdin.write('update-rc.d -f ' + name + ' remove\n');
419 + this._update.stdin.write('exit\n');
420 + this._update.waitExit();
421 + try
422 + {
423 + require('fs').unlinkSync('/etc/init.d/' + name);
424 + console.log(name + ' uninstalled');
425 +
426 + }
427 + catch (e)
428 + {
429 + console.log(name + ' could not be uninstalled', e)
430 + }
431 + break;
432 + case 'systemd':
433 + this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
434 + this._update.stdout.on('data', function (chunk) { });
435 + this._update.stdin.write('systemctl stop ' + name + '.service\n');
436 + this._update.stdin.write('systemctl disable ' + name + '.service\n');
437 + this._update.stdin.write('exit\n');
438 + this._update.waitExit();
439 + try
440 + {
441 + require('fs').unlinkSync('/usr/local/mesh/' + name);
442 + require('fs').unlinkSync('/lib/systemd/system/' + name + '.service');
443 + console.log(name + ' uninstalled');
444 + }
445 + catch (e)
446 + {
447 + console.log(name + ' could not be uninstalled', e)
448 + }
449 + break;
450 + default: // unknown platform service type
451 + break;
452 + }
453 + }
454 + else if(process.platform == 'darwin')
455 + {
456 + if (require('fs').existsSync('/Library/LaunchDaemons/' + name + '.plist'))
457 + {
458 + var child = require('child_process').execFile('/bin/sh', ['sh']);
459 + child.stdout.on('data', function (chunk) { });
460 + child.stdin.write('launchctl stop ' + name + '\n');
461 + child.stdin.write('launchctl unload /Library/LaunchDaemons/' + name + '.plist\n');
462 + child.stdin.write('exit\n');
463 + child.waitExit();
464 +
465 + try
466 + {
467 + require('fs').unlinkSync('/usr/local/mesh_services/' + name + '/' + name);
468 + require('fs').unlinkSync('/Library/LaunchDaemons/' + name + '.plist');
469 + }
470 + catch(e)
471 + {
472 + throw ('Error uninstalling service: ' + name + ' => ' + e);
473 + }
474 +
475 + try
476 + {
477 + require('fs').rmdirSync('/usr/local/mesh_services/' + name);
478 + }
479 + catch(e)
480 + {}
481 + }
482 + else
483 + {
484 + throw ('Service: ' + name + ' does not exist');
485 + }
486 + }
487 + }
488 + if(process.platform == 'linux')
489 + {
490 + this.getServiceType = function getServiceType()
491 + {
492 + return (require('process-manager').getProcessInfo(1).Name);
493 + };
494 + }
495 +}
496 +
497 +module.exports = serviceManager;
\ No newline at end of file
agents-new/modules_meshcore/x/user-sessions.js new
+750
@@ -0,0 +1,750 @@
1 +/*
2 +Copyright 2018 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var NOTIFY_FOR_THIS_SESSION = 0;
18 +var NOTIFY_FOR_ALL_SESSIONS = 1;
19 +var WM_WTSSESSION_CHANGE = 0x02B1;
20 +var WM_POWERBROADCAST = 0x218;
21 +var PBT_POWERSETTINGCHANGE = 0x8013;
22 +var PBT_APMSUSPEND = 0x4;
23 +var PBT_APMRESUMESUSPEND = 0x7;
24 +var PBT_APMRESUMEAUTOMATIC = 0x12;
25 +var PBT_APMPOWERSTATUSCHANGE = 0xA;
26 +
27 +var WTS_CONSOLE_CONNECT = (0x1);
28 +var WTS_CONSOLE_DISCONNECT = (0x2);
29 +var WTS_REMOTE_CONNECT = (0x3);
30 +var WTS_REMOTE_DISCONNECT = (0x4);
31 +var WTS_SESSION_LOGON = (0x5);
32 +var WTS_SESSION_LOGOFF = (0x6);
33 +var WTS_SESSION_LOCK = (0x7);
34 +var WTS_SESSION_UNLOCK = (0x8);
35 +var WTS_SESSION_REMOTE_CONTROL = (0x9);
36 +var WTS_SESSION_CREATE = (0xA);
37 +var WTS_SESSION_TERMINATE = (0xB);
38 +
39 +var GUID_ACDC_POWER_SOURCE;
40 +var GUID_BATTERY_PERCENTAGE_REMAINING;
41 +var GUID_CONSOLE_DISPLAY_STATE;
42 +
43 +function UserSessions()
44 +{
45 + this._ObjectID = 'user-sessions';
46 + require('events').EventEmitter.call(this, true)
47 + .createEvent('changed')
48 + .createEvent('locked')
49 + .createEvent('unlocked');
50 +
51 + this.enumerateUsers = function enumerateUsers()
52 + {
53 + var promise = require('promise');
54 + var p = new promise(function (res, rej)
55 + {
56 + this.__resolver = res;
57 + this.__rejector = rej;
58 + });
59 + p.__handler = function __handler(users)
60 + {
61 + p.__resolver(users);
62 + };
63 + try
64 + {
65 + this.Current(p.__handler);
66 + }
67 + catch(e)
68 + {
69 + p.__rejector(e);
70 + }
71 + p.parent = this;
72 + return (p);
73 + }
74 +
75 + if (process.platform == 'win32')
76 + {
77 + this._serviceHooked = false;
78 + this._marshal = require('_GenericMarshal');
79 + this._kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll');
80 + this._kernel32.CreateMethod('GetLastError');
81 +
82 + try
83 + {
84 + this._wts = this._marshal.CreateNativeProxy('Wtsapi32.dll');
85 + this._wts.CreateMethod('WTSEnumerateSessionsA');
86 + this._wts.CreateMethod('WTSQuerySessionInformationA');
87 + this._wts.CreateMethod('WTSRegisterSessionNotification');
88 + this._wts.CreateMethod('WTSUnRegisterSessionNotification');
89 + this._wts.CreateMethod('WTSFreeMemory');
90 + }
91 + catch(exc)
92 + {
93 + }
94 +
95 + this._advapi = this._marshal.CreateNativeProxy('Advapi32.dll');
96 + this._advapi.CreateMethod('AllocateAndInitializeSid');
97 + this._advapi.CreateMethod('CheckTokenMembership');
98 + this._advapi.CreateMethod('FreeSid');
99 +
100 + this._user32 = this._marshal.CreateNativeProxy('user32.dll');
101 + this._user32.CreateMethod({ method: 'RegisterPowerSettingNotification', threadDispatch: 1});
102 + this._user32.CreateMethod('UnregisterPowerSettingNotification');
103 + this._rpcrt = this._marshal.CreateNativeProxy('Rpcrt4.dll');
104 + this._rpcrt.CreateMethod('UuidFromStringA');
105 + this._rpcrt.StringToUUID = function StringToUUID(guid)
106 + {
107 + var retVal = StringToUUID.us._marshal.CreateVariable(16);
108 + if(StringToUUID.us._rpcrt.UuidFromStringA(StringToUUID.us._marshal.CreateVariable(guid), retVal).Val == 0)
109 + {
110 + return (retVal);
111 + }
112 + else
113 + {
114 + throw ('Could not convert string to UUID');
115 + }
116 + }
117 + this._rpcrt.StringToUUID.us = this;
118 +
119 + GUID_ACDC_POWER_SOURCE = this._rpcrt.StringToUUID('5d3e9a59-e9D5-4b00-a6bd-ff34ff516548');
120 + GUID_BATTERY_PERCENTAGE_REMAINING = this._rpcrt.StringToUUID('a7ad8041-b45a-4cae-87a3-eecbb468a9e1');
121 + GUID_CONSOLE_DISPLAY_STATE = this._rpcrt.StringToUUID('6fe69556-704a-47a0-8f24-c28d936fda47');
122 +
123 + this.SessionStates = ['Active', 'Connected', 'ConnectQuery', 'Shadow', 'Disconnected', 'Idle', 'Listening', 'Reset', 'Down', 'Init'];
124 + this.InfoClass =
125 + {
126 + 'WTSInitialProgram': 0,
127 + 'WTSApplicationName': 1,
128 + 'WTSWorkingDirectory': 2,
129 + 'WTSOEMId': 3,
130 + 'WTSSessionId': 4,
131 + 'WTSUserName': 5,
132 + 'WTSWinStationName': 6,
133 + 'WTSDomainName': 7,
134 + 'WTSConnectState': 8,
135 + 'WTSClientBuildNumber': 9,
136 + 'WTSClientName': 10,
137 + 'WTSClientDirectory': 11,
138 + 'WTSClientProductId': 12,
139 + 'WTSClientHardwareId': 13,
140 + 'WTSClientAddress': 14,
141 + 'WTSClientDisplay': 15,
142 + 'WTSClientProtocolType': 16,
143 + 'WTSIdleTime': 17,
144 + 'WTSLogonTime': 18,
145 + 'WTSIncomingBytes': 19,
146 + 'WTSOutgoingBytes': 20,
147 + 'WTSIncomingFrames': 21,
148 + 'WTSOutgoingFrames': 22,
149 + 'WTSClientInfo': 23,
150 + 'WTSSessionInfo': 24,
151 + 'WTSSessionInfoEx': 25,
152 + 'WTSConfigInfo': 26,
153 + 'WTSValidationInfo': 27,
154 + 'WTSSessionAddressV4': 28,
155 + 'WTSIsRemoteSession': 29
156 + };
157 +
158 + this.isRoot = function isRoot()
159 + {
160 + var NTAuthority = this._marshal.CreateVariable(6);
161 + NTAuthority.toBuffer().writeInt8(5, 5);
162 +
163 + var AdministratorsGroup = this._marshal.CreatePointer();
164 + var admin = false;
165 +
166 + if (this._advapi.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0)
167 + {
168 + var member = this._marshal.CreateInteger();
169 + if (this._advapi.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0)
170 + {
171 + if (member.toBuffer().readUInt32LE() != 0) { admin = true; }
172 + }
173 + this._advapi.FreeSid(AdministratorsGroup.Deref());
174 + }
175 + return admin;
176 + }
177 +
178 + this.getSessionAttribute = function getSessionAttribute(sessionId, attr)
179 + {
180 + var buffer = this._marshal.CreatePointer();
181 + var bytesReturned = this._marshal.CreateVariable(4);
182 +
183 + if (this._wts.WTSQuerySessionInformationA(0, sessionId, attr, buffer, bytesReturned).Val == 0)
184 + {
185 + throw ('Error calling WTSQuerySessionInformation: ' + this._kernel32.GetLastError.Val);
186 + }
187 +
188 + var retVal = buffer.Deref().String;
189 +
190 + this._wts.WTSFreeMemory(buffer.Deref());
191 + return (retVal);
192 + };
193 +
194 + this.Current = function Current(cb)
195 + {
196 + var retVal = {};
197 + var pinfo = this._marshal.CreatePointer();
198 + var count = this._marshal.CreateVariable(4);
199 + if (this._wts.WTSEnumerateSessionsA(0, 0, 1, pinfo, count).Val == 0)
200 + {
201 + throw ('Error calling WTSEnumerateSessionsA: ' + this._kernel32.GetLastError().Val);
202 + }
203 +
204 + for (var i = 0; i < count.toBuffer().readUInt32LE() ; ++i)
205 + {
206 + var info = pinfo.Deref().Deref(i * (this._marshal.PointerSize == 4 ? 12 : 24), this._marshal.PointerSize == 4 ? 12 : 24);
207 + var j = { SessionId: info.toBuffer().readUInt32LE() };
208 + j.StationName = info.Deref(this._marshal.PointerSize == 4 ? 4 : 8, this._marshal.PointerSize).Deref().String;
209 + j.State = this.SessionStates[info.Deref(this._marshal.PointerSize == 4 ? 8 : 16, 4).toBuffer().readUInt32LE()];
210 + if (j.State == 'Active') {
211 + j.Username = this.getSessionAttribute(j.SessionId, this.InfoClass.WTSUserName);
212 + j.Domain = this.getSessionAttribute(j.SessionId, this.InfoClass.WTSDomainName);
213 + }
214 + retVal[j.SessionId] = j;
215 + }
216 +
217 + this._wts.WTSFreeMemory(pinfo.Deref());
218 +
219 + Object.defineProperty(retVal, 'Active', { value: showActiveOnly(retVal) });
220 + if (cb) { cb(retVal); }
221 + return (retVal);
222 + };
223 +
224 +
225 + // We need to spin up a message pump, and fetch a window handle
226 + var message_pump = require('win-message-pump');
227 + this._messagepump = new message_pump({ filter: WM_WTSSESSION_CHANGE }); this._messagepump.parent = this;
228 + this._messagepump.on('exit', function (code) { this.parent._wts.WTSUnRegisterSessionNotification(this.parent.hwnd); });
229 + this._messagepump.on('hwnd', function (h)
230 + {
231 + this.parent.hwnd = h;
232 +
233 + // We need to yield, and do this in the next event loop pass, becuase we don't want to call 'RegisterPowerSettingNotification'
234 + // from the messagepump 'thread', because we are actually on the microstack thread, such that the message pump thread, is holding
235 + // on a semaphore for us to return. If we call now, we may deadlock on Windows 7, becuase it will try to notify immediately
236 + this.immediate = setImmediate(function (self)
237 + {
238 + // Now that we have a window handle, we can register it to receive Windows Messages
239 + if (self.parent._wts) { self.parent._wts.WTSRegisterSessionNotification(self.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS); }
240 + self.parent._user32.ACDC_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0);
241 + self.parent._user32.BATT_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0);
242 + self.parent._user32.DISP_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0);
243 + //console.log(self.parent._user32.ACDC_H.Val, self.parent._user32.BATT_H.Val, self.parent._user32.DISP_H.Val);
244 + }, this);
245 + });
246 + this._messagepump.on('message', function (msg)
247 + {
248 + switch(msg.message)
249 + {
250 + case WM_WTSSESSION_CHANGE:
251 + switch(msg.wparam)
252 + {
253 + case WTS_SESSION_LOCK:
254 + this.parent.enumerateUsers().then(function (users)
255 + {
256 + if (users[msg.lparam]) { this.parent.emit('locked', users[msg.lparam]); }
257 + });
258 + break;
259 + case WTS_SESSION_UNLOCK:
260 + this.parent.enumerateUsers().then(function (users)
261 + {
262 + if (users[msg.lparam]) { this.parent.emit('unlocked', users[msg.lparam]); }
263 + });
264 + break;
265 + case WTS_SESSION_LOGON:
266 + case WTS_SESSION_LOGOFF:
267 + this.parent.emit('changed');
268 + break;
269 + }
270 + break;
271 + case WM_POWERBROADCAST:
272 + switch(msg.wparam)
273 + {
274 + default:
275 + console.log('WM_POWERBROADCAST [UNKNOWN wparam]: ' + msg.wparam);
276 + break;
277 + case PBT_APMSUSPEND:
278 + require('power-monitor').emit('sx', 'SLEEP');
279 + break;
280 + case PBT_APMRESUMEAUTOMATIC:
281 + require('power-monitor').emit('sx', 'RESUME_NON_INTERACTIVE');
282 + break;
283 + case PBT_APMRESUMESUSPEND:
284 + require('power-monitor').emit('sx', 'RESUME_INTERACTIVE');
285 + break;
286 + case PBT_APMPOWERSTATUSCHANGE:
287 + require('power-monitor').emit('changed');
288 + break;
289 + case PBT_POWERSETTINGCHANGE:
290 + var lparam = this.parent._marshal.CreatePointer(Buffer.from(msg.lparam_hex, 'hex'));
291 + var data = lparam.Deref(20, lparam.Deref(16, 4).toBuffer().readUInt32LE(0)).toBuffer();
292 + switch(lparam.Deref(0, 16).toBuffer().toString('hex'))
293 + {
294 + case GUID_ACDC_POWER_SOURCE.Deref(0, 16).toBuffer().toString('hex'):
295 + switch(data.readUInt32LE(0))
296 + {
297 + case 0:
298 + require('power-monitor').emit('acdc', 'AC');
299 + break;
300 + case 1:
301 + require('power-monitor').emit('acdc', 'BATTERY');
302 + break;
303 + case 2:
304 + require('power-monitor').emit('acdc', 'HOT');
305 + break;
306 + }
307 + break;
308 + case GUID_BATTERY_PERCENTAGE_REMAINING.Deref(0, 16).toBuffer().toString('hex'):
309 + require('power-monitor').emit('batteryLevel', data.readUInt32LE(0));
310 + break;
311 + case GUID_CONSOLE_DISPLAY_STATE.Deref(0, 16).toBuffer().toString('hex'):
312 + switch(data.readUInt32LE(0))
313 + {
314 + case 0:
315 + require('power-monitor').emit('display', 'OFF');
316 + break;
317 + case 1:
318 + require('power-monitor').emit('display', 'ON');
319 + break;
320 + case 2:
321 + require('power-monitor').emit('display', 'DIMMED');
322 + break;
323 + }
324 + break;
325 + }
326 + break;
327 + }
328 + break;
329 + default:
330 + break;
331 + }
332 + });
333 + }
334 + else if(process.platform == 'linux')
335 + {
336 + var dbus = require('linux-dbus');
337 + this._linuxWatcher = require('fs').watch('/var/run/utmp');
338 + this._linuxWatcher.user_session = this;
339 + this._linuxWatcher.on('change', function (a, b)
340 + {
341 + this.user_session.emit('changed');
342 + });
343 + this._users = function _users()
344 + {
345 + var child = require('child_process').execFile('/bin/sh', ['sh']);
346 + child.stdout.str = '';
347 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
348 + child.stdin.write('awk -F: \'($3 >= 0) {printf "%s:%s\\n", $1, $3}\' /etc/passwd\nexit\n');
349 + child.waitExit();
350 +
351 + var lines = child.stdout.str.split('\n');
352 + var ret = {}, tokens;
353 + for (var ln in lines)
354 + {
355 + tokens = lines[ln].split(':');
356 + if (tokens[0]) { ret[tokens[0]] = tokens[1]; }
357 + }
358 + return (ret);
359 + }
360 + this._uids = function _uids() {
361 + var child = require('child_process').execFile('/bin/sh', ['sh']);
362 + child.stdout.str = '';
363 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
364 + child.stdin.write('awk -F: \'($3 >= 0) {printf "%s:%s\\n", $1, $3}\' /etc/passwd\nexit\n');
365 + child.waitExit();
366 +
367 + var lines = child.stdout.str.split('\n');
368 + var ret = {}, tokens;
369 + for (var ln in lines) {
370 + tokens = lines[ln].split(':');
371 + if (tokens[0]) { ret[tokens[1]] = tokens[0]; }
372 + }
373 + return (ret);
374 + }
375 + this.Self = function Self()
376 + {
377 + var promise = require('promise');
378 + var p = new promise(function (res, rej)
379 + {
380 + this.__resolver = res; this.__rejector = rej;
381 + this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u']);
382 + this.__child.promise = this;
383 + this.__child.stdout._txt = '';
384 + this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); });
385 + this.__child.on('exit', function (code)
386 + {
387 + try
388 + {
389 + parseInt(this.stdout._txt);
390 + }
391 + catch (e)
392 + {
393 + this.promise.__rejector('invalid uid');
394 + return;
395 + }
396 +
397 + var id = parseInt(this.stdout._txt);
398 + this.promise.__resolver(id);
399 + });
400 + });
401 + return (p);
402 + };
403 + this.Current = function Current(cb)
404 + {
405 + var retVal = {};
406 + retVal._ObjectID = 'UserSession'
407 + Object.defineProperty(retVal, '_callback', { value: cb });
408 + Object.defineProperty(retVal, '_child', { value: require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']) });
409 +
410 + retVal._child.Parent = retVal;
411 + retVal._child._txt = '';
412 + retVal._child.on('exit', function (code)
413 + {
414 + var lines = this._txt.split('\n');
415 + var sessions = [];
416 + var users = {};
417 +
418 + for(var i in lines)
419 + {
420 + if (lines[i])
421 + {
422 + var tokens = getTokens(lines[i]);
423 + var s = { Username: tokens[0], SessionId: tokens[1] }
424 + if (tokens[3].includes('still logged in'))
425 + {
426 + s.State = 'Active';
427 + }
428 + else
429 + {
430 + s.LastActive = tokens[3];
431 + }
432 +
433 + sessions.push(s);
434 + }
435 + }
436 + sessions.pop();
437 +
438 +
439 + var usernames = {};
440 + var promises = [];
441 +
442 + for (var i in sessions)
443 + {
444 + if (sessions[i].Username != 'reboot')
445 + {
446 + users[sessions[i].SessionId] = sessions[i];
447 + if(usernames[sessions[i].Username] == null)
448 + {
449 + usernames[sessions[i].Username] = -1;
450 + }
451 + }
452 + }
453 +
454 + try
455 + {
456 + require('promise');
457 + }
458 + catch(e)
459 + {
460 + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
461 + if (this.Parent._callback) { this.Parent._callback.call(this.Parent, users); }
462 + return;
463 + }
464 +
465 + var promise = require('promise');
466 + for (var n in usernames)
467 + {
468 + var p = new promise(function (res, rej)
469 + {
470 + this.__username = n;
471 + this.__resolver = res; this.__rejector = rej;
472 + this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u', n]);
473 + this.__child.promise = this;
474 + this.__child.stdout._txt = '';
475 + this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); });
476 + this.__child.on('exit', function (code)
477 + {
478 + try
479 + {
480 + parseInt(this.stdout._txt);
481 + }
482 + catch(e)
483 + {
484 + this.promise.__rejector('invalid uid');
485 + return;
486 + }
487 +
488 + var id = parseInt(this.stdout._txt);
489 + this.promise.__resolver(id);
490 + });
491 + });
492 + promises.push(p);
493 + }
494 + promise.all(promises).then(function (plist)
495 + {
496 + // Done
497 + var table = {};
498 + for(var i in plist)
499 + {
500 + table[plist[i].__username] = plist[i]._internal.completedArgs[0];
501 + }
502 + for(var i in users)
503 + {
504 + users[i].uid = table[users[i].Username];
505 + }
506 + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
507 + if (retVal._callback) { retVal._callback.call(retVal, users); }
508 + }, function (reason)
509 + {
510 + // Failed
511 + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
512 + if (retVal._callback) { retVal._callback.call(retVal, users); }
513 + });
514 + });
515 + retVal._child.stdout.Parent = retVal._child;
516 + retVal._child.stdout.on('data', function (chunk) { this.Parent._txt += chunk.toString(); });
517 +
518 + return (retVal);
519 + }
520 + this._recheckLoggedInUsers = function _recheckLoggedInUsers()
521 + {
522 + this.enumerateUsers().then(function (u)
523 + {
524 +
525 + if (u.Active.length > 0)
526 + {
527 + // There is already a user logged in, so we can monitor DBUS for lock/unlock
528 + if (this.parent._linux_lock_watcher != null && this.parent._linux_lock_watcher.uid != u.Active[0].uid)
529 + {
530 + delete this.parent._linux_lock_watcher;
531 + }
532 + this.parent._linux_lock_watcher = new dbus(process.env['XDG_CURRENT_DESKTOP'] == 'Unity' ? 'com.ubuntu.Upstart0_6' : 'org.gnome.ScreenSaver', u.Active[0].uid);
533 + this.parent._linux_lock_watcher.user_session = this.parent;
534 + this.parent._linux_lock_watcher.on('signal', function (s)
535 + {
536 + var p = this.user_session.enumerateUsers();
537 + p.signalData = s.data[0];
538 + p.then(function (u)
539 + {
540 + switch (this.signalData)
541 + {
542 + case true:
543 + case 'desktop-lock':
544 + this.parent.emit('locked', u.Active[0]);
545 + break;
546 + case false:
547 + case 'desktop-unlock':
548 + this.parent.emit('unlocked', u.Active[0]);
549 + break;
550 + }
551 + });
552 + });
553 + }
554 + else if (this.parent._linux_lock_watcher != null)
555 + {
556 + delete this.parent._linux_lock_watcher;
557 + }
558 + });
559 +
560 + };
561 + this.on('changed', this._recheckLoggedInUsers); // For linux Lock/Unlock monitoring, we need to watch for LogOn/LogOff, and keep track of the UID.
562 +
563 +
564 + // First step, is to see if there is a user logged in:
565 + this._recheckLoggedInUsers();
566 + }
567 + else if(process.platform == 'darwin')
568 + {
569 + this._users = function ()
570 + {
571 + var child = require('child_process').execFile('/usr/bin/dscl', ['dscl', '.', 'list', '/Users', 'UniqueID']);
572 + child.stdout.str = '';
573 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
574 + child.stdin.write('exit\n');
575 + child.waitExit();
576 +
577 + var lines = child.stdout.str.split('\n');
578 + var tokens, i;
579 + var users = {};
580 +
581 + for (i = 0; i < lines.length; ++i) {
582 + tokens = lines[i].split(' ');
583 + if (tokens[0]) { users[tokens[0]] = tokens[tokens.length - 1]; }
584 + }
585 +
586 + return (users);
587 + }
588 + this._uids = function () {
589 + var child = require('child_process').execFile('/usr/bin/dscl', ['dscl', '.', 'list', '/Users', 'UniqueID']);
590 + child.stdout.str = '';
591 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
592 + child.stdin.write('exit\n');
593 + child.waitExit();
594 +
595 + var lines = child.stdout.str.split('\n');
596 + var tokens, i;
597 + var users = {};
598 +
599 + for (i = 0; i < lines.length; ++i) {
600 + tokens = lines[i].split(' ');
601 + if (tokens[0]) { users[tokens[tokens.length - 1]] = tokens[0]; }
602 + }
603 +
604 + return (users);
605 + }
606 + this._idTable = function()
607 + {
608 + var table = {};
609 + var child = require('child_process').execFile('/usr/bin/id', ['id']);
610 + child.stdout.str = '';
611 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
612 + child.waitExit();
613 +
614 + var lines = child.stdout.str.split('\n')[0].split(' ');
615 + for (var i = 0; i < lines.length; ++i) {
616 + var types = lines[i].split('=');
617 + var tokens = types[1].split(',');
618 + table[types[0]] = {};
619 +
620 + for (var j in tokens) {
621 + var idarr = tokens[j].split('(');
622 + var id = idarr[0];
623 + var name = idarr[1].substring(0, idarr[1].length - 1).trim();
624 + table[types[0]][name] = id;
625 + table[types[0]][id] = name;
626 + }
627 + }
628 + return (table);
629 + }
630 + this.Current = function (cb)
631 + {
632 + var users = {};
633 + var table = this._idTable();
634 + var child = require('child_process').execFile('/usr/bin/last', ['last']);
635 + child.stdout.str = '';
636 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
637 + child.waitExit();
638 +
639 + var lines = child.stdout.str.split('\n');
640 + for (var i = 0; i < lines.length && lines[i].length > 0; ++i)
641 + {
642 + if (!users[lines[i].split(' ')[0]])
643 + {
644 + try
645 + {
646 + 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]] };
647 + }
648 + catch(e)
649 + {}
650 + }
651 + else
652 + {
653 + if(users[lines[i].split(' ')[0]].State != 'Active' && lines[i].split('still logged in').length > 1)
654 + {
655 + users[lines[i].split(' ')[0]].State = 'Active';
656 + }
657 + }
658 + }
659 +
660 + Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
661 + if (cb) { cb.call(this, users); }
662 + }
663 + }
664 +
665 + if(process.platform == 'linux' || process.platform == 'darwin')
666 + {
667 + this._self = function _self()
668 + {
669 + var child = require('child_process').execFile('/usr/bin/id', ['id', '-u']);
670 + child.stdout.str = '';
671 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
672 + child.waitExit();
673 + return (parseInt(child.stdout.str));
674 + }
675 + this.isRoot = function isRoot()
676 + {
677 + return (this._self() == 0);
678 + }
679 + this.consoleUid = function consoleUid()
680 + {
681 + var checkstr = process.platform == 'darwin' ? 'console' : ((process.env['DISPLAY'])?process.env['DISPLAY']:':0')
682 + var child = require('child_process').execFile('/bin/sh', ['sh']);
683 + child.stdout.str = '';
684 + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
685 + child.stdin.write('who\nexit\n');
686 + child.waitExit();
687 +
688 + var lines = child.stdout.str.split('\n');
689 + var tokens, i, j;
690 + for (i in lines)
691 + {
692 + tokens = lines[i].split(' ');
693 + for (j = 1; j < tokens.length; ++j)
694 + {
695 + if (tokens[j].length > 0)
696 + {
697 + return (parseInt(this._users()[tokens[0]]));
698 + }
699 + }
700 + }
701 +
702 + throw ('nobody logged into console');
703 + }
704 + }
705 +
706 +
707 +}
708 +function showActiveOnly(source)
709 +{
710 + var retVal = [];
711 + var unique = {};
712 + var usernames = [];
713 + var tmp;
714 +
715 + for (var i in source)
716 + {
717 + if (source[i].State == 'Active')
718 + {
719 + retVal.push(source[i]);
720 + tmp = (source[i].Domain ? (source[i].Domain + '\\') : '') + source[i].Username;
721 + if (!unique[tmp]) { unique[tmp] = tmp;}
722 + }
723 + }
724 +
725 + for (var i in unique)
726 + {
727 + usernames.push(i);
728 + }
729 +
730 + Object.defineProperty(retVal, 'usernames', { value: usernames });
731 + return (retVal);
732 +}
733 +function getTokens(str)
734 +{
735 + var columns = [];
736 + var i;
737 +
738 + columns.push(str.substring(0, (i=str.indexOf(' '))));
739 + while (str[++i] == ' ');
740 + columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i)));
741 + while (str[++i] == ' ');
742 + columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i)));
743 + while (str[++i] == ' ');
744 + var status = str.substring(i).trim();
745 + columns.push(status);
746 +
747 + return (columns);
748 +}
749 +
750 +module.exports = new UserSessions();
\ No newline at end of file
agents-new/modules_meshcore/x/win-message-pump.js new
+124
@@ -0,0 +1,124 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var WH_CALLWNDPROC = 4;
18 +var WM_QUIT = 0x0012;
19 +
20 +var GM = require('_GenericMarshal');
21 +
22 +function WindowsMessagePump(options)
23 +{
24 + this._ObjectID = 'win-message-pump';
25 + this._options = options;
26 + var emitterUtils = require('events').inherits(this);
27 + emitterUtils.createEvent('hwnd');
28 + emitterUtils.createEvent('error');
29 + emitterUtils.createEvent('message');
30 + emitterUtils.createEvent('exit');
31 +
32 + this._msg = GM.CreateVariable(GM.PointerSize == 4 ? 28 : 48);
33 + this._kernel32 = GM.CreateNativeProxy('Kernel32.dll');
34 + this._kernel32.mp = this;
35 + this._kernel32.CreateMethod('GetLastError');
36 + this._kernel32.CreateMethod('GetModuleHandleA');
37 +
38 + this._user32 = GM.CreateNativeProxy('User32.dll');
39 + this._user32.mp = this;
40 + this._user32.CreateMethod('GetMessageA');
41 + this._user32.CreateMethod('CreateWindowExA');
42 + this._user32.CreateMethod('TranslateMessage');
43 + this._user32.CreateMethod('DispatchMessageA');
44 + this._user32.CreateMethod('RegisterClassExA');
45 + this._user32.CreateMethod('DefWindowProcA');
46 + this._user32.CreateMethod('PostMessageA');
47 +
48 +
49 + this.wndclass = GM.CreateVariable(GM.PointerSize == 4 ? 48 : 80);
50 + this.wndclass.mp = this;
51 + this.wndclass.hinstance = this._kernel32.GetModuleHandleA(0);
52 + this.wndclass.cname = GM.CreateVariable('MainWWWClass');
53 + this.wndclass.wndproc = GM.GetGenericGlobalCallback(4);
54 + this.wndclass.wndproc.mp = this;
55 + this.wndclass.toBuffer().writeUInt32LE(this.wndclass._size);
56 + this.wndclass.cname.pointerBuffer().copy(this.wndclass.Deref(GM.PointerSize == 4 ? 40 : 64, GM.PointerSize).toBuffer());
57 + this.wndclass.wndproc.pointerBuffer().copy(this.wndclass.Deref(8, GM.PointerSize).toBuffer());
58 + this.wndclass.hinstance.pointerBuffer().copy(this.wndclass.Deref(GM.PointerSize == 4 ? 20 : 24, GM.PointerSize).toBuffer());
59 + this.wndclass.wndproc.on('GlobalCallback', function onWndProc(xhwnd, xmsg, wparam, lparam)
60 + {
61 + if (this.mp._hwnd != null && this.mp._hwnd.Val == xhwnd.Val)
62 + {
63 + // This is for us
64 + this.mp.emit('message', { message: xmsg.Val, wparam: wparam.Val, lparam: lparam.Val, lparam_hex: lparam.pointerBuffer().toString('hex') });
65 + return (this.mp._user32.DefWindowProcA(xhwnd, xmsg, wparam, lparam));
66 + }
67 + else if(this.mp._hwnd == null && this.CallingThread() == this.mp._user32.RegisterClassExA.async.threadId())
68 + {
69 + // This message was generated from our CreateWindowExA method
70 + return (this.mp._user32.DefWindowProcA(xhwnd, xmsg, wparam, lparam));
71 + }
72 + });
73 +
74 + this._user32.RegisterClassExA.async(this.wndclass).then(function ()
75 + {
76 + this.nativeProxy.CreateWindowExA.async(this.nativeProxy.RegisterClassExA.async, 0x00000088, this.nativeProxy.mp.wndclass.cname, 0, 0x00800000, 0, 0, 100, 100, 0, 0, 0, 0)
77 + .then(function(h)
78 + {
79 + if (h.Val == 0)
80 + {
81 + // Error creating hidden window
82 + this.nativeProxy.mp.emit('error', 'Error creating hidden window');
83 + }
84 + else
85 + {
86 + this.nativeProxy.mp._hwnd = h;
87 + this.nativeProxy.mp.emit('hwnd', h);
88 + this.nativeProxy.mp._startPump();
89 + }
90 + });
91 + });
92 + this._startPump = function _startPump()
93 + {
94 + this._user32.GetMessageA.async(this._user32.RegisterClassExA.async, this._msg, this._hwnd, 0, 0).then(function (r)
95 + {
96 + if(r.Val > 0)
97 + {
98 + this.nativeProxy.TranslateMessage.async(this.nativeProxy.RegisterClassExA.async, this.nativeProxy.mp._msg).then(function ()
99 + {
100 + this.nativeProxy.DispatchMessageA.async(this.nativeProxy.RegisterClassExA.async, this.nativeProxy.mp._msg).then(function ()
101 + {
102 + this.nativeProxy.mp._startPump();
103 + });
104 + });
105 + }
106 + else
107 + {
108 + // We got a 'QUIT' message
109 + delete this.nativeProxy.mp._hwnd;
110 + this.nativeProxy.mp.emit('exit', 0);
111 + }
112 + }, function (err) { this.nativeProxy.mp.stop(); });
113 + }
114 +
115 + this.stop = function stop()
116 + {
117 + if (this._hwnd)
118 + {
119 + this._user32.PostMessageA(this._hwnd, WM_QUIT, 0, 0);
120 + }
121 + };
122 +}
123 +
124 +module.exports = WindowsMessagePump;
agents-new/modules_meshcore/x/win-registry.js new
+218
@@ -0,0 +1,218 @@
1 +/*
2 +Copyright 2018 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +var KEY_QUERY_VALUE = 0x0001;
18 +var KEY_ENUMERATE_SUB_KEYS = 0x0008;
19 +var KEY_WRITE = 0x20006;
20 +
21 +var KEY_DATA_TYPES =
22 + {
23 + REG_NONE: 0,
24 + REG_SZ: 1,
25 + REG_EXPAND_SZ: 2,
26 + REG_BINARY: 3,
27 + REG_DWORD: 4,
28 + REG_DWORD_BIG_ENDIAN: 5,
29 + REG_LINK: 6,
30 + REG_MULTI_SZ: 7,
31 + REG_RESOURCE_LIST: 8,
32 + REG_FULL_RESOURCE_DESCRIPTOR: 9,
33 + REG_RESOURCE_REQUIREMENTS_LIST: 10,
34 + REG_QWORD: 11
35 + };
36 +
37 +function windows_registry()
38 +{
39 + this._ObjectId = 'win-registry';
40 + this._marshal = require('_GenericMarshal');
41 + this._AdvApi = this._marshal.CreateNativeProxy('Advapi32.dll');
42 + this._AdvApi.CreateMethod('RegCreateKeyExA');
43 + this._AdvApi.CreateMethod('RegEnumKeyExA');
44 + this._AdvApi.CreateMethod('RegEnumValueA');
45 + this._AdvApi.CreateMethod('RegOpenKeyExA');
46 + this._AdvApi.CreateMethod('RegQueryInfoKeyA');
47 + this._AdvApi.CreateMethod('RegQueryValueExA');
48 + this._AdvApi.CreateMethod('RegCloseKey');
49 + this._AdvApi.CreateMethod('RegDeleteKeyA');
50 + this._AdvApi.CreateMethod('RegDeleteValueA');
51 + this._AdvApi.CreateMethod('RegSetValueExA');
52 + 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() };
53 +
54 + this.QueryKey = function QueryKey(hkey, path, key)
55 + {
56 + var err;
57 + var h = this._marshal.CreatePointer();
58 + var len = this._marshal.CreateVariable(4);
59 + var valType = this._marshal.CreateVariable(4);
60 + var HK = this._marshal.CreatePointer(hkey);
61 + var retVal = null;
62 + if (key) { key = this._marshal.CreateVariable(key); }
63 + if (!path) { path = ''; }
64 +
65 +
66 + if ((err = this._AdvApi.RegOpenKeyExA(HK, this._marshal.CreateVariable(path), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, h).Val) != 0)
67 + {
68 + throw ('Opening Registry Key: ' + path + ' => Returned Error: ' + err);
69 + }
70 +
71 + if ((path == '' && !key) || !key)
72 + {
73 + var result = { subkeys: [], values: [] };
74 +
75 + // Enumerate keys
76 + var achClass = this._marshal.CreateVariable(1024);
77 + var achKey = this._marshal.CreateVariable(1024);
78 + var achValue = this._marshal.CreateVariable(32768);
79 + var achValueSize = this._marshal.CreateVariable(4);
80 + var nameSize = this._marshal.CreateVariable(4);
81 + var achClassSize = this._marshal.CreateVariable(4); achClassSize.toBuffer().writeUInt32LE(1024);
82 + var numSubKeys = this._marshal.CreateVariable(4);
83 + var numValues = this._marshal.CreateVariable(4);
84 + var longestSubkeySize = this._marshal.CreateVariable(4);
85 + var longestClassString = this._marshal.CreateVariable(4);
86 + var longestValueName = this._marshal.CreateVariable(4);
87 + var longestValueData = this._marshal.CreateVariable(4);
88 + var securityDescriptor = this._marshal.CreateVariable(4);
89 + var lastWriteTime = this._marshal.CreateVariable(8);
90 +
91 + retVal = this._AdvApi.RegQueryInfoKeyA(h.Deref(), achClass, achClassSize, 0,
92 + numSubKeys, longestSubkeySize, longestClassString, numValues,
93 + longestValueName, longestValueData, securityDescriptor, lastWriteTime);
94 + if (retVal.Val != 0) { throw ('RegQueryInfoKeyA() returned error: ' + retVal.Val); }
95 + for(var i = 0; i < numSubKeys.toBuffer().readUInt32LE(); ++i)
96 + {
97 + nameSize.toBuffer().writeUInt32LE(1024);
98 + retVal = this._AdvApi.RegEnumKeyExA(h.Deref(), i, achKey, nameSize, 0, 0, 0, lastWriteTime);
99 + if(retVal.Val == 0)
100 + {
101 + result.subkeys.push(achKey.String);
102 + }
103 + }
104 + for (var i = 0; i < numValues.toBuffer().readUInt32LE() ; ++i)
105 + {
106 + achValueSize.toBuffer().writeUInt32LE(32768);
107 + if(this._AdvApi.RegEnumValueA(h.Deref(), i, achValue, achValueSize, 0, 0, 0, 0).Val == 0)
108 + {
109 + result.values.push(achValue.String);
110 + }
111 + }
112 + return (result);
113 + }
114 +
115 + if(this._AdvApi.RegQueryValueExA(h.Deref(), key, 0, 0, 0, len).Val == 0)
116 + {
117 + var data = this._marshal.CreateVariable(len.toBuffer().readUInt32LE());
118 + if (this._AdvApi.RegQueryValueExA(h.Deref(), key, 0, valType, data, len).Val == 0)
119 + {
120 + switch(valType.toBuffer().readUInt32LE())
121 + {
122 + case KEY_DATA_TYPES.REG_DWORD:
123 + retVal = data.toBuffer().readUInt32LE();
124 + break;
125 + case KEY_DATA_TYPES.REG_DWORD_BIG_ENDIAN:
126 + retVal = data.toBuffer().readUInt32BE();
127 + break;
128 + case KEY_DATA_TYPES.REG_SZ:
129 + retVal = data.String;
130 + break;
131 + case KEY_DATA_TYPES.REG_BINARY:
132 + default:
133 + retVal = data.toBuffer();
134 + retVal._data = data;
135 + break;
136 + }
137 + }
138 + }
139 + else
140 + {
141 + this._AdvApi.RegCloseKey(h.Deref());
142 + throw ('Not Found');
143 + }
144 + this._AdvApi.RegCloseKey(h.Deref());
145 + return (retVal);
146 + };
147 + this.WriteKey = function WriteKey(hkey, path, key, value)
148 + {
149 + var result;
150 + var h = this._marshal.CreatePointer();
151 +
152 + if (this._AdvApi.RegCreateKeyExA(this._marshal.CreatePointer(hkey), this._marshal.CreateVariable(path), 0, 0, 0, KEY_WRITE, 0, h, 0).Val != 0)
153 + {
154 + throw ('Error Opening Registry Key: ' + path);
155 + }
156 +
157 + var data;
158 + var dataType;
159 +
160 + switch(typeof(value))
161 + {
162 + case 'boolean':
163 + dataType = KEY_DATA_TYPES.REG_DWORD;
164 + data = this._marshal.CreateVariable(4);
165 + data.toBuffer().writeUInt32LE(value ? 1 : 0);
166 + break;
167 + case 'number':
168 + dataType = KEY_DATA_TYPES.REG_DWORD;
169 + data = this._marshal.CreateVariable(4);
170 + data.toBuffer().writeUInt32LE(value);
171 + break;
172 + case 'string':
173 + dataType = KEY_DATA_TYPES.REG_SZ;
174 + data = this._marshal.CreateVariable(value);
175 + break;
176 + default:
177 + dataType = KEY_DATA_TYPES.REG_BINARY;
178 + data = this._marshal.CreateVariable(value.length);
179 + value.copy(data.toBuffer());
180 + break;
181 + }
182 +
183 + if(this._AdvApi.RegSetValueExA(h.Deref(), this._marshal.CreateVariable(key), 0, dataType, data, data._size).Val != 0)
184 + {
185 + this._AdvApi.RegCloseKey(h.Deref());
186 + throw ('Error writing reg key: ' + key);
187 + }
188 + this._AdvApi.RegCloseKey(h.Deref());
189 + };
190 + this.DeleteKey = function DeleteKey(hkey, path, key)
191 + {
192 + if(!key)
193 + {
194 + if(this._AdvApi.RegDeleteKeyA(this._marshal.CreatePointer(hkey), this._marshal.CreateVariable(path)).Val != 0)
195 + {
196 + throw ('Error Deleting Key: ' + path);
197 + }
198 + }
199 + else
200 + {
201 + var h = this._marshal.CreatePointer();
202 + var result;
203 + if (this._AdvApi.RegOpenKeyExA(this._marshal.CreatePointer(hkey), this._marshal.CreateVariable(path), 0, KEY_QUERY_VALUE | KEY_WRITE, h).Val != 0)
204 + {
205 + throw ('Error Opening Registry Key: ' + path);
206 + }
207 + if ((result = this._AdvApi.RegDeleteValueA(h.Deref(), this._marshal.CreateVariable(key)).Val) != 0)
208 + {
209 + this._AdvApi.RegCloseKey(h.Deref());
210 + throw ('Error[' + result + '] Deleting Key: ' + path + '.' + key);
211 + }
212 + this._AdvApi.RegCloseKey(h.Deref());
213 + }
214 + };
215 +}
216 +
217 +module.exports = new windows_registry();
218 +
agents-new/recoverycore.js new
+466
@@ -0,0 +1,466 @@
1 +
2 +var http = require('http');
3 +var childProcess = require('child_process');
4 +var meshCoreObj = { "action": "coreinfo", "value": "MeshCore Recovery", "caps": 14 }; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript
5 +var nextTunnelIndex = 1;
6 +var tunnels = {};
7 +var fs = require('fs');
8 +
9 +//attachDebugger({ webport: 9994, wait: 1 }).then(function (p) { console.log('Debug on port: ' + p); });
10 +
11 +function sendConsoleText(msg)
12 +{
13 + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": msg });
14 +}
15 +// Return p number of spaces
16 +function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ret; } return r; }
17 +
18 +var path =
19 + {
20 + join: function ()
21 + {
22 + var x = [];
23 + for (var i in arguments)
24 + {
25 + var w = arguments[i];
26 + if (w != null)
27 + {
28 + while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
29 + if (i != 0)
30 + {
31 + while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); }
32 + }
33 + x.push(w);
34 + }
35 + }
36 + if (x.length == 0) return '/';
37 + return x.join('/');
38 + }
39 + };
40 +// Convert an object to string with all functions
41 +function objToString(x, p, pad, ret) {
42 + if (ret == undefined) ret = '';
43 + if (p == undefined) p = 0;
44 + if (x == null) { return '[null]'; }
45 + if (p > 8) { return '[...]'; }
46 + if (x == undefined) { return '[undefined]'; }
47 + if (typeof x == 'string') { if (p == 0) return x; return '"' + x + '"'; }
48 + if (typeof x == 'buffer') { return '[buffer]'; }
49 + if (typeof x != 'object') { return x; }
50 + var r = '{' + (ret ? '\r\n' : ' ');
51 + for (var i in x) { if (i != '_ObjectID') { r += (addPad(p + 2, pad) + i + ': ' + objToString(x[i], p + 2, pad, ret) + (ret ? '\r\n' : ' ')); } }
52 + return r + addPad(p, pad) + '}';
53 +}
54 +
55 +// Split a string taking into account the quoats. Used for command line parsing
56 +function splitArgs(str)
57 +{
58 + var myArray = [], myRegexp = /[^\s"]+|"([^"]*)"/gi;
59 + do { var match = myRegexp.exec(str); if (match != null) { myArray.push(match[1] ? match[1] : match[0]); } } while (match != null);
60 + return myArray;
61 +}
62 +
63 +// Parse arguments string array into an object
64 +function parseArgs(argv)
65 +{
66 + var results = { '_': [] }, current = null;
67 + for (var i = 1, len = argv.length; i < len; i++) {
68 + var x = argv[i];
69 + if (x.length > 2 && x[0] == '-' && x[1] == '-') {
70 + if (current != null) { results[current] = true; }
71 + current = x.substring(2);
72 + } else {
73 + if (current != null) { results[current] = toNumberIfNumber(x); current = null; } else { results['_'].push(toNumberIfNumber(x)); }
74 + }
75 + }
76 + if (current != null) { results[current] = true; }
77 + return results;
78 +}
79 +// Get server target url with a custom path
80 +function getServerTargetUrl(path)
81 +{
82 + var x = require('MeshAgent').ServerUrl;
83 + //sendConsoleText("mesh.ServerUrl: " + mesh.ServerUrl);
84 + if (x == null) { return null; }
85 + if (path == null) { path = ''; }
86 + x = http.parseUri(x);
87 + if (x == null) return null;
88 + return x.protocol + '//' + x.host + ':' + x.port + '/' + path;
89 +}
90 +
91 +// Get server url. If the url starts with "*/..." change it, it not use the url as is.
92 +function getServerTargetUrlEx(url)
93 +{
94 + if (url.substring(0, 2) == '*/') { return getServerTargetUrl(url.substring(2)); }
95 + return url;
96 +}
97 +
98 +require('MeshAgent').on('Connected', function ()
99 +{
100 + require('os').name().then(function (v)
101 + {
102 + sendConsoleText("Mesh Agent Receovery Console, OS: " + v);
103 + require('MeshAgent').SendCommand(meshCoreObj);
104 + });
105 +});
106 +
107 +// Tunnel callback operations
108 +function onTunnelUpgrade(response, s, head) {
109 + this.s = s;
110 + s.httprequest = this;
111 + s.end = onTunnelClosed;
112 + s.tunnel = this;
113 +
114 + //sendConsoleText('onTunnelUpgrade');
115 +
116 + if (this.tcpport != null) {
117 + // This is a TCP relay connection, pause now and try to connect to the target.
118 + s.pause();
119 + s.data = onTcpRelayServerTunnelData;
120 + var connectionOptions = { port: parseInt(this.tcpport) };
121 + if (this.tcpaddr != null) { connectionOptions.host = this.tcpaddr; } else { connectionOptions.host = '127.0.0.1'; }
122 + s.tcprelay = net.createConnection(connectionOptions, onTcpRelayTargetTunnelConnect);
123 + s.tcprelay.peerindex = this.index;
124 + } else {
125 + // This is a normal connect for KVM/Terminal/Files
126 + s.data = onTunnelData;
127 + }
128 +}
129 +
130 +require('MeshAgent').AddCommandHandler(function (data)
131 +{
132 + if (typeof data == 'object')
133 + {
134 + // If this is a console command, parse it and call the console handler
135 + switch (data.action)
136 + {
137 + case 'msg':
138 + {
139 + switch (data.type)
140 + {
141 + case 'console': { // Process a console command
142 + if (data.value && data.sessionid)
143 + {
144 + var args = splitArgs(data.value);
145 + processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid);
146 + }
147 + break;
148 + }
149 + case 'tunnel':
150 + {
151 + if (data.value != null) { // Process a new tunnel connection request
152 + // Create a new tunnel object
153 + var xurl = getServerTargetUrlEx(data.value);
154 + if (xurl != null) {
155 + var woptions = http.parseUri(xurl);
156 + woptions.rejectUnauthorized = 0;
157 + //sendConsoleText(JSON.stringify(woptions));
158 + var tunnel = http.request(woptions);
159 + tunnel.on('upgrade', function (response, s, head)
160 + {
161 + this.s = s;
162 + s.httprequest = this;
163 + s.tunnel = this;
164 + s.on('end', function ()
165 + {
166 + if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls.
167 +
168 + // If there is a upload or download active on this connection, close the file
169 + if (this.httprequest.uploadFile) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
170 + if (this.httprequest.downloadFile) { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; }
171 +
172 +
173 + //sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid);
174 + delete tunnels[this.httprequest.index];
175 +
176 + // Clean up WebSocket
177 + this.removeAllListeners('data');
178 + });
179 + s.on('data', function (data)
180 + {
181 + // If this is upload data, save it to file
182 + if (this.httprequest.uploadFile)
183 + {
184 + 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.
185 + this.write(new Buffer(JSON.stringify({ action: 'uploadack', reqid: this.httprequest.uploadFileid }))); // Ask for more data
186 + return;
187 + }
188 +
189 + if (this.httprequest.state == 0) {
190 + // Check if this is a relay connection
191 + if (data == 'c') { this.httprequest.state = 1; sendConsoleText("Tunnel #" + this.httprequest.index + " now active", this.httprequest.sessionid); }
192 + } else {
193 + // Handle tunnel data
194 + if (this.httprequest.protocol == 0)
195 + {
196 + // Take a look at the protocol
197 + this.httprequest.protocol = parseInt(data);
198 + if (typeof this.httprequest.protocol != 'number') { this.httprequest.protocol = 0; }
199 + if (this.httprequest.protocol == 1)
200 + {
201 + // Remote terminal using native pipes
202 + if (process.platform == "win32")
203 + {
204 + this.httprequest._term = require('win-terminal').Start(80, 25);
205 + this.httprequest._term.pipe(this, { dataTypeSkip: 1 });
206 + this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false });
207 + this.prependListener('end', function () { this.httprequest._term.end(function () { sendConsoleText('Terminal was closed'); }); });
208 + }
209 + else
210 + {
211 + this.httprequest.process = childProcess.execFile("/bin/sh", ["sh"], { type: childProcess.SpawnTypes.TERM });
212 + this.httprequest.process.tunnel = this;
213 + this.httprequest.process.on('exit', function (ecode, sig) { this.tunnel.end(); });
214 + this.httprequest.process.stderr.on('data', function (chunk) { this.parent.tunnel.write(chunk); });
215 + this.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
216 + this.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
217 + this.prependListener('end', function () { this.httprequest.process.kill(); });
218 + }
219 +
220 + this.on('end', function () {
221 + if (process.platform == "win32")
222 + {
223 + // Unpipe the web socket
224 + this.unpipe(this.httprequest._term);
225 + this.httprequest._term.unpipe(this);
226 +
227 + // Clean up
228 + this.httprequest._term.end();
229 + this.httprequest._term = null;
230 + }
231 + });
232 + }
233 + }
234 + else if (this.httprequest.protocol == 5)
235 + {
236 + // Process files commands
237 + var cmd = null;
238 + try { cmd = JSON.parse(data); } catch (e) { };
239 + if (cmd == null) { return; }
240 + if ((cmd.ctrlChannel == '102938') || ((cmd.type == 'offer') && (cmd.sdp != null))) { return; } // If this is control data, handle it now.
241 + if (cmd.action == undefined) { return; }
242 + console.log('action: ', cmd.action);
243 +
244 + //sendConsoleText('CMD: ' + JSON.stringify(cmd));
245 +
246 + if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
247 + //console.log(objToString(cmd, 0, ' '));
248 + switch (cmd.action)
249 + {
250 + case 'ls':
251 + // Send the folder content to the browser
252 + var response = getDirectoryInfo(cmd.path);
253 + if (cmd.reqid != undefined) { response.reqid = cmd.reqid; }
254 + this.write(new Buffer(JSON.stringify(response)));
255 + break;
256 + case 'mkdir': {
257 + // Create a new empty folder
258 + fs.mkdirSync(cmd.path);
259 + break;
260 + }
261 + case 'rm': {
262 + // Delete, possibly recursive delete
263 + for (var i in cmd.delfiles)
264 + {
265 + try { deleteFolderRecursive(path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (e) { }
266 + }
267 + break;
268 + }
269 + case 'rename': {
270 + // Rename a file or folder
271 + var oldfullpath = path.join(cmd.path, cmd.oldname);
272 + var newfullpath = path.join(cmd.path, cmd.newname);
273 + try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); }
274 + break;
275 + }
276 + case 'upload': {
277 + // Upload a file, browser to agent
278 + if (this.httprequest.uploadFile != undefined) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
279 + if (cmd.path == undefined) break;
280 + var filepath = cmd.name ? path.join(cmd.path, cmd.name) : cmd.path;
281 + try { this.httprequest.uploadFile = fs.openSync(filepath, 'wbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror', reqid: cmd.reqid }))); break; }
282 + this.httprequest.uploadFileid = cmd.reqid;
283 + if (this.httprequest.uploadFile) { this.write(new Buffer(JSON.stringify({ action: 'uploadstart', reqid: this.httprequest.uploadFileid }))); }
284 + break;
285 + }
286 + case 'copy': {
287 + // Copy a bunch of files from scpath to dspath
288 + for (var i in cmd.names) {
289 + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
290 + if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
291 + }
292 + break;
293 + }
294 + case 'move': {
295 + // Move a bunch of files from scpath to dspath
296 + for (var i in cmd.names) {
297 + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
298 + if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
299 + }
300 + break;
301 + }
302 + }
303 + }
304 + }
305 + });
306 + });
307 + tunnel.onerror = function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); }
308 + tunnel.sessionid = data.sessionid;
309 + tunnel.rights = data.rights;
310 + tunnel.state = 0;
311 + tunnel.url = xurl;
312 + tunnel.protocol = 0;
313 + tunnel.tcpaddr = data.tcpaddr;
314 + tunnel.tcpport = data.tcpport;
315 + tunnel.end();
316 + // Put the tunnel in the tunnels list
317 + var index = nextTunnelIndex++;
318 + tunnel.index = index;
319 + tunnels[index] = tunnel;
320 +
321 + //sendConsoleText('New tunnel connection #' + index + ': ' + tunnel.url + ', rights: ' + tunnel.rights, data.sessionid);
322 + }
323 + }
324 + break;
325 + }
326 +
327 + default:
328 + // Unknown action, ignore it.
329 + break;
330 + }
331 + break;
332 + }
333 + default:
334 + // Unknown action, ignore it.
335 + break;
336 + }
337 + }
338 +});
339 +
340 +function processConsoleCommand(cmd, args, rights, sessionid)
341 +{
342 + try
343 + {
344 + var response = null;
345 + switch (cmd)
346 + {
347 + case 'help':
348 + response = 'Available commands are: osinfo, dbkeys, dbget, dbset, dbcompact, netinfo.';
349 + break;
350 +
351 + case 'osinfo': { // Return the operating system information
352 + var i = 1;
353 + if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; }
354 + for (var j = 0; j < i; j++) {
355 + var pr = require('os').name();
356 + pr.sessionid = sessionid;
357 + pr.then(function (v) { sendConsoleText("OS: " + v, this.sessionid); });
358 + }
359 + break;
360 + }
361 + case 'dbkeys': { // Return all data store keys
362 + response = JSON.stringify(db.Keys);
363 + break;
364 + }
365 + case 'dbget': { // Return the data store value for a given key
366 + if (db == null) { response = 'Database not accessible.'; break; }
367 + if (args['_'].length != 1) {
368 + response = 'Proper usage: dbget (key)'; // Display the value for a given database key
369 + } else {
370 + response = db.Get(args['_'][0]);
371 + }
372 + break;
373 + }
374 + case 'dbset': { // Set a data store key and value pair
375 + if (db == null) { response = 'Database not accessible.'; break; }
376 + if (args['_'].length != 2) {
377 + response = 'Proper usage: dbset (key) (value)'; // Set a database key
378 + } else {
379 + var r = db.Put(args['_'][0], args['_'][1]);
380 + response = 'Key set: ' + r;
381 + }
382 + break;
383 + }
384 + case 'dbcompact': { // Compact the data store
385 + if (db == null) { response = 'Database not accessible.'; break; }
386 + var r = db.Compact();
387 + response = 'Database compacted: ' + r;
388 + break;
389 + }
390 + case 'tunnels': { // Show the list of current tunnels
391 + response = '';
392 + for (var i in tunnels) { response += 'Tunnel #' + i + ', ' + tunnels[i].url + '\r\n'; }
393 + if (response == '') { response = 'No websocket sessions.'; }
394 + break;
395 + }
396 + case 'netinfo': { // Show network interface information
397 + //response = objToString(mesh.NetInfo, 0, ' ');
398 + var interfaces = require('os').networkInterfaces();
399 + response = objToString(interfaces, 0, ' ', true);
400 + break;
401 + }
402 + default: { // This is an unknown command, return an error message
403 + response = 'Unknown command \"' + cmd + '\", type \"help\" for list of avaialble commands.';
404 + break;
405 + }
406 + }
407 + } catch (e) { response = 'Command returned an exception error: ' + e; console.log(e); }
408 + if (response != null) { sendConsoleText(response, sessionid); }
409 +}
410 +
411 +// Get a formated response for a given directory path
412 +function getDirectoryInfo(reqpath)
413 +{
414 + var response = { path: reqpath, dir: [] };
415 + if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) {
416 + // List all the drives in the root, or the root itself
417 + var results = null;
418 + try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
419 + if (results != null) {
420 + for (var i = 0; i < results.length; ++i) {
421 + var drive = { n: results[i].name, t: 1 };
422 + if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons.
423 + response.dir.push(drive);
424 + }
425 + }
426 + } else {
427 + // List all the files and folders in this path
428 + if (reqpath == '') { reqpath = '/'; }
429 + var results = null, xpath = path.join(reqpath, '*');
430 + //if (process.platform == "win32") { xpath = xpath.split('/').join('\\'); }
431 + try { results = fs.readdirSync(xpath); } catch (e) { }
432 + if (results != null) {
433 + for (var i = 0; i < results.length; ++i) {
434 + if ((results[i] != '.') && (results[i] != '..')) {
435 + var stat = null, p = path.join(reqpath, results[i]);
436 + //if (process.platform == "win32") { p = p.split('/').join('\\'); }
437 + try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date
438 + if ((stat != null) && (stat != undefined)) {
439 + if (stat.isDirectory() == true) {
440 + response.dir.push({ n: results[i], t: 2, d: stat.mtime });
441 + } else {
442 + response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime });
443 + }
444 + }
445 + }
446 + }
447 + }
448 + }
449 + return response;
450 +}
451 +// Delete a directory with a files and directories within it
452 +function deleteFolderRecursive(path, rec) {
453 + if (fs.existsSync(path)) {
454 + if (rec == true) {
455 + fs.readdirSync(path.join(path, '*')).forEach(function (file, index) {
456 + var curPath = path.join(path, file);
457 + if (fs.statSync(curPath).isDirectory()) { // recurse
458 + deleteFolderRecursive(curPath, true);
459 + } else { // delete file
460 + fs.unlinkSync(curPath);
461 + }
462 + });
463 + }
464 + fs.unlinkSync(path);
465 + }
466 +};
agents-new/testsuite.js new
+157
@@ -0,0 +1,157 @@
1 +/*
2 +Copyright 2017-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +
18 +// Polyfill String.endsWith
19 +if (!String.prototype.endsWith) {
20 + String.prototype.endsWith = function (searchString, position) {
21 + var subjectString = this.toString();
22 + if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { position = subjectString.length; }
23 + position -= searchString.length;
24 + var lastIndex = subjectString.lastIndexOf(searchString, position);
25 + return lastIndex !== -1 && lastIndex === position;
26 + };
27 +}
28 +
29 +// Replace a string with a number if the string is an exact number
30 +function toNumberIfNumber(x) { if ((typeof x == 'string') && (+parseInt(x) == x)) { x = parseInt(x); } return x; }
31 +
32 +// Convert decimal to hex
33 +function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); }
34 +
35 +// Convert a raw string to a hex string
36 +function rstr2hex(input) { var r = '', i; for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); } return r; }
37 +
38 +// Convert a buffer into a string
39 +function buf2rstr(buf) { var r = ''; for (var i = 0; i < buf.length; i++) { r += String.fromCharCode(buf[i]); } return r; }
40 +
41 +// Convert a hex string to a raw string // TODO: Do this using Buffer(), will be MUCH faster
42 +function hex2rstr(d) {
43 + if (typeof d != "string" || d.length == 0) return '';
44 + var r = '', m = ('' + d).match(/../g), t;
45 + while (t = m.shift()) r += String.fromCharCode('0x' + t);
46 + return r
47 +}
48 +
49 +// Convert an object to string with all functions
50 +function objToString(x, p, ret) {
51 + if (ret == undefined) ret = '';
52 + if (p == undefined) p = 0;
53 + if (x == null) { return '[null]'; }
54 + if (p > 8) { return '[...]'; }
55 + if (x == undefined) { return '[undefined]'; }
56 + if (typeof x == 'string') { if (p == 0) return x; return '"' + x + '"'; }
57 + if (typeof x == 'buffer') { return '[buffer]'; }
58 + if (typeof x != 'object') { return x; }
59 + var r = '{' + (ret ? '\r\n' : ' ');
60 + for (var i in x) { r += (addPad(p + 2, ret) + i + ': ' + objToString(x[i], p + 2, ret) + (ret ? '\r\n' : ' ')); }
61 + return r + addPad(p, ret) + '}';
62 +}
63 +
64 +// Return p number of spaces
65 +function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ret; } return r; }
66 +
67 +// Split a string taking into account the quoats. Used for command line parsing
68 +function splitArgs(str) {
69 + var myArray = [], myRegexp = /[^\s"]+|"([^"]*)"/gi;
70 + do { var match = myRegexp.exec(str); if (match != null) { myArray.push(match[1] ? match[1] : match[0]); } } while (match != null);
71 + return myArray;
72 +}
73 +
74 +// Parse arguments string array into an object
75 +function parseArgs(argv) {
76 + var results = { '_': [] }, current = null;
77 + for (var i = 1, len = argv.length; i < len; i++) {
78 + var x = argv[i];
79 + if (x.length > 2 && x[0] == '-' && x[1] == '-') {
80 + if (current != null) { results[current] = true; }
81 + current = x.substring(2);
82 + } else {
83 + if (current != null) { results[current] = toNumberIfNumber(x); current = null; } else { results['_'].push(toNumberIfNumber(x)); }
84 + }
85 + }
86 + if (current != null) { results[current] = true; }
87 + return results;
88 +}
89 +
90 +// Parge a URL string into an options object
91 +function parseUrl(url) {
92 + var x = url.split('/');
93 + if (x.length < 4) return null;
94 + var y = x[2].split(':');
95 + var options = {};
96 + var options = { protocol: x[0], hostname: y[0], path: '/' + x.splice(3).join('/') };
97 + if (y.length == 1) { options.port = ((x[0] == 'https:') || (x[0] == 'wss:')) ? 443 : 80; } else { options.port = parseInt(y[1]); }
98 + if (isNaN(options.port) == true) return null;
99 + return options;
100 +}
101 +
102 +//console.log(objToString(db2, 2, ' '));
103 +
104 +{
105 + // TODO: Fix this to use the event emitor
106 + // TODO: Add SHA256 sync
107 + console.log('--- Test 1: SHA256 hashing ---');
108 + var sha256 = require('SHA256Stream');
109 + sha256.hashString = function (x) { if (x == '81B637D8FCD2C6DA6359E6963113A1170DE795E4B725B84D1E0B4CFD9EC58CE9') { console.log('Test 1 - OK: ' + x); } else { console.log('Test 1 - FAIL: ' + x); } };
110 + sha256.write('bob');
111 + sha256.end();
112 +}
113 +{
114 + // FAIL!!!!!!!!!
115 + var sha256x = require('SHA256Stream');
116 + sha256x.hashString = function (x) { if (x == '81B637D8FCD2C6DA6359E6963113A1170DE795E4B725B84D1E0B4CFD9EC58CE9') { console.log('Test 1 - OK: ' + x); } else { console.log('Test 1 - FAIL: ' + x); } };
117 + sha256x.write('bob');
118 + sha256x.end();
119 +}
120 +
121 +/*
122 +{
123 + console.log('--- Test 2: Database ---');
124 + var db = require('SimpleDataStore').Create('TestSuite.db');
125 + var sha256 = require('SHA256Stream');
126 +
127 + // Write a pile of hashes to the DB
128 + sha256.hashString = function (x) { db.Put(x.substring(0, 16), x.substring(16)); console.log('ADD: ' + x.substring(0, 16) + ': ' + x.substring(16)); };
129 + for (var i = 0; i < 10; i++) { console.log(i); sha256.write('A' + i); sha256.end(); }
130 +
131 + // Compact plenty of times
132 + for (var i = 0; i < 10; i++) { console.log(i); db.Compact(); }
133 +
134 + // Check all the hashes
135 + sha256.hashString = function (x) {
136 + var r = db.Get(x.substring(0, 16));
137 + console.log('GET: ' + x.substring(0, 16) + ': ' + r);
138 + if (r != x.substring(16)) { console.log('FAILED ' + x.substring(0, 16) + ': ' + x.substring(16) + ' != ' + r); }
139 + //db.Put(x.substring(0, 16), '');
140 + };
141 + for (var i = 0; i < 10; i++) { console.log(i); sha256.write('A' + i); sha256.end(); }
142 + console.log('Test 2 - Completed.');
143 +}
144 +*/
145 +
146 +{
147 + console.log('--- Test 3: Files ---');
148 + var r, fs = require('fs');
149 + //console.log(objToString(fs, 2, ' '));
150 + r = fs.mkdirSync('TestSuite-123');
151 + r = fs.renameSync('TestSuite-123', 'TestSuite-1234');
152 + console.log(r);
153 + r = fs.unlinkSync('TestSuite-1234');
154 +}
155 +
156 +console.log('--- Tests Completed ---');
157 +process.exit(2);
\ No newline at end of file
agents-new/tinycore.js new
+67
@@ -0,0 +1,67 @@
1 +/*
2 +Copyright 2018-2019 Intel Corporation
3 +
4 +Licensed under the Apache License, Version 2.0 (the "License");
5 +you may not use this file except in compliance with the License.
6 +You may obtain a copy of the License at
7 +
8 + http://www.apache.org/licenses/LICENSE-2.0
9 +
10 +Unless required by applicable law or agreed to in writing, software
11 +distributed under the License is distributed on an "AS IS" BASIS,
12 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 +See the License for the specific language governing permissions and
14 +limitations under the License.
15 +*/
16 +
17 +function createMeshCore(agent) {
18 + var obj = {};
19 +
20 + // MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent.
21 + obj.meshCoreInfo = "TinyCore v1";
22 +
23 + if (agent == null) {
24 + // If we are running in Duktape, agent will be null
25 + var mesh = require('MeshAgent');
26 + } else {
27 + // Running in nodejs
28 + var mesh = agent.getMeshApi();
29 + }
30 +
31 + // Handle a mesh agent command
32 + function handleServerCommand(data) {
33 + if ((typeof data == 'object') && (data.action == 'msg') && (data.type == 'console') && data.value && data.sessionid) {
34 + mesh.SendCommand({ "action": "msg", "type": "console", "value": "Tiny core: " + data.value, "sessionid": data.sessionid });
35 + }
36 + }
37 +
38 + // Called when the server connection state changes
39 + function handleServerConnection(state) {
40 + if (state == 1) { mesh.SendCommand({ "action": "coreinfo", "value": obj.meshCoreInfo }); } // Server connected, send mesh core information
41 + }
42 +
43 + obj.start = function() {
44 + // Hook up mesh agent events
45 + mesh.AddCommandHandler(handleServerCommand);
46 + mesh.AddConnectHandler(handleServerConnection);
47 + mesh.SendCommand({ "action": "coreinfo", "value": obj.meshCoreInfo }); // TODO: Check if connected before sending
48 + }
49 +
50 + obj.stop = function() {
51 + mesh.AddCommandHandler(null);
52 + mesh.AddConnectHandler(null);
53 + }
54 +
55 + return obj;
56 +}
57 +
58 +var xexports = null;
59 +try { xexports = module.exports; } catch (e) { }
60 +
61 +if (xexports != null) {
62 + // If we are running within NodeJS, export the core
63 + module.exports.createMeshCore = createMeshCore;
64 +} else {
65 + // If we are not running in NodeJS, launch the core
66 + createMeshCore().start(null);
67 +}
meshagent.js
+1
@@ -1094,6 +1094,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1094 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.
1095 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.
1096 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.
1097 + if (device.ip != obj.remoteaddr) { device.ip = obj.remoteaddr; change = 1; }
1098 if (command.intelamt) {
1099 if (!device.intelamt) { device.intelamt = {}; }
1100 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; }
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.3.0-i",
3 + "version": "0.3.0-k",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
views/default-min.handlebars
+1 -1
@@ -1 +1 @@
1 -<!DOCTYPE html> <html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> <meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="format-detection" content="telephone=no"> <style>body{margin:0;padding:0;border:0;color:black;font-size:13px;font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;background-color:#d3d9d6;}#container{background-color:#fff;width:960px;min-width:960px;margin:0 auto;border-top:0;border-right:1px solid #b7b7b7;border-bottom:0;border-left:1px solid #b7b7b7;padding:0;}#masthead{width:auto;margin:0;padding:0;overflow:auto;text-align:right;background-color:#036;width:960px;}#column_l{position:relative;float:left;width:930px;margin:0;padding:0 15px;background-color:#fff;}#footer{clear:both;overflow:auto;width:100%;text-align:center;background-color:#113962;padding-top:5px;padding-bottom:5px;}#masthead img{float:left;}#masthead p{font-size:11px;color:#fff;margin:10px 10px 0;}#footer a{color:#fff;text-decoration:underline;}#footer a:hover{color:#fff;text-decoration:none;}a{color:#036;text-decoration:underline;}.i1{background:url(../images/icons50.png) 0px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i2{background:url(../images/icons50.png) -50px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i3{background:url(../images/icons50.png) -100px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i4{background:url(../images/icons50.png) -150px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i5{background:url(../images/icons50.png) -200px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i6{background:url(../images/icons50.png) -250px 0px;height:50px;width:50px;cursor:pointer;border:none;}.j1{background:url(../images/icons16.png) 0px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j2{background:url(../images/icons16.png) -16px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j3{background:url(../images/icons16.png) -32px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j4{background:url(../images/icons16.png) -48px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j5{background:url(../images/icons16.png) -64px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j6{background:url(../images/icons16.png) -80px 0px;height:16px;width:16px;cursor:pointer;border:none;}.lbbutton{width:74px;height:74px;border-radius:5px;background-color:white;margin-left:8px;margin-top:8px;position:relative;cursor:pointer;opacity:0.5;}.lbbutton:hover{opacity:1;}.lbbuttonsel{opacity:0.9;}.lbbuttonsel2{width:82px;border-radius:5px 0px 0px 5px;opacity:1;}.lb1{background:url(../images/leftbar-62.jpg) -0px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb2{background:url(../images/leftbar-62.jpg) -75px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb3{background:url(../images/leftbar-62.jpg) -150px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb4{background:url(../images/leftbar-62.jpg) -225px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb5{background:url(../images/leftbar-62.jpg) -294px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb6{background:url(../images/leftbar-62.jpg) -360px 0px;height:62px;width:62px;cursor:pointer;border:none;}.m0{background :url(../images/images16.png) -32px 0px;height :16px;width :16px;border:none;float:left }.m1{background :url(../images/images16.png) -16px 0px;height :16px;width :16px;border:none;float:left }.m2{background :url(../images/images16.png) -96px 0px;height :16px;width :16px;border:none;float:left }.m3{background :url(../images/images16.png) -112px 0px;height :16px;width :16px;border:none;float:left }.si0{background :url(../images/icons16.png) 0px 0px;height :16px;width :16px;border:none;float:left }.si1{background :url(../images/icons16.png) -16px 0px;height :16px;width :16px;border:none;float:left }.si2{background :url(../images/icons16.png) -32px 0px;height :16px;width :16px;border:none;float:left }.si3{background :url(../images/icons16.png) -48px 0px;height :16px;width :16px;border:none;float:left }.si4{background :url(../images/icons16.png) -64px 0px;height :16px;width :16px;border:none;float:left }.mi{background :url(../images/meshicon50.png) 0px 0px;height:50px;width:50px;cursor:pointer;border:none }#floatframe{position:fixed;top:200px;height:300px;z-index:200;display:none;}.style1{text-align:center;}.style2{text-align:center;background-color:#808080;font-weight:bold;}.style3{text-align:center;color:white;background-color:#808080;font-weight:bold;}.style3x{text-align:center;color:white;background-color:#808080;font-weight:bold;}.style3x:hover{background-color:#606060;}.style3sel{text-align:center;color:white;background-color:#003366;font-weight:bold;}.style4{color:white;text-decoration:none;}.style5{text-align:center;background-color:#808080;font-weight:normal;}.style6{text-align:center;background-color:#D3D9D6;}.style7{font-size:large;background-color:#FFFFFF;}.style10{background-color:#C9C9C9;}.style11{font-size:large;background-color:#C9C9C9;}.style14{text-align:left;background-color:#D3D9D6;}.auto-style1{text-align:right;background-color:#D3D9D6;}.fileIcon1{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb49Y2Sj9LT2f///yH5BAEAAAMALAAAAAAQABAAAAImnI+py+1vhJwyUYAzHTL4D3qdlJWaIFJqmKod607sDKIiDUP63hQAOw==);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon2{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAM2xV/Xur+XPgP///yH5BAEAAAMALAAAAAAQABAAAAJD3ISZIGHWUGihznesYDYATFVM+D2hJ4lgN1olxALAtAlmPCJvuMmJd6PJckDYwicrHhTD5o7plJmg0Uc0asNMkphHAQA7);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon3{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb19IGBgbq6uv///yH5BAEAAAMALAAAAAAQABAAAAIy3ISpxgcPH2ouQgFEw1YmxnUXKEaaEZZnVWZk66JwzKpvuwZzwOgwb/C1gIOA8Yg8DgoAOw==);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon4{background:url(../images/meshicon16.png);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.filelist{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;cursor:default;-khtml-user-drag:element;background-color:white;clear:both;}.noselect{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.fsize{float:right;text-align:right;width:180px;}.g1{background-position:0% 0%;width:14px;height:100%;float:left; background-image:linear-gradient(to right, #ffffff 0%, #c9c9c9 100%);background-color:#c9c9c9;background-repeat:repeat;background-attachment:scroll;}.g1s{background-image:linear-gradient(to right, #ffffff 0%, #b9b9b9 100%);}.g2{background-position:0% 0%;width:14px;height:100%;float:right; background-image:linear-gradient(to right, #c9c9c9 0%, #ffffff 100%);background-color:#c9c9c9;background-repeat:repeat;background-attachment:scroll;}.g2s{background-image:linear-gradient(to right, #b9b9b9 0%, #ffffff 100%);}.h1{background-position:0% 0%;width:14px;height:100%; background-image:linear-gradient(to right, #ffffff 0%, #d3d9d6 100%);background-color:#d3d9d6;background-repeat:repeat;background-attachment:scroll;}.h2{background-position:0% 0%;width:14px;height:100%; background-image:linear-gradient(to right, #d3d9d6 0%, #ffffff 100%);background-color:#d3d9d6;background-repeat:repeat;background-attachment:scroll;}.e1{font-size:large;margin-top:4px;margin-bottom:3px;overflow:hidden;word-wrap:hyphenate;white-space:nowrap;text-overflow:ellipsis;}.e2{float:left;height:100%;background-color:#c9c9c9;}.e2s{background-color:#b9b9b9;}.bar{font-size:large;background-color:#C9C9C9;height:24px;float:left;margin-bottom:2px;}.bar2{font-size:large;height:24px;float:left;margin-bottom:2px;}.bar18{font-size:large;background-color:#C9C9C9;height:18px;float:left;margin-bottom:2px;}.bar182{font-size:large;height:18px;float:left;margin-bottom:2px;}.devHeaderx{color:lightgray;}.DevSt{border-bottom-style:solid;border-bottom-width:1px;border-bottom-color:#DDDDDD;}.contextMenu{background:#F9F9F9;box-shadow:0 0 12px rgba( 0, 0, 0, .3 );border:1px solid #ccc; display:none;position:absolute;top:0;left:0;list-style:none;margin:0;padding:5px;min-width:100px;max-width:150px;z-index:500;}.cmtext{color:#444;display:inline-block;padding-left:8px;padding-right:8px;padding-top:5px;padding-bottom:5px;text-decoration:none;width:85%;cursor:default;overflow:hidden;position:relative;}.cmtext:hover{color:#f9f9f9;background:#444;}.gray{ filter:gray; -webkit-filter:grayscale(100%) opacity(60%); }.unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.notifiyBox{position:absolute;z-index:1000;top:50px;right:26px;width:300px;text-align:left;background-color:#F0ECCD;border:4px solid #666;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:2px 2px 4px #888;-moz-box-shadow:2px 2px 4px #888;box-shadow:2px 2px 4px #888;max-height:200px;}.notifiyBox:before{content:' ';position:absolute;width:0;height:0;right:5px;top:-30px;border:15px solid;border-color:transparent #666 #666 transparent;}.notifiyBox:after{content:' ';position:absolute;width:0;height:0;right:7px;top:-24px;border:12px solid;border-color:transparent #F0ECCD #F0ECCD transparent;}.notification{width:100%;min-height:30px;}.notification:hover{background-color:#EFE8B6;}.deskToolsBar{padding:3px;}.deskToolsBar:hover{background-color:#EFE8B6;}.userTableHeader{border-bottom:1pt solid lightgray;padding-top:4px;padding-bottom:4px;}.viewSelector{width:32px;height:32px;background-color:#DDD;border-radius:3px;float:left;margin-left:5px;cursor:pointer;opacity:0.3;}.viewSelectorSel{background-color:#BBB;opacity:0.8;}.viewSelector:hover{opacity:0.5;background-color:#AAA;}.viewSelector1{margin-left:2px;margin-top:2px;background:url(../images/views.png) -0px 0px;height:28px;width:28px;}.viewSelector2{margin-left:2px;margin-top:2px;background:url(../images/views.png) -28px 0px;height:28px;width:28px;}.viewSelector3{margin-left:2px;margin-top:2px;background:url(../images/views.png) -56px 0px;height:28px;width:28px;}.viewSelector4{margin-left:2px;margin-top:2px;background:url(../images/views.png) -84px 0px;height:28px;width:28px;}.viewSelector5{margin-left:2px;margin-top:2px;background:url(../images/views.png) -112px 0px;height:28px;width:28px;}.backButtonEx{margin-left:2px;margin-top:2px;background:url(../images/views.png) -140px 0px;height:28px;width:28px;}.backButton{width:32px;height:32px;background-color:#DDD;border-radius:3px;float:left;margin-right:5px;cursor:pointer;opacity:0.3;}.backButton:hover{opacity:0.5;background-color:#AAA;}.hoverButton{opacity:0.5;}.hoverButton:hover{opacity:1;}</style> <style>.ol-box{box-sizing:border-box;border-radius:2px;border:2px solid #00f;}.ol-mouse-position{top:8px;right:8px;position:absolute;}.ol-scale-line{background:rgba(0,60,136,.3);border-radius:4px;bottom:8px;left:8px;padding:2px;position:absolute;}.ol-scale-line-inner{border:1px solid #eee;border-top:none;color:#eee;font-size:10px;text-align:center;margin:1px;will-change:contents,width;}.ol-overlay-container{will-change:left,right,top,bottom;}.ol-unsupported{display:none;}.ol-unselectable, .ol-viewport{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;}.ol-selectable{-webkit-touch-callout:default;-webkit-user-select:auto;-moz-user-select:auto;-ms-user-select:auto;user-select:auto;}.ol-grabbing{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing;}.ol-grab{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab;}.ol-control{position:absolute;background-color:rgba(255,255,255,.4);border-radius:4px;padding:2px;}.ol-control:hover{background-color:rgba(255,255,255,.6);}.ol-zoom{top:.5em;right:.5em;}.ol-rotate{top:.5em;right:.5em;transition:opacity .25s linear,visibility 0s linear;}.ol-rotate.ol-hidden{opacity:0;visibility:hidden;transition:opacity .25s linear,visibility 0s linear .25s;}.ol-zoom-extent{top:4.643em;left:.5em;}.ol-full-screen{right:.5em;top:.5em;}@media print{.ol-control{display:none;}}.ol-control button{display:block;margin:1px;padding:0;color:#fff;font-size:1.14em;font-weight:700;text-decoration:none;text-align:center;height:1.375em;width:1.375em;line-height:.4em;background-color:rgba(0,60,136,.5);border:none;border-radius:2px;}.ol-control button::-moz-focus-inner{border:none;padding:0;}.ol-zoom-extent button{line-height:1.4em;}.ol-compass{display:block;font-weight:400;font-size:1.2em;will-change:transform;}.ol-touch .ol-control button{font-size:1.5em;}.ol-touch .ol-zoom-extent{top:5.5em;}.ol-control button:focus, .ol-control button:hover{text-decoration:none;background-color:rgba(0,60,136,.7);}.ol-zoom .ol-zoom-in{border-radius:2px 2px 0 0;}.ol-zoom .ol-zoom-out{border-radius:0 0 2px 2px;}.ol-attribution{text-align:right;bottom:.5em;right:.5em;max-width:calc(100% - 1.3em);}.ol-attribution ul{margin:0;padding:0 .5em;font-size:.7rem;line-height:1.375em;color:#000;text-shadow:0 0 2px #fff;}.ol-attribution li{display:inline;list-style:none;line-height:inherit;}.ol-attribution li:not(:last-child):after{content:" ";}.ol-attribution img{max-height:2em;max-width:inherit;vertical-align:middle;}.ol-attribution button, .ol-attribution ul{display:inline-block;}.ol-attribution.ol-collapsed ul{display:none;}.ol-attribution.ol-logo-only ul{display:block;}.ol-attribution:not(.ol-collapsed){background:rgba(255,255,255,.8);}.ol-attribution.ol-uncollapsible{bottom:0;right:0;border-radius:4px 0 0;height:1.1em;line-height:1em;}.ol-attribution.ol-logo-only{background:0 0;bottom:.4em;height:1.1em;line-height:1em;}.ol-attribution.ol-uncollapsible img{margin-top:-.2em;max-height:1.6em;}.ol-attribution.ol-logo-only button, .ol-attribution.ol-uncollapsible button{display:none;}.ol-zoomslider{top:4.5em;left:.5em;height:200px;}.ol-zoomslider button{position:relative;height:10px;}.ol-touch .ol-zoomslider{top:5.5em;}.ol-overviewmap{left:.5em;bottom:.5em;}.ol-overviewmap.ol-uncollapsible{bottom:0;left:0;border-radius:0 4px 0 0;}.ol-overviewmap .ol-overviewmap-map, .ol-overviewmap button{display:inline-block;}.ol-overviewmap .ol-overviewmap-map{border:1px solid #7b98bc;height:150px;margin:2px;width:150px;}.ol-overviewmap:not(.ol-collapsed) button{bottom:1px;left:2px;position:absolute;}.ol-overviewmap.ol-collapsed .ol-overviewmap-map, .ol-overviewmap.ol-uncollapsible button{display:none;}.ol-overviewmap:not(.ol-collapsed){background:rgba(255,255,255,.8);}.ol-overviewmap-box{border:2px dotted rgba(0,60,136,.7);}.ol-overviewmap .ol-overviewmap-box:hover{cursor:move;}</style> <style> .ol-ctx-menu-container{position:absolute;padding:8px;background:#fff;color:#222;font-size:13px;border-radius:5px;box-shadow:3px 3px 5px rgba(0,0,0,.2);box-sizing:border-box}.ol-ctx-menu-container a,.ol-ctx-menu-container div,.ol-ctx-menu-container img,.ol-ctx-menu-container li,.ol-ctx-menu-container span,.ol-ctx-menu-container ul{margin:0;padding:0;border:0;font:inherit;font-size:100%;vertical-align:baseline}.ol-ctx-menu-container a img{border:none}.ol-ctx-menu-container *,.ol-ctx-menu-container :after,.ol-ctx-menu-container :before{box-sizing:inherit}.ol-ctx-menu-container.ol-ctx-menu-hidden{opacity:0;visibility:hidden;-webkit-transition:visibility 0s linear .3s,opacity .3s;transition:visibility 0s linear .3s,opacity .3s}.ol-ctx-menu-container ul{list-style:none}.ol-ctx-menu-container li{position:relative;line-height:20px;padding:2px 5px}.ol-ctx-menu-container li:not(.ol-ctx-menu-separator):hover{cursor:pointer;background-color:#333;color:#eee}.ol-ctx-menu-container li.ol-ctx-menu-submenu .ol-ctx-menu-container{border:1px solid #eee;padding:8px;top:0;opacity:0;visibility:hidden;-webkit-transition:visibility 0s linear .3s,opacity .3s;transition:visibility 0s linear .3s,opacity .3s}.ol-ctx-menu-container li.ol-ctx-menu-submenu:hover .ol-ctx-menu-container{opacity:1;visibility:visible;-webkit-transition-delay:0s;transition-delay:0s}.ol-ctx-menu-container li.ol-ctx-menu-submenu:after{position:absolute;top:7px;right:10px;content:"";display:inline-block;width:.6em;height:.6em;border-right:.3em solid #222;border-top:.3em solid #222;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ol-ctx-menu-container li.ol-ctx-menu-submenu:hover:after{border-color:#eee}.ol-ctx-menu-container li.ol-ctx-menu-separator{padding:0}.ol-ctx-menu-container li.ol-ctx-menu-separator hr{border:0;height:1px;background-image:-webkit-linear-gradient(right,transparent,rgba(0,0,0,.75),transparent);background-image:linear-gradient(270deg,transparent,rgba(0,0,0,.75),transparent)}.ol-ctx-menu-icon{text-indent:20px;background-size:20px auto;background-repeat:no-repeat;background-position:0}.ol-ctx-menu-zoom-in{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABaUlEQVQ4T72U7VHCQBCGn90GtAMuNGCswFiBWIFQgWMFxg6wArECsQKhArEBiB1Qwa1zgQn5IAYcxv13k71n3919L8KJQ07M47+BzgG9TRfZ/JBuWhS6BJFHRJICYrZGZIz3z5Ct2+B7gG6I6kt+wewdkQVwjtkAkR5mC8yu26A1oItR/cTsOweQBdgutD8G7jGm2PJ2n8oqUKIpIjd4HxTM8gvaT/F+AlmWnyWaIXKF95eNguFzTYFhNsdWu9kFgFlaFMANUH3D8wDLoLgSTSD2il8NCe2ZXQBxWDGwxmyUzzOMBZ7wy7Qb2K0wQfXjMOBuhlFpZtNty5sFaTQBuTusZdymeqs1SpYKcO9HkE3KbTd9WFijMHJQ5hBNEAYNq5Qd0dhyke0GiE4QzjqfW23mHT8Hl4DG4Lce3FPE7AtbBSdsbNqpoJLgYkRnNeUV+xwJDHTnUEkxHGbhBXUs5TjJjew/KPy94g+NRaIVRYmMXwAAAABJRU5ErkJggg==")}.ol-ctx-menu-container li:hover.ol-ctx-menu-zoom-in{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABc0lEQVQ4T71U21ECQRDsJgGdvQDECMQIxAjECMQILCPwzAAjECIQI0AiEDPQAPaWCBhrcKHuCUcV5f7dY3v6tUscefHIePhfwBBCF8CZqRCReRs1tQxDCH1VfQLQz4EsSY4AvIjIsgm8AhhCGKrqa9zwrqoLAKckB5HtguR1E2gBMITQU9VPAD8GICIGtl3e+xHJBwBT59xtHcsCYJZlUwA3kcGHbfDep51OZywi3/acZZm9vyJ5WR5o38uACmDunNt6ZwAkUxFZDwghDFT1jeSjiJinhVUBVNVJkiTDKO8CQA+AsbNQ7s1Ps0VVn5MkSfcCtmBoDZi1Bdx4eJ7zbBolrwPy3o9J3rWSHPs3A1BbjVKlYBaIyDgvu9LDXDU2RTZmXVW1oKyLxRD+OrkOrJLy5mVM0iaftDhuhVbsvBzMglzKUNW6IV/OOWtCM8MmVvEkmbwt83LaB19fdgOtVquUZJeknaDdobTwbOcvBzPcN/AXH1DFFWP7u9oAAAAASUVORK5CYII=")}.ol-ctx-menu-zoom-out{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABU0lEQVQ4T72U7VECMRRFz3sNaAdkacC1AtcKxApcKnCsQOwAK3CtQKxAqEBsANYOqCDPyTIC+8WCw5jfybn33dxEOPGSE/P4b6BzQG89RT47ZJoWhy5B5BGRZAMxWyEyxvtnyFdt8AagS1F9KQ6YvSMyB84xGyDSw2yO2XUbtAJ0MaqfmH0XAPIA2y7tj4F7jAm2uG1yWQZKNEHkBu+Dg2njWBJNEbnC+8uaIFRuWfuG2QxbbrOrUd0A1Tc8D7AIjkur7DAAsVf8MiWMZ3ZR2m02LPIMscATfjHqBnY7TFD9OAy4zTCCPG/MUKMM5O6wkXFr9dZq7FQqqHk/hDzbFa73cFONTZFDdRyiCcKg5rrSiLaXkiI6RjjrfG6VzDs+B5eAxuDXeYpmNRGzL2wZ/wof+du4GNFpBVqqz5HA4MM5VEYYDrOs+1I6Q9u/4Q8O9wN/AGgWjBVqQjjgAAAAAElFTkSuQmCC")}.ol-ctx-menu-container li:hover.ol-ctx-menu-zoom-out{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABYklEQVQ4T72U4VHCQBCF36tA91KAWIFYgViBWIFYgWMFYgdYgVCBWAFSgdiBFpAsFWSdxcDkQoBkhnF/ZjbfvX377ogjF4/Mw/8CVbUD4MynEJF5k2lqFapqz8yeAPRKkCXJEYAXEVnugm8BVXVgZq/FD+9mtgBwSrJfqF2QvN4FjYCq2jWzTwA/DhARh20qTdMRyQcA0xDCbZ3KCJhl2RTATaHgo+6HLMv8+xXJy+qB3l8FGoB5CKHsXcRV1b6ZvZF8FBH3NKotoJlNkiQZFONdlLtJ3rufbouZPSdJMjwIbKDQEzBrClx7eC4i33Uepmk6JnnXaOQifzMAtdGoRApugYiMI1uqKkrRWAfZo9MxM1+UZzFewl8mN4nYdVM83L7BkwbXLUrF3sfBLQDQBbDy08x8vOohXyEE71lVq9emuEk+3gZa3XYroCvwFyjP8yHJDsnxwaU08GxvS2uFhw78BbzWrxXgMbsHAAAAAElFTkSuQmCC")}</style> <script type="text/javascript" src="scripts/charts.js"></script> <script type="text/javascript" src="scripts/filesaver.1.1.20151003.js"></script> <script type="text/javascript" src="scripts/ol.js"></script> <script type="text/javascript" src="scripts/ol3-contextmenu.js"></script> <title>MeshCentral</title> </head> <body id="body" onload="if (typeof(startup) !== 'undefined') startup();" oncontextmenu="handleContextMenu(event)" style="display:none"> <div id="contextMenu" class="contextMenu noselect" style="display:none"> <div id="cxinfo" class="cmtext" onclick="cmaction(1,event)"><b>Information</b></div> <div id="cxdesktop" class="cmtext" onclick="cmaction(3,event)">Desktop</div> <div id="cxterminal" class="cmtext" onclick="cmaction(2,event)">Terminal</div> <div id="cxfiles" class="cmtext" onclick="cmaction(4,event)">Files</div> <div id="cxevents" class="cmtext" onclick="cmaction(5,event)">Events</div> <div id="cxconsole" class="cmtext" onclick="cmaction(6,event)">Console</div> <hr id="cxmgroupsplit"> <div id="cxmdesktop" class="cmtext" onclick="cmaction(7,event)" style="display:none">Multi-Desktop</div> </div> <div id="meshContextMenu" class="contextMenu,noselect" style="display:none;min-width:0px"> <div id="cxselectall" class="cmtext" onclick="cmmeshaction(1,event)">Select All</div> <div id="cxselectnone" class="cmtext" onclick="cmmeshaction(2,event)">Select None</div> <hr id="cxmgroupsplit2" style="display:none"> <div id="cxmmdesktop" class="cmtext" style="display:none" onclick="cmmeshaction(3,event)">Multi-Desktop</div> </div> <div id="container" style="max-height:100vh;position:relative"> <div id="notifiyBox" class="notifiyBox" style="display:none"></div> <div id="mastheadx"></div> <div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"> <div style="float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px"> <strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong> </div> <div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px"> <strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong> </div> <div style="float:right"> <div id="notificationCount" onclick="clickNotificationIcon()" class="unselectable" style="display:none;min-width:28px;font-size:20px;border-radius:5px;background-color:lightblue;text-align:center;margin:8px;cursor:pointer;padding:4px" title="Click to view current notifications">0</div> </div> <p id="logoutControl">{{{logoutControl}}}</p> </div> <div id="page_leftbar" style="height:calc(100vh - 66px);width:90px;position:absolute;z-index:1000;background:#113962;background:linear-gradient(to bottom, #104893 0%,#113962 100%);color:white;display:none"> <div style="height:16px"></div> <div id="LeftMenuMyDevices" class="lbbutton lbbuttonsel" title="My Devices" onclick="go(1)"> <div class="lb2" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyAccount" class="lbbutton" title="My Account" onclick="go(2)"> <div class="lb1" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyEvents" class="lbbutton" title="My Events" onclick="go(3)"> <div class="lb3" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyFiles" class="lbbutton" title="My Files" onclick="go(5)"> <div class="lb4" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyUsers" class="lbbutton" title="My Users" onclick="go(4)"> <div class="lb5" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyServer" class="lbbutton" title="My Server" onclick="go(6)" style="display:none"> <div class="lb6" style="position:absolute;top:6px;left:6px"></div> </div> </div> <div id="page_content" style="max-height:calc(100vh - 130px)"> <div id="topbarmaster"> <div id="topbar" class="noselect"> <div> <div style="position:relative"> <div style="position:absolute;top:3px;right:6px"> <span title="Toggle full width" style="cursor:pointer;color:white" onclick="toggleFullScreen(1)">&harr;</span> </div> <table id="MainMenuSpan" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="MainMenuMyDevices" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(1)">My Devices</td> <td id="MainMenuMyAccount" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(2)">My Account</td> <td id="MainMenuMyEvents" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(3)">My Events</td> <td id="MainMenuMyFiles" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(5)">My Files</td> <td id="MainMenuMyUsers" style="width:100px;height:24px;cursor:pointer;display:none" class="style3x" onclick="go(4)">My Users</td> <td id="MainMenuMyServer" style="width:100px;height:24px;cursor:pointer;display:none" class="style3x" onclick="go(6)">My Server</td> <td class="style3" style="text-align:right;height:24px">&nbsp;</td> </tr> </table> <div id="MainSubMenuSpan" style="display:none"> <table id="MainSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="MainDev" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(10)">General</td> <td id="MainDevDesktop" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(11)">Desktop</td> <td id="MainDevTerminal" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(12)">Terminal</td> <td id="MainDevFiles" style="width:100px;height:24px;cursor:pointer;display:none" class="style3x" onclick="go(13)">Files</td> <td id="MainDevEvents" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(16)">Events</td> <td id="MainDevAmt" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(14)">Intel&reg; AMT</td> <td id="MainDevConsole" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(15)">Console</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="MeshSubMenuSpan" style="display:none"> <table id="MeshSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="MeshGeneral" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(20)">General</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="UserSubMenuSpan" style="display:none"> <table id="UserSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="UserGeneral" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(30)">General</td> <td id="UserEvents" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(31)">Events</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="ServerSubMenuSpan" style="display:none"> <table id="ServerSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="ServerGeneral" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(6)">General</td> <td id="ServerConsole" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(115)">Console</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="UserDummyMenuSpan"> <table id="UserDummyMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr><td class="style3" style="text-align:right;height:24px">&nbsp;</td></tr> </table> </div> </div> </div> </div> </div> <div id="column_l"> <div id="p0" style="display:none"> <div id="p0message" style="margin:50px;text-align:center"><span id="p0span">Server disconnected</span>, <href onclick="reload()" style="cursor:pointer"><u>click to reconnect</u></href>.</div> </div> <div id="p1" style="display:none"> <div style="float:right;display:none" id="devListToolbarViewIcons"> <div id="devViewButton1" class="viewSelector" onclick="onDeviceViewChange(1)" title="Columns"><div class="viewSelector2"></div></div> <div id="devViewButton2" class="viewSelector" onclick="onDeviceViewChange(2)" title="List"><div class="viewSelector1"></div></div> <div id="devViewButton3" class="viewSelector" onclick="onDeviceViewChange(3)" title="Desktops"><div class="viewSelector3"></div></div> <div id="devViewButton4" class="viewSelector" onclick="onDeviceViewChange(4)" title="Map"><div class="viewSelector4"></div></div> </div><div><h1>My Devices</h1></div> <table class="noselect" style="width:100%;height:24px;background-color:#d3d9d6;vertical-align:middle;border-spacing:0"> <tr> <td class="h1"></td> <td id="devListToolbar" class="style14" style="display:none"> &nbsp;&nbsp;<input type="button" id="SelectAllButton" onclick="selectallButtonFunction();" value="Select All">&nbsp; <input type="button" id="GroupActionButton" disabled="disabled" value="Group Action" onclick="groupActionFunction()">&nbsp; <input id="SearchInput" type="text" style="width:120px" placeholder="Filter" onchange="masterUpdate(5)" onkeyup="masterUpdate(5)" autocomplete="off" onfocus="onSearchFocus(1)" onblur="onSearchFocus(0)">&nbsp; <label><input type="checkbox" id="RealNameCheckBox" onclick="onRealNameCheckBox()"><span title="Show devices operating system name">OS Name</span></label> </td> <td id="kvmListToolbar" class="style14" style="height:100%;display:none"> &nbsp;&nbsp;<input type="button" onclick="connectAllKvmFunction()" value="Connect All">&nbsp; <input type="button" onclick="disconnectAllKvmFunction()" value="Disconnect All">&nbsp; <label><input type="checkbox" id="autoConnectDesktopCheckbox" onclick="autoConnectDesktops(event)" title="Automatic connect">Auto&nbsp;</label> <input type="button" onclick="showMultiDesktopSettings()" value="Settings">&nbsp; </td> <td id="devMapToolbar" class="style14" style="height:100%;display:none"> &nbsp;&nbsp;<input type="text" id="mapSearchLocation" placeholder="Search Location" onfocus="onMapSearchFocus(1)" onblur="onMapSearchFocus(0)"> <input type="button" value="Search" title="Search for location" onclick="getSearchLocation()"> <input type="button" id="refreshmap" title="Reset map view" value="Reset" style="margin-left:5px" onclick="refreshMap(false,true)"> </td> <td class="auto-style1" style="height:100%"> <div style="float:right;display:none" id="devListToolbarView"> View <select id="viewselect" onchange="onDeviceViewChange()"> <option value="1">Columns <option value="2">List <option value="3">Desktops <option id="viewselectmapoption" value="4">Map </select> </div> <div style="float:right;display:none" id="devListToolbarSort"> Sort <select id="sortselect" onchange="masterUpdate(6)"> <option>Group <option>Power <option>Device <option>Tags </select> &nbsp; </div> <div style="float:right;display:none" id="devListToolbarSize"> Size <select id="sizeselect" onchange="onDeviceViewChange()"> <option value="0">Small <option value="1">Medium <option value="2">Large </select> &nbsp; </div> </td> <td class="h2"></td> </tr> </table> <div id="NoMeshesPanel" style="display:none"> <table style="width:100%;padding:20px"> <tr> <td valign="top" style="width:50px"> <img src="images/info.png" height="48" width="47"> </td> <td> To get started, <a onclick="account_createMesh()" style="cursor:pointer"><strong>click here to create a device group</strong></a>. </td> </tr> </table> </div> <div id="xdevices" class="noselect" style="max-height:calc(100vh - 239px);overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;display:none"></div> <div id="xdevicesmap" style="height:calc(100vh - 239px);width:100%;overflow:hidden;position:relative;display:none"> <div id="xmapSearchResultsDlg" style="position:absolute;display:none;max-height:280px;left:5px;top:5px;max-width:250px;z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666"> <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0"> <div id="xmapSearchClose" style="float:right;padding:5px;cursor:pointer" onclick="mapCloseSearchWindow()"><b>X</b></div> <div style="padding:5px">Location Results</div> <div style="width:100%;margin:6px"></div> </div> <div id="xmapSearchResults" style="margin:6px"></div> </div> </div> <div id="xmap-info-window" style="text-shadow:0px 0px 15px #FFF"></div> </div> <div id="p2" style="display:none"> <h1>My Account</h1> <img id="p2AccountImage" alt="" width="150" height="103" src="images/mainaccount.jpg" style="margin-bottom:10px;margin-right:20px;float:right"> <div id="p2AccountSecurity" style="display:none"> <p><strong>Account security</strong></p> <div style="margin-left:25px"> <div id="manageAuthApp"><div style="width:15px;display:inline-block"><span id="authAppSetupCheck" style="color:green;font-size:10px"><strong>&#x2713;</strong></span></div><span><a onclick="account_manageAuthApp()" style="cursor:pointer">Manage authenticator app</a><br></span></div> <div id="manageHardwareOtp"><div style="width:15px;display:inline-block"><span id="authKeySetupCheck" style="color:green;font-size:10px"><strong>&#x2713;</strong></span></div><span><a onclick="account_manageHardwareOtp(0)" style="cursor:pointer">Manage security keys</a><br></span></div> <div id="manageOtp"><div style="width:15px;display:inline-block"><span id="authCodesSetupCheck" style="color:green;font-size:10px"><strong>&#x2713;</strong></span></div><span><a onclick="account_manageOtp(0)" style="cursor:pointer">Manage backup codes</a><br></span></div> </div> </div> <div id="p2AccountActions"> <p><strong>Account actions</strong></p> <p style="margin-left:40px"> <span id="verifyEmailId" style="display:none"><a onclick="account_showVerifyEmail()" style="cursor:pointer">Verify email</a><br></span> <a onclick="account_showChangeEmail()" style="cursor:pointer">Change email address</a><br> <a onclick="account_showChangePassword()" style="cursor:pointer">Change password</a><span id="p2nextPasswordUpdateTime"></span><br> <a onclick="account_showDeleteAccount()" style="cursor:pointer">Delete account</a><br> </p> <br style="clear:both"> </div> <strong>Device Groups</strong> ( <a onclick="account_createMesh()" style="cursor:pointer"><img height="12" src="images/icon-addnew.png" width="12" border="0"> New</a> ) <br><br> <div id="p2meshes"></div> <div id="p2noMeshFound" style="margin-left:40px;display:none">No device groups. <a onclick="account_createMesh()" style="cursor:pointer"><strong>Get started here!</strong></a></div> <br style="clear:both"> </div> <div id="p3" style="display:none"> <h1>My Events</h1> <table style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0"> <tr> <td class="h1"></td> <td>&nbsp;<input id="p2deleteall" type="button" onclick="showDeleteAllEventsDialog()" style="display:none" value="Delete All..."></td> <td class="auto-style1"> Show <select id="p3limitdropdown" onchange="refreshEvents()"> <option value="60">Last 60 <option value="120">Last 120 <option value="250">Last 250 <option value="500">Last 500 <option value="1000">Last 1000 </select> </td> <td class="h2"></td> </tr> </table> <div id="p3events" style="height:calc(100vh - 243px);overflow-y:scroll"></div> </div> <div id="p4" style="display:none"> <h1>My Users</h1> <table style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0"> <tr> <td class="h1"></td> <td class="style14"> <div style="float:right"> <input type="button" onclick="showUserBroadcastDialog()" style="margin-right:6px" value="Broadcast"> </div> <div> <input id="UserNewAccountButton" type="button" style="margin-left:6px" onclick="showCreateNewAccountDialog()" value="New Account..."> <input id="UserSearchInput" type="text" style="width:120px;margin-left:6px" placeholder="Filter" onchange="onUserSearchInputChanged()" onkeyup="onUserSearchInputChanged()" autocomplete="off" onfocus="onUserSearchFocus(1)" onblur="onUserSearchFocus(0)"> </div> </td> <td class="h2"></td> </tr> </table> <div id="p3users" style="max-height:calc(100vh - 243px);overflow-y:auto"></div> </div> <div id="p5" style="display:none"> <h1>My Files</h1> <table id="p5toolbar" style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="width:100%;background-color:#d3d9d6;text-align:left;padding:4px" valign="bottom"> <div id="p5rightOfButtons" style="float:right;margin-top:3px"></div> <div> <input type="button" id="p5FolderUp" disabled="disabled" onclick="p5folderup();" value="Up">&nbsp; <input type="button" id="p5SelectAllButton" disabled="disabled" onclick="p5selectallfile();" value="Select All" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5RenameFileButton" disabled="disabled" value="Rename" onclick="p5renamefile();" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5DeleteFileButton" disabled="disabled" value="Delete" onclick="p5deletefile();" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5NewFolderButton" disabled="disabled" value="New Folder" onclick="p5createfolder();" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5UploadButton" disabled="disabled" value="Upload" onclick="p5uploadFile()" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5CutButton" disabled="disabled" value="Cut" onclick="p5copyFile(1)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p5CopyButton" disabled="disabled" value="Copy" onclick="p5copyFile(0)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p5PasteButton" disabled="disabled" value="Paste" onclick="p5pasteFile()" onkeypress="return false" onkeydown="return false">&nbsp; </div> </td> </tr> <tr> <td style="background-color:#E4E9E7;height:28px"> <div style="float:right"> <select id="p5sortdropdown" onchange="updateFiles()"> <option value="1" selected="selected">Sort by name <option value="2">Sort by size <option value="3">Sort by date <option value="4">Descend by name <option value="5">Descend by size <option value="6">Descend by date </select> </div> <div>&nbsp;&nbsp;<span id="p5currentpath"></span></div> </td> </tr> </table> <div id="p5filetable" style="width:100%;height:calc(100vh - 294px);overflow:auto;-webkit-user-select:none;position:relative"> <div id="p5PublicShare" style="display:none;width:100%;overflow:auto;-webkit-user-select:none;background-color:lightsteelblue"><div style="padding:4px">These files are shared publicly, click "link" to get public url.</div></div> <div id="bigok" style="width:256px;overflow:hidden;position:absolute;left:337px;top:20px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&checkmark;</b></div> <div id="bigfail" style="width:256px;overflow:hidden;position:absolute;left:337px;top:20px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&#10007;</b></div> <span id="p5files"></span> </div> <table id="p5toolbarBottom" style="width:100%" cellpadding="0" cellspacing="0"> <tr><td class="style6" style="text-align:left;padding:3px">&nbsp;<span id="p5bottomstatus"></span></td></tr> </table> </div> <div id="p6" style="display:none"> <img id="MainMeshImage" src="serverpic.ashx" style="border-width:0px;height:200px;width:200px;float:right"> <h1>My Server</h1> <p id="p2ServerActions"><strong>Server actions</strong></p> <p style="margin-left:40px"> <div id="p2ServerActionsBackup" style="margin-left:40px"><a href="/backup.zip" rel="noreferrer noopener" target="_blank" style="cursor:pointer">Download server backup</a></div> <div id="p2ServerActionsRestore" style="margin-left:40px"><a onclick="server_showRestoreDlg()" style="cursor:pointer">Restore server with backup</a></div> <div id="p2ServerActionsVersion" style="margin-left:40px"><a onclick="server_showVersionDlg()" style="cursor:pointer">Check server version</a></div> <div id="p2ServerActionsErrors" style="margin-left:40px"><a onclick="server_showErrorsDlg()" style="cursor:pointer">Show server error log</a></div> </p> <br><strong>Server Statistics</strong><br><br> <div id="serverStats" style="margin-left:40px"> <div id="serverCpuChartView" style="display:none"> <div style="width:60px;display:inline-block"><canvas id="serverCpuChart" style="width:60px;height:60px"></canvas></div> <div style="width:160px;display:inline-block" id="serverCpuChartText"></div> </div> <div id="serverMemoryChartView" style="display:none"> <div style="width:60px;display:inline-block"><canvas id="serverMemoryChart" style="width:60px;height:60px"></canvas></div> <div style="width:160px;display:inline-block" id="serverMemoryChartText"></div> </div><br><br> <div id="serverStatsTable"></div> </div> </div> <div id="p10" style="display:none"> <table style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="width:auto" valign="top"> <div id="p10title"> <div id="p10BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>General - <span id="p10deviceName"></span></h1> </div> <div id="p10html"></div> </td> <td style="width:20px"></td> <td style="width:200px"> <a style="cursor:pointer" onclick="p10showiconselector()"><img id="MainComputerImage" style="border-width:0px;height:200px;width:200px"></a> <div style="width:100%;text-align:center"><strong><span id="MainComputerState"></span></strong></div> </td> </tr> </table><br> <div id="p10html2"></div> <div id="p10html3"></div> </div> <div id="p11" class="noselect" style="display:none"> <div id="p11title"> <div id="p11deviceNameHeader"> <div id="p11BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <div style="float:right" id="devListToolbarViewIcons"><div class="viewSelector" onclick="deskToggleFull(event)" title="Full Screen. Hold shift to browser full screen."><div class="viewSelector5"></div></div></div> <h1>Desktop - <span id="p11deviceName"></span></h1> </div> </div> <div id="p14warning" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showFeaturesDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Intel&reg; AMT Redirection port or KVM feature is disabled<span id="p14warninga">, click here to enable it.</span></div> </div> <div id="p14warning2" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showPowerActionDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Remote computer is not powered on, click here to issue a power command.</div> </div> <table id="deskarea0" cellpadding="0" cellspacing="0" style="width:100%;padding:0px;padding:0px;margin-top:0px"> <tr id="deskarea1"> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <span id="p14power"></span>&nbsp; <div style='cursor:pointer;border:none;float:right;font-size:130%;margin-right:4px' title="Rotate Left" onclick="drotate(-1)">&olarr;</div> <div style='cursor:pointer;border:none;float:right;font-size:130%;margin-right:4px' title="Rotate Right" onclick="drotate(1)">&orarr;</div> <input id="deskFocusBtn" type="button" title="Toggle focus mode, when active only the region around the mouse is updated" onkeypress="return false" onkeydown="return false" value="Focus All" onclick="deskToggleFocus()" style="margin-right:3px;display:none"> <input id="deskSaveBtn" type="button" title="Save a screenshot of the remote desktop" onkeypress="return false" onkeydown="return false" value="Save..." onclick="deskSaveImage()" style="margin-right:3px"> <input id="deskActionsBtn" type="button" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value="Actions" onclick="deviceActionFunction()" style="margin-right:3px"> <input id="deskActionsSettings" type="button" value="Settings..." title="Edit remote desktop settings" onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()" style="margin-right:3px"> <input type="button" title="Change the power state of the remote machine" onkeypress="return false" onkeydown="return false" value="Power Actions..." onclick="showPowerActionDlg()" style="margin-right:3px;display:none"> </div> <div> <div id="idx_deskFullBtn2" onclick="deskToggleFull(event)" style="float:left;font-size:large;cursor:pointer;display:none">&nbsp;&#x2716;</div> <input type="button" id="autoconnectbutton1" value="AutoConnect" onclick="autoConnectDesktop(event)" onkeypress="return false" onkeydown="return false" style="display:none"> <span id="connectbutton1span">&nbsp;<input type="button" id="connectbutton1" value="Connect" onclick="connectDesktop(event,1)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="connectbutton1hspan">&nbsp;<input type="button" id="connectbutton1h" value="HW Connect" onclick="connectDesktop(event,2)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="disconnectbutton1span">&nbsp;<input type="button" id="disconnectbutton1" value="Disconnect" onclick="connectDesktop(event,0)" onkeypress="return false" onkeydown="return false"></span> &nbsp;<span id="deskstatus">Disconnected</span> </div> </td> </tr> <tr id="deskarea2"> <td> <div style="background-color:gray"><div id="progressbar" style="height:2px;width:0%;background-color:red"></div></div> </td> </tr> <tr id="deskarea3"> <td id="deskarea3x" style="background:black;text-align:center;position:relative;overflow:hidden"> <div id="DeskFocus" style="overflow:hidden;color:transparent;border:3px dotted rgba(255,0,0,.2);position:absolute;border-radius:5px" oncontextmenu="return false" onmousedown="dmousedown(event)" onmouseup="dmouseup(event)" onmousemove="dmousemove(event)"></div> <div id="DeskParent" style="overflow:hidden"> <canvas id="Desk" width="640" height="480" style="overflow:hidden;width:100%;-ms-touch-action:none;margin-left:0px" oncontextmenu="return false" onmousedown="dmousedown(event)" onmouseup="dmouseup(event)" onmousemove="dmousemove(event)" onmousewheel="dmousewheel(event)"></canvas> </div> <div id="DeskTools" style="position:absolute;width:400px;height:100%;background-color:gray;top:0;right:0;border-left:2px solid lightgray;display:none"> <a id="DeskToolsRefreshButton" style="float:right;padding:3px;cursor:pointer" onclick="refreshDeskTools()">Refresh</a> <div id="DeskToolsBar" style="position:absolute;padding:3px;border-radius:3px 3px 0px 0px;top:5px;left:4px;bottom:26px;background-color:lightgray;cursor:pointer">Processes</div> <div style="position:absolute;top:26px;left:4px;right:4px;bottom:4px;background-color:lightgray;text-align:left"> <div style="border-bottom:1px solid darkgray;padding:3px"><a style="width:50px;padding-right:5px;float:left;cursor:pointer" title="Sort by process id" onclick="sortProcess(0)">PID</a><a style="cursor:pointer" title="Sort by name" onclick="sortProcess(1)">Name</a></div> <div id="DeskToolsProcesses" style="overflow-y:scroll;position:absolute;top:24px;bottom:0px;width:100%"></div> </div> </div> </td> </tr> <tr id="deskarea4"> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <select id="termdisplays" style="display:none" onchange="deskSetDisplay(event)" onclick="deskGetDisplayNumbers(event)"></select>&nbsp; <input id="DeskToolsButton" type="button" value="Tools" title="Toggle tools view" onkeypress="return false" onkeydown="return false" onclick="toggleDeskTools()">&nbsp; <span id="DeskChatButton" style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Open chat window to this computer"><img src='images/icon-chat.png' onclick="deviceChat()" height="16" width="16" style="padding-top:2px"></span> <span id="DeskNotifyButton" style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Display a notification on the remote computer"><img src='images/icon-notify.png' onclick="deviceToastFunction()" height="16" width="16" style="padding-top:2px"></span> <span id="DeskOpenWebButton" style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Open a web address on remote computer"><img src='images/icon-url2.png' onclick="deviceUrlFunction()" height="16" width="16" style="padding-top:2px"></span> </div> <div> <select style="margin-left:6px" id="deskkeys"> <option value="5">Win <option value="0">Win+Down <option value="1">Win+Up <option value="2">Win+L <option value="3">Win+M <option value="4">Shift+Win+M <option value="6">Win+R </select> <input id="DeskWD" type="button" value="Send" onkeypress="return false" onkeydown="return false" onclick="deskSendKeys()"> <input id="DeskClip" style="margin-left:6px;display:none" type="button" value="Clipboard" onkeypress="return false" onkeydown="return false" onclick="showDeskClip()"> <input id="DeskCAD" type="button" value="Ctrl-Alt-Del" onkeypress="return false" onkeydown="return false" onclick="sendCAD()"> <label><span id="DeskControlSpan" style="margin-left:6px" title="Toggle mouse and keyboard input"><input id="DeskControl" type="checkbox" onkeypress="return false" onkeydown="return false" onclick="toggleKvmControl()">Input</span></label>&nbsp; </div> </td> </tr> </table> </div> <div id="p12" style="display:none"> <div id="p12title"> <div id="p12BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Terminal - <span id="p12deviceName"></span></h1> </div> <div id="p12warning" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showFeaturesDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Intel&reg; AMT Redirection port or KVM feature is disabled<span id="p14warninga">, click here to enable it.</span></div> </div> <div id="p12warning2" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showPowerActionDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Remote computer is not powered on, click here to issue a power command.</div> </div> <table cellpadding="0" cellspacing="0" style="width:100%;padding:0px;padding:0px;margin-top:0px"> <tr> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <input id="termActionsBtn" type="button" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value="Actions" onclick="deviceActionFunction()" style="margin-right:3px"> </div> <div> <input type="button" id="autoconnectbutton2" value="AutoConnect" onclick="autoConnectTerminal(event)" onkeypress="return false" onkeydown="return false" style="display:none"> <span id="connectbutton2span">&nbsp;<input type="button" id="connectbutton2" value="Connect" onclick="connectTerminal(event,1)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="connectbutton2hspan">&nbsp;<input type="button" id="connectbutton2h" value="HW Connect" onclick="connectTerminal(event,2)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="disconnectbutton2span">&nbsp;<input type="button" id="disconnectbutton2" value="Disconnect" onclick="connectTerminal(event,0)" onkeypress="return false" onkeydown="return false"></span> &nbsp;<span id="termstatus">Disconnected</span> </div> </td> </tr> <tr> <td> <div style="background-color:gray"><div id="termprogressbar" style="height:2px;width:0%;background-color:red"></div></div> </td> </tr> <tr> <td style="background:black;text-align:center;height:500px;position:relative"> <pre id="Term" style="background:black;margin:0;padding:0"></pre> </td> </tr> <tr> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <span id="terminalSettingsButtons" style="display:none"> <input id="id_tcrbutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="CR+LF" title="Toggle what the return key will send" onclick="termToggleCr()"> <input id="id_tfxkeysbutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Intel (F10 = ESC+[OM)" title="Toggle F1 to F10 keys emulation type" onclick="termToggleFx()"> <input id="id_ttypebutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Extended Ascii" title="Toggle terminal emulation type" onclick="termToggleType()"> </span> <select id="specialkeylist" onkeypress="return false" style="margin-left:5px"></select> <input id="specialkeylistinput" type="button" onkeypress="return false" class="bottombutton" value="Send" title="Send the selected special key" onclick="sendSpecialKey()"> </div> <div> &nbsp; <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="ctrlcbutton" value="Ctl-C" onclick="termSendKey(3,'ctrlcbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="ctrlxbutton" value="Ctl-X" onclick="termSendKey(24,'ctrlxbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="escbutton" value="ESC" onclick="termSendKey(27,'escbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="bsbutton" value="Backspace" onclick="termSendKey(8,'bsbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="pastebutton" value="Paste" title="Paste text into the terminal" onclick="showTermPasteDialog()"> </div> </td> </tr> </table> </div> <div id="p13" style="display:none"> <div id="p13title"> <div id="p13BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Files - <span id="p13deviceName"></span></h1> </div> <table id="p13toolbar" style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="background-color:#C0C0C0;border-bottom:2px solid black;padding:2px"> <div style="float:right;text-align:right"> <input id="filesActionsBtn" type="button" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value="Actions" onclick="deviceActionFunction()" style="margin-right:3px"> </div> <div> <input id="p13AutoConnect" value="AutoConnect" onclick="autoConnectFiles(event)" onkeypress="return false" onkeydown="return false" type="button" style="display:none"> <input id="p13Connect" value="Connect" onclick="connectFiles(event)" onkeypress="return false" onkeydown="return false" type="button"> <span id="p13Status">Disconnected</span> </div> </td> </tr> <tr> <td style="width:100%;background-color:#d3d9d6;text-align:left;padding:4px" valign="bottom"> <div id="p13rightOfButtons" style="float:right;margin-top:3px"></div> <div> <input type="button" id="p13FolderUp" disabled="disabled" onclick="p13folderup()" value="Up">&nbsp; <input type="button" id="p13SelectAllButton" disabled="disabled" onclick="p13selectallfile()" value="Select All" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13RenameFileButton" disabled="disabled" value="Rename" onclick="p13renamefile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13DeleteFileButton" disabled="disabled" value="Delete" onclick="p13deletefile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13NewFolderButton" disabled="disabled" value="New Folder" onclick="p13createfolder()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13UploadButton" disabled="disabled" value="Upload" onclick="p13uploadFile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13CutButton" disabled="disabled" value="Cut" onclick="p13copyFile(1)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13CopyButton" disabled="disabled" value="Copy" onclick="p13copyFile(0)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13PasteButton" disabled="disabled" value="Paste" onclick="p13pasteFile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13RefreshButton" disabled="disabled" value="Refresh" onclick="p13folderup(9999)" onkeypress="return false" onkeydown="return false">&nbsp; </div> </td> </tr> <tr> <td style="background-color:#E4E9E7;height:28px"> <div style="float:right"> <select id="p13sortdropdown" onchange="p13updateFiles()"> <option value="1" selected="selected">Sort by name <option value="2">Sort by size <option value="3">Sort by date <option value="4">Descend by name <option value="5">Descend by size <option value="6">Descend by date </select> </div> <div>&nbsp;&nbsp;<span id="p13currentpath"></span></div> </td> </tr> </table> <div id="p13filetable" style="width:100%;height:calc(100vh - 346px);overflow:auto;-webkit-user-select:none"> <div id="p13bigok" style="width:256px;overflow:hidden;position:absolute;left:337px;top:200px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&checkmark;</b></div> <div id="p13bigfail" style="width:256px;overflow:hidden;position:absolute;left:337px;top:200px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&#10007;</b></div> <span id="p13files"></span> </div> <table id="p13toolbarBottom" style="width:100%" cellpadding="0" cellspacing="0"> <tr><td class="style6" style="text-align:left;padding:3px">&nbsp;<span id="p13bottomstatus"></span></td></tr> </table> </div> <div id="p14" style="display:none"> <div id="p14title"> <div id="p14BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Intel&reg; AMT - <span id="p14deviceName"></span></h1> </div> <iframe id="p14iframe" style="width:100%;height:calc(100vh - 242px);border:0;overflow:hidden" src="/commander.htm"></iframe> </div> <div id="p15" style="display:none"> <div id="p15title"> <div id="p15BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1><span id="p15deviceName"></span></h1> </div> <table cellpadding="0" cellspacing="0" style="width:100%;padding:0px;padding:0px;margin-top:0px"> <tr> <td style="background:#C0C0C0"> <div style="float:right;padding-right:4px"> <div style="padding:4px;display:inline-block" id="p15coreName" title="Information about current core running on this agent"></div> <input type="button" id="p15uploadCore" value="Agent Action" onclick="p15uploadCore(event)" title="Change the agent Java Script code module"> </div> <div id="p15statetext" style="padding:4px"></div> </td> </tr> <tr> <td> <div style="background-color:gray"><div id="consoleprogressbar" style="height:2px;width:0%;background-color:red"></div></div> </td> </tr> <tr> <td id="p15agentConsole" style="background:black;margin:0;padding:0;color:lightgray;width:100%;height:calc(100vh - 296px);max-height:500px;position:relative"> <pre id="p15agentConsoleText" style="position:absolute;margin:0;padding:0;top:0;bottom:0;left:0;right:0;overflow-y:scroll;overflow-x:auto"></pre> </td> </tr> <tr> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <table style="width:100%"> <tr> <td style="width:99%"> <input id="p15consoleText" style="width:100%" onkeyup="p15consoleSend(event)" onfocus="onConsoleFocus(1)" onblur="onConsoleFocus(0)"> </td> <td>&nbsp;</td> <td style="width:1%"><input id="id_p15consoleClear" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Clear" onclick="p15consoleClear()"></td> </tr> </table> </td> </tr> </table> </div> <div id="p16" style="display:none"> <div id="p16title"> <div id="p16BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Events - <span id="p16deviceName"></span></h1> </div> <div style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px"> <div class="style7" style="width:16px;height:100%;float:left">&nbsp;</div> <div class="h1" style="height:100%;float:left">&nbsp;</div> <div class="style14" style="height:100%;float:left">&nbsp;&nbsp;<input type="button" value="Refresh" onclick="refreshDeviceEvents()">&nbsp;</div> <div class="auto-style1" style="height:100%;float:right"> Show <select id="p16limitdropdown" onchange="refreshDeviceEvents()"> <option value="60">Last 60 <option value="120">Last 120 <option value="250">Last 250 <option value="500">Last 500 <option value="1000">Last 1000 </select> <div style="height:100%;width:20px;float:right;background-color:#ffffff"></div> <div class="h2" style="height:100%;float:right">&nbsp;</div> </div> </div> <div id="p16events" style="max-height:calc(100vh - 267px);overflow-y:auto"></div> </div> <div id="p20" style="display:none"> <picture id="MainMeshImage" style="border-width:0px;height:200px;width:200px;float:right"> <source type="image/webp" width="200" height="200" srcset="images/webp/mesh-200.webp"> <img alt="" width="200" height="200" src="images/mesh-200.jpg"> </source></picture> <div style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>General - <span id="p20meshName"></span></h1> <p id="p20info"> </div> <div id="p30" style="display:none"> <table style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="width:auto" valign="top"> <div id="p30title"> <div style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>General - <span id="p30userName"></span></h1> </div> <div id="p30html"></div> </td> <td style="width:20px"></td> <td style="width:200px"> <picture id="MainUserImage" style="border-width:0px;height:200px;width:200px;float:right"> <source type="image/webp" width="200" height="200" srcset="images/webp/user-200.webp"> <img alt="" width="200" height="200" src="images/user-200.jpg"> </source></picture> <div style="width:100%;text-align:center"><strong><span id="MainUserState"></span></strong></div> </td> </tr> </table><br> <div id="p30html2"></div> <div id="p30html3"></div> </div> <div id="p31" style="display:none"> <div style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Events - <span id="p31userName"></span></h1> <div style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px"> <div class="style7" style="width:16px;height:100%;float:left">&nbsp;</div> <div class="h1" style="height:100%;float:left">&nbsp;</div> <div class="style14" style="height:100%;float:left">&nbsp;&nbsp;<input type="button" value="Refresh" onclick="refreshUsersEvents()">&nbsp;</div> <div class="auto-style1" style="height:100%;float:right"> Show <select id="p31limitdropdown" onchange="refreshUsersEvents()"> <option value="60">Last 60 <option value="120">Last 120 <option value="250">Last 250 <option value="500">Last 500 <option value="1000">Last 1000 </select> <div style="height:100%;width:20px;float:right;background-color:#ffffff"></div> <div class="h2" style="height:100%;float:right;">&nbsp;</div> </div> </div> <div id="p31events" style="max-height:calc(100vh - 267px);overflow-y:scroll"></div> </div> <br id="column_l_bottomgap"> </div> <div id="footer" class="noselect"> <table cellpadding="0" cellspacing="10" style="width:100%"> <tr> <td style="text-align:left;color:white"> {{{footer}}} </td> <td style="text-align:right"> <a id="verifyEmailId2" style="color:yellow;margin-left:3px;cursor:pointer;display:none" onclick="account_showVerifyEmail()">Verify Email</a> <a style="margin-left:3px" href="terms">Terms &amp; Privacy</a> </td> </tr> </table> </div> <div id="dialog" style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:5px;position:fixed;top:160px;width:400px;left:calc((100% / 2) - 200px);display:none"> <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0"> <div id="id_dialogclose" style="float:right;padding:3px;margin-right:3px;cursor:pointer" onclick="setDialogMode()">&#x2716;</div> <div id="id_dialogtitle" style="padding:5px"></div> <div style="width:100%;margin:6px"></div> </div> <div style="margin-right:16px;margin-left:8px"> <div id="dialog1" style="margin:auto;text-align:center;margin:3px"> <div id="id_dialogMessage" style="padding:10px"></div> </div> <div id="dialog2" style="margin:auto;margin:3px"> <div id="id_dialogOptions"></div> </div> <div id="dialog3" style="margin:auto;margin:3px"> <div style="height:26px"> <select id="d3uploadMode" style="float:right;width:260px" onchange="d3modechange()"> <option value="1">Local file upload <option value="2">Server file selection </select> <div>File Selection</div> </div> <div id="d3localmode" style="height:26px;display:none"> <form id="d3localmodeform" method="post" enctype="multipart/form-data" action="uploadfile.ashx" target="fileUploadFrame"> <input type="text" id="d3attrib" name="attrib" style="display:none"> <input type="file" id="d3localFile" name="files" style="float:right;width:260px" onchange="d3setActions()"> <input type="submit" id="d3submit" style="display:none"> </form> <div>Upload File</div> </div> <div id="d3servermode"> <div style="width:100%;background-color:#d3d9d6;text-align:left;padding:3px" valign="bottom"> <input type="button" id="p3FolderUp" disabled="disabled" onclick="d3folderup()" value="Up">&nbsp; </div> <div id="d3serverfiles" style="width:100%;height:150px;background-color:white;padding:2px;border:1px solid gray;overflow-y:scroll"></div> </div> </div> <div id="dialog7" style="margin:auto;margin:3px"> <div id="d7meshkvm"> <h4 style="width:100%;border-bottom:1px solid gray">Agent Remote Desktop</h4> <div style="margin:3px 0 3px 0"> <select id="d7bitmapquality" style="float:right;width:200px;height:20px" dir="rtl"></select> <div style="height:20px">Quality</div> </div> <div style="margin:3px 0 3px 0"> <select id="d7bitmapscaling" style="float:right;width:200px;height:20px" dir="rtl"> <option selected="selected" value="1024">100% <option value="896">87.5% <option value="768">75% <option value="640">62.5% <option value="512">50% <option value="384">37.5% <option value="256">25% <option value="128">12.5% </select> <div style="height:20px">Scaling</div> </div> <div style="margin:3px 0 3px 0"> <select id="d7framelimiter" style="float:right;width:200px;height:20px" dir="rtl"> <option selected="selected" value="50">Fast <option value="100">Medium <option value="400">Slow <option value="1000">Very slow </select> <div style="height:20px">Frame rate</div> </div> </div> <div id="d7amtkvm"> <h4 style="width:100%;border-bottom:1px solid gray">Intel&reg; AMT Hardware KVM</h4> <div style='height:26px'> <select id="d7desktopmode" style="float:right;width:200px"> <option value="1">RLE8, Fastest <option value="2">RLE16, Recommended <option value="3">RAW8, Slow <option value="4">RAW16, Very Slow </select> <div>Image Encoding</div> </div> <div style="height:60px"> <div style="float:right;border:1px solid #666;width:200px;height:60px;overflow-y:scroll;background-color:white"> <label><input type="checkbox" id='d7showfocus'>Show Focus Tool<br></label> <label><input type="checkbox" id='d7showcursor'>Show Local Mouse Cursor<br></label> <label><input type="checkbox" id='d7localKeyMap'>Local Keyboard Map<br></label> </div> <div>Other Settings</div> </div> </div> </div> </div> <div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:4px"> <input id="idx_dlgCancelButton" type="button" value="Cancel" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)"> <input id="idx_dlgOkButton" type="button" value="OK" style="float:right;width:80px" onclick="dialogclose(1)"> <div style="height:25px"><input id="idx_dlgDeleteButton" type="button" value="Delete" style="width:80px;display:none" onclick="dialogclose(2)"></div> </div> </div> <iframe name="fileUploadFrame" style="display:none"></iframe> <form style="display:none" method="post" action="uploadfile.ashx" enctype="multipart/form-data" target="fileUploadFrame"><input id="p5fileDragName" name="name"><input id="p5fileDragSize" name="size"><input id="p5fileDragType" name="type"><input id="p5fileDragData" name="data"><input id="p5fileDragLink" name="link"><input type="submit" id="p5loginSubmit2" style="display:none"></form> <form style="display:none" method="post" action="uploadnodefile.ashx" enctype="multipart/form-data" target="fileUploadFrame"><input id="p13fileDragName" name="name"><input id="p13fileDragSize" name="size"><input id="p13fileDragType" name="type"><input id="p13fileDragData" name="data"><input id="p13fileDragLink" name="link"><input type="submit" id="p13loginSubmit2" style="display:none"></form> <audio id="chimes"><source src="sounds/chimes.mp3" type="audio/mp3"></source></audio> </div> </div> <script>if(!String.prototype.startsWith){String.prototype.startsWith=function(a){return this.lastIndexOf(a,0)===0}}if(!String.prototype.endsWith){String.prototype.endsWith=function(a){return this.indexOf(a,this.length-a.length)!==-1}}function Q(a){return document.getElementById(a)}function QS(a){try{return Q(a).style}catch(a){}}function QE(a,b){try{Q(a).disabled=!b}catch(a){}}function QV(a,b){try{QS(a).display=(b?"":"none")}catch(a){}}function QA(a,b){Q(a).innerHTML+=b}function QH(a,b){Q(a).innerHTML=b}function inputBoxFocus(b){Q(b).focus();var a=Q(b).value;Q(b).value="";Q(b).value=a}function ReadShort(b,a){return(b.charCodeAt(a)<<8)+b.charCodeAt(a+1)}function ReadShortX(b,a){return(b.charCodeAt(a+1)<<8)+b.charCodeAt(a)}function ReadInt(b,a){return(b.charCodeAt(a)*16777216)+(b.charCodeAt(a+1)<<16)+(b.charCodeAt(a+2)<<8)+b.charCodeAt(a+3)}function ReadSInt(b,a){return(b.charCodeAt(a)<<24)+(b.charCodeAt(a+1)<<16)+(b.charCodeAt(a+2)<<8)+b.charCodeAt(a+3)}function ReadIntX(b,a){return(b.charCodeAt(a+3)*16777216)+(b.charCodeAt(a+2)<<16)+(b.charCodeAt(a+1)<<8)+b.charCodeAt(a)}function ShortToStr(a){return String.fromCharCode((a>>8)&255,a&255)}function ShortToStrX(a){return String.fromCharCode(a&255,(a>>8)&255)}function IntToStr(a){return String.fromCharCode((a>>24)&255,(a>>16)&255,(a>>8)&255,a&255)}function IntToStrX(a){return String.fromCharCode(a&255,(a>>8)&255,(a>>16)&255,(a>>24)&255)}function MakeToArray(a){if(!a||a==null||typeof a=="object"){return a}return[a]}function SplitArray(a){return a.split(",")}function Clone(a){return JSON.parse(JSON.stringify(a))}function EscapeHtml(a){if(typeof a=="string"){return a.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}if(typeof a=="boolean"){return a}if(typeof a=="number"){return a}}function EscapeHtmlBreaks(a){if(typeof a=="string"){return a.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/\r/g,"<br />").replace(/\n/g,"").replace(/\t/g,"&nbsp;&nbsp;")}if(typeof a=="boolean"){return a}if(typeof a=="number"){return a}}function ArrayElementMove(a,b,c){a.splice(c,0,a.splice(b,1)[0])}function ObjectToStringEx(e,a){var d="";if(e!=0&&(!e||e==null)){return"(Null)"}if(e instanceof Array){for(var b in e){d+="<br />"+gap(a)+"Item #"+b+": "+ObjectToStringEx(e[b],a+1)}}else{if(e instanceof Object){for(var b in e){d+="<br />"+gap(a)+b+" = "+ObjectToStringEx(e[b],a+1)}}else{d+=EscapeHtml(e)}}return d}function ObjectToStringEx2(e,a){var d="";if(e!=0&&(!e||e==null)){return"(Null)"}if(e instanceof Array){for(var b in e){d+="\r\n"+gap2(a)+"Item #"+b+": "+ObjectToStringEx2(e[b],a+1)}}else{if(e instanceof Object){for(var b in e){d+="\r\n"+gap2(a)+b+" = "+ObjectToStringEx2(e[b],a+1)}}else{d+=EscapeHtml(e)}}return d}function gap(a){var d="";for(var b=0;b<(a*4);b++){d+="&nbsp;"}return d}function gap2(a){var d="";for(var b=0;b<(a*4);b++){d+=" "}return d}function ObjectToString(a){return ObjectToStringEx(a,0)}function ObjectToString2(a){return ObjectToStringEx2(a,0)}function hex2rstr(a){if(typeof a!="string"||a.length==0){return""}var c="",b=(""+a).match(/../g),e;while(e=b.shift()){c+=String.fromCharCode("0x"+e)}return c}function char2hex(a){return(a+256).toString(16).substr(-2).toUpperCase()}function rstr2hex(b){var c="",a;for(a=0;a<b.length;a++){c+=char2hex(b.charCodeAt(a))}return c}function encode_utf8(a){return unescape(encodeURIComponent(a))}function decode_utf8(a){return decodeURIComponent(escape(a))}function data2blob(c){var b=new Array(c.length);for(var d=0;d<c.length;d++){b[d]=c.charCodeAt(d)}var a=new Blob([new Uint8Array(b)]);return a}function random(a){return Math.floor(Math.random()*a)}function trademarks(a){return a.replace(/\(R\)/g,"&reg;").replace(/\(TM\)/g,"&trade;")}var MeshServerCreateControl=function(b,a){var c={};c.State=0;c.connectstate=0;c.pingTimer=null;c.authCookie=a;c.xxStateChange=function(e,d){if(c.State==e){return}var g=c.State;c.State=e;if(c.onStateChanged){c.onStateChanged(c,c.State,g,d)}};c.Start=function(){if(c.connectstate!=0){return}c.connectstate=0;var d=window.location.protocol.replace("http","ws")+"//"+window.location.host+b+"control.ashx";if(c.authCookie&&(c.authCookie!="")){d+="?auth="+c.authCookie}c.socket=new WebSocket(d);c.socket.onopen=function(g){c.connectstate=1};c.socket.onmessage=c.xxOnMessage;c.socket.onclose=function(g){c.Stop(g.code)};c.xxStateChange(1,0);if(c.pingTimer!=null){clearInterval(c.pingTimer)}c.pingTimer=setInterval(function(){c.send({action:"ping"})},29000)};c.Stop=function(d){c.connectstate=0;if(c.socket){c.socket.close();delete c.socket}if(c.pingTimer!=null){clearInterval(c.pingTimer);c.pingTimer=null}c.xxStateChange(0,d)};c.xxOnMessage=function(d){if(c.State==1){c.xxStateChange(2)}var g;try{g=JSON.parse(d.data)}catch(d){return}if((typeof g!="object")||(g.action=="pong")){return}if(g.action=="close"){if(g.msg){console.log(g.msg)}c.Stop(g.cause);return}if(c.onMessage){c.onMessage(c,g)}};c.send=function(d){if(c.socket!=null&&c.connectstate==1){c.socket.send(JSON.stringify(d))}};return c};function AmtStackCreateService(t){var s=new Object();s.wsman=t;s.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/"];s.PendingEnums=[];s.PendingBatchOperations=0;s.ActiveEnumsCount=0;s.MaxActiveEnumsCount=1;s.onProcessChanged=null;var n=0;var m=0;s.GetPendingActions=function(){return(s.PendingEnums.length*2)+(s.ActiveEnumsCount)+s.wsman.comm.PendingAjax.length+s.wsman.comm.ActiveAjaxCount+s.PendingBatchOperations};function r(){var u=s.GetPendingActions();if(n<u){n=u}if(s.onProcessChanged!=null&&m!=u){m=u;s.onProcessChanged(u,n)}if(u==0){n=0}}s.Subscribe=function(w,v,C,u,B,z,A,x,D,y){s.wsman.ExecSubscribe(s.CompleteName(w),v,C,function(G,F,E,H){r();u(s,w,E,H,B)},0,z,A,x,D,y);r()};s.UnSubscribe=function(v,u,y,w,x){s.wsman.ExecUnSubscribe(s.CompleteName(v),function(B,A,z,C){r();u(s,v,z,C,y)},0,w,x);r()};s.Get=function(v,u,x,w){s.wsman.ExecGet(s.CompleteName(v),function(A,z,y,B){r();u(s,v,y,B,x)},0,w);r()};s.Put=function(v,x,u,z,w,y){s.wsman.ExecPut(s.CompleteName(v),x,function(C,B,A,D){r();u(s,v,A,D,z)},0,w,y);r()};s.Create=function(v,x,u,y,w){s.wsman.ExecCreate(s.CompleteName(v),x,function(B,A,z,C){r();u(s,v,z,C,y)},0,w);r()};s.Delete=function(v,x,u,y,w){s.wsman.ExecDelete(s.CompleteName(v),x,function(B,A,z,C){r();u(s,v,z,C,y)},0,w);r()};s.Exec=function(x,w,u,v,A,y,z){s.wsman.ExecMethod(s.CompleteName(x),w,u,function(D,C,B,E){r();v(s,x,s.CompleteExecResponse(B),E,A)},0,y,z);r()};s.ExecWithXml=function(x,w,u,v,A,y,z){s.wsman.ExecMethodXml(s.CompleteName(x),w,execArgumentsToXml(u),function(D,C,B,E){r();v(s,x,s.CompleteExecResponse(B),E,A)},0,y,z);r()};s.Enum=function(v,u,x,w){if(s.ActiveEnumsCount<s.MaxActiveEnumsCount){s.ActiveEnumsCount++;s.wsman.ExecEnum(s.CompleteName(v),function(B,z,y,C,A){r();d(v,y,u,z,C,A)},x,w)}else{s.PendingEnums.push([v,u,x,w])}r()};function d(w,y,u,z,A,B,x){if(A!=200){u(s,w,null,A,B);c(1);return}if(y==null||y.Header.Method!="EnumerateResponse"||!y.Body.EnumerationContext){u(s,w,null,603,B);c(1);return}var v=y.Body.EnumerationContext;s.wsman.ExecPull(z,v,function(E,D,C,F){b(w,C,u,D,[],F,B,x)})}function b(z,B,u,C,x,D,E,A){if(D!=200){u(s,z,null,D,E);c(1);return}if(B==null||B.Header.Method!="PullResponse"){u(s,z,null,604,E);c(1);return}for(var w in B.Body.Items){if(B.Body.Items[w] instanceof Array){for(var y in B.Body.Items[w]){x.push(B.Body.Items[w][y])}}else{x.push(B.Body.Items[w])}}if(B.Body.EnumerationContext){var v=B.Body.EnumerationContext;s.wsman.ExecPull(C,v,function(H,G,F,I){b(z,F,u,G,x,I,E,1)})}else{c(1);u(s,z,x,D,E);r()}}function c(u){s.ActiveEnumsCount-=u;if(s.ActiveEnumsCount>=s.MaxActiveEnumsCount||s.PendingEnums.length==0){return}var v=s.PendingEnums.shift();s.Enum(v[0],v[1],v[2]);c(0)}s.BatchEnum=function(u,x,v,z,w,y){s.PendingBatchOperations+=(x.length*2);a(u,Clone(x),v,z,{},w,y);r()};function a(u,z,v,C,B,w,A){s.PendingBatchOperations-=2;var y=z.shift(),x=s.Enum;if(y[0]=="*"){x=s.Get;y=y.substring(1)}x(y,function(F,D,E,G,H){H[2][D]={response:(E==null?null:E.Body),responses:E,status:G};if(H[1].length==0||G==401||(w!=true&&G!=200&&G!=400)){s.PendingBatchOperations-=(z.length*2);r();v(s,u,H[2],G,C)}else{r();a(u,z,v,C,H[2],A)}},[u,z,B],A);r()}s.BatchGet=function(u,w,v,y,x){h({name:u,names:w,callback:v,current:0,responses:{},tag:y,pri:x});r()};function h(u){if(u.names.length<=u.current){u.callback(s,u.name,u.responses,200,u.tag)}else{s.wsman.ExecGet(s.CompleteName(u.names[u.current]),function(x,w,v,y){g(u,v,y)},u.pri);u.current++}r()}function g(u,v,w){if(v==null||w!=200){u.callback(s,u.name,null,w,u.tag)}else{u.responses[v.Header.Method]=v;h(u)}}s.CompleteName=function(u){if(u.indexOf("AMT_")==0){return s.pfx[0]+u}if(u.indexOf("CIM_")==0){return s.pfx[1]+u}if(u.indexOf("IPS_")==0){return s.pfx[2]+u}};s.CompleteExecResponse=function(u){if(u&&u!=null&&u.Body&&u.Body.ReturnValue){u.Body.ReturnValueStr=s.AmtStatusToStr(u.Body.ReturnValue)}return u};s.RequestPowerStateChange=function(v,u){s.CIM_PowerManagementService_RequestPowerStateChange(v,'<Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing"><ResourceURI xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystem</ResourceURI><SelectorSet xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"><Selector Name="CreationClassName">CIM_ComputerSystem</Selector><Selector Name="Name">ManagedSystem</Selector></SelectorSet></ReferenceParameters>',null,null,u)};s.SetBootConfigRole=function(v,u){s.CIM_BootService_SetBootConfigRole('<Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing"><ResourceURI xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_BootConfigSetting</ResourceURI><SelectorSet xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"><Selector Name="InstanceID">Intel(r) AMT: Boot Configuration 0</Selector></SelectorSet></ReferenceParameters>',v,u)};s.CancelAllQueries=function(u){s.wsman.CancelAllQueries(u)};s.AMT_AgentPresenceWatchdog_RegisterAgent=function(u){s.Exec("AMT_AgentPresenceWatchdog","RegisterAgent",{},u)};s.AMT_AgentPresenceWatchdog_AssertPresence=function(v,u){s.Exec("AMT_AgentPresenceWatchdog","AssertPresence",{SequenceNumber:v},u)};s.AMT_AgentPresenceWatchdog_AssertShutdown=function(v,u){s.Exec("AMT_AgentPresenceWatchdog","AssertShutdown",{SequenceNumber:v},u)};s.AMT_AgentPresenceWatchdog_AddAction=function(z,y,x,v,u,w,C,A,B){s.Exec("AMT_AgentPresenceWatchdog","AddAction",{OldState:z,NewState:y,EventOnTransition:x,ActionSd:v,ActionEac:u},w,C,A,B)};s.AMT_AgentPresenceWatchdog_DeleteAllActions=function(u,x,v,w){s.Exec("AMT_AgentPresenceWatchdog","DeleteAllActions",{},u,x,v,w)};s.AMT_AgentPresenceWatchdogAction_GetActionEac=function(u){s.Exec("AMT_AgentPresenceWatchdogAction","GetActionEac",{},u)};s.AMT_AgentPresenceWatchdogVA_RegisterAgent=function(u){s.Exec("AMT_AgentPresenceWatchdogVA","RegisterAgent",{},u)};s.AMT_AgentPresenceWatchdogVA_AssertPresence=function(v,u){s.Exec("AMT_AgentPresenceWatchdogVA","AssertPresence",{SequenceNumber:v},u)};s.AMT_AgentPresenceWatchdogVA_AssertShutdown=function(v,u){s.Exec("AMT_AgentPresenceWatchdogVA","AssertShutdown",{SequenceNumber:v},u)};s.AMT_AgentPresenceWatchdogVA_AddAction=function(z,y,x,v,u,w){s.Exec("AMT_AgentPresenceWatchdogVA","AddAction",{OldState:z,NewState:y,EventOnTransition:x,ActionSd:v,ActionEac:u},w)};s.AMT_AgentPresenceWatchdogVA_DeleteAllActions=function(u,v){s.Exec("AMT_AgentPresenceWatchdogVA","DeleteAllActions",{_method_dummy:u},v)};s.AMT_AuditLog_ClearLog=function(u){s.Exec("AMT_AuditLog","ClearLog",{},u)};s.AMT_AuditLog_RequestStateChange=function(v,w,u){s.Exec("AMT_AuditLog","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AMT_AuditLog_ReadRecords=function(v,u,w){s.Exec("AMT_AuditLog","ReadRecords",{StartIndex:v},u,w)};s.AMT_AuditLog_SetAuditLock=function(x,v,w,u){s.Exec("AMT_AuditLog","SetAuditLock",{LockTimeoutInSeconds:x,Flag:v,Handle:w},u)};s.AMT_AuditLog_ExportAuditLogSignature=function(v,u){s.Exec("AMT_AuditLog","ExportAuditLogSignature",{SigningMechanism:v},u)};s.AMT_AuditLog_SetSigningKeyMaterial=function(y,x,w,v,u){s.Exec("AMT_AuditLog","SetSigningKeyMaterial",{SigningMechanismType:y,SigningKey:x,LengthOfCertificates:w,Certificates:v},u)};s.AMT_AuditPolicyRule_SetAuditPolicy=function(w,u,x,y,v){s.Exec("AMT_AuditPolicyRule","SetAuditPolicy",{Enable:w,AuditedAppID:u,EventID:x,PolicyType:y},v)};s.AMT_AuditPolicyRule_SetAuditPolicyBulk=function(w,u,x,y,v){s.Exec("AMT_AuditPolicyRule","SetAuditPolicyBulk",{Enable:w,AuditedAppID:u,EventID:x,PolicyType:y},v)};s.AMT_AuthorizationService_AddUserAclEntryEx=function(x,w,y,u,z,v){s.Exec("AMT_AuthorizationService","AddUserAclEntryEx",{DigestUsername:x,DigestPassword:w,KerberosUserSid:y,AccessPermission:u,Realms:z},v)};s.AMT_AuthorizationService_EnumerateUserAclEntries=function(v,u){s.Exec("AMT_AuthorizationService","EnumerateUserAclEntries",{StartIndex:v},u)};s.AMT_AuthorizationService_GetUserAclEntryEx=function(v,u,w){s.Exec("AMT_AuthorizationService","GetUserAclEntryEx",{Handle:v},u,w)};s.AMT_AuthorizationService_UpdateUserAclEntryEx=function(y,x,w,z,u,A,v){s.Exec("AMT_AuthorizationService","UpdateUserAclEntryEx",{Handle:y,DigestUsername:x,DigestPassword:w,KerberosUserSid:z,AccessPermission:u,Realms:A},v)};s.AMT_AuthorizationService_RemoveUserAclEntry=function(v,u){s.Exec("AMT_AuthorizationService","RemoveUserAclEntry",{Handle:v},u)};s.AMT_AuthorizationService_SetAdminAclEntryEx=function(w,v,u){s.Exec("AMT_AuthorizationService","SetAdminAclEntryEx",{Username:w,DigestPassword:v},u)};s.AMT_AuthorizationService_GetAdminAclEntry=function(u){s.Exec("AMT_AuthorizationService","GetAdminAclEntry",{},u)};s.AMT_AuthorizationService_GetAdminAclEntryStatus=function(u){s.Exec("AMT_AuthorizationService","GetAdminAclEntryStatus",{},u)};s.AMT_AuthorizationService_GetAdminNetAclEntryStatus=function(u){s.Exec("AMT_AuthorizationService","GetAdminNetAclEntryStatus",{},u)};s.AMT_AuthorizationService_SetAclEnabledState=function(w,v,u,x){s.Exec("AMT_AuthorizationService","SetAclEnabledState",{Handle:w,Enabled:v},u,x)};s.AMT_AuthorizationService_GetAclEnabledState=function(v,u,w){s.Exec("AMT_AuthorizationService","GetAclEnabledState",{Handle:v},u,w)};s.AMT_EndpointAccessControlService_RequestStateChange=function(v,w,u){s.Exec("AMT_EndpointAccessControlService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AMT_EndpointAccessControlService_GetPosture=function(v,u){s.Exec("AMT_EndpointAccessControlService","GetPosture",{PostureType:v},u)};s.AMT_EndpointAccessControlService_GetPostureHash=function(v,u){s.Exec("AMT_EndpointAccessControlService","GetPostureHash",{PostureType:v},u)};s.AMT_EndpointAccessControlService_UpdatePostureState=function(v,u){s.Exec("AMT_EndpointAccessControlService","UpdatePostureState",{UpdateType:v},u)};s.AMT_EndpointAccessControlService_GetEacOptions=function(u){s.Exec("AMT_EndpointAccessControlService","GetEacOptions",{},u)};s.AMT_EndpointAccessControlService_SetEacOptions=function(v,w,u){s.Exec("AMT_EndpointAccessControlService","SetEacOptions",{EacVendors:v,PostureHashAlgorithm:w},u)};s.AMT_EnvironmentDetectionSettingData_SetSystemDefensePolicy=function(v,u){s.Exec("AMT_EnvironmentDetectionSettingData","SetSystemDefensePolicy",{Policy:v},u)};s.AMT_EnvironmentDetectionSettingData_EnableVpnRouting=function(v,u){s.Exec("AMT_EnvironmentDetectionSettingData","EnableVpnRouting",{Enable:v},u)};s.AMT_EthernetPortSettings_SetLinkPreference=function(v,w,u){s.Exec("AMT_EthernetPortSettings","SetLinkPreference",{LinkPreference:v,Timeout:w},u)};s.AMT_HeuristicPacketFilterStatistics_ResetSelectedStats=function(v,u){s.Exec("AMT_HeuristicPacketFilterStatistics","ResetSelectedStats",{SelectedStatistics:v},u)};s.AMT_KerberosSettingData_GetCredentialCacheState=function(u){s.Exec("AMT_KerberosSettingData","GetCredentialCacheState",{},u)};s.AMT_KerberosSettingData_SetCredentialCacheState=function(v,u){s.Exec("AMT_KerberosSettingData","SetCredentialCacheState",{Enable:v},u)};s.AMT_MessageLog_CancelIteration=function(v,u){s.Exec("AMT_MessageLog","CancelIteration",{IterationIdentifier:v},u)};s.AMT_MessageLog_RequestStateChange=function(v,w,u){s.Exec("AMT_MessageLog","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AMT_MessageLog_ClearLog=function(u){s.Exec("AMT_MessageLog","ClearLog",{},u)};s.AMT_MessageLog_GetRecords=function(v,w,u,x){s.Exec("AMT_MessageLog","GetRecords",{IterationIdentifier:v,MaxReadRecords:w},u,x)};s.AMT_MessageLog_GetRecord=function(v,w,u){s.Exec("AMT_MessageLog","GetRecord",{IterationIdentifier:v,PositionToNext:w},u)};s.AMT_MessageLog_PositionAtRecord=function(v,w,x,u){s.Exec("AMT_MessageLog","PositionAtRecord",{IterationIdentifier:v,MoveAbsolute:w,RecordNumber:x},u)};s.AMT_MessageLog_PositionToFirstRecord=function(u,v){s.Exec("AMT_MessageLog","PositionToFirstRecord",{},u,v)};s.AMT_MessageLog_FreezeLog=function(v,u){s.Exec("AMT_MessageLog","FreezeLog",{Freeze:v},u)};s.AMT_PublicKeyManagementService_AddCRL=function(w,v,u){s.Exec("AMT_PublicKeyManagementService","AddCRL",{Url:w,SerialNumbers:v},u)};s.AMT_PublicKeyManagementService_ResetCRLList=function(u,v){s.Exec("AMT_PublicKeyManagementService","ResetCRLList",{_method_dummy:u},v)};s.AMT_PublicKeyManagementService_AddCertificate=function(v,u){s.Exec("AMT_PublicKeyManagementService","AddCertificate",{CertificateBlob:v},u)};s.AMT_PublicKeyManagementService_AddTrustedRootCertificate=function(v,u){s.Exec("AMT_PublicKeyManagementService","AddTrustedRootCertificate",{CertificateBlob:v},u)};s.AMT_PublicKeyManagementService_AddKey=function(v,u){s.Exec("AMT_PublicKeyManagementService","AddKey",{KeyBlob:v},u)};s.AMT_PublicKeyManagementService_GeneratePKCS10Request=function(w,v,x,u){s.Exec("AMT_PublicKeyManagementService","GeneratePKCS10Request",{KeyPair:w,DNName:v,Usage:x},u)};s.AMT_PublicKeyManagementService_GeneratePKCS10RequestEx=function(v,x,w,u){s.Exec("AMT_PublicKeyManagementService","GeneratePKCS10RequestEx",{KeyPair:v,SigningAlgorithm:x,NullSignedCertificateRequest:w},u)};s.AMT_PublicKeyManagementService_GenerateKeyPair=function(v,w,u){s.Exec("AMT_PublicKeyManagementService","GenerateKeyPair",{KeyAlgorithm:v,KeyLength:w},u)};s.AMT_RedirectionService_RequestStateChange=function(v,u){s.Exec("AMT_RedirectionService","RequestStateChange",{RequestedState:v},u)};s.AMT_RedirectionService_TerminateSession=function(v,u){s.Exec("AMT_RedirectionService","TerminateSession",{SessionType:v},u)};s.AMT_RemoteAccessService_AddMpServer=function(u,z,B,v,x,C,A,y,w){s.Exec("AMT_RemoteAccessService","AddMpServer",{AccessInfo:u,InfoFormat:z,Port:B,AuthMethod:v,Certificate:x,Username:C,Password:A,CN:y},w)};s.AMT_RemoteAccessService_AddRemoteAccessPolicyRule=function(x,y,v,w,u){s.Exec("AMT_RemoteAccessService","AddRemoteAccessPolicyRule",{Trigger:x,TunnelLifeTime:y,ExtendedData:v,MpServer:w},u)};s.AMT_RemoteAccessService_CloseRemoteAccessConnection=function(u,v){s.Exec("AMT_RemoteAccessService","CloseRemoteAccessConnection",{_method_dummy:u},v)};s.AMT_SetupAndConfigurationService_CommitChanges=function(u,v){s.Exec("AMT_SetupAndConfigurationService","CommitChanges",{_method_dummy:u},v)};s.AMT_SetupAndConfigurationService_Unprovision=function(v,u){s.Exec("AMT_SetupAndConfigurationService","Unprovision",{ProvisioningMode:v},u)};s.AMT_SetupAndConfigurationService_PartialUnprovision=function(u,v){s.Exec("AMT_SetupAndConfigurationService","PartialUnprovision",{_method_dummy:u},v)};s.AMT_SetupAndConfigurationService_ResetFlashWearOutProtection=function(u,v){s.Exec("AMT_SetupAndConfigurationService","ResetFlashWearOutProtection",{_method_dummy:u},v)};s.AMT_SetupAndConfigurationService_ExtendProvisioningPeriod=function(v,u){s.Exec("AMT_SetupAndConfigurationService","ExtendProvisioningPeriod",{Duration:v},u)};s.AMT_SetupAndConfigurationService_SetMEBxPassword=function(v,u){s.Exec("AMT_SetupAndConfigurationService","SetMEBxPassword",{Password:v},u)};s.AMT_SetupAndConfigurationService_SetTLSPSK=function(v,w,u){s.Exec("AMT_SetupAndConfigurationService","SetTLSPSK",{PID:v,PPS:w},u)};s.AMT_SetupAndConfigurationService_GetProvisioningAuditRecord=function(u){s.Exec("AMT_SetupAndConfigurationService","GetProvisioningAuditRecord",{},u)};s.AMT_SetupAndConfigurationService_GetUuid=function(u){s.Exec("AMT_SetupAndConfigurationService","GetUuid",{},u)};s.AMT_SetupAndConfigurationService_GetUnprovisionBlockingComponents=function(u){s.Exec("AMT_SetupAndConfigurationService","GetUnprovisionBlockingComponents",{},u)};s.AMT_SetupAndConfigurationService_GetProvisioningAuditRecordV2=function(u){s.Exec("AMT_SetupAndConfigurationService","GetProvisioningAuditRecordV2",{},u)};s.AMT_SystemDefensePolicy_GetTimeout=function(u){s.Exec("AMT_SystemDefensePolicy","GetTimeout",{},u)};s.AMT_SystemDefensePolicy_SetTimeout=function(v,u){s.Exec("AMT_SystemDefensePolicy","SetTimeout",{Timeout:v},u)};s.AMT_SystemDefensePolicy_UpdateStatistics=function(v,x,u,z,w,y){s.Exec("AMT_SystemDefensePolicy","UpdateStatistics",{NetworkInterface:v,ResetOnRead:x},u,z,w,y)};s.AMT_SystemPowerScheme_SetPowerScheme=function(u,v,w){s.Exec("AMT_SystemPowerScheme","SetPowerScheme",{},u,w,0,{InstanceID:v})};s.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch=function(u,v){s.Exec("AMT_TimeSynchronizationService","GetLowAccuracyTimeSynch",{},u,v)};s.AMT_TimeSynchronizationService_SetHighAccuracyTimeSynch=function(v,x,y,u,w){s.Exec("AMT_TimeSynchronizationService","SetHighAccuracyTimeSynch",{Ta0:v,Tm1:x,Tm2:y},u,w)};s.AMT_UserInitiatedConnectionService_RequestStateChange=function(v,w,u){s.Exec("AMT_UserInitiatedConnectionService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AMT_WebUIService_RequestStateChange=function(v,w,u){s.Exec("AMT_WebUIService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AMT_WiFiPortConfigurationService_AddWiFiSettings=function(y,z,x,w,u,v){s.ExecWithXml("AMT_WiFiPortConfigurationService","AddWiFiSettings",{WiFiEndpoint:y,WiFiEndpointSettingsInput:z,IEEE8021xSettingsInput:x,ClientCredential:w,CACredential:u},v)};s.AMT_WiFiPortConfigurationService_UpdateWiFiSettings=function(y,z,x,w,u,v){s.ExecWithXml("AMT_WiFiPortConfigurationService","UpdateWiFiSettings",{WiFiEndpointSettings:y,WiFiEndpointSettingsInput:z,IEEE8021xSettingsInput:x,ClientCredential:w,CACredential:u},v)};s.AMT_WiFiPortConfigurationService_DeleteAllITProfiles=function(u,v){s.Exec("AMT_WiFiPortConfigurationService","DeleteAllITProfiles",{_method_dummy:u},v)};s.AMT_WiFiPortConfigurationService_DeleteAllUserProfiles=function(u,v){s.Exec("AMT_WiFiPortConfigurationService","DeleteAllUserProfiles",{_method_dummy:u},v)};s.CIM_Account_RequestStateChange=function(v,w,u){s.Exec("CIM_Account","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_AccountManagementService_CreateAccount=function(w,u,v){s.Exec("CIM_AccountManagementService","CreateAccount",{System:w,AccountTemplate:u},v)};s.CIM_BootConfigSetting_ChangeBootOrder=function(v,u){s.Exec("CIM_BootConfigSetting","ChangeBootOrder",{Source:v},u)};s.CIM_BootService_SetBootConfigRole=function(u,w,v){s.Exec("CIM_BootService","SetBootConfigRole",{BootConfigSetting:u,Role:w},v,0,1)};s.CIM_Card_ConnectorPower=function(v,w,u){s.Exec("CIM_Card","ConnectorPower",{Connector:v,PoweredOn:w},u)};s.CIM_Card_IsCompatible=function(v,u){s.Exec("CIM_Card","IsCompatible",{ElementToCheck:v},u)};s.CIM_Chassis_IsCompatible=function(v,u){s.Exec("CIM_Chassis","IsCompatible",{ElementToCheck:v},u)};s.CIM_Fan_SetSpeed=function(v,u){s.Exec("CIM_Fan","SetSpeed",{DesiredSpeed:v},u)};s.CIM_KVMRedirectionSAP_RequestStateChange=function(v,w,u){s.Exec("CIM_KVMRedirectionSAP","RequestStateChange",{RequestedState:v},u)};s.CIM_MediaAccessDevice_LockMedia=function(v,u){s.Exec("CIM_MediaAccessDevice","LockMedia",{Lock:v},u)};s.CIM_MediaAccessDevice_SetPowerState=function(v,w,u){s.Exec("CIM_MediaAccessDevice","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_MediaAccessDevice_Reset=function(u){s.Exec("CIM_MediaAccessDevice","Reset",{},u)};s.CIM_MediaAccessDevice_EnableDevice=function(v,u){s.Exec("CIM_MediaAccessDevice","EnableDevice",{Enabled:v},u)};s.CIM_MediaAccessDevice_OnlineDevice=function(v,u){s.Exec("CIM_MediaAccessDevice","OnlineDevice",{Online:v},u)};s.CIM_MediaAccessDevice_QuiesceDevice=function(v,u){s.Exec("CIM_MediaAccessDevice","QuiesceDevice",{Quiesce:v},u)};s.CIM_MediaAccessDevice_SaveProperties=function(u){s.Exec("CIM_MediaAccessDevice","SaveProperties",{},u)};s.CIM_MediaAccessDevice_RestoreProperties=function(u){s.Exec("CIM_MediaAccessDevice","RestoreProperties",{},u)};s.CIM_MediaAccessDevice_RequestStateChange=function(v,w,u){s.Exec("CIM_MediaAccessDevice","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_PhysicalFrame_IsCompatible=function(v,u){s.Exec("CIM_PhysicalFrame","IsCompatible",{ElementToCheck:v},u)};s.CIM_PhysicalPackage_IsCompatible=function(v,u){s.Exec("CIM_PhysicalPackage","IsCompatible",{ElementToCheck:v},u)};s.CIM_PowerManagementService_RequestPowerStateChange=function(w,v,x,y,u){s.Exec("CIM_PowerManagementService","RequestPowerStateChange",{PowerState:w,ManagedElement:v,Time:x,TimeoutPeriod:y},u,0,1)};s.CIM_PowerSupply_SetPowerState=function(v,w,u){s.Exec("CIM_PowerSupply","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_PowerSupply_Reset=function(u){s.Exec("CIM_PowerSupply","Reset",{},u)};s.CIM_PowerSupply_EnableDevice=function(v,u){s.Exec("CIM_PowerSupply","EnableDevice",{Enabled:v},u)};s.CIM_PowerSupply_OnlineDevice=function(v,u){s.Exec("CIM_PowerSupply","OnlineDevice",{Online:v},u)};s.CIM_PowerSupply_QuiesceDevice=function(v,u){s.Exec("CIM_PowerSupply","QuiesceDevice",{Quiesce:v},u)};s.CIM_PowerSupply_SaveProperties=function(u){s.Exec("CIM_PowerSupply","SaveProperties",{},u)};s.CIM_PowerSupply_RestoreProperties=function(u){s.Exec("CIM_PowerSupply","RestoreProperties",{},u)};s.CIM_PowerSupply_RequestStateChange=function(v,w,u){s.Exec("CIM_PowerSupply","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_Processor_SetPowerState=function(v,w,u){s.Exec("CIM_Processor","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_Processor_Reset=function(u){s.Exec("CIM_Processor","Reset",{},u)};s.CIM_Processor_EnableDevice=function(v,u){s.Exec("CIM_Processor","EnableDevice",{Enabled:v},u)};s.CIM_Processor_OnlineDevice=function(v,u){s.Exec("CIM_Processor","OnlineDevice",{Online:v},u)};s.CIM_Processor_QuiesceDevice=function(v,u){s.Exec("CIM_Processor","QuiesceDevice",{Quiesce:v},u)};s.CIM_Processor_SaveProperties=function(u){s.Exec("CIM_Processor","SaveProperties",{},u)};s.CIM_Processor_RestoreProperties=function(u){s.Exec("CIM_Processor","RestoreProperties",{},u)};s.CIM_Processor_RequestStateChange=function(v,w,u){s.Exec("CIM_Processor","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_RecordLog_ClearLog=function(u){s.Exec("CIM_RecordLog","ClearLog",{},u)};s.CIM_RecordLog_RequestStateChange=function(v,w,u){s.Exec("CIM_RecordLog","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_RedirectionService_RequestStateChange=function(v,w,u){s.Exec("CIM_RedirectionService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_Sensor_SetPowerState=function(v,w,u){s.Exec("CIM_Sensor","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_Sensor_Reset=function(u){s.Exec("CIM_Sensor","Reset",{},u)};s.CIM_Sensor_EnableDevice=function(v,u){s.Exec("CIM_Sensor","EnableDevice",{Enabled:v},u)};s.CIM_Sensor_OnlineDevice=function(v,u){s.Exec("CIM_Sensor","OnlineDevice",{Online:v},u)};s.CIM_Sensor_QuiesceDevice=function(v,u){s.Exec("CIM_Sensor","QuiesceDevice",{Quiesce:v},u)};s.CIM_Sensor_SaveProperties=function(u){s.Exec("CIM_Sensor","SaveProperties",{},u)};s.CIM_Sensor_RestoreProperties=function(u){s.Exec("CIM_Sensor","RestoreProperties",{},u)};s.CIM_Sensor_RequestStateChange=function(v,w,u){s.Exec("CIM_Sensor","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_StatisticalData_ResetSelectedStats=function(v,u){s.Exec("CIM_StatisticalData","ResetSelectedStats",{SelectedStatistics:v},u)};s.CIM_Watchdog_KeepAlive=function(u){s.Exec("CIM_Watchdog","KeepAlive",{},u)};s.CIM_Watchdog_SetPowerState=function(v,w,u){s.Exec("CIM_Watchdog","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_Watchdog_Reset=function(u){s.Exec("CIM_Watchdog","Reset",{},u)};s.CIM_Watchdog_EnableDevice=function(v,u){s.Exec("CIM_Watchdog","EnableDevice",{Enabled:v},u)};s.CIM_Watchdog_OnlineDevice=function(v,u){s.Exec("CIM_Watchdog","OnlineDevice",{Online:v},u)};s.CIM_Watchdog_QuiesceDevice=function(v,u){s.Exec("CIM_Watchdog","QuiesceDevice",{Quiesce:v},u)};s.CIM_Watchdog_SaveProperties=function(u){s.Exec("CIM_Watchdog","SaveProperties",{},u)};s.CIM_Watchdog_RestoreProperties=function(u){s.Exec("CIM_Watchdog","RestoreProperties",{},u)};s.CIM_Watchdog_RequestStateChange=function(v,w,u){s.Exec("CIM_Watchdog","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_WiFiPort_SetPowerState=function(v,w,u){s.Exec("CIM_WiFiPort","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_WiFiPort_Reset=function(u){s.Exec("CIM_WiFiPort","Reset",{},u)};s.CIM_WiFiPort_EnableDevice=function(v,u){s.Exec("CIM_WiFiPort","EnableDevice",{Enabled:v},u)};s.CIM_WiFiPort_OnlineDevice=function(v,u){s.Exec("CIM_WiFiPort","OnlineDevice",{Online:v},u)};s.CIM_WiFiPort_QuiesceDevice=function(v,u){s.Exec("CIM_WiFiPort","QuiesceDevice",{Quiesce:v},u)};s.CIM_WiFiPort_SaveProperties=function(u){s.Exec("CIM_WiFiPort","SaveProperties",{},u)};s.CIM_WiFiPort_RestoreProperties=function(u){s.Exec("CIM_WiFiPort","RestoreProperties",{},u)};s.CIM_WiFiPort_RequestStateChange=function(v,w,u){s.Exec("CIM_WiFiPort","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.IPS_HostBasedSetupService_Setup=function(y,z,x,v,A,w,u){s.Exec("IPS_HostBasedSetupService","Setup",{NetAdminPassEncryptionType:y,NetworkAdminPassword:z,McNonce:x,Certificate:v,SigningAlgorithm:A,DigitalSignature:w},u)};s.IPS_HostBasedSetupService_AddNextCertInChain=function(x,v,w,u){s.Exec("IPS_HostBasedSetupService","AddNextCertInChain",{NextCertificate:x,IsLeafCertificate:v,IsRootCertificate:w},u)};s.IPS_HostBasedSetupService_AdminSetup=function(x,y,w,z,v,u){s.Exec("IPS_HostBasedSetupService","AdminSetup",{NetAdminPassEncryptionType:x,NetworkAdminPassword:y,McNonce:w,SigningAlgorithm:z,DigitalSignature:v},u)};s.IPS_HostBasedSetupService_UpgradeClientToAdmin=function(w,x,v,u){s.Exec("IPS_HostBasedSetupService","UpgradeClientToAdmin",{McNonce:w,SigningAlgorithm:x,DigitalSignature:v},u)};s.IPS_HostBasedSetupService_DisableClientControlMode=function(u,v){s.Exec("IPS_HostBasedSetupService","DisableClientControlMode",{_method_dummy:u},v)};s.IPS_KVMRedirectionSettingData_TerminateSession=function(u){s.Exec("IPS_KVMRedirectionSettingData","TerminateSession",{},u)};s.IPS_OptInService_StartOptIn=function(u){s.Exec("IPS_OptInService","StartOptIn",{},u)};s.IPS_OptInService_CancelOptIn=function(u){s.Exec("IPS_OptInService","CancelOptIn",{},u)};s.IPS_OptInService_SendOptInCode=function(v,u){s.Exec("IPS_OptInService","SendOptInCode",{OptInCode:v},u)};s.IPS_OptInService_StartService=function(u){s.Exec("IPS_OptInService","StartService",{},u)};s.IPS_OptInService_StopService=function(u){s.Exec("IPS_OptInService","StopService",{},u)};s.IPS_OptInService_RequestStateChange=function(v,w,u){s.Exec("IPS_OptInService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.IPS_ProvisioningRecordLog_RequestStateChange=function(v,w,u){s.Exec("IPS_ProvisioningRecordLog","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.IPS_ProvisioningRecordLog_ClearLog=function(u,v){s.Exec("IPS_ProvisioningRecordLog","ClearLog",{_method_dummy:u},v)};s.IPS_SecIOService_RequestStateChange=function(v,w,u){s.Exec("IPS_SecIOService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AmtStatusToStr=function(u){if(s.AmtStatusCodes[u]){return s.AmtStatusCodes[u]}else{return"UNKNOWN_ERROR"}};s.AmtStatusCodes={0:"SUCCESS",1:"INTERNAL_ERROR",2:"NOT_READY",3:"INVALID_PT_MODE",4:"INVALID_MESSAGE_LENGTH",5:"TABLE_FINGERPRINT_NOT_AVAILABLE",6:"INTEGRITY_CHECK_FAILED",7:"UNSUPPORTED_ISVS_VERSION",8:"APPLICATION_NOT_REGISTERED",9:"INVALID_REGISTRATION_DATA",10:"APPLICATION_DOES_NOT_EXIST",11:"NOT_ENOUGH_STORAGE",12:"INVALID_NAME",13:"BLOCK_DOES_NOT_EXIST",14:"INVALID_BYTE_OFFSET",15:"INVALID_BYTE_COUNT",16:"NOT_PERMITTED",17:"NOT_OWNER",18:"BLOCK_LOCKED_BY_OTHER",19:"BLOCK_NOT_LOCKED",20:"INVALID_GROUP_PERMISSIONS",21:"GROUP_DOES_NOT_EXIST",22:"INVALID_MEMBER_COUNT",23:"MAX_LIMIT_REACHED",24:"INVALID_AUTH_TYPE",25:"AUTHENTICATION_FAILED",26:"INVALID_DHCP_MODE",27:"INVALID_IP_ADDRESS",28:"INVALID_DOMAIN_NAME",29:"UNSUPPORTED_VERSION",30:"REQUEST_UNEXPECTED",31:"INVALID_TABLE_TYPE",32:"INVALID_PROVISIONING_STATE",33:"UNSUPPORTED_OBJECT",34:"INVALID_TIME",35:"INVALID_INDEX",36:"INVALID_PARAMETER",37:"INVALID_NETMASK",38:"FLASH_WRITE_LIMIT_EXCEEDED",39:"INVALID_IMAGE_LENGTH",40:"INVALID_IMAGE_SIGNATURE",41:"PROPOSE_ANOTHER_VERSION",42:"INVALID_PID_FORMAT",43:"INVALID_PPS_FORMAT",44:"BIST_COMMAND_BLOCKED",45:"CONNECTION_FAILED",46:"CONNECTION_TOO_MANY",47:"RNG_GENERATION_IN_PROGRESS",48:"RNG_NOT_READY",49:"CERTIFICATE_NOT_READY",1024:"DISABLED_BY_POLICY",2048:"NETWORK_IF_ERROR_BASE",2049:"UNSUPPORTED_OEM_NUMBER",2050:"UNSUPPORTED_BOOT_OPTION",2051:"INVALID_COMMAND",2052:"INVALID_SPECIAL_COMMAND",2053:"INVALID_HANDLE",2054:"INVALID_PASSWORD",2055:"INVALID_REALM",2056:"STORAGE_ACL_ENTRY_IN_USE",2057:"DATA_MISSING",2058:"DUPLICATE",2059:"EVENTLOG_FROZEN",2060:"PKI_MISSING_KEYS",2061:"PKI_GENERATING_KEYS",2062:"INVALID_KEY",2063:"INVALID_CERT",2064:"CERT_KEY_NOT_MATCH",2065:"MAX_KERB_DOMAIN_REACHED",2066:"UNSUPPORTED",2067:"INVALID_PRIORITY",2068:"NOT_FOUND",2069:"INVALID_CREDENTIALS",2070:"INVALID_PASSPHRASE",2072:"NO_ASSOCIATION",2075:"AUDIT_FAIL",2076:"BLOCKING_COMPONENT",2081:"USER_CONSENT_REQUIRED",4096:"APP_INTERNAL_ERROR",4097:"NOT_INITIALIZED",4098:"LIB_VERSION_UNSUPPORTED",4099:"INVALID_PARAM",4100:"RESOURCES",4101:"HARDWARE_ACCESS_ERROR",4102:"REQUESTOR_NOT_REGISTERED",4103:"NETWORK_ERROR",4104:"PARAM_BUFFER_TOO_SHORT",4105:"COM_NOT_INITIALIZED_IN_THREAD",4106:"URL_REQUIRED"};s.GetMessageLog=function(u,v){s.AMT_MessageLog_PositionToFirstRecord(k,[u,v,[]])};function k(w,u,v,x,y){if(x!=200||v.Body.ReturnValue!="0"){y[0](s,null,y[2]);return}s.AMT_MessageLog_GetRecords(v.Body.IterationIdentifier,390,l,y)}function l(D,A,C,E,G){if(E!=200||C.Body.ReturnValue!="0"){G[0](s,null,G[2]);return}var y,z,I,v,u=G[2],F=new Date(),H,B=C.Body.RecordArray;if(typeof B==="string"){C.Body.RecordArray=[C.Body.RecordArray]}for(y in B){v=null;try{v=window.atob(B[y])}catch(w){}if(v!=null){H=ReadIntX(v,0);if((H>0)&&(H<4294967295)){I={DeviceAddress:v.charCodeAt(4),EventSensorType:v.charCodeAt(5),EventType:v.charCodeAt(6),EventOffset:v.charCodeAt(7),EventSourceType:v.charCodeAt(8),EventSeverity:v.charCodeAt(9),SensorNumber:v.charCodeAt(10),Entity:v.charCodeAt(11),EntityInstance:v.charCodeAt(12),EventData:[],Time:new Date((H+(F.getTimezoneOffset()*60))*1000)};for(z=13;z<21;z++){I.EventData.push(v.charCodeAt(z))}I.EntityStr=o[I.Entity];I.Desc=j(I.EventSensorType,I.EventOffset,I.EventData,I.Entity);if(!I.EntityStr){I.EntityStr="Unknown"}u.push(I)}}}if(C.Body.NoMoreRecords!=true){s.AMT_MessageLog_GetRecords(C.Body.IterationIdentifier,390,l,[G[0],u,G[2]])}else{G[0](s,u,G[2])}}var e="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 p="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 q="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 o="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("|");s.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("|");s.WatchdogCurrentStates={1:"Not Started",2:"Stopped",4:"Running",8:"Expired",16:"Suspended"};function j(x,w,v,u){if(x==15){if(v[0]==235){return"Invalid Data"}if(w==0){return p[v[1]]}return q[v[1]]}if(x==18&&v[0]==170){return"Agent watchdog "+char2hex(v[4])+char2hex(v[3])+char2hex(v[2])+char2hex(v[1])+"-"+char2hex(v[6])+char2hex(v[5])+"-... changed to "+s.WatchdogCurrentStates[v[7]]}if(x==6){return"Authentication failed "+(v[1]+(v[2]<<8))+" times. The system may be under attack."}if(x==30){return"No bootable media"}if(x==32){return"Operating system lockup or power interrupt"}if(x==35){return"System boot failure"}if(x==37){return"System firmware started (at least one CPU is properly executing)."}return"Unknown Sensor Type #"+x}return s}var md5_k=[];for(var i=0;i<64;){md5_k[i]=0|(Math.abs(Math.sin(++i))*4294967296)}function hex_md5(p){var g,k,l,o,r=[],q=unescape(encodeURI(p)),e=q.length,m=[g=1732584193,k=-271733879,~g,~k],n=0;for(;n<=e;){r[n>>2]|=(q.charCodeAt(n)||128)<<8*(n++%4)}r[p=(e+8>>6)*16+14]=e*8;n=0;for(;n<p;n+=16){e=m;o=0;for(;o<64;){e=[l=e[3],((g=e[1]|0)+((l=((e[0]+[g&(k=e[2])|~g&l,l&g|~l&k,g^k^l,k^(g|~l)][e=o>>4])+(md5_k[o]+(r[[o,5*o+1,3*o+5,7*o][e]%16+n]|0))))<<(e=[7,12,17,22,5,9,14,20,4,11,16,23,6,10,15,21][4*e+o++%4])|l>>>32-e)),g,k]}for(o=4;o;){m[--o]=m[o]+e[o]}}p="";for(;o<32;){p+=((m[o>>3]>>((1^o++&7)*4))&15).toString(16)}return p}function rstr_md5(a){return hex2rstr(hex_md5(a))}function execArgumentsToXml(c){if(c===undefined||c===null){return null}var d="";for(var b in c){var a=c[b];if(!a){continue}if(a.__parameterType==="reference"){d+=referenceToXml(b,a)}else{d+=instanceToXml(b,a)}}return d}function instanceToXml(d,c){if(c===undefined||c===null){return null}var b=!!c.__namespace;var j=b?"<q:":"<";var a=b?"</q:":"</";var e=b?(' xmlns:q="'+c.__namespace+'"'):"";var h="<r:"+d+e+">";for(var g in c){if(!c.hasOwnProperty(g)||g.indexOf("__")===0){continue}if(typeof c[g]==="function"||Array.isArray(c[g])){continue}if(typeof c[g]==="object"){console.error("only convert one level down...")}else{h+=j+g+">"+c[g].toString()+a+g+">"}}h+="</r:"+d+">";return h}function referenceToXml(b,a){if(a===undefined||a===null){return null}var c="<r:"+b+"><a:Address>/wsman</a:Address><a:ReferenceParameters><w:ResourceURI>"+a.__resourceUri+"</w:ResourceURI><w:SelectorSet>";for(var d in a){if(!a.hasOwnProperty(d)||d.indexOf("__")===0){continue}if(typeof a[d]==="function"||typeof a[d]==="object"||Array.isArray(a[d])){continue}c+='<w:Selector Name="'+d+'">'+a[d].toString()+"</w:Selector>"}c+="</w:SelectorSet></a:ReferenceParameters></r:"+b+">";return c}function GetSidString(c){var b="S-"+c.charCodeAt(0)+"-"+c.charCodeAt(7);for(var a=2;a<(c.length/4);a++){b+="-"+ReadIntX(c,a*4)}return b}function GetSidByteArray(d){if(!d||d==null){return null}var c=d.split("-");if(c.length<4||(c[0]!="s"&&c[0]!="S")){return null}for(var a=1;a<c.length;a++){var e=parseInt(c[a]);if(e!=c[a]){return null}c[a]=e}var b=String.fromCharCode(c[1])+String.fromCharCode(c.length-3)+ShortToStr(Math.floor(c[2]/Math.pow(2,32)))+IntToStr((c[2])&65535);for(var a=3;a<c.length;a++){b+=IntToStrX(c[a])}return b}var WsmanStackCreateService=function(h,l,n,k,m,g){var j={};j.NextMessageId=1;j.Address="/wsman";j.comm=CreateWsmanComm(h,l,n,k,m,g);j.PerformAjax=function(q,o,s,r,p){if(p==undefined){p=""}j.comm.PerformAjax('<?xml version="1.0" encoding="utf-8"?><Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns="http://www.w3.org/2003/05/soap-envelope" '+p+"><Header><a:Action>"+q,function(t,u,v){if(u!=200){o(j,null,{Header:{HttpError:u}},u,v);return}var w=j.ParseWsman(t);if(!w||w==null){o(j,null,{Header:{HttpError:u}},601,v)}else{o(j,w.Header.ResourceURI,w,200,v)}},s,r)};j.CancelAllQueries=function(o){j.comm.CancelAllQueries(o)};j.GetNameFromUrl=function(o){var p=o.lastIndexOf("/");return(p==-1)?o:o.substring(p+1)};j.ExecSubscribe=function(w,q,z,o,y,v,x,t,A,u){var r="",s="";if(A!=undefined&&u!=undefined){r="<t:IssuedTokens><t:RequestSecurityTokenResponse><t:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</t:TokenType><t:RequestedSecurityToken><se:UsernameToken><se:Username>"+A+'</se:Username><se:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText">'+u+"</se:Password></se:UsernameToken></t:RequestedSecurityToken></t:RequestSecurityTokenResponse></t:IssuedTokens>";s='<Auth Profile="http://schemas.xmlsoap.org/ws/2004/08/eventing/DeliveryModes/secprofile/http/digest"/>'}if(t!=undefined&&t!=null){t="<a:ReferenceParameters>"+t+"</a:ReferenceParameters>"}else{t=""}var p="http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+w+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>"+d(x)+r+'</Header><Body><e:Subscribe><e:Delivery Mode="http://schemas.dmtf.org/wbem/wsman/1/wsman/'+q+'"><e:NotifyTo><a:Address>'+z+"</a:Address></e:NotifyTo>"+s+"</e:Delivery><e:Expires>PT0.000000S</e:Expires></e:Subscribe>";j.PerformAjax(p+"</Body></Envelope>",o,y,v,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:se="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:m="http://x.com"')};j.ExecUnSubscribe=function(r,o,t,q,s){var p="http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+r+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>"+d(s)+"</Header><Body><e:Unsubscribe/>";j.PerformAjax(p+"</Body></Envelope>",o,t,q,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"')};j.ExecPut=function(s,r,o,u,q,t){var p="http://schemas.xmlsoap.org/ws/2004/09/transfer/Put</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+s+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout>"+d(t)+"</Header><Body>"+c(s,r);j.PerformAjax(p+"</Body></Envelope>",o,u,q)};j.ExecCreate=function(u,t,o,w,s,v){var r=j.GetNameFromUrl(u);var p="http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+u+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+d(v)+"</Header><Body><g:"+r+' xmlns:g="'+u+'">';for(var q in t){p+="<g:"+q+">"+t[q]+"</g:"+q+">"}j.PerformAjax(p+"</g:"+r+"></Body></Envelope>",o,w,s)};j.ExecCreateXml=function(s,o,p,u,r){var q=j.GetNameFromUrl(s),t="";j.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+s+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout></Header><Body><r:"+q+' xmlns:r="'+s+'">'+o+"</r:"+q+"></Body></Envelope>",p,u,r)};j.ExecDelete=function(s,r,o,t,q){var p="http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+s+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+d(r)+"</Header><Body /></Envelope>";j.PerformAjax(p,o,t,q)};j.ExecGet=function(q,o,r,p){j.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+q+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body /></Envelope>",o,r,p)};j.ExecMethod=function(u,s,o,q,w,t,v){var p="";for(var r in o){if(o[r]!=null){if(Array.isArray(o[r])){for(var y in o[r]){p+="<r:"+r+">"+o[r][y]+"</r:"+r+">"}}else{p+="<r:"+r+">"+o[r]+"</r:"+r+">"}}}j.ExecMethodXml(u,s,p,q,w,t,v)};j.ExecMethodXml=function(s,q,o,p,u,r,t){j.PerformAjax(s+"/"+q+"</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+s+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+d(t)+"</Header><Body><r:"+q+'_INPUT xmlns:r="'+s+'">'+o+"</r:"+q+"_INPUT></Body></Envelope>",p,u,r)};j.ExecEnum=function(q,o,r,p){j.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+q+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+'</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Enumerate xmlns="http://schemas.xmlsoap.org/ws/2004/09/enumeration" /></Body></Envelope>',o,r,p)};j.ExecPull=function(r,p,o,s,q){j.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+r+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+'</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns="http://schemas.xmlsoap.org/ws/2004/09/enumeration"><EnumerationContext>'+p+"</EnumerationContext><MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters></Pull></Body></Envelope>",o,s,q)};j.ParseWsman=function(x){try{if(!x.childNodes){x=e(x)}var v={Header:{}},s=x.getElementsByTagName("Header")[0],w;if(!s){s=x.getElementsByTagName("a:Header")[0]}if(!s){return null}for(var u=0;u<s.childNodes.length;u++){var p=s.childNodes[u];v.Header[p.localName]=p.textContent}var o=x.getElementsByTagName("Body")[0];if(!o){o=x.getElementsByTagName("a:Body")[0]}if(!o){return null}if(o.childNodes.length>0){w=o.childNodes[0].localName;if(w.indexOf("_OUTPUT")==w.length-7){w=w.substring(0,w.length-7)}v.Header.Method=w;v.Body=b(o.childNodes[0])}return v}catch(q){console.log("Unable to parse XML: "+x);return null}};function b(u){var q,v={};for(var s=0;s<u.childNodes.length;s++){var o=u.childNodes[s];if(o.childElementCount==0){q=o.textContent}else{q=b(o)}if(q=="true"){q=true}if(q=="false"){q=false}var p=q;if(o.attributes.length>0){p={Value:q};for(var t=0;t<o.attributes.length;t++){p["@"+o.attributes[t].name]=o.attributes[t].value}}if(v[o.localName] instanceof Array){v[o.localName].push(p)}else{if(v[o.localName]==undefined){v[o.localName]=p}else{v[o.localName]=[v[o.localName],p]}}}return v}function c(t,r){if(!t||r===undefined||r===null){return""}var p=j.GetNameFromUrl(t);var s="<r:"+p+' xmlns:r="'+t+'">';for(var q in r){if(!r.hasOwnProperty(q)||q.indexOf("__")===0||q.indexOf("@")===0){continue}if(r[q]===undefined||r[q]===null||typeof r[q]==="function"){continue}if(typeof r[q]==="object"&&r[q]["ReferenceParameters"]){s+="<r:"+q+"><a:Address>"+r[q].Address+"</a:Address><a:ReferenceParameters><w:ResourceURI>"+r[q]["ReferenceParameters"]["ResourceURI"]+"</w:ResourceURI><w:SelectorSet>";var u=r[q]["ReferenceParameters"]["SelectorSet"]["Selector"];if(Array.isArray(u)){for(var o=0;o<u.length;o++){s+="<w:Selector"+a(u[o])+">"+u[o]["Value"]+"</w:Selector>"}}else{s+="<w:Selector"+a(u)+">"+u.Value+"</w:Selector>"}s+="</w:SelectorSet></a:ReferenceParameters></r:"+q+">"}else{if(Array.isArray(r[q])){for(var o=0;o<r[q].length;o++){s+="<r:"+q+">"+r[q][o].toString()+"</r:"+q+">"}}else{s+="<r:"+q+">"+r[q].toString()+"</r:"+q+">"}}}s+="</r:"+p+">";return s}function a(o){if(!o){return""}var q=" ";for(var p in o){if(!o.hasOwnProperty(p)||p.indexOf("@")!==0){continue}q+=p.substring(1)+'="'+o[p]+'" '}return q}function d(s){if(!s){return""}if(typeof s=="string"){return s}if(s.InstanceID){return'<w:SelectorSet><w:Selector Name="InstanceID">'+s.InstanceID+"</w:Selector></w:SelectorSet>"}var q="<w:SelectorSet>";for(var p in s){if(!s.hasOwnProperty(p)){continue}q+='<w:Selector Name="'+p+'">';if(s[p]["ReferenceParameters"]){q+="<a:EndpointReference>";q+="<a:Address>"+s[p]["Address"]+"</a:Address><a:ReferenceParameters><w:ResourceURI>"+s[p]["ReferenceParameters"]["ResourceURI"]+"</w:ResourceURI><w:SelectorSet>";var r=s[p]["ReferenceParameters"]["SelectorSet"]["Selector"];if(Array.isArray(r)){for(var o=0;o<r.length;o++){q+="<w:Selector"+a(r[o])+">"+r[o]["Value"]+"</w:Selector>"}}else{q+="<w:Selector"+a(r)+">"+r.Value+"</w:Selector>"}q+="</w:SelectorSet></a:ReferenceParameters></a:EndpointReference>"}else{q+=s[p]}q+="</w:Selector>"}q+="</w:SelectorSet>";return q}function e(o){if(window.DOMParser){return new DOMParser().parseFromString(o,"text/xml")}else{var p=new ActiveXObject("Microsoft.XMLDOM");p.async=false;p.loadXML(o);return p}}return j};var CreateAmtRemoteDesktop=function(m,p){var o={};o.canvasid=m;o.CanvasId=Q(m);o.scrolldiv=p;o.canvas=Q(m).getContext("2d");o.protocol=2;o.state=0;o.acc="";o.ScreenWidth=960;o.ScreenHeight=700;o.width=0;o.height=0;o.rwidth=0;o.rheight=0;o.bpp=2;o.useZRLE=true;o.showmouse=true;o.buttonmask=0;o.localKeyMap=true;o.spare=null;o.sparew=0;o.spareh=0;o.sparew2=0;o.spareh2=0;o.sparecache={};o.ZRLEfirst=1;o.onScreenSizeChange=null;o.frameRateDelay=0;o.kvmDataSupported=false;o.onKvmData=null;o.onKvmDataPending=[];o.onKvmDataAck=-1;o.holding=false;o.lastKeepAlive=Date.now();o.Debug=function(q){console.log(q)};o.xxStateChange=function(q){if(q==0){o.canvas.fillStyle="#000000";o.canvas.fillRect(0,0,o.width,o.height);o.canvas.canvas.width=o.rwidth=o.width=640;o.canvas.canvas.height=o.rheight=o.height=400;QS(o.canvasid).cursor="default"}else{QS(o.canvasid).cursor=o.showmouse?"default":"none"}};o.ProcessData=function(t){if(!t){return}o.acc+=t;while(o.acc.length>0){var q=0;if(o.state==0&&o.acc.length>=12){q=12;o.state=1;o.send("RFB 003.008\n")}else{if(o.state==1&&o.acc.length>=1){q=o.acc.charCodeAt(0)+1;o.send(String.fromCharCode(1));o.state=2}else{if(o.state==2&&o.acc.length>=4){q=4;if(ReadInt(o.acc,0)!=0){return o.Stop()}o.send(String.fromCharCode(1));o.state=3}else{if(o.state==3&&o.acc.length>=24){var D=ReadInt(o.acc,20);if(o.acc.length<24+D){return}q=24+D;o.canvas.canvas.width=o.rwidth=o.width=o.ScreenWidth=ReadShort(o.acc,0);o.canvas.canvas.height=o.rheight=o.height=o.ScreenHeight=ReadShort(o.acc,2);var G="";if(o.useZRLE){G+=IntToStr(16)}G+=IntToStr(0);G+=IntToStr(1092);o.send(String.fromCharCode(2,0)+ShortToStr((G.length/4)+1)+G+IntToStr(-223));if(o.bpp==1){o.send(String.fromCharCode(0,0,0,0,8,8,0,1)+ShortToStr(7)+ShortToStr(7)+ShortToStr(3)+String.fromCharCode(5,2,0,0,0,0))}o.state=4;o.parent.xxStateChange(3);h();if(o.onScreenSizeChange!=null){o.onScreenSizeChange(o,o.ScreenWidth,o.ScreenHeight)}}else{if(o.state==4){switch(o.acc.charCodeAt(0)){case 0:if(o.acc.length<4){return}o.state=100+ReadShort(o.acc,2);q=4;break;case 2:q=1;break;case 3:if(o.acc.length<8){return}var C=ReadInt(o.acc,4)+8;if(o.acc.length<C){return}q=n(o.acc);break}}else{if(o.state>100&&o.acc.length>=12){var I=ReadShort(o.acc,0),K=ReadShort(o.acc,2),H=ReadShort(o.acc,4),A=ReadShort(o.acc,6),F=H*A,z=ReadInt(o.acc,8);if(z<17){if(H<1||H>64||A<1||A>64){console.log("Invalid tile size ("+H+","+A+"), disconnecting.");return o.Stop()}if(o.sparew!=H||o.spareh!=A){o.sparew=o.sparew2=H;o.spareh=o.spareh2=A;var J=o.sparew2+"x"+o.spareh2;o.spare=o.sparecache[J];if(!o.spare){o.sparecache[J]=o.spare=o.canvas.createImageData(o.sparew2,o.spareh2)}}}if(z==4294967073){o.canvas.canvas.width=o.rwidth=o.width=H;o.canvas.canvas.height=o.rheight=o.height=A;o.send(String.fromCharCode(3,0,0,0,0,0)+ShortToStr(o.width)+ShortToStr(o.height));q=12;if(o.onScreenSizeChange!=null){o.onScreenSizeChange(o,o.ScreenWidth,o.ScreenHeight)}}else{if(z==0){var E=12,r=12+(F*o.bpp);if(o.acc.length<r){return}q=r;for(var B=0;B<F;B++){j(o.acc.charCodeAt(E++)+((o.bpp==2)?(o.acc.charCodeAt(E++)<<8):0),B)}g(o.spare,I,K)}else{if(z==16){if(o.acc.length<16){return}var u=ReadInt(o.acc,12);if(o.acc.length<(16+u)){return}var E=16,v=5,w=0;if(u>5&&o.acc.charCodeAt(E)==0&&ReadShortX(o.acc,E+1)==(u-v)){a(o.acc,E+5,I,K,H,A,F,u)}q=16+u}else{o.Debug("Unknown Encoding: "+z);return o.Stop()}}}if(--o.state==100){o.state=4;if(o.frameRateDelay==0){h()}else{setTimeout(h,o.frameRateDelay)}}}}}}}}if(q==0){return}o.acc=o.acc.substring(q)}};function a(t,C,K,L,J,w,G,u){var H=t.charCodeAt(C++),A,I,F,B={},D=0,E=0,z;if(H==0){for(z=0;z<G;z++){j(t.charCodeAt(C++)+((o.bpp==2)?(t.charCodeAt(C++)<<8):0),z)}g(o.spare,K,L)}else{if(H==1){I=t.charCodeAt(C++)+((o.bpp==2)?(t.charCodeAt(C++)<<8):0);o.canvas.fillStyle="rgb("+((o.bpp==1)?((I&224)+","+((I&28)<<3)+","+b((I&3)<<6)):(((I>>8)&248)+","+((I>>3)&252)+","+((I&31)<<3)))+")";o.canvas.fillRect(K,L,J,w)}else{if(H>1&&H<17){var r=4,q=15;for(z=0;z<H;z++){B[z]=t.charCodeAt(C++)+((o.bpp==2)?(t.charCodeAt(C++)<<8):0)}if(H==2){r=1;q=1}else{if(H<=4){r=2;q=3}}while(D<G&&C<t.length){I=t.charCodeAt(C++);for(z=(8-r);z>=0;z-=r){j(B[(I>>z)&q],D++)}}g(o.spare,K,L)}else{if(H==128){while(D<G&&C<t.length){I=t.charCodeAt(C++)+((o.bpp==2)?(t.charCodeAt(C++)<<8):0);E=1;do{E+=(F=t.charCodeAt(C++))}while(F==255);while(--E>=0){j(I,D++)}}g(o.spare,K,L)}else{if(H>129){for(z=0;z<(H-128);z++){B[z]=t.charCodeAt(C++)+((o.bpp==2)?(t.charCodeAt(C++)<<8):0)}while(D<G&&C<t.length){E=1;A=t.charCodeAt(C++);I=B[A%128];if(A>127){do{E+=(F=t.charCodeAt(C++))}while(F==255)}while(--E>=0){j(I,D++)}}g(o.spare,K,L)}}}}}}o.hold=function(q){if(o.holding==q){return}o.holding=q;o.canvas.fillStyle="#000000";o.canvas.fillRect(0,0,o.width,o.height);if(o.holding==false){if((o.canvas.canvas.width!=o.width)||(o.canvas.canvas.height!=o.height)){o.canvas.canvas.width=o.width;o.canvas.canvas.height=o.height;if(o.onScreenSizeChange!=null){o.onScreenSizeChange(o,o.ScreenWidth,o.ScreenHeight)}}o.Send(String.fromCharCode(3,0,0,0,0,0)+ShortToStr(o.width)+ShortToStr(o.height))}else{o.UnGrabMouseInput();o.UnGrabKeyInput()}};function g(q,r,s){if(o.holding==true){return}o.canvas.putImageData(q,r,s)}function j(s,q){var r=q*4;if(o.bpp==1){o.spare.data[r++]=s&224;o.spare.data[r++]=(s&28)<<3;o.spare.data[r++]=b((s&3)<<6)}else{o.spare.data[r++]=(s>>8)&248;o.spare.data[r++]=(s>>3)&252;o.spare.data[r++]=(s&31)<<3}o.spare.data[r]=255}function b(q){return(q>127)?(q+32):q}function h(){if(o.holding==true){return}o.send(String.fromCharCode(3,1,0,0,0,0)+ShortToStr(o.rwidth)+ShortToStr(o.rheight))}o.Start=function(){o.state=0;o.acc="";o.ZRLEfirst=1;o.onKvmDataPending=[];o.onKvmDataAck=-1;o.kvmDataSupported=false;for(var q in o.sparecache){delete o.sparecache[q]}};o.Stop=function(){o.UnGrabMouseInput();o.UnGrabKeyInput();o.parent.Stop()};o.send=function(q){o.parent.send(q)};var l={Pause:19,CapsLock:20,Space:32,Quote:39,Minus:45,NumpadMultiply:42,NumpadAdd:43,PrintScreen:44,Comma:44,NumpadSubtract:45,NumpadDecimal:46,Period:46,Slash:47,NumpadDivide:47,Semicolon:59,Equal:61,OSLeft:91,BracketLeft:91,OSRight:91,Backslash:92,BracketRight:93,ContextMenu:93,Backquote:96,NumLock:144,ScrollLock:145,Backspace:65288,Tab:65289,Enter:65293,NumpadEnter:65293,Escape:65307,Delete:65535,Home:65360,PageUp:65365,PageDown:65366,ArrowLeft:65361,ArrowUp:65362,ArrowRight:65363,ArrowDown:65364,End:65367,Insert:65379,F1:65470,F2:65471,F3:65472,F4:65473,F5:65474,F6:65475,F7:65476,F8:65477,F9:65478,F10:65479,F11:65480,F12:65481,ShiftLeft:65505,ShiftRight:65506,ControlLeft:65507,ControlRight:65508,AltLeft:65513,AltRight:65514,MetaLeft:65511,MetaRight:65512};function k(q){if(q.code.startsWith("Key")&&q.code.length==4){return q.code.charCodeAt(3)+((q.shiftKey==false)?32:0)}if(q.code.startsWith("Digit")&&q.code.length==6){return q.code.charCodeAt(5)}if(q.code.startsWith("Numpad")&&q.code.length==7){return q.code.charCodeAt(6)}return l[q.code]}function c(q,r){if(!r){r=window.event}if(r.code&&(o.localKeyMap==false)){var s=k(r);if(s!=null){o.sendkey(s,q)}}else{var s=r.keyCode,t=s;if(r.shiftKey==false&&s>=65&&s<=90){t=s+32}if(s>=112&&s<=124){t=s+65358}if(s==8){t=65288}if(s==9){t=65289}if(s==13){t=65293}if(s==16){t=65505}if(s==17){t=65507}if(s==18){t=65513}if(s==27){t=65307}if(s==33){t=65365}if(s==34){t=65366}if(s==35){t=65367}if(s==36){t=65360}if(s==37){t=65361}if(s==38){t=65362}if(s==39){t=65363}if(s==40){t=65364}if(s==45){t=65379}if(s==46){t=65535}if(s>=96&&s<=105){t=s-48}if(s==106){t=42}if(s==107){t=43}if(s==109){t=45}if(s==110){t=46}if(s==111){t=47}if(s==186){t=59}if(s==187){t=61}if(s==188){t=44}if(s==189){t=45}if(s==190){t=46}if(s==191){t=47}if(s==192){t=96}if(s==219){t=91}if(s==220){t=92}if(s==221){t=93}if(s==222){t=39}o.sendkey(t,q)}return o.haltEvent(r)}o.sendkey=function(s,q){if(typeof s=="object"){for(var r in s){o.sendkey(s[r][0],s[r][1])}}else{o.send(String.fromCharCode(4,q,0,0)+IntToStr(s))}};function n(q){if(q.length<8){return 0}var s=ReadInt(o.acc,4)+8;if(q.length<s){return 0}if(o.onKvmData!=null){var r=q.substring(8,s);if((r.length>=16)&&(r.substring(0,15)=="\0KvmDataChannel")){if(o.kvmDataSupported==false){o.kvmDataSupported=true;console.log("KVM Data Channel Supported.")}if(((o.onKvmDataAck==-1)&&(r.length==16))||(r.charCodeAt(15)!=0)){o.onKvmDataAck=true}if(r.length>=16){o.onKvmData(r.substring(16))}if((o.onKvmDataAck==true)&&(o.onKvmDataPending.length>0)){o.sendKvmData(o.onKvmDataPending.shift())}}}return s}o.sendKvmData=function(q){if(o.onKvmDataAck!==true){o.onKvmDataPending.push(q)}else{q="\0KvmDataChannel\0"+q;o.send(String.fromCharCode(6,0,0,0)+IntToStr(q.length)+q);o.onKvmDataAck=false}};o.sendKeepAlive=function(){if(o.lastKeepAlive<Date.now()-5000){o.lastKeepAlive=Date.now();o.send(String.fromCharCode(6,0,0,0)+IntToStr(16)+"\0KvmDataChannel\0")}};o.SendCtrlAltDelMsg=function(){o.sendcad()};o.sendcad=function(){o.sendkey([[65507,1],[65513,1],[65535,1],[65535,0],[65513,0],[65507,0]])};var e=false;var d=false;o.GrabMouseInput=function(){if(e==true){return}var q=o.canvas.canvas;q.onmouseup=o.mouseup;q.onmousedown=o.mousedown;q.onmousemove=o.mousemove;e=true};o.UnGrabMouseInput=function(){if(e==false){return}var q=o.canvas.canvas;q.onmousemove=null;q.onmouseup=null;q.onmousedown=null;e=false};o.GrabKeyInput=function(){if(d==true){return}document.onkeyup=o.handleKeyUp;document.onkeydown=o.handleKeyDown;document.onkeypress=o.handleKeys;d=true};o.UnGrabKeyInput=function(){if(d==false){return}document.onkeyup=null;document.onkeydown=null;document.onkeypress=null;d=false};o.handleKeys=function(q){return o.haltEvent(q)};o.handleKeyUp=function(q){return c(0,q)};o.handleKeyDown=function(q){return c(1,q)};o.haltEvent=function(q){if(q.preventDefault){q.preventDefault()}if(q.stopPropagation){q.stopPropagation()}return false};o.mousedblclick=function(q){};o.mousedown=function(q){o.buttonmask|=(1<<q.button);return o.mousemove(q)};o.mouseup=function(q){o.buttonmask&=(65535-(1<<q.button));return o.mousemove(q)};o.mousemove=function(q){if(o.state!=4){return true}var r=o.getPositionOfControl(Q(o.canvasid));o.mx=(q.pageX-r[0])*(o.canvas.canvas.height/Q(o.canvasid).offsetHeight);o.my=((q.pageY-r[1]+(p?p.scrollTop:0))*(o.canvas.canvas.width/Q(o.canvasid).offsetWidth));o.send(String.fromCharCode(5,o.buttonmask)+ShortToStr(o.mx)+ShortToStr(o.my));return o.haltEvent(q)};o.getPositionOfControl=function(q){var r=Array(2);r[0]=r[1]=0;while(q){r[0]+=q.offsetLeft;r[1]+=q.offsetTop;q=q.offsetParent}return r};return o};var CreateAmtRemoteTerminal=function(B){var C={};C.DivId=B;C.DivElement=document.getElementById(B);C.protocol=1;C.fxEmulation=0;C.lineFeed="\r\n";C.debugmode=0;C.width=80;C.height=25;var r=21;var s=13;var m=["000000","BB0000","00BB00","BBBB00","0000BB","BB00BB","00BBBB","BBBBBB","555555","FF5555","55FF55","FFFF55","5555FF","FF55FF","55FFFF","FFFFFF"];var p=0;var o=7;var n=0;var t=true;var w=0;var x=0;var v=0;var d=[];var e=0;var l=[];var y=[];var A=1;var z=2;C.Start=function(){};C.Init=function(E,D){C.width=E?E:80;C.height=D?D:25;for(var G=0;G<C.height;G++){y[G]=[];l[G]=[];for(var F=0;F<C.width;F++){y[G][F]=" ";l[G][F]=(7<<6)}}C.TermInit();C.TermDraw()};C.xxStateChange=function(D){};C.ProcessData=function(D){if(C.debugmode==2){console.log("TRecv("+D.length+"): "+rstr2hex(D))}if(C.capture!=null){C.capture+=D}k(D);C.TermDraw()};function k(E){for(var D=0;D<E.length;D++){j(String.fromCharCode(E.charCodeAt(D)),E.charCodeAt(D))}}function j(D,E){switch(v){case 0:switch(E){case 27:v=1;break;default:h(D);break}break;case 1:switch(D){case"[":e=0;d=[];v=2;break;case"(":v=4;break;case")":v=5;break;default:v=0;break}break;case 2:if(D>="0"&&D<="9"){if(!d[e]){d[e]=(D-"0")}else{d[e]=((d[e]*10)+(D-"0"))}break}else{if(D==";"){e++;break}else{if(!d[0]){d[0]=0}g(D,d,e+1);v=0}}break;case 4:v=0;break;case 5:v=0;break}}function g(G,D,E){var H;switch(G){case"c":C.TermResetScreen();break;case"A":if(E==1){x-=D[0];if(x<0){x=0}}break;case"B":if(E==1){x+=D[0];if(x>C.height){x=C.height}}break;case"C":if(E==1){w+=D[0];if(w>C.width){w=C.width}}break;case"D":if(E==1){w-=D[0];if(w<0){w=0}}break;case"d":if(E==1){x=D[0]-1;if(x>C.height){x=C.height}if(x<0){x=0}}break;case"G":if(E==1){w=D[0]-1;if(w<0){w=0}if(w>79){w=79}}break;case"J":if(E==1&&D[0]==2){C.TermClear((n<<12)+(o<<6));w=0;x=0}else{if(E==0||E==1&&D[0]==0){b();for(H=x+1;H<C.height;H++){c(H)}}else{if(E==1&&D[0]==1){b();for(H=0;H<x-1;H++){c(H)}}}}break;case"H":if(E==2){if(D[0]<1){D[0]=1}if(D[1]<1){D[1]=1}if(D[0]>C.height){D[0]=C.height}if(D[1]>C.width){D[1]=C.width}x=D[0]-1;w=D[1]-1}else{x=0;w=0}break;case"m":for(H=0;H<E;H++){if(!D[H]||D[H]==0){n=0;o=7;p=0}else{if(D[H]==1){if(o<8){o+=8}}else{if(D[H]==2||D[H]==22){if(o>=8){o-=8}}else{if(D[H]==7){p=2}else{if(D[H]==27){p=0}else{if(D[H]>=30&&D[H]<=37){var F=(o>=8);o=(D[H]-30);if(F&&o<=8){o+=8}}else{if(D[H]>=40&&D[H]<=47){n=(D[H]-40)}else{if(D[H]>=90&&D[H]<=99){o=(D[H]-82)}else{if(D[H]>=100&&D[H]<=109){n=(D[H]-92)}}}}}}}}}}break;case"K":if(E==0||(E==1&&(!D[0]||D[0]==0))){b()}else{if(E==1){if(D[0]==1){a()}else{if(D[0]==2){c(x)}}}}break;case"h":t=true;break;case"l":t=false;break;default:break}}C.ProcessVt100String=function(E){for(var D=0;D<E.length;D++){h(String.fromCharCode(E.charCodeAt(D)))}};function h(D){if(D=="\0"||D.charCodeAt()==7){return}var E=D.charCodeAt();switch(E){case 16:D=" ";break;case 24:D="?";break;case 25:D="?";break}if(w>C.width){w=C.width}if(x>(C.height-1)){x=(C.height-1)}switch(D){case"\b":if(w>0){w=w-1;q(" ")}break;case"\t":var F=8-(w%8);for(var G=0;G<F;G++){h(" ")}break;case"\n":x++;if(x>(C.height-1)){u(1);x=(C.height-1)}if(C.lineFeed="\n"){w=0}break;case"\r":w=0;break;default:if(w>=C.width){w=0;if(t){x++}if(x>=(C.height-1)){u(1);x=(C.height-1)}}q(D);w++;break}}function q(D){y[x][w]=D;l[x][w]=(o<<6)+(n<<12)+p}C.TermClear=function(D){for(var F=0;F<C.height;F++){for(var E=0;E<C.width;E++){y[F][E]=" ";l[F][E]=D}}};C.TermResetScreen=function(){p=0;o=7;n=0;t=true;w=0;x=0;C.TermClear(7<<6)};function b(){var D=(n<<12);for(var E=w;E<C.width;E++){y[x][E]=" ";l[x][E]=D}}function a(){var D=(n<<12);for(var E=0;E<w;E++){y[x][E]=" ";l[x][E]=D}}function c(D){var E=(n<<12);for(var F=0;F<C.width;F++){y[D][F]=" ";l[D][F]=E}}C.TermSendKeys=function(D){if(C.debugmode==2){if(C.debugmode==2){console.log("TSend("+D.length+"): "+rstr2hex(D))}}C.parent.send(D)};C.TermSendKey=function(D){if(C.debugmode==2){if(C.debugmode==2){console.log("TSend(1): "+rstr2hex(String.fromCharCode(D)))}}C.parent.send(String.fromCharCode(D))};function u(D){var E,F;for(F=0;F<C.height-D;F++){y[F]=y[F+D];l[F]=l[F+D]}for(F=C.height-D;F<C.height;F++){y[F]=[];l[F]=[];for(E=0;E<C.width;E++){y[F][E]=" ";l[F][E]=(7<<6)}}}C.TermHandleKeys=function(D){if(!D.ctrlKey){if(D.which==127){C.TermSendKey(8)}else{if(D.which==13){C.TermSendKeys(C.lineFeed)}else{if(D.which!=0){C.TermSendKey(D.which)}}}return false}if(D.preventDefault){D.preventDefault()}if(D.stopPropagation){D.stopPropagation()}};C.TermHandleKeyUp=function(D){if((D.which!=8)&&(D.which!=32)&&(D.which!=9)){return true}if(D.preventDefault){D.preventDefault()}if(D.stopPropagation){D.stopPropagation()}return false};C.TermHandleKeyDown=function(D){if((D.which>=65)&&(D.which<=90)&&(D.ctrlKey==true)){C.TermSendKey(D.which-64);if(D.preventDefault){D.preventDefault()}if(D.stopPropagation){D.stopPropagation()}return}if(D.which==27){C.TermSendKeys(String.fromCharCode(27));return true}if(D.which==37){C.TermSendKeys(String.fromCharCode(27,91,68));return true}if(D.which==38){C.TermSendKeys(String.fromCharCode(27,91,65));return true}if(D.which==39){C.TermSendKeys(String.fromCharCode(27,91,67));return true}if(D.which==40){C.TermSendKeys(String.fromCharCode(27,91,66));return true}if(D.which==9){C.TermSendKeys("\t");if(D.preventDefault){D.preventDefault()}if(D.stopPropagation){D.stopPropagation()}return true}if(D.which!=8&&D.which!=32&&D.which!=9){return true}C.TermSendKey(D.which);if(D.preventDefault){D.preventDefault()}if(D.stopPropagation){D.stopPropagation()}return false};C.TermDraw=function(){var E,D="",F="",G,H=1,J,K;for(var L=0;L<C.height;++L){for(var I=0;I<C.width;++I){G=l[L][I];if(w==I&&x==L){G|=z}if(G!=H){D+=F;F="";J=6;K=12;if(G&z){J=12;K=6}D+='<span style="color:#'+m[(G>>J)&63]+";background-color:#"+m[(G>>K)&63];if(G&A){D+=";text-decoration:underline"}D+=';">';F="</span>"+F;H=G}E=y[L][I];switch(E){case"&":D+="&amp;";break;case"<":D+="&lt;";break;case">":D+="&gt;";break;case" ":D+="&nbsp;";break;default:D+=E;break}}if(L!=(C.height-1)){D+="<br>"}}C.DivElement.innerHTML="<font size='4'><b>"+D+F+"</b></font>"};C.TermInit=function(){C.TermResetScreen()};C.Init();return C};var ZLIB=(ZLIB||{});if(typeof ZLIB.common_initialized==="undefined"){ZLIB.Z_NO_FLUSH=0;ZLIB.Z_PARTIAL_FLUSH=1;ZLIB.Z_SYNC_FLUSH=2;ZLIB.Z_FULL_FLUSH=3;ZLIB.Z_FINISH=4;ZLIB.Z_BLOCK=5;ZLIB.Z_TREES=6;ZLIB.Z_OK=0;ZLIB.Z_STREAM_END=1;ZLIB.Z_NEED_DICT=2;ZLIB.Z_ERRNO=(-1);ZLIB.Z_STREAM_ERROR=(-2);ZLIB.Z_DATA_ERROR=(-3);ZLIB.Z_MEM_ERROR=(-4);ZLIB.Z_BUF_ERROR=(-5);ZLIB.Z_VERSION_ERROR=(-6);ZLIB.Z_DEFLATED=8;ZLIB.z_stream=function(){this.next_in=0;this.avail_in=0;this.total_in=0;this.next_out=0;this.avail_out=0;this.total_out=0;this.msg=null;this.state=null;this.data_type=0;this.adler=0;this.input_data="";this.output_data="";this.error=0;this.checksum_function=null};ZLIB.gz_header=function(){this.text=0;this.time=0;this.xflags=0;this.os=255;this.extra=null;this.extra_len=0;this.extra_max=0;this.name=null;this.name_max=0;this.comment=null;this.comm_max=0;this.hcrc=0;this.done=0};ZLIB.common_initialized=true}if(typeof ZLIB==="undefined"){alert("ZLIB is not defined. SRC zlib.js before zlib-inflate.js")}(function(){var o=15;var G=0;var D=1;var am=2;var af=3;var A=4;var B=5;var ac=6;var j=7;var F=8;var q=9;var p=10;var an=11;var ao=12;var aj=13;var l=14;var k=15;var al=16;var W=17;var g=18;var S=19;var R=20;var T=21;var r=22;var s=23;var aa=24;var Y=25;var d=26;var V=27;var v=28;var a=29;var ab=30;var ak=31;var z=852;var y=592;var x=(z+y);var h=0;var X=1;var u=2;var N=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0];var O=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,203,69];var L=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0];var M=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];ZLIB.inflate_copyright=" inflate 1.2.6 Copyright 1995-2012 Mark Adler ";function K(aR,aV){var aM=15;var aU=aR.next;var at=(aV==u?aR.distbits:aR.lenbits);var aX=aR.work;var aH=aR.lens;var aI=(aV==u?aR.nlen:0);var aS=aR.codes;var au;if(aV==X){au=aR.nlen}else{if(aV==u){au=aR.ndist}else{au=19}}var aG;var aT;var aN,aL;var aQ;var aw;var ax;var aF;var aW;var aD;var aE;var aB;var aJ;var aK;var aC;var aO;var aq;var ar;var az;var aA;var ay;var av=new Array(aM+1);var aP=new Array(aM+1);for(aG=0;aG<=aM;aG++){av[aG]=0}for(aT=0;aT<au;aT++){av[aH[aI+aT]]++}aQ=at;for(aL=aM;aL>=1;aL--){if(av[aL]!=0){break}}if(aQ>aL){aQ=aL}if(aL==0){aC={op:64,bits:1,val:0};aS[aU++]=aC;aS[aU++]=aC;if(aV==u){aR.distbits=1}else{aR.lenbits=1}aR.next=aU;return 0}for(aN=1;aN<aL;aN++){if(av[aN]!=0){break}}if(aQ<aN){aQ=aN}aF=1;for(aG=1;aG<=aM;aG++){aF<<=1;aF-=av[aG];if(aF<0){return -1}}if(aF>0&&(aV==h||aL!=1)){aR.next=aU;return -1}aP[1]=0;for(aG=1;aG<aM;aG++){aP[aG+1]=aP[aG]+av[aG]}for(aT=0;aT<au;aT++){if(aH[aI+aT]!=0){aX[aP[aH[aI+aT]]++]=aT}}switch(aV){case h:aq=az=aX;ar=0;aA=0;ay=19;break;case X:aq=N;ar=-257;az=O;aA=-257;ay=256;break;default:aq=L;az=M;ar=0;aA=0;ay=-1}aD=0;aT=0;aG=aN;aO=aU;aw=aQ;ax=0;aJ=-1;aW=1<<aQ;aK=aW-1;if((aV==X&&aW>=z)||(aV==u&&aW>=y)){aR.next=aU;return 1}for(;;){aC={op:0,bits:aG-ax,val:0};if(aX[aT]<ay){aC.val=aX[aT]}else{if(aX[aT]>ay){aC.op=az[aA+aX[aT]];aC.val=aq[ar+aX[aT]]}else{aC.op=32+64}}aE=1<<(aG-ax);aB=1<<aw;aN=aB;do{aB-=aE;aS[aO+(aD>>>ax)+aB]=aC}while(aB!=0);aE=1<<(aG-1);while(aD&aE){aE>>>=1}if(aE!=0){aD&=aE-1;aD+=aE}else{aD=0}aT++;if(--(av[aG])==0){if(aG==aL){break}aG=aH[aI+aX[aT]]}if(aG>aQ&&(aD&aK)!=aJ){if(ax==0){ax=aQ}aO+=aN;aw=aG-ax;aF=(1<<aw);while(aw+ax<aL){aF-=av[aw+ax];if(aF<=0){break}aw++;aF<<=1}aW+=1<<aw;if((aV==X&&aW>=z)||(aV==u&&aW>=y)){aR.next=aU;return 1}aJ=aD&aK;aS[aU+aJ]={op:aw,bits:aQ,val:aO-aU}}}if(aD!=0){aS[aO+aD]={op:64,bits:aG-ax,val:0}}aR.next=aU+aW;if(aV==u){aR.distbits=aQ}else{aR.lenbits=aQ}return 0}function H(aN,aL){var aM;var aC;var aI;var aD;var aK;var aq;var ax;var aR;var aO;var aQ;var aP;var aB;var ar;var at;var aE;var au;var aH;var aw;var aA;var aJ;var aF;var av;var az=-1;var ay=-1;aM=aN.state;aC=aN.input_data;aI=aN.next_in;aD=aI+aN.avail_in-5;aK=aN.next_out;aq=aK-(aL-aN.avail_out);ax=aK+(aN.avail_out-257);aR=aM.wsize;aO=aM.whave;aQ=aM.wnext;aP=aM.window;aB=aM.hold;ar=aM.bits;at=aM.codes;aE=aM.lencode;au=aM.distcode;aH=(1<<aM.lenbits)-1;aw=(1<<aM.distbits)-1;loop:do{if(ar<15){aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8;aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8}aA=at[aE+(aB&aH)];dolen:while(true){aJ=aA.bits;aB>>>=aJ;ar-=aJ;aJ=aA.op;if(aJ==0){aN.output_data+=String.fromCharCode(aA.val);aK++}else{if(aJ&16){aF=aA.val;aJ&=15;if(aJ){if(ar<aJ){aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8}aF+=aB&((1<<aJ)-1);aB>>>=aJ;ar-=aJ}if(ar<15){aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8;aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8}aA=at[au+(aB&aw)];dodist:while(true){aJ=aA.bits;aB>>>=aJ;ar-=aJ;aJ=aA.op;if(aJ&16){av=aA.val;aJ&=15;if(ar<aJ){aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8;if(ar<aJ){aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8}}av+=aB&((1<<aJ)-1);aB>>>=aJ;ar-=aJ;aJ=aK-aq;if(av>aJ){aJ=av-aJ;if(aJ>aO){if(aM.sane){aN.msg="invalid distance too far back";aM.mode=a;break loop}}az=0;ay=-1;if(aQ==0){az+=aR-aJ;if(aJ<aF){aF-=aJ;aN.output_data+=aP.substring(az,az+aJ);aK+=aJ;aJ=0;az=-1;ay=aK-av}}else{az+=aQ-aJ;if(aJ<aF){aF-=aJ;aN.output_data+=aP.substring(az,az+aJ);aK+=aJ;az=-1;ay=aK-av}}}else{az=-1;ay=aK-av}if(az>=0){aN.output_data+=aP.substring(az,az+aF);aK+=aF;az+=aF}else{var aG=aF;if(aG>aK-ay){aG=aK-ay}aN.output_data+=aN.output_data.substring(ay,ay+aG);aK+=aG;aF-=aG;ay+=aG;aK+=aF;while(aF>2){aN.output_data+=aN.output_data.charAt(ay++);aN.output_data+=aN.output_data.charAt(ay++);aN.output_data+=aN.output_data.charAt(ay++);aF-=3}if(aF){aN.output_data+=aN.output_data.charAt(ay++);if(aF>1){aN.output_data+=aN.output_data.charAt(ay++)}}}}else{if((aJ&64)==0){aA=at[au+(aA.val+(aB&((1<<aJ)-1)))];continue dodist}else{aN.msg="invalid distance code";aM.mode=a;break loop}}break dodist}}else{if((aJ&64)==0){aA=at[aE+(aA.val+(aB&((1<<aJ)-1)))];continue dolen}else{if(aJ&32){aM.mode=an;break loop}else{aN.msg="invalid literal/length code";aM.mode=a;break loop}}}}break dolen}}while(aI<aD&&aK<ax);aF=ar>>>3;aI-=aF;ar-=aF<<3;aB&=(1<<ar)-1;aN.next_in=aI;aN.next_out=aK;aN.avail_in=(aI<aD?5+(aD-aI):5-(aI-aD));aN.avail_out=(aK<ax?257+(ax-aK):257-(aK-ax));aM.hold=aB;aM.bits=ar}function ae(at){var ar;var aq=new Array(at);for(ar=0;ar<at;ar++){aq[ar]=0}return aq}function E(at,ar,aq){return(at&&(ar in at))?at[ar]:aq}function e(){return 0}function J(){var ar;this.mode=0;this.last=0;this.wrap=0;this.havedict=0;this.flags=0;this.dmax=0;this.check=0;this.total=0;this.head=null;this.wbits=0;this.wsize=0;this.whave=0;this.wnext=0;this.window=null;this.hold=0;this.bits=0;this.length=0;this.offset=0;this.extra=0;this.lencode=0;this.distcode=0;this.lenbits=0;this.distbits=0;this.ncode=0;this.nlen=0;this.ndist=0;this.have=0;this.next=0;this.lens=ae(320);this.work=ae(288);this.codes=new Array(x);var aq={op:0,bits:0,val:0};for(ar=0;ar<x;ar++){this.codes[ar]=aq}this.sane=0;this.back=0;this.was=0}ZLIB.inflateResetKeep=function(ar){var aq;if(!ar||!ar.state){return ZLIB.Z_STREAM_ERROR}aq=ar.state;ar.total_in=ar.total_out=aq.total=0;ar.msg=null;if(aq.wrap){ar.adler=aq.wrap&1}aq.mode=G;aq.last=0;aq.havedict=0;aq.dmax=32768;aq.head=null;aq.hold=0;aq.bits=0;aq.lencode=0;aq.distcode=0;aq.next=0;aq.sane=1;aq.back=-1;return ZLIB.Z_OK};ZLIB.inflateReset=function(ar,at){var au;var aq;if(!ar||!ar.state){return ZLIB.Z_STREAM_ERROR}aq=ar.state;if(typeof at==="undefined"){at=o}if(at<0){au=0;at=-at}else{au=(at>>>4)+1;if(at<48){at&=15}}if(au==1&&(typeof ZLIB.adler32==="function")){ar.checksum_function=ZLIB.adler32}else{if(au==2&&(typeof ZLIB.crc32==="function")){ar.checksum_function=ZLIB.crc32}else{ar.checksum_function=e}}if(at&&(at<8||at>15)){return ZLIB.Z_STREAM_ERROR}if(aq.window&&aq.wbits!=at){aq.window=null}aq.wrap=au;aq.wbits=at;aq.wsize=0;aq.whave=0;aq.wnext=0;return ZLIB.inflateResetKeep(ar)};ZLIB.inflateInit=function(ar){var aq=new ZLIB.z_stream();aq.state=new J();ZLIB.inflateReset(aq,ar);return aq};ZLIB.inflatePrime=function(at,aq,au){var ar;if(!at||!at.state){return ZLIB.Z_STREAM_ERROR}ar=at.state;if(aq<0){ar.hold=0;ar.bits=0;return ZLIB.Z_OK}if(aq>16||ar.bits+aq>32){return ZLIB.Z_STREAM_ERROR}au&=(1<<aq)-1;ar.hold+=au<<ar.bits;ar.bits+=aq;return ZLIB.Z_OK};var U=null;var t=null;function C(ar){var aq;if(!U){U=[{op:96,bits:7,val:0},{op:0,bits:8,val:80},{op:0,bits:8,val:16},{op:20,bits:8,val:115},{op:18,bits:7,val:31},{op:0,bits:8,val:112},{op:0,bits:8,val:48},{op:0,bits:9,val:192},{op:16,bits:7,val:10},{op:0,bits:8,val:96},{op:0,bits:8,val:32},{op:0,bits:9,val:160},{op:0,bits:8,val:0},{op:0,bits:8,val:128},{op:0,bits:8,val:64},{op:0,bits:9,val:224},{op:16,bits:7,val:6},{op:0,bits:8,val:88},{op:0,bits:8,val:24},{op:0,bits:9,val:144},{op:19,bits:7,val:59},{op:0,bits:8,val:120},{op:0,bits:8,val:56},{op:0,bits:9,val:208},{op:17,bits:7,val:17},{op:0,bits:8,val:104},{op:0,bits:8,val:40},{op:0,bits:9,val:176},{op:0,bits:8,val:8},{op:0,bits:8,val:136},{op:0,bits:8,val:72},{op:0,bits:9,val:240},{op:16,bits:7,val:4},{op:0,bits:8,val:84},{op:0,bits:8,val:20},{op:21,bits:8,val:227},{op:19,bits:7,val:43},{op:0,bits:8,val:116},{op:0,bits:8,val:52},{op:0,bits:9,val:200},{op:17,bits:7,val:13},{op:0,bits:8,val:100},{op:0,bits:8,val:36},{op:0,bits:9,val:168},{op:0,bits:8,val:4},{op:0,bits:8,val:132},{op:0,bits:8,val:68},{op:0,bits:9,val:232},{op:16,bits:7,val:8},{op:0,bits:8,val:92},{op:0,bits:8,val:28},{op:0,bits:9,val:152},{op:20,bits:7,val:83},{op:0,bits:8,val:124},{op:0,bits:8,val:60},{op:0,bits:9,val:216},{op:18,bits:7,val:23},{op:0,bits:8,val:108},{op:0,bits:8,val:44},{op:0,bits:9,val:184},{op:0,bits:8,val:12},{op:0,bits:8,val:140},{op:0,bits:8,val:76},{op:0,bits:9,val:248},{op:16,bits:7,val:3},{op:0,bits:8,val:82},{op:0,bits:8,val:18},{op:21,bits:8,val:163},{op:19,bits:7,val:35},{op:0,bits:8,val:114},{op:0,bits:8,val:50},{op:0,bits:9,val:196},{op:17,bits:7,val:11},{op:0,bits:8,val:98},{op:0,bits:8,val:34},{op:0,bits:9,val:164},{op:0,bits:8,val:2},{op:0,bits:8,val:130},{op:0,bits:8,val:66},{op:0,bits:9,val:228},{op:16,bits:7,val:7},{op:0,bits:8,val:90},{op:0,bits:8,val:26},{op:0,bits:9,val:148},{op:20,bits:7,val:67},{op:0,bits:8,val:122},{op:0,bits:8,val:58},{op:0,bits:9,val:212},{op:18,bits:7,val:19},{op:0,bits:8,val:106},{op:0,bits:8,val:42},{op:0,bits:9,val:180},{op:0,bits:8,val:10},{op:0,bits:8,val:138},{op:0,bits:8,val:74},{op:0,bits:9,val:244},{op:16,bits:7,val:5},{op:0,bits:8,val:86},{op:0,bits:8,val:22},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:118},{op:0,bits:8,val:54},{op:0,bits:9,val:204},{op:17,bits:7,val:15},{op:0,bits:8,val:102},{op:0,bits:8,val:38},{op:0,bits:9,val:172},{op:0,bits:8,val:6},{op:0,bits:8,val:134},{op:0,bits:8,val:70},{op:0,bits:9,val:236},{op:16,bits:7,val:9},{op:0,bits:8,val:94},{op:0,bits:8,val:30},{op:0,bits:9,val:156},{op:20,bits:7,val:99},{op:0,bits:8,val:126},{op:0,bits:8,val:62},{op:0,bits:9,val:220},{op:18,bits:7,val:27},{op:0,bits:8,val:110},{op:0,bits:8,val:46},{op:0,bits:9,val:188},{op:0,bits:8,val:14},{op:0,bits:8,val:142},{op:0,bits:8,val:78},{op:0,bits:9,val:252},{op:96,bits:7,val:0},{op:0,bits:8,val:81},{op:0,bits:8,val:17},{op:21,bits:8,val:131},{op:18,bits:7,val:31},{op:0,bits:8,val:113},{op:0,bits:8,val:49},{op:0,bits:9,val:194},{op:16,bits:7,val:10},{op:0,bits:8,val:97},{op:0,bits:8,val:33},{op:0,bits:9,val:162},{op:0,bits:8,val:1},{op:0,bits:8,val:129},{op:0,bits:8,val:65},{op:0,bits:9,val:226},{op:16,bits:7,val:6},{op:0,bits:8,val:89},{op:0,bits:8,val:25},{op:0,bits:9,val:146},{op:19,bits:7,val:59},{op:0,bits:8,val:121},{op:0,bits:8,val:57},{op:0,bits:9,val:210},{op:17,bits:7,val:17},{op:0,bits:8,val:105},{op:0,bits:8,val:41},{op:0,bits:9,val:178},{op:0,bits:8,val:9},{op:0,bits:8,val:137},{op:0,bits:8,val:73},{op:0,bits:9,val:242},{op:16,bits:7,val:4},{op:0,bits:8,val:85},{op:0,bits:8,val:21},{op:16,bits:8,val:258},{op:19,bits:7,val:43},{op:0,bits:8,val:117},{op:0,bits:8,val:53},{op:0,bits:9,val:202},{op:17,bits:7,val:13},{op:0,bits:8,val:101},{op:0,bits:8,val:37},{op:0,bits:9,val:170},{op:0,bits:8,val:5},{op:0,bits:8,val:133},{op:0,bits:8,val:69},{op:0,bits:9,val:234},{op:16,bits:7,val:8},{op:0,bits:8,val:93},{op:0,bits:8,val:29},{op:0,bits:9,val:154},{op:20,bits:7,val:83},{op:0,bits:8,val:125},{op:0,bits:8,val:61},{op:0,bits:9,val:218},{op:18,bits:7,val:23},{op:0,bits:8,val:109},{op:0,bits:8,val:45},{op:0,bits:9,val:186},{op:0,bits:8,val:13},{op:0,bits:8,val:141},{op:0,bits:8,val:77},{op:0,bits:9,val:250},{op:16,bits:7,val:3},{op:0,bits:8,val:83},{op:0,bits:8,val:19},{op:21,bits:8,val:195},{op:19,bits:7,val:35},{op:0,bits:8,val:115},{op:0,bits:8,val:51},{op:0,bits:9,val:198},{op:17,bits:7,val:11},{op:0,bits:8,val:99},{op:0,bits:8,val:35},{op:0,bits:9,val:166},{op:0,bits:8,val:3},{op:0,bits:8,val:131},{op:0,bits:8,val:67},{op:0,bits:9,val:230},{op:16,bits:7,val:7},{op:0,bits:8,val:91},{op:0,bits:8,val:27},{op:0,bits:9,val:150},{op:20,bits:7,val:67},{op:0,bits:8,val:123},{op:0,bits:8,val:59},{op:0,bits:9,val:214},{op:18,bits:7,val:19},{op:0,bits:8,val:107},{op:0,bits:8,val:43},{op:0,bits:9,val:182},{op:0,bits:8,val:11},{op:0,bits:8,val:139},{op:0,bits:8,val:75},{op:0,bits:9,val:246},{op:16,bits:7,val:5},{op:0,bits:8,val:87},{op:0,bits:8,val:23},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:119},{op:0,bits:8,val:55},{op:0,bits:9,val:206},{op:17,bits:7,val:15},{op:0,bits:8,val:103},{op:0,bits:8,val:39},{op:0,bits:9,val:174},{op:0,bits:8,val:7},{op:0,bits:8,val:135},{op:0,bits:8,val:71},{op:0,bits:9,val:238},{op:16,bits:7,val:9},{op:0,bits:8,val:95},{op:0,bits:8,val:31},{op:0,bits:9,val:158},{op:20,bits:7,val:99},{op:0,bits:8,val:127},{op:0,bits:8,val:63},{op:0,bits:9,val:222},{op:18,bits:7,val:27},{op:0,bits:8,val:111},{op:0,bits:8,val:47},{op:0,bits:9,val:190},{op:0,bits:8,val:15},{op:0,bits:8,val:143},{op:0,bits:8,val:79},{op:0,bits:9,val:254},{op:96,bits:7,val:0},{op:0,bits:8,val:80},{op:0,bits:8,val:16},{op:20,bits:8,val:115},{op:18,bits:7,val:31},{op:0,bits:8,val:112},{op:0,bits:8,val:48},{op:0,bits:9,val:193},{op:16,bits:7,val:10},{op:0,bits:8,val:96},{op:0,bits:8,val:32},{op:0,bits:9,val:161},{op:0,bits:8,val:0},{op:0,bits:8,val:128},{op:0,bits:8,val:64},{op:0,bits:9,val:225},{op:16,bits:7,val:6},{op:0,bits:8,val:88},{op:0,bits:8,val:24},{op:0,bits:9,val:145},{op:19,bits:7,val:59},{op:0,bits:8,val:120},{op:0,bits:8,val:56},{op:0,bits:9,val:209},{op:17,bits:7,val:17},{op:0,bits:8,val:104},{op:0,bits:8,val:40},{op:0,bits:9,val:177},{op:0,bits:8,val:8},{op:0,bits:8,val:136},{op:0,bits:8,val:72},{op:0,bits:9,val:241},{op:16,bits:7,val:4},{op:0,bits:8,val:84},{op:0,bits:8,val:20},{op:21,bits:8,val:227},{op:19,bits:7,val:43},{op:0,bits:8,val:116},{op:0,bits:8,val:52},{op:0,bits:9,val:201},{op:17,bits:7,val:13},{op:0,bits:8,val:100},{op:0,bits:8,val:36},{op:0,bits:9,val:169},{op:0,bits:8,val:4},{op:0,bits:8,val:132},{op:0,bits:8,val:68},{op:0,bits:9,val:233},{op:16,bits:7,val:8},{op:0,bits:8,val:92},{op:0,bits:8,val:28},{op:0,bits:9,val:153},{op:20,bits:7,val:83},{op:0,bits:8,val:124},{op:0,bits:8,val:60},{op:0,bits:9,val:217},{op:18,bits:7,val:23},{op:0,bits:8,val:108},{op:0,bits:8,val:44},{op:0,bits:9,val:185},{op:0,bits:8,val:12},{op:0,bits:8,val:140},{op:0,bits:8,val:76},{op:0,bits:9,val:249},{op:16,bits:7,val:3},{op:0,bits:8,val:82},{op:0,bits:8,val:18},{op:21,bits:8,val:163},{op:19,bits:7,val:35},{op:0,bits:8,val:114},{op:0,bits:8,val:50},{op:0,bits:9,val:197},{op:17,bits:7,val:11},{op:0,bits:8,val:98},{op:0,bits:8,val:34},{op:0,bits:9,val:165},{op:0,bits:8,val:2},{op:0,bits:8,val:130},{op:0,bits:8,val:66},{op:0,bits:9,val:229},{op:16,bits:7,val:7},{op:0,bits:8,val:90},{op:0,bits:8,val:26},{op:0,bits:9,val:149},{op:20,bits:7,val:67},{op:0,bits:8,val:122},{op:0,bits:8,val:58},{op:0,bits:9,val:213},{op:18,bits:7,val:19},{op:0,bits:8,val:106},{op:0,bits:8,val:42},{op:0,bits:9,val:181},{op:0,bits:8,val:10},{op:0,bits:8,val:138},{op:0,bits:8,val:74},{op:0,bits:9,val:245},{op:16,bits:7,val:5},{op:0,bits:8,val:86},{op:0,bits:8,val:22},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:118},{op:0,bits:8,val:54},{op:0,bits:9,val:205},{op:17,bits:7,val:15},{op:0,bits:8,val:102},{op:0,bits:8,val:38},{op:0,bits:9,val:173},{op:0,bits:8,val:6},{op:0,bits:8,val:134},{op:0,bits:8,val:70},{op:0,bits:9,val:237},{op:16,bits:7,val:9},{op:0,bits:8,val:94},{op:0,bits:8,val:30},{op:0,bits:9,val:157},{op:20,bits:7,val:99},{op:0,bits:8,val:126},{op:0,bits:8,val:62},{op:0,bits:9,val:221},{op:18,bits:7,val:27},{op:0,bits:8,val:110},{op:0,bits:8,val:46},{op:0,bits:9,val:189},{op:0,bits:8,val:14},{op:0,bits:8,val:142},{op:0,bits:8,val:78},{op:0,bits:9,val:253},{op:96,bits:7,val:0},{op:0,bits:8,val:81},{op:0,bits:8,val:17},{op:21,bits:8,val:131},{op:18,bits:7,val:31},{op:0,bits:8,val:113},{op:0,bits:8,val:49},{op:0,bits:9,val:195},{op:16,bits:7,val:10},{op:0,bits:8,val:97},{op:0,bits:8,val:33},{op:0,bits:9,val:163},{op:0,bits:8,val:1},{op:0,bits:8,val:129},{op:0,bits:8,val:65},{op:0,bits:9,val:227},{op:16,bits:7,val:6},{op:0,bits:8,val:89},{op:0,bits:8,val:25},{op:0,bits:9,val:147},{op:19,bits:7,val:59},{op:0,bits:8,val:121},{op:0,bits:8,val:57},{op:0,bits:9,val:211},{op:17,bits:7,val:17},{op:0,bits:8,val:105},{op:0,bits:8,val:41},{op:0,bits:9,val:179},{op:0,bits:8,val:9},{op:0,bits:8,val:137},{op:0,bits:8,val:73},{op:0,bits:9,val:243},{op:16,bits:7,val:4},{op:0,bits:8,val:85},{op:0,bits:8,val:21},{op:16,bits:8,val:258},{op:19,bits:7,val:43},{op:0,bits:8,val:117},{op:0,bits:8,val:53},{op:0,bits:9,val:203},{op:17,bits:7,val:13},{op:0,bits:8,val:101},{op:0,bits:8,val:37},{op:0,bits:9,val:171},{op:0,bits:8,val:5},{op:0,bits:8,val:133},{op:0,bits:8,val:69},{op:0,bits:9,val:235},{op:16,bits:7,val:8},{op:0,bits:8,val:93},{op:0,bits:8,val:29},{op:0,bits:9,val:155},{op:20,bits:7,val:83},{op:0,bits:8,val:125},{op:0,bits:8,val:61},{op:0,bits:9,val:219},{op:18,bits:7,val:23},{op:0,bits:8,val:109},{op:0,bits:8,val:45},{op:0,bits:9,val:187},{op:0,bits:8,val:13},{op:0,bits:8,val:141},{op:0,bits:8,val:77},{op:0,bits:9,val:251},{op:16,bits:7,val:3},{op:0,bits:8,val:83},{op:0,bits:8,val:19},{op:21,bits:8,val:195},{op:19,bits:7,val:35},{op:0,bits:8,val:115},{op:0,bits:8,val:51},{op:0,bits:9,val:199},{op:17,bits:7,val:11},{op:0,bits:8,val:99},{op:0,bits:8,val:35},{op:0,bits:9,val:167},{op:0,bits:8,val:3},{op:0,bits:8,val:131},{op:0,bits:8,val:67},{op:0,bits:9,val:231},{op:16,bits:7,val:7},{op:0,bits:8,val:91},{op:0,bits:8,val:27},{op:0,bits:9,val:151},{op:20,bits:7,val:67},{op:0,bits:8,val:123},{op:0,bits:8,val:59},{op:0,bits:9,val:215},{op:18,bits:7,val:19},{op:0,bits:8,val:107},{op:0,bits:8,val:43},{op:0,bits:9,val:183},{op:0,bits:8,val:11},{op:0,bits:8,val:139},{op:0,bits:8,val:75},{op:0,bits:9,val:247},{op:16,bits:7,val:5},{op:0,bits:8,val:87},{op:0,bits:8,val:23},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:119},{op:0,bits:8,val:55},{op:0,bits:9,val:207},{op:17,bits:7,val:15},{op:0,bits:8,val:103},{op:0,bits:8,val:39},{op:0,bits:9,val:175},{op:0,bits:8,val:7},{op:0,bits:8,val:135},{op:0,bits:8,val:71},{op:0,bits:9,val:239},{op:16,bits:7,val:9},{op:0,bits:8,val:95},{op:0,bits:8,val:31},{op:0,bits:9,val:159},{op:20,bits:7,val:99},{op:0,bits:8,val:127},{op:0,bits:8,val:63},{op:0,bits:9,val:223},{op:18,bits:7,val:27},{op:0,bits:8,val:111},{op:0,bits:8,val:47},{op:0,bits:9,val:191},{op:0,bits:8,val:15},{op:0,bits:8,val:143},{op:0,bits:8,val:79},{op:0,bits:9,val:255}]}if(!t){t=[{op:16,bits:5,val:1},{op:23,bits:5,val:257},{op:19,bits:5,val:17},{op:27,bits:5,val:4097},{op:17,bits:5,val:5},{op:25,bits:5,val:1025},{op:21,bits:5,val:65},{op:29,bits:5,val:16385},{op:16,bits:5,val:3},{op:24,bits:5,val:513},{op:20,bits:5,val:33},{op:28,bits:5,val:8193},{op:18,bits:5,val:9},{op:26,bits:5,val:2049},{op:22,bits:5,val:129},{op:64,bits:5,val:0},{op:16,bits:5,val:2},{op:23,bits:5,val:385},{op:19,bits:5,val:25},{op:27,bits:5,val:6145},{op:17,bits:5,val:7},{op:25,bits:5,val:1537},{op:21,bits:5,val:97},{op:29,bits:5,val:24577},{op:16,bits:5,val:4},{op:24,bits:5,val:769},{op:20,bits:5,val:49},{op:28,bits:5,val:12289},{op:18,bits:5,val:13},{op:26,bits:5,val:3073},{op:22,bits:5,val:193},{op:64,bits:5,val:0}]}ar.lencode=0;ar.distcode=512;for(aq=0;aq<512;aq++){ar.codes[aq]=U[aq]}for(aq=0;aq<32;aq++){ar.codes[aq+512]=t[aq]}ar.lenbits=9;ar.distbits=5}function ap(at){var ar=at.state;var aq=at.output_data.length;if(ar.window===null){ar.window=""}if(ar.wsize==0){ar.wsize=1<<ar.wbits}if(aq>=ar.wsize){ar.window=at.output_data.substring(aq-ar.wsize)}else{if(ar.whave+aq<ar.wsize){ar.window+=at.output_data}else{ar.window=ar.window.substring(ar.whave-(ar.wsize-aq))+at.output_data}}ar.whave=ar.window.length;if(ar.whave<ar.wsize){ar.wnext=ar.whave}else{ar.wnext=0}return 0}function m(ar,at){var aq=[at&255,(at>>>8)&255];ar.state.check=ar.checksum_function(ar.state.check,aq,0,2)}function n(ar,at){var aq=[at&255,(at>>>8)&255,(at>>>16)&255,(at>>>24)&255];ar.state.check=ar.checksum_function(ar.state.check,aq,0,4)}function Z(ar,aq){aq.strm=ar;aq.left=ar.avail_out;aq.next=ar.next_in;aq.have=ar.avail_in;aq.hold=ar.state.hold;aq.bits=ar.state.bits;return aq}function ah(aq){var ar=aq.strm;ar.next_in=aq.next;ar.avail_out=aq.left;ar.avail_in=aq.have;ar.state.hold=aq.hold;ar.state.bits=aq.bits}function P(aq){aq.hold=0;aq.bits=0}function ag(aq){if(aq.have==0){return false}aq.have--;aq.hold+=(aq.strm.input_data.charCodeAt(aq.next++)&255)<<aq.bits;aq.bits+=8;return true}function ad(ar,aq){while(ar.bits<aq){if(!ag(ar)){return false}}return true}function b(ar,aq){return ar.hold&((1<<aq)-1)}function w(ar,aq){ar.hold>>>=aq;ar.bits-=aq}function c(aq){aq.hold>>>=aq.bits&7;aq.bits-=aq.bits&7}function ai(aq){return((aq>>>24)&255)+((aq>>>8)&65280)+((aq&65280)<<8)+((aq&255)<<24)}var I=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];ZLIB.inflate=function(aD,at){var aC;var aB;var aq,az;var ar;var av=-1;var au=-1;var aw;var ax;var ay;var aA;if(!aD||!aD.state||(!aD.input_data&&aD.avail_in!=0)){return ZLIB.Z_STREAM_ERROR}aC=aD.state;if(aC.mode==an){aC.mode=ao}aB={};Z(aD,aB);aq=aB.have;az=aB.left;aA=ZLIB.Z_OK;inf_leave:for(;;){switch(aC.mode){case G:if(aC.wrap==0){aC.mode=ao;break}if(!ad(aB,16)){break inf_leave}if((aC.wrap&2)&&aB.hold==35615){aC.check=aD.checksum_function(0,null,0,0);m(aD,aB.hold);P(aB);aC.mode=D;break}aC.flags=0;if(aC.head!==null){aC.head.done=-1}if(!(aC.wrap&1)||((b(aB,8)<<8)+(aB.hold>>>8))%31){aD.msg="incorrect header check";aC.mode=a;break}if(b(aB,4)!=ZLIB.Z_DEFLATED){aD.msg="unknown compression method";aC.mode=a;break}w(aB,4);ay=b(aB,4)+8;if(aC.wbits==0){aC.wbits=ay}else{if(ay>aC.wbits){aD.msg="invalid window size";aC.mode=a;break}}aC.dmax=1<<ay;aD.adler=aC.check=aD.checksum_function(0,null,0,0);aC.mode=aB.hold&512?q:an;P(aB);break;case D:if(!ad(aB,16)){break inf_leave}aC.flags=aB.hold;if((aC.flags&255)!=ZLIB.Z_DEFLATED){aD.msg="unknown compression method";aC.mode=a;break}if(aC.flags&57344){aD.msg="unknown header flags set";aC.mode=a;break}if(aC.head!==null){aC.head.text=(aB.hold>>>8)&1}if(aC.flags&512){m(aD,aB.hold)}P(aB);aC.mode=am;case am:if(!ad(aB,32)){break inf_leave}if(aC.head!==null){aC.head.time=aB.hold}if(aC.flags&512){n(aD,aB.hold)}P(aB);aC.mode=af;case af:if(!ad(aB,16)){break inf_leave}if(aC.head!==null){aC.head.xflags=aB.hold&255;aC.head.os=aB.hold>>>8}if(aC.flags&512){m(aD,aB.hold)}P(aB);aC.mode=A;case A:if(aC.flags&1024){if(!ad(aB,16)){break inf_leave}aC.length=aB.hold;if(aC.head!==null){aC.head.extra_len=aB.hold}if(aC.flags&512){m(aD,aB.hold)}P(aB);aC.head.extra=""}else{if(aC.head!==null){aC.head.extra=null}}aC.mode=B;case B:if(aC.flags&1024){ar=aC.length;if(ar>aB.have){ar=aB.have}if(ar){if(aC.head!==null&&aC.head.extra!==null){ay=aC.head.extra_len-aC.length;aC.head.extra+=aD.input_data.substring(aB.next,aB.next+(ay+ar>aC.head.extra_max?aC.head.extra_max-ay:ar))}if(aC.flags&512){aC.check=aD.checksum_function(aC.check,aD.input_data,aB.next,ar)}aB.have-=ar;aB.next+=ar;aC.length-=ar}if(aC.length){break inf_leave}}aC.length=0;aC.mode=ac;case ac:if(aC.flags&2048){if(aB.have==0){break inf_leave}if(aC.head!==null&&aC.head.name===null){aC.head.name=""}ar=0;do{ay=aD.input_data.charAt(aB.next+ar);ar++;if(ay==="\0"){break}if(aC.head!==null&&aC.length<aC.head.name_max){aC.head.name+=ay;aC.length++}}while(ar<aB.have);if(aC.flags&512){aC.check=aD.checksum_function(aC.check,aD.input_data,aB.next,ar)}aB.have-=ar;aB.next+=ar;if(ay!=="\0"){break inf_leave}}else{if(aC.head!==null){aC.head.name=null}}aC.length=0;aC.mode=j;case j:if(aC.flags&4096){if(aB.have==0){break inf_leave}ar=0;if(aC.head!==null&&aC.head.comment===null){aC.head.comment=""}do{ay=aD.input_data.charAt(aB.next+ar);ar++;if(ay==="\0"){break}if(aC.head!==null&&aC.length<aC.head.comm_max){aC.head.comment+=ay;aC.length++}}while(ar<aB.have);if(aC.flags&512){aC.check=aD.checksum_function(aC.check,aD.input_data,aB.next,ar)}aB.have-=ar;aB.next+=ar;if(ay!=="\0"){break inf_leave}}else{if(aC.head!==null){aC.head.comment=null}}aC.mode=F;case F:if(aC.flags&512){if(!ad(aB,16)){break inf_leave}if(aB.hold!=(aC.check&65535)){aD.msg="header crc mismatch";aC.mode=a;break}P(aB)}if(aC.head!==null){aC.head.hcrc=(aC.flags>>>9)&1;aC.head.done=1}aD.adler=aC.check=aD.checksum_function(0,null,0,0);aC.mode=an;break;case q:if(!ad(aB,32)){break inf_leave}aD.adler=aC.check=ai(aB.hold);P(aB);aC.mode=p;case p:if(aC.havedict==0){ah(aB);return ZLIB.Z_NEED_DICT}aD.adler=aC.check=aD.checksum_function(0,null,0,0);aC.mode=an;case an:if(at==ZLIB.Z_BLOCK||at==ZLIB.Z_TREES){break inf_leave}case ao:if(aC.last){c(aB);aC.mode=d;break}if(!ad(aB,3)){break inf_leave}aC.last=b(aB,1);w(aB,1);switch(b(aB,2)){case 0:aC.mode=aj;break;case 1:C(aC);aC.mode=S;if(at==ZLIB.Z_TREES){w(aB,2);break inf_leave}break;case 2:aC.mode=al;break;case 3:aD.msg="invalid block type";aC.mode=a}w(aB,2);break;case aj:c(aB);if(!ad(aB,32)){break inf_leave}if((aB.hold&65535)!=(((aB.hold>>>16)&65535)^65535)){aD.msg="invalid stored block lengths";aC.mode=a;break}aC.length=aB.hold&65535;P(aB);aC.mode=l;if(at==ZLIB.Z_TREES){break inf_leave}case l:aC.mode=k;case k:ar=aC.length;if(ar){if(ar>aB.have){ar=aB.have}if(ar>aB.left){ar=aB.left}if(ar==0){break inf_leave}aD.output_data+=aD.input_data.substring(aB.next,aB.next+ar);aD.next_out+=ar;aB.have-=ar;aB.next+=ar;aB.left-=ar;aC.length-=ar;break}aC.mode=an;break;case al:if(!ad(aB,14)){break inf_leave}aC.nlen=b(aB,5)+257;w(aB,5);aC.ndist=b(aB,5)+1;w(aB,5);aC.ncode=b(aB,4)+4;w(aB,4);if(aC.nlen>286||aC.ndist>30){aD.msg="too many length or distance symbols";aC.mode=a;break}aC.have=0;aC.mode=W;case W:while(aC.have<aC.ncode){if(!ad(aB,3)){break inf_leave}var aE=b(aB,3);aC.lens[I[aC.have++]]=aE;w(aB,3)}while(aC.have<19){aC.lens[I[aC.have++]]=0}aC.next=0;aC.lencode=0;aC.lenbits=7;aA=K(aC,h);if(aA){aD.msg="invalid code lengths set";aC.mode=a;break}aC.have=0;aC.mode=g;case g:while(aC.have<aC.nlen+aC.ndist){for(;;){aw=aC.codes[aC.lencode+b(aB,aC.lenbits)];if(aw.bits<=aB.bits){break}if(!ag(aB)){break inf_leave}}if(aw.val<16){w(aB,aw.bits);aC.lens[aC.have++]=aw.val}else{if(aw.val==16){if(!ad(aB,aw.bits+2)){break inf_leave}w(aB,aw.bits);if(aC.have==0){aD.msg="invalid bit length repeat";aC.mode=a;break}ay=aC.lens[aC.have-1];ar=3+b(aB,2);w(aB,2)}else{if(aw.val==17){if(!ad(aB,aw.bits+3)){break inf_leave}w(aB,aw.bits);ay=0;ar=3+b(aB,3);w(aB,3)}else{if(!ad(aB,aw.bits+7)){break inf_leave}w(aB,aw.bits);ay=0;ar=11+b(aB,7);w(aB,7)}}if(aC.have+ar>aC.nlen+aC.ndist){aD.msg="invalid bit length repeat";aC.mode=a;break}while(ar--){aC.lens[aC.have++]=ay}}}if(aC.mode==a){break}if(aC.lens[256]==0){aD.msg="invalid code -- missing end-of-block";aC.mode=a;break}aC.next=0;aC.lencode=aC.next;aC.lenbits=9;aA=K(aC,X);if(aA){aD.msg="invalid literal/lengths set";aC.mode=a;break}aC.distcode=aC.next;aC.distbits=6;aA=K(aC,u);if(aA){aD.msg="invalid distances set";aC.mode=a;break}aC.mode=S;if(at==ZLIB.Z_TREES){break inf_leave}case S:aC.mode=R;case R:if(aB.have>=6&&aB.left>=258){ah(aB);H(aD,az);Z(aD,aB);if(aC.mode==an){aC.back=-1}break}aC.back=0;for(;;){aw=aC.codes[aC.lencode+b(aB,aC.lenbits)];if(aw.bits<=aB.bits){break}if(!ag(aB)){break inf_leave}}if(aw.op&&(aw.op&240)==0){ax=aw;for(;;){aw=aC.codes[aC.lencode+ax.val+(b(aB,ax.bits+ax.op)>>>ax.bits)];if(ax.bits+aw.bits<=aB.bits){break}if(!ag(aB)){break inf_leave}}w(aB,ax.bits);aC.back+=ax.bits}w(aB,aw.bits);aC.back+=aw.bits;aC.length=aw.val;if(aw.op==0){aC.mode=Y;break}if(aw.op&32){aC.back=-1;aC.mode=an;break}if(aw.op&64){aD.msg="invalid literal/length code";aC.mode=a;break}aC.extra=aw.op&15;aC.mode=T;case T:if(aC.extra){if(!ad(aB,aC.extra)){break inf_leave}aC.length+=b(aB,aC.extra);w(aB,aC.extra);aC.back+=aC.extra}aC.was=aC.length;aC.mode=r;case r:for(;;){aw=aC.codes[aC.distcode+b(aB,aC.distbits)];if(aw.bits<=aB.bits){break}if(!ag(aB)){break inf_leave}}if((aw.op&240)==0){ax=aw;for(;;){aw=aC.codes[aC.distcode+ax.val+(b(aB,ax.bits+ax.op)>>>ax.bits)];if((ax.bits+aw.bits)<=aB.bits){break}if(!ag(aB)){break inf_leave}}w(aB,ax.bits);aC.back+=ax.bits}w(aB,aw.bits);aC.back+=aw.bits;if(aw.op&64){aD.msg="invalid distance code";aC.mode=a;break}aC.offset=aw.val;aC.extra=aw.op&15;aC.mode=s;case s:if(aC.extra){if(!ad(aB,aC.extra)){break inf_leave}aC.offset+=b(aB,aC.extra);w(aB,aC.extra);aC.back+=aC.extra}aC.mode=aa;case aa:if(aB.left==0){break inf_leave}ar=az-aB.left;if(aC.offset>ar){ar=aC.offset-ar;if(ar>aC.whave){if(aC.sane){aD.msg="invalid distance too far back";aC.mode=a;break}}if(ar>aC.wnext){ar-=aC.wnext;av=aC.wsize-ar;au=-1}else{av=aC.wnext-ar;au=-1}if(ar>aC.length){ar=aC.length}}else{av=-1;au=aD.next_out-aC.offset;ar=aC.length}if(ar>aB.left){ar=aB.left}aB.left-=ar;aC.length-=ar;if(av>=0){aD.output_data+=aC.window.substring(av,av+ar);aD.next_out+=ar;ar=0}else{aD.next_out+=ar;do{aD.output_data+=aD.output_data.charAt(au++)}while(--ar)}if(aC.length==0){aC.mode=R}break;case Y:if(aB.left==0){break inf_leave}aD.output_data+=String.fromCharCode(aC.length);aD.next_out++;aB.left--;aC.mode=R;break;case d:if(aC.wrap){if(!ad(aB,32)){break inf_leave}az-=aB.left;aD.total_out+=az;aC.total+=az;if(az){aD.adler=aC.check=aD.checksum_function(aC.check,aD.output_data,aD.output_data.length-az,az)}az=aB.left;if((aC.flags?aB.hold:ai(aB.hold))!=aC.check){aD.msg="incorrect data check";aC.mode=a;break}P(aB)}aC.mode=V;case V:if(aC.wrap&&aC.flags){if(!ad(aB,32)){break inf_leave}if(aB.hold!=(aC.total&4294967295)){aD.msg="incorrect length check";aC.mode=a;break}P(aB)}aC.mode=v;case v:aA=ZLIB.Z_STREAM_END;break inf_leave;case a:aA=ZLIB.Z_DATA_ERROR;break inf_leave;case ab:return ZLIB.Z_MEM_ERROR;case ak:default:return ZLIB.Z_STREAM_ERROR}}inf_leave:ah(aB);if(aC.wsize||(az!=aD.avail_out&&aC.mode<a&&(aC.mode<d||at!=ZLIB.Z_FINISH))){if(ap(aD)){aC.mode=ab;return ZLIB.Z_MEM_ERROR}}aq-=aD.avail_in;az-=aD.avail_out;aD.total_in+=aq;aD.total_out+=az;aC.total+=az;if(aC.wrap&&az){aD.adler=aC.check=aD.checksum_function(aC.check,aD.output_data,0,aD.output_data.length)}aD.data_type=aC.bits+(aC.last?64:0)+(aC.mode==an?128:0)+(aC.mode==S||aC.mode==l?256:0);if(((aq==0&&az==0)||at==ZLIB.Z_FINISH)&&aA==ZLIB.Z_OK){aA=ZLIB.Z_BUF_ERROR}return aA};ZLIB.inflateEnd=function(ar){var aq;if(!ar||!ar.state){return ZLIB.Z_STREAM_ERROR}aq=ar.state;aq.window=null;ar.state=null;return ZLIB.Z_OK};ZLIB.z_stream.prototype.inflate=function(au,av){var at;var aq;var ar=16384;this.input_data=au;this.next_in=E(av,"next_in",0);this.avail_in=E(av,"avail_in",au.length-this.next_in);at=E(av,"flush",ZLIB.Z_SYNC_FLUSH);aq=E(av,"avail_out",-1);var aw="";do{this.avail_out=(aq>=0?aq:ar);this.output_data="";this.next_out=0;this.error=ZLIB.inflate(this,at);if(aq>=0){return this.output_data}aw+=this.output_data;if(this.avail_out>0){break}}while(this.error==ZLIB.Z_OK);return aw};ZLIB.z_stream.prototype.inflateReset=function(aq){return ZLIB.inflateReset(this,aq)}}());if(typeof ZLIB==="undefined"){alert("ZLIB is not defined. SRC zlib.js before zlib-adler32.js")}(function(){var c=65521;var d=5552;function b(e,g,k,h){var l;var j;l=(e>>>16)&65535;e&=65535;if(h==1){e+=g.charCodeAt(k)&255;if(e>=c){e-=c}l+=e;if(l>=c){l-=c}return e|(l<<16)}if(g===null){return 1}if(h<16){while(h--){e+=g.charCodeAt(k++)&255;l+=e}if(e>=c){e-=c}l%=c;return e|(l<<16)}while(h>=d){h-=d;j=d>>4;do{e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e}while(--j);e%=c;l%=c}if(h){while(h>=16){h-=16;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e}while(h--){e+=g.charCodeAt(k++)&255;l+=e}e%=c;l%=c}return e|(l<<16)}function a(e,g,k,h){var l;var j;l=(e>>>16)&65535;e&=65535;if(h==1){e+=g[k];if(e>=c){e-=c}l+=e;if(l>=c){l-=c}return e|(l<<16)}if(g===null){return 1}if(h<16){while(h--){e+=g[k++];l+=e}if(e>=c){e-=c}l%=c;return e|(l<<16)}while(h>=d){h-=d;j=d>>4;do{e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e}while(--j);e%=c;l%=c}if(h){while(h>=16){h-=16;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e}while(h--){e+=g[k++];l+=e}e%=c;l%=c}return e|(l<<16)}ZLIB.adler32=function(e,g,j,h){if(typeof g==="string"){return b(e,g,j,h)}else{return a(e,g,j,h)}};ZLIB.adler32_combine=function(e,g,h){var k;var l;var j;if(h<0){return 4294967295}h%=c;j=h;k=e&65535;l=j*k;l%=c;k+=(g&65535)+c-1;l+=((e>>16)&65535)+((g>>16)&65535)+c-j;if(k>=c){k-=c}if(k>=c){k-=c}if(l>=(c<<1)){l-=(c<<1)}if(l>=c){l-=c}return k|(l<<16)}}());if(typeof ZLIB==="undefined"){alert("ZLIB is not defined. SRC zlib.js before zlib-crc32.js")}(function(){var a=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918000,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];function c(j,h,l,k){if(h==null){return 0}j=j^4294967295;while(k>=8){j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);k-=8}if(k){do{j=a[(j^h.charCodeAt(l++))&255]^(j>>>8)}while(--k)}return j^4294967295}function b(j,h,l,k){if(h==null){return 0}j=j^4294967295;while(k>=8){j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);k-=8}if(k){do{j=a[(j^h[l++])&255]^(j>>>8)}while(--k)}return j^4294967295}ZLIB.crc32=function(j,h,l,k){if(typeof h==="string"){return c(j,h,l,k)}else{return b(j,h,l,k)}};var d=32;function g(h,l){var k;var j=0;k=0;while(l){if(l&1){k^=h[j]}l>>=1;j++}return k}function e(k,h){var j;for(j=0;j<d;j++){k[j]=g(h,h[j])}}ZLIB.crc32_combine=function(h,j,l){var m;var p;var k;var o;if(l<=0){return h}k=new Array(d);o=new Array(d);o[0]=3988292384;p=1;for(m=1;m<d;m++){o[m]=p;p<<=1}e(k,o);e(o,k);do{e(k,o);if(l&1){h=g(k,h)}l>>=1;if(l==0){break}e(o,k);if(l&1){h=g(o,h)}l>>=1}while(l!=0);h^=j;return h}}());var CreateAmtRedirect=function(e,a){var g={};g.m=e;e.parent=g;g.authCookie=a;g.State=0;g.socket=null;g.host=null;g.port=0;g.user=null;g.pass=null;g.authuri="/RedirectionService";g.tlsv1only=0;g.inDataCount=0;g.connectstate=0;g.protocol=e.protocol;g.debugmode=0;g.amtaccumulator="";g.amtsequence=1;g.amtkeepalivetimer=null;g.onStateChanged=null;g.Start=function(h,k,n,j,l){g.host=h;g.port=k;g.user=n;g.pass=j;g.connectstate=0;g.inDataCount=0;var m=window.location.protocol.replace("http","ws")+"//"+window.location.host+window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/"))+"/webrelay.ashx?p=2&host="+h+"&port="+k+"&tls="+l+((n=="*")?"&serverauth=1":"")+((typeof j==="undefined")?("&serverauth=1&user="+n):"");if((a!=null)&&(a!="")){m+="&auth="+a}g.socket=new WebSocket(m);g.socket.onopen=g.xxOnSocketConnected;g.socket.onmessage=g.xxOnMessage;g.socket.onclose=g.xxOnSocketClosed;g.xxStateChange(1)};g.xxOnSocketConnected=function(){if(g.debugmode==1){console.log("onSocketConnected")}g.xxStateChange(2);if(g.protocol==1){g.xxSend(g.RedirectStartSol)}if(g.protocol==2){g.xxSend(g.RedirectStartKvm)}if(g.protocol==3){g.xxSend(g.RedirectStartIder)}};var b=new FileReader();var d=false,c=[];if(b.readAsBinaryString){b.onload=function(h){g.xxOnSocketData(h.target.result);if(c.length==0){d=false}else{b.readAsBinaryString(new Blob([c.shift()]))}}}else{if(b.readAsArrayBuffer){b.onloadend=function(h){g.xxOnSocketData(h.target.result);if(c.length==0){d=false}else{b.readAsArrayBuffer(c.shift())}}}}g.xxOnMessage=function(k){g.inDataCount++;if(typeof k.data=="object"){if(d==true){c.push(k.data);return}if(b.readAsBinaryString){d=true;b.readAsBinaryString(new Blob([k.data]))}else{if(f.readAsArrayBuffer){d=true;b.readAsArrayBuffer(k.data)}else{var h="",j=new Uint8Array(k.data),m=j.byteLength;for(var l=0;l<m;l++){h+=String.fromCharCode(j[l])}g.xxOnSocketData(h)}}}else{g.xxOnSocketData(k.data)}};g.xxOnSocketData=function(t){if(!t||g.connectstate==-1){return}if(typeof t==="object"){var m="";var o=new Uint8Array(t);var y=o.byteLength;for(var x=0;x<y;x++){m+=String.fromCharCode(o[x])}t=m}else{if(typeof t!=="string"){return}}if((g.protocol==2||g.protocol==3)&&g.connectstate==1){return g.m.ProcessData(t)}g.amtaccumulator+=t;while(g.amtaccumulator.length>=1){var p=0;switch(g.amtaccumulator.charCodeAt(0)){case 17:if(g.amtaccumulator.length<4){return}var L=g.amtaccumulator.charCodeAt(1);switch(L){case 0:if(g.amtaccumulator.length<13){return}var C=g.amtaccumulator.charCodeAt(12);if(g.amtaccumulator.length<13+C){return}g.xxSend(String.fromCharCode(19,0,0,0,0,0,0,0,0));p=(13+C);break;default:g.Stop(1);break}break;case 20:if(g.amtaccumulator.length<9){return}var k=ReadIntX(g.amtaccumulator,5);if(g.amtaccumulator.length<9+k){return}var K=g.amtaccumulator.charCodeAt(1);var l=g.amtaccumulator.charCodeAt(4);var h=[];for(x=0;x<k;x++){h.push(g.amtaccumulator.charCodeAt(9+x))}var j=g.amtaccumulator.substring(9,9+k);p=9+k;if(l==0){if(h.indexOf(4)>=0){g.xxSend(String.fromCharCode(19,0,0,0,4)+IntToStrX(g.user.length+g.authuri.length+8)+String.fromCharCode(g.user.length)+g.user+String.fromCharCode(0,0)+String.fromCharCode(g.authuri.length)+g.authuri+String.fromCharCode(0,0,0,0))}else{if(h.indexOf(3)>=0){g.xxSend(String.fromCharCode(19,0,0,0,3)+IntToStrX(g.user.length+g.authuri.length+7)+String.fromCharCode(g.user.length)+g.user+String.fromCharCode(0,0)+String.fromCharCode(g.authuri.length)+g.authuri+String.fromCharCode(0,0,0))}else{if(h.indexOf(1)>=0){g.xxSend(String.fromCharCode(19,0,0,0,1)+IntToStrX(g.user.length+g.pass.length+2)+String.fromCharCode(g.user.length)+g.user+String.fromCharCode(g.pass.length)+g.pass)}else{g.Stop(2)}}}}else{if((l==3||l==4)&&K==1){var s=0;var G=j.charCodeAt(s);var F=j.substring(s+1,s+1+G);s+=(G+1);var B=j.charCodeAt(s);var A=j.substring(s+1,s+1+B);s+=(B+1);var E=0;var D=null;var q=g.xxRandomNonce(32);var J="00000002";var v="";if(l==4){E=j.charCodeAt(s);D=j.substring(s+1,s+1+E);s+=(E+1);v=J+":"+q+":"+D+":"}var u=hex_md5(hex_md5(g.user+":"+F+":"+g.pass)+":"+A+":"+v+hex_md5("POST:"+g.authuri));var M=g.user.length+F.length+A.length+g.authuri.length+q.length+J.length+u.length+7;if(l==4){M+=(D.length+1)}var n=String.fromCharCode(19,0,0,0,l)+IntToStrX(M)+String.fromCharCode(g.user.length)+g.user+String.fromCharCode(F.length)+F+String.fromCharCode(A.length)+A+String.fromCharCode(g.authuri.length)+g.authuri+String.fromCharCode(q.length)+q+String.fromCharCode(J.length)+J+String.fromCharCode(u.length)+u;if(l==4){n+=(String.fromCharCode(D.length)+D)}g.xxSend(n)}else{if(K==0){if(g.protocol==1){var z=10000;var O=100;var N=0;var I=10000;var H=100;var w=0;g.xxSend(String.fromCharCode(32,0,0,0)+IntToStrX(g.amtsequence++)+ShortToStrX(z)+ShortToStrX(O)+ShortToStrX(N)+ShortToStrX(I)+ShortToStrX(H)+ShortToStrX(w)+IntToStrX(0))}if(g.protocol==2){g.xxSend(String.fromCharCode(64,0,0,0,0,0,0,0))}if(g.protocol==3){g.connectstate=1;g.xxStateChange(3)}}else{g.Stop(3)}}}break;case 33:if(g.amtaccumulator.length<23){break}p=23;g.xxSend(String.fromCharCode(39,0,0,0)+IntToStrX(g.amtsequence++)+String.fromCharCode(0,0,27,0,0,0));if(g.protocol==1){g.amtkeepalivetimer=setInterval(g.xxSendAmtKeepAlive,2000)}g.connectstate=1;g.xxStateChange(3);break;case 41:if(g.amtaccumulator.length<10){break}p=10;break;case 42:if(g.amtaccumulator.length<10){break}var r=(10+((g.amtaccumulator.charCodeAt(9)&255)<<8)+(g.amtaccumulator.charCodeAt(8)&255));if(g.amtaccumulator.length<r){break}g.m.ProcessData(g.amtaccumulator.substring(10,r));p=r;break;case 43:if(g.amtaccumulator.length<8){break}p=8;break;case 65:if(g.amtaccumulator.length<8){break}g.connectstate=1;g.m.Start();if(g.amtaccumulator.length>8){g.m.ProcessData(g.amtaccumulator.substring(8))}p=g.amtaccumulator.length;break;default:console.log("Unknown Intel AMT command: "+g.amtaccumulator.charCodeAt(0)+" acclen="+g.amtaccumulator.length);g.Stop(4);return}if(p==0){return}g.amtaccumulator=g.amtaccumulator.substring(p)}};g.xxSend=function(k){if(g.socket!=null&&g.socket.readyState==WebSocket.OPEN){if(g.debugmode==1){console.log("Send",k)}var h=new Uint8Array(k.length);for(var j=0;j<k.length;++j){h[j]=k.charCodeAt(j)}g.socket.send(h.buffer)}};g.send=function(h){if(g.socket==null||g.connectstate!=1){return}if(g.protocol==1){g.xxSend(String.fromCharCode(40,0,0,0)+IntToStrX(g.amtsequence++)+ShortToStrX(h.length)+h)}else{g.xxSend(h)}};g.xxSendAmtKeepAlive=function(){if(g.socket==null){return}g.xxSend(String.fromCharCode(43,0,0,0)+IntToStrX(g.amtsequence++))};g.xxRandomNonceX="abcdef0123456789";g.xxRandomNonce=function(j){var k="";for(var h=0;h<j;h++){k+=g.xxRandomNonceX.charAt(Math.floor(Math.random()*g.xxRandomNonceX.length))}return k};g.xxOnSocketClosed=function(){if(g.debugmode==1){console.log("onSocketClosed")}if((g.inDataCount==0)&&(g.tlsv1only==0)){g.tlsv1only=1;g.socket=new WebSocket(window.location.protocol.replace("http","ws")+"//"+window.location.host+window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/"))+"/webrelay.ashx?p=2&host="+g.host+"&port="+g.port+"&tls="+g.tls+"&tls1only=1"+((g.user=="*")?"&serverauth=1":"")+((typeof pass==="undefined")?("&serverauth=1&user="+g.user):""));g.socket.onopen=g.xxOnSocketConnected;g.socket.onmessage=g.xxOnMessage;g.socket.onclose=g.xxOnSocketClosed}else{g.Stop(5)}};g.xxStateChange=function(h){if(g.State==h){return}g.State=h;g.m.xxStateChange(g.State);if(g.onStateChanged!=null){g.onStateChanged(g,g.State)}};g.Stop=function(h){if(g.debugmode==1){console.log("onSocketStop",h)}g.xxStateChange(0);g.connectstate=-1;g.amtaccumulator="";if(g.socket!=null){g.socket.close();g.socket=null}if(g.amtkeepalivetimer!=null){clearInterval(g.amtkeepalivetimer);g.amtkeepalivetimer=null}};g.RedirectStartSol=String.fromCharCode(16,0,0,0,83,79,76,32);g.RedirectStartKvm=String.fromCharCode(16,1,0,0,75,86,77,82);g.RedirectStartIder=String.fromCharCode(16,0,0,0,73,68,69,82);return g};var CreateWsmanComm=function(l,o,q,n,p){var m={};m.PendingAjax=[];m.ActiveAjaxCount=0;m.MaxActiveAjaxCount=1;m.FailAllError=0;m.challengeParams=null;m.noncecounter=1;m.authcounter=0;m.socket=null;m.socketState=0;m.host=l;m.port=o;m.user=q;m.pass=n;m.tls=p;m.tlsv1only=1;m.cnonce=Math.random().toString(36).substring(7);m.PerformAjax=function(t,s,v,u,w,r){if(m.ActiveAjaxCount<m.MaxActiveAjaxCount&&m.PendingAjax.length==0){m.PerformAjaxEx(t,s,v,w,r)}else{if(u==1){m.PendingAjax.unshift([t,s,v,w,r])}else{m.PendingAjax.push([t,s,v,w,r])}}};m.PerformNextAjax=function(){if(m.ActiveAjaxCount>=m.MaxActiveAjaxCount||m.PendingAjax.length==0){return}var r=m.PendingAjax.shift();m.PerformAjaxEx(r[0],r[1],r[2],r[3],r[4]);m.PerformNextAjax()};m.PerformAjaxEx=function(t,s,u,v,r){if(m.FailAllError!=0){m.gotNextMessagesError({status:m.FailAllError},"error",null,[t,s,u,v,r]);return}if(!t){t=""}m.ActiveAjaxCount++;return m.PerformAjaxExNodeJS(t,s,u,v,r)};m.pendingAjaxCall=[];m.PerformAjaxExNodeJS=function(t,s,u,v,r){m.PerformAjaxExNodeJS2(t,s,u,v,r,3)};m.PerformAjaxExNodeJS2=function(t,s,v,w,r,u){if(u<=0||m.FailAllError!=0){m.ActiveAjaxCount--;if(m.FailAllError!=999){m.gotNextMessages(null,"error",{status:((m.FailAllError==0)?408:m.FailAllError)},[t,s,v,w,r])}m.PerformNextAjax();return}m.pendingAjaxCall.push([t,s,v,w,r,u]);if(m.socketState==0){m.xxConnectHttpSocket()}else{if(m.socketState==2){m.sendRequest(t,w,r)}}};m.sendRequest=function(t,v,r){v=v?v:"/wsman";r=r?r:"POST";var s=r+" "+v+" HTTP/1.1\r\n";if(m.challengeParams!=null){var u=hex_md5(hex_md5(m.user+":"+m.challengeParams.realm+":"+m.pass)+":"+m.challengeParams.nonce+":"+m.noncecounter+":"+m.cnonce+":"+m.challengeParams.qop+":"+hex_md5(r+":"+v));s+="Authorization: "+m.renderDigest({username:m.user,realm:m.challengeParams.realm,nonce:m.challengeParams.nonce,uri:v,qop:m.challengeParams.qop,response:u,nc:m.noncecounter++,cnonce:m.cnonce})+"\r\n"}s+="Host: "+m.host+":"+m.port+"\r\nTransfer-Encoding: chunked\r\n\r\n"+t.length.toString(16).toUpperCase()+"\r\n"+t+"\r\n0\r\n\r\n";g(s)};m.parseDigest=function(r){var s=r.substring(7).split(",");for(i in s){s[i]=s[i].trim()}return s.reduce(function(t,v){var u=v.split("=");t[u[0]]=u[1].replace(/"/g,"");return t},{})};m.renderDigest=function(r){var s=[];for(i in r){s.push(i)}return"Digest "+s.reduce(function(u,t){return u+","+t+'="'+r[t]+'"'},"").substring(1)};m.xxConnectHttpSocket=function(){m.socketParseState=0;m.socketAccumulator="";m.socketHeader=null;m.socketData="";m.socketState=1;console.log(m.tlsv1only);m.socket=new WebSocket(window.location.protocol.replace("http","ws")+"//"+window.location.host+window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/"))+"/webrelay.ashx?p=1&host="+m.host+"&port="+m.port+"&tls="+m.tls+"&tlsv1only="+m.tlsv1only+((q=="*")?"&serverauth=1":"")+((typeof n==="undefined")?("&serverauth=1&user="+q):""));m.socket.onopen=c;m.socket.onmessage=a;m.socket.onclose=b};function c(){m.socketState=2;for(i in m.pendingAjaxCall){m.sendRequest(m.pendingAjaxCall[i][0],m.pendingAjaxCall[i][3],m.pendingAjaxCall[i][4])}}var h=new FileReader();var k=false,j=[];if(h.readAsBinaryString){h.onload=function(r){d(r.target.result);if(j.length==0){k=false}else{h.readAsBinaryString(new Blob([j.shift()]))}}}else{if(h.readAsArrayBuffer){h.onloadend=function(r){d(r.target.result);if(j.length==0){k=false}else{h.readAsArrayBuffer(j.shift())}}}}function a(t){if(typeof t.data=="object"){if(k==true){j.push(t.data);return}if(h.readAsBinaryString){k=true;h.readAsBinaryString(new Blob([t.data]))}else{if(h.readAsArrayBuffer){k=true;h.readAsArrayBuffer(t.data)}else{var r="",s=new Uint8Array(t.data),v=s.byteLength;for(var u=0;u<v;u++){r+=String.fromCharCode(s[u])}d(r)}}}else{d(t.data)}}function d(v){if(typeof v==="object"){var r="",s=new Uint8Array(v),y=s.byteLength;for(var x=0;x<y;x++){r+=String.fromCharCode(s[x])}v=r}else{if(typeof v!=="string"){return}}m.socketAccumulator+=v;while(true){if(m.socketParseState==0){var w=m.socketAccumulator.indexOf("\r\n\r\n");if(w<0){return}m.socketHeader=m.socketAccumulator.substring(0,w).split("\r\n");m.socketAccumulator=m.socketAccumulator.substring(w+4);m.socketParseState=1;m.socketData="";m.socketXHeader={Directive:m.socketHeader[0].split(" ")};for(x in m.socketHeader){if(x!=0){var z=m.socketHeader[x].indexOf(":");m.socketXHeader[m.socketHeader[x].substring(0,z).toLowerCase()]=m.socketHeader[x].substring(z+2)}}}if(m.socketParseState==1){var u=-1;if((m.socketXHeader.connection!=undefined)&&(m.socketXHeader.connection.toLowerCase()=="close")&&((m.socketXHeader["transfer-encoding"]==undefined)||(m.socketXHeader["transfer-encoding"].toLowerCase()!="chunked"))){u=0}else{if(m.socketXHeader["content-length"]!=undefined){u=parseInt(m.socketXHeader["content-length"]);if(m.socketAccumulator.length<u){return}var v=m.socketAccumulator.substring(0,u);m.socketAccumulator=m.socketAccumulator.substring(u);m.socketData=v;u=0}else{var t=m.socketAccumulator.indexOf("\r\n");if(t<0){return}u=parseInt(m.socketAccumulator.substring(0,t),16);if(isNaN(u)){if(m.websocket){m.websocket.close()}return}if(m.socketAccumulator.length<t+2+u+2){return}var v=m.socketAccumulator.substring(t+2,t+2+u);m.socketAccumulator=m.socketAccumulator.substring(t+2+u+2);m.socketData+=v}}if(u==0){e(m.socketXHeader,m.socketData);m.socketParseState=0;m.socketHeader=null}}}}function e(u,t){var w=parseInt(u.Directive[1]);if(isNaN(w)){w=602}if(w==401&&++(m.authcounter)<3){m.challengeParams=m.parseDigest(u["www-authenticate"])}else{var v=m.pendingAjaxCall.shift();m.authcounter=0;m.ActiveAjaxCount--;m.gotNextMessages(t,"success",{status:w},v);m.PerformNextAjax()}}function b(s){m.socketState=0;if(m.socket!=null){m.socket.close();m.socket=null}if(m.pendingAjaxCall.length>0){var t=m.pendingAjaxCall.shift();var u=t[5];m.PerformAjaxExNodeJS2(t[0],t[1],t[2],t[3],t[4],--u)}}function g(u){if(m.socketState==2&&m.socket!=null&&m.socket.readyState==WebSocket.OPEN){var r=new Uint8Array(u.length);for(var t=0;t<u.length;++t){r[t]=u.charCodeAt(t)}try{m.socket.send(r.buffer)}catch(s){}}}m.gotNextMessages=function(s,u,t,r){if(m.FailAllError==999){return}if(m.FailAllError!=0){r[1](null,m.FailAllError,r[2]);return}if(t.status!=200){r[1](null,t.status,r[2]);return}r[1](s,200,r[2])};m.gotNextMessagesError=function(t,u,s,r){if(m.FailAllError==999){return}if(m.FailAllError!=0){r[1](null,m.FailAllError,r[2]);return}r[1](m,null,{Header:{HttpError:t.status}},t.status,r[2])};m.CancelAllQueries=function(r){while(m.PendingAjax.length>0){var t=m.PendingAjax.shift();t[1](null,r,t[2])}if(m.websocket!=null){m.websocket.close();m.websocket=null;m.socketState=0}};return m};var CreateAgentRedirect=function(e,g,k,a){var h={};h.m=g;g.parent=h;h.meshserver=e;h.authCookie=a;h.State=0;h.nodeid=null;h.socket=null;h.connectstate=-1;h.tunnelid=Math.random().toString(36).substring(2);h.protocol=g.protocol;h.onStateChanged=null;h.ctrlMsgAllowed=true;h.attemptWebRTC=false;h.webRtcActive=false;h.webSwitchOk=false;h.webchannel=null;h.webrtc=null;h.debugmode=0;h.Start=function(l){var n,m=window.location.protocol.replace("http","ws")+"//"+window.location.host+window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/"))+"/meshrelay.ashx?id="+h.tunnelid;if((a!=null)&&(a!="")){m+="&auth="+a}h.nodeid=l;h.connectstate=0;h.socket=new WebSocket(m);h.socket.onopen=h.xxOnSocketConnected;h.socket.onmessage=h.xxOnMessage;h.socket.onerror=function(o){};h.socket.onclose=h.xxOnSocketClosed;h.xxStateChange(1);h.meshserver.send({action:"msg",type:"tunnel",nodeid:h.nodeid,value:"*/meshrelay.ashx?id="+h.tunnelid})};h.xxOnSocketConnected=function(){if(h.debugmode==1){console.log("onSocketConnected")}h.xxStateChange(2)};h.xxOnControlCommand=function(n){var l;try{l=JSON.parse(n)}catch(m){return}if(l.ctrlChannel!="102938"){h.xxOnSocketData(n);return}if(h.webrtc!=null){if(l.type=="answer"){h.webrtc.setRemoteDescription(new RTCSessionDescription(l),function(){},h.xxCloseWebRTC)}else{if(l.type=="webrtc0"){h.webSwitchOk=true;j()}else{if(l.type=="webrtc1"){h.sendCtrlMsg('{"ctrlChannel":"102938","type":"webrtc2"}')}else{if(l.type=="webrtc2"){}}}}}};h.sendCtrlMsg=function(m){if(h.ctrlMsgAllowed==true){if((typeof args!="undefined")&&args.redirtrace){console.log("RedirSend",typeof m,m)}try{h.socket.send(m)}catch(l){}}};function j(){if((h.webSwitchOk==true)&&(h.webRtcActive==true)){h.sendCtrlMsg('{"ctrlChannel":"102938","type":"webrtc0"}');h.sendCtrlMsg('{"ctrlChannel":"102938","type":"webrtc1"}');if(h.onStateChanged!=null){h.onStateChanged(h,h.State)}}}h.xxOnMessage=function(o){if(h.State<3){if(o.data=="c"){try{h.socket.send(h.protocol)}catch(p){}h.xxStateChange(3);if(h.attemptWebRTC==true){var n=null;if(typeof RTCPeerConnection!=="undefined"){h.webrtc=new RTCPeerConnection(n)}else{if(typeof webkitRTCPeerConnection!=="undefined"){h.webrtc=new webkitRTCPeerConnection(n)}}if(h.webrtc!=null){h.webchannel=h.webrtc.createDataChannel("DataChannel",{});h.webchannel.onmessage=h.xxOnMessage;h.webchannel.onopen=function(){h.webRtcActive=true;j()};h.webchannel.onclose=function(s){if(h.webRtcActive){h.Stop()}};h.webrtc.onicecandidate=function(s){if(s.candidate==null){try{h.socket.send(JSON.stringify(h.webrtcoffer))}catch(t){}}else{h.webrtcoffer.sdp+=("a="+s.candidate.candidate+"\r\n")}};h.webrtc.oniceconnectionstatechange=function(){if(h.webrtc!=null){if(h.webrtc.iceConnectionState=="disconnected"){if(h.webRtcActive==true){h.Stop()}else{h.xxCloseWebRTC()}}else{if(h.webrtc.iceConnectionState=="failed"){h.xxCloseWebRTC()}}}};h.webrtc.createOffer(function(s){h.webrtcoffer=s;h.webrtc.setLocalDescription(s,function(){},h.xxCloseWebRTC)},h.xxCloseWebRTC,{mandatory:{OfferToReceiveAudio:false,OfferToReceiveVideo:false}})}}return}}if(typeof o.data=="string"){h.xxOnControlCommand(o.data);return}if(typeof o.data=="object"){if(d==true){c.push(o.data);return}if(b.readAsBinaryString){d=true;b.readAsBinaryString(new Blob([o.data]))}else{if(b.readAsArrayBuffer){d=true;b.readAsArrayBuffer(o.data)}else{var l="",m=new Uint8Array(o.data),r=m.byteLength;for(var q=0;q<r;q++){l+=String.fromCharCode(m[q])}h.xxOnSocketData(l)}}}else{h.xxOnSocketData(o.data)}};var b=new FileReader();var d=false,c=[];if(b.readAsBinaryString){b.onload=function(l){h.xxOnSocketData(l.target.result);if(c.length==0){d=false}else{b.readAsBinaryString(new Blob([c.shift()]))}}}else{if(b.readAsArrayBuffer){b.onloadend=function(l){h.xxOnSocketData(l.target.result);if(c.length==0){d=false}else{b.readAsArrayBuffer(c.shift())}}}}h.xxOnSocketData=function(n){if(!n||h.connectstate==-1){return}if(typeof n==="object"){var l="",m=new Uint8Array(n),p=m.byteLength;for(var o=0;o<p;o++){l+=String.fromCharCode(m[o])}n=l}else{if(typeof n!=="string"){return}}if((typeof args!="undefined")&&args.redirtrace){console.log("RedirRecv",typeof n,n.length,n)}return h.m.ProcessData(n)};h.sendText=function(l){if(typeof l!="string"){l=JSON.stringify(l)}h.send(encode_utf8(l))};h.send=function(p){if((typeof args!="undefined")&&args.redirtrace){console.log("RedirSend",typeof p,p.length,p)}try{if(h.socket!=null&&h.socket.readyState==WebSocket.OPEN){if(typeof p=="string"){if(h.debugmode==1){var l=new Uint8Array(p.length),m=[];for(var o=0;o<p.length;++o){l[o]=p.charCodeAt(o);m.push(p.charCodeAt(o))}if(h.webRtcActive==true){h.webchannel.send(l.buffer)}else{h.socket.send(l.buffer)}}else{var l=new Uint8Array(p.length);for(var o=0;o<p.length;++o){l[o]=p.charCodeAt(o)}if(h.webRtcActive==true){h.webchannel.send(l.buffer)}else{h.socket.send(l.buffer)}}}else{if(h.webRtcActive==true){h.webchannel.send(p)}else{h.socket.send(p)}}}}catch(n){}};h.xxOnSocketClosed=function(){h.Stop(1)};h.xxStateChange=function(l){if(h.State==l){return}h.State=l;h.m.xxStateChange(h.State);if(h.onStateChanged!=null){h.onStateChanged(h,h.State)}};h.xxCloseWebRTC=function(){if(h.webchannel!=null){try{h.webchannel.close()}catch(l){}h.webchannel=null}if(h.webrtc!=null){try{h.webrtc.close()}catch(l){}h.webrtc=null}h.webRtcActive=false};h.Stop=function(m){if(h.debugmode==1){console.log("stop",m)}h.xxCloseWebRTC();h.connectstate=-1;if(h.socket!=null){try{if(h.socket.readyState==1){h.sendCtrlMsg('{"ctrlChannel":"102938","type":"close"}');h.socket.close()}}catch(l){}h.socket=null}h.xxStateChange(0)};return h};var CreateKvmDataChannel=function(h,e,d){var g={};g.m=e;e.parent=g;g.webchannel=h;g.State=0;g.protocol=e.protocol;g.onStateChanged=null;g.onControlMsg=null;g.debugmode=0;g.keepalive=d;g.rtcKeepAlive=null;g.Start=function(){if(g.debugmode==1){console.log("start")}g.xxStateChange(3);g.webchannel.onmessage=g.xxOnMessage;g.rtcKeepAlive=setInterval(g.xxSendRtcKeepAlive,30000)};var a=new FileReader();var c=false,b=[];if(a.readAsBinaryString){a.onload=function(j){g.xxOnSocketData(j.target.result);if(b.length==0){c=false}else{a.readAsBinaryString(new Blob([b.shift()]))}}}else{if(a.readAsArrayBuffer){a.onloadend=function(j){g.xxOnSocketData(j.target.result);if(b.length==0){c=false}else{a.readAsArrayBuffer(b.shift())}}}}g.xxOnMessage=function(l){if(typeof l.data=="string"){if(g.onControlMsg!=null){g.onControlMsg(l.data)}return}if(typeof l.data=="object"){if(c==true){b.push(l.data);return}if(a.readAsBinaryString){c=true;a.readAsBinaryString(new Blob([l.data]))}else{if(f.readAsArrayBuffer){c=true;a.readAsArrayBuffer(l.data)}else{var j="",k=new Uint8Array(l.data),n=k.byteLength;for(var m=0;m<n;m++){j+=String.fromCharCode(k[m])}g.xxOnSocketData(j)}}}else{g.xxOnSocketData(l.data)}};g.xxOnSocketData=function(l){if(!l){return}if(typeof l==="object"){var j="",k=new Uint8Array(l),n=k.byteLength;for(var m=0;m<n;m++){j+=String.fromCharCode(k[m])}l=j}else{if(typeof l!=="string"){return}}return g.m.ProcessData(l)};g.sendCtrlMsg=function(j){if(typeof j=="string"){g.webchannel.send(j);if(g.keepalive!=null){g.keepalive.sendKeepAlive()}}};g.send=function(l){if(typeof l=="string"){var j=new Uint8Array(l.length);for(var k=0;k<l.length;++k){j[k]=l.charCodeAt(k)}l=j}g.webchannel.send(l)};g.xxStateChange=function(j){if(g.State==j){return}g.State=j;g.m.xxStateChange(g.State);if(g.onStateChanged!=null){g.onStateChanged(g,g.State)}};g.Stop=function(){if(g.debugmode==1){console.log("stop")}if(g.rtcKeepAlive!=null){clearInterval(g.rtcKeepAlive);g.rtcKeepAlive=null}g.xxStateChange(0)};g.xxSendRtcKeepAlive=function(){g.sendCtrlMsg(JSON.stringify({action:"ping"}))};return g};var CreateAgentRemoteDesktop=function(a,e){var d={};d.CanvasId=a;if(typeof a==="string"){d.CanvasId=Q(a)}d.Canvas=d.CanvasId.getContext("2d");d.scrolldiv=e;d.State=0;d.PendingOperations=[];d.tilesReceived=0;d.TilesDrawn=0;d.KillDraw=0;d.ipad=false;d.tabletKeyboardVisible=false;d.LastX=0;d.LastY=0;d.touchenabled=0;d.submenuoffset=0;d.touchtimer=null;d.TouchArray={};d.connectmode=0;d.connectioncount=0;d.rotation=0;d.protocol=2;d.debugmode=0;d.firstUpKeys=[];d.stopInput=false;d.localKeyMap=true;d.sessionid=0;d.username;d.oldie=false;d.CompressionLevel=50;d.ScalingLevel=1024;d.FrameRateTimer=50;d.FirstDraw=false;d.ScreenWidth=960;d.ScreenHeight=700;d.width=960;d.height=960;d.onScreenSizeChange=null;d.onMessage=null;d.onConnectCountChanged=null;d.onDebugMessage=null;d.onTouchEnabledChanged=null;d.onDisplayinfo=null;d.accumulator=null;d.Start=function(){d.State=0;d.accumulator=null};d.Stop=function(){d.setRotation(0);d.UnGrabKeyInput();d.UnGrabMouseInput();d.touchenabled=0;if(d.onScreenSizeChange!=null){d.onScreenSizeChange(d,d.ScreenWidth,d.ScreenHeight,d.CanvasId)}d.Canvas.clearRect(0,0,d.CanvasId.width,d.CanvasId.height)};d.xxStateChange=function(g){if(d.State==g){return}d.State=g;d.CanvasId.style.cursor="default";switch(g){case 0:d.Stop();break;case 3:break}};d.send=function(g){if(d.debugmode>1){console.log("KSend("+g.length+"): "+rstr2hex(g))}d.parent.send(g)};d.ProcessPictureMsg=function(h,k,l){var j=new Image();j.xcount=d.tilesReceived++;var g=d.tilesReceived;j.src="data:image/jpeg;base64,"+btoa(h.substring(4,h.length));j.onload=function(){if(d.Canvas!=null&&d.KillDraw<g&&d.State!=0){d.PendingOperations.push([g,2,j,k,l]);while(d.DoPendingOperations()){}}};j.error=function(){console.log("DecodeTileError")}};d.DoPendingOperations=function(){if(d.PendingOperations.length==0){return false}for(var g=0;g<d.PendingOperations.length;g++){var h=d.PendingOperations[g];if(h[0]==(d.TilesDrawn+1)){if(h[1]==1){d.ProcessCopyRectMsg(h[2])}else{if(h[1]==2){d.Canvas.drawImage(h[2],d.rotX(h[3],h[4]),d.rotY(h[3],h[4]));delete h[2]}}d.PendingOperations.splice(g,1);delete h;d.TilesDrawn++;if(d.TilesDrawn==d.tilesReceived&&d.KillDraw<d.TilesDrawn){d.KillDraw=d.TilesDrawn=d.tilesReceived=0}return true}}if(d.oldie&&d.PendingOperations.length>0){d.TilesDrawn++}return false};d.ProcessCopyRectMsg=function(k){var l=((k.charCodeAt(0)&255)<<8)+(k.charCodeAt(1)&255);var m=((k.charCodeAt(2)&255)<<8)+(k.charCodeAt(3)&255);var g=((k.charCodeAt(4)&255)<<8)+(k.charCodeAt(5)&255);var h=((k.charCodeAt(6)&255)<<8)+(k.charCodeAt(7)&255);var n=((k.charCodeAt(8)&255)<<8)+(k.charCodeAt(9)&255);var j=((k.charCodeAt(10)&255)<<8)+(k.charCodeAt(11)&255);d.Canvas.drawImage(Canvas.canvas,l,m,n,j,g,h,n,j)};d.SendUnPause=function(){d.send(String.fromCharCode(0,8,0,5,0))};d.SendPause=function(){d.send(String.fromCharCode(0,8,0,5,1))};d.SendCompressionLevel=function(k,h,j,g){if(h){d.CompressionLevel=h}if(j){d.ScalingLevel=j}if(g){d.FrameRateTimer=g}d.send(String.fromCharCode(0,5,0,10,k,d.CompressionLevel)+d.shortToStr(d.ScalingLevel)+d.shortToStr(d.FrameRateTimer))};d.SendRefresh=function(){d.send(String.fromCharCode(0,6,0,4))};d.ProcessScreenMsg=function(h,g){if(d.debugmode>0){console.log("ScreenSize: "+h+" x "+g)}d.Canvas.setTransform(1,0,0,1,0,0);d.rotation=0;d.FirstDraw=true;d.ScreenWidth=d.width=h;d.ScreenHeight=d.height=g;d.KillDraw=d.tilesReceived;while(d.PendingOperations.length>0){d.PendingOperations.shift()}d.SendCompressionLevel(1);d.SendUnPause();if(d.onScreenSizeChange!=null){d.onScreenSizeChange(d,d.ScreenWidth,d.ScreenHeight,d.CanvasId)}};d.ProcessData=function(h){var g=0;while(g<h.length){g+=d.ProcessDataEx(h.substring(g))}};d.ProcessDataEx=function(r){if(d.accumulator!=null){r=d.accumulator+r;console.log("KVM using accumulated data, total size is now "+r.length+" bytes.");d.accumulator=null}if(d.debugmode>1){console.log("KRecv("+r.length+"): "+rstr2hex(r.substring(0,Math.min(r.length,40))))}if(r.length<4){return}var g=null,s=0,t=0,j=ReadShort(r,0),h=ReadShort(r,2),n=0;if((j==27)&&(h==8)){if(r.length<12){return}j=ReadShort(r,8);h=ReadInt(r,4);if((h+8)>r.length){console.log("KVM accumulator set to "+r.length+" bytes, need "+h+" bytes.");d.accumulator=r;return}r=r.substring(8);n=8}if((h!=r.length)&&(d.debugmode>0)){console.log(h,r.length,h==r.length)}if((j>=18)&&(j!=65)){console.error("Invalid KVM command "+j+" of size "+h);console.log("Invalid KVM data",r.length,rstr2hex(r.substring(0,40))+"...");return}if(h>r.length){console.log("KVM accumulator set to "+r.length+" bytes, need "+h+" bytes.");d.accumulator=r;return}if(j==3||j==4||j==7){g=r.substring(4,h);s=((g.charCodeAt(0)&255)<<8)+(g.charCodeAt(1)&255);t=((g.charCodeAt(2)&255)<<8)+(g.charCodeAt(3)&255);if(d.debugmode>0){console.log("CMD"+j+" at X="+s+" Y="+t)}}switch(j){case 3:if(d.FirstDraw){d.onResize()}d.ProcessPictureMsg(g,s,t);break;case 4:if(d.FirstDraw){d.onResize()}if(d.TilesDrawn==d.tilesReceived){d.ProcessCopyRectMsg(g)}else{d.PendingOperations.push([++tilesReceived,1,g])}break;case 7:d.ProcessScreenMsg(s,t);d.SendKeyMsgKC(d.KeyAction.UP,16);d.SendKeyMsgKC(d.KeyAction.UP,17);d.SendKeyMsgKC(d.KeyAction.UP,18);d.SendKeyMsgKC(d.KeyAction.UP,91);d.SendKeyMsgKC(d.KeyAction.UP,92);d.SendKeyMsgKC(d.KeyAction.UP,16);d.send(String.fromCharCode(0,14,0,4));break;case 11:var o=[],k=((r.charCodeAt(4)&255)<<8)+(r.charCodeAt(5)&255);if(k>0){var q=0,p=((r.charCodeAt(6+(k*2))&255)<<8)+(r.charCodeAt(7+(k*2))&255);for(var m=0;m<k;m++){var l=((r.charCodeAt(6+(m*2))&255)<<8)+(r.charCodeAt(7+(m*2))&255);if(l==65535){o.push("All Displays")}else{o.push("Display "+l)}if(l==p){q=m}}}if(d.onDisplayinfo!=null){d.onDisplayinfo(d,o,q)}break;case 12:break;case 14:d.touchenabled=1;d.TouchArray={};if(d.onTouchEnabledChanged!=null){d.onTouchEnabledChanged(d.touchenabled)}break;case 15:d.TouchArray={};break;case 16:d.connectioncount=ReadInt(r,4);if(d.onConnectCountChanged!=null){d.onConnectCountChanged(d.connectioncount,d)}break;case 17:if(d.onMessage!=null){d.onMessage(r.substring(4,h),d)}break;case 65:r=r.substring(4);if(r[0]!="."){console.log(r);alert("KVM: "+r)}else{console.log("KVM: "+r.substring(1))}break}return h+n};d.MouseButton={NONE:0,LEFT:2,RIGHT:8,MIDDLE:32};d.KeyAction={NONE:0,DOWN:1,UP:2,SCROLL:3,EXUP:4,EXDOWN:5,DBLCLICK:6};d.InputType={KEY:1,MOUSE:2,CTRLALTDEL:10,TOUCH:15};d.Alternate=0;var c={Pause:19,CapsLock:20,Space:32,Quote:222,Minus:189,NumpadMultiply:106,NumpadAdd:107,PrintScreen:44,Comma:188,NumpadSubtract:109,NumpadDecimal:110,Period:190,Slash:191,NumpadDivide:111,Semicolon:186,Equal:187,OSLeft:91,BracketLeft:219,OSRight:91,Backslash:220,BracketRight:221,ContextMenu:93,Backquote:192,NumLock:144,ScrollLock:145,Backspace:8,Tab:9,Enter:13,NumpadEnter:13,Escape:27,Delete:46,Home:36,PageUp:33,PageDown:34,ArrowLeft:37,ArrowUp:38,ArrowRight:39,ArrowDown:40,End:35,Insert:45,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,ShiftLeft:16,ShiftRight:16,ControlLeft:17,ControlRight:17,AltLeft:18,AltRight:18,MetaLeft:91,MetaRight:92,VolumeMute:181};function b(g){if(g.code.startsWith("Key")&&g.code.length==4){return g.code.charCodeAt(3)}if(g.code.startsWith("Digit")&&g.code.length==6){return g.code.charCodeAt(5)}if(g.code.startsWith("Numpad")&&g.code.length==7){return g.code.charCodeAt(6)+48}return c[g.code]}d.SendKeyMsg=function(g,h){if(g==null){return}if(!h){h=window.event}if(h.code&&(d.localKeyMap==false)){var j=b(h);if(j!=null){d.SendKeyMsgKC(g,j)}}else{var j=h.keyCode;if(j==59){j=186}d.SendKeyMsgKC(g,j)}};d.SendMessage=function(g){if(d.State==3){d.send(String.fromCharCode(0,17)+d.shortToStr(4+g.length)+g)}};d.SendKeyMsgKC=function(g,j){if(d.State!=3){return}if(typeof g=="object"){for(var h in g){d.SendKeyMsgKC(g[h][0],g[h][1])}}else{d.send(String.fromCharCode(0,d.InputType.KEY,0,6,(g-1),j))}};d.sendcad=function(){d.SendCtrlAltDelMsg()};d.SendCtrlAltDelMsg=function(){if(d.State==3){d.send(String.fromCharCode(0,d.InputType.CTRLALTDEL,0,4))}};d.SendEscKey=function(){if(d.State==3){d.send(String.fromCharCode(0,d.InputType.KEY,0,6,0,27,0,d.InputType.KEY,0,6,1,27))}};d.SendStartMsg=function(){d.SendKeyMsgKC(d.KeyAction.EXDOWN,91);d.SendKeyMsgKC(d.KeyAction.EXUP,91)};d.SendCharmsMsg=function(){d.SendKeyMsgKC(d.KeyAction.EXDOWN,91);d.SendKeyMsgKC(d.KeyAction.DOWN,67);d.SendKeyMsgKC(d.KeyAction.UP,67);d.SendKeyMsgKC(d.KeyAction.EXUP,91)};d.SendTouchMsg1=function(h,g,j,k){if(d.State==3){d.send(String.fromCharCode(0,d.InputType.TOUCH)+d.shortToStr(14)+String.fromCharCode(1,h)+d.intToStr(g)+d.shortToStr(j)+d.shortToStr(k))}};d.SendTouchMsg2=function(j,g){var m="";var h;var n="TOUCHSEND: ";for(var l in d.TouchArray){if(l==j){h=g}else{if(d.TouchArray[l].f==1){h=65536|2|4;d.TouchArray[l].f=3;n+="START"+l}else{if(d.TouchArray[l].f==2){h=262144;n+="STOP"+l}else{h=2|4|131072}}}m+=String.fromCharCode(l)+d.intToStr(h)+d.shortToStr(d.TouchArray[l].x)+d.shortToStr(d.TouchArray[l].y);if(d.TouchArray[l].f==2){delete d.TouchArray[l]}}if(d.State==3){d.send(String.fromCharCode(0,d.InputType.TOUCH)+d.shortToStr(5+m.length)+String.fromCharCode(2)+m)}if(Object.keys(d.TouchArray).length==0&&d.touchtimer!=null){clearInterval(d.touchtimer);d.touchtimer=null}};d.SendMouseMsg=function(g,k){if(d.State!=3){return}if(g!=null&&d.Canvas!=null){if(!k){var k=window.event}var n=(d.Canvas.canvas.height/d.CanvasId.clientHeight);var o=(d.Canvas.canvas.width/d.CanvasId.clientWidth);var m=d.GetPositionOfControl(d.Canvas.canvas);var p=((k.pageX-m[0])*o);var q=((k.pageY-m[1])*n);if(p>=0&&p<=d.Canvas.canvas.width&&q>=0&&q<=d.Canvas.canvas.height){var h=0;var j=0;if(g==d.KeyAction.UP||g==d.KeyAction.DOWN){if(k.which){((k.which==1)?(h=d.MouseButton.LEFT):((k.which==2)?(h=d.MouseButton.MIDDLE):(h=d.MouseButton.RIGHT)))}else{if(k.button){((k.button==0)?(h=d.MouseButton.LEFT):((k.button==1)?(h=d.MouseButton.MIDDLE):(h=d.MouseButton.RIGHT)))}}}else{if(g==d.KeyAction.SCROLL){if(k.detail){j=(-1*(k.detail*120))}else{if(k.wheelDelta){j=(k.wheelDelta*3)}}}}var l="";if(g==d.KeyAction.DBLCLICK){l=String.fromCharCode(0,d.InputType.MOUSE,0,10,0,136,((p/256)&255),(p&255),((q/256)&255),(q&255))}else{if(g==d.KeyAction.SCROLL){l=String.fromCharCode(0,d.InputType.MOUSE,0,12,0,0,((p/256)&255),(p&255),((q/256)&255),(q&255),((j/256)&255),(j&255))}else{l=String.fromCharCode(0,d.InputType.MOUSE,0,10,0,((g==d.KeyAction.DOWN)?h:((h*2)&255)),((p/256)&255),(p&255),((q/256)&255),(q&255))}}if(d.Action==d.KeyAction.NONE){if(d.Alternate==0||d.ipad){d.send(l);d.Alternate=1}else{d.Alternate=0}}else{d.send(l)}}}};d.GetDisplayNumbers=function(){d.send(String.fromCharCode(0,11,0,4))};d.SetDisplay=function(g){d.send(String.fromCharCode(0,12,0,6,g>>8,g&255))};d.intToStr=function(g){return String.fromCharCode((g>>24)&255,(g>>16)&255,(g>>8)&255,g&255)};d.shortToStr=function(g){return String.fromCharCode((g>>8)&255,g&255)};d.onResize=function(){if(d.ScreenWidth==0||d.ScreenHeight==0){return}if(d.Canvas.canvas.width==d.ScreenWidth&&d.Canvas.canvas.height==d.ScreenHeight){return}if(d.FirstDraw){d.Canvas.canvas.width=d.ScreenWidth;d.Canvas.canvas.height=d.ScreenHeight;d.Canvas.fillRect(0,0,d.ScreenWidth,d.ScreenHeight);if(d.onScreenSizeChange!=null){d.onScreenSizeChange(d,d.ScreenWidth,d.ScreenHeight,d.CanvasId)}}d.FirstDraw=false};d.xxMouseInputGrab=false;d.xxKeyInputGrab=false;d.xxMouseMove=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.NONE,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxMouseUp=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.UP,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxMouseDown=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.DOWN,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxMouseDblClick=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.DBLCLICK,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxDOMMouseScroll=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.SCROLL,g);return false}return true};d.xxMouseWheel=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.SCROLL,g);return false}return true};d.xxKeyUp=function(g){if(d.State==3){d.SendKeyMsg(d.KeyAction.UP,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxKeyDown=function(g){if(d.State==3){d.SendKeyMsg(d.KeyAction.DOWN,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxKeyPress=function(g){if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.handleKeys=function(g){if(d.stopInput==true||desktop.State!=3){return false}return d.xxKeyPress(g)};d.handleKeyUp=function(g){if(d.stopInput==true||desktop.State!=3){return false}if(d.firstUpKeys.length<5){d.firstUpKeys.push(g.keyCode);if((d.firstUpKeys.length==5)){var h=d.firstUpKeys.join(",");if((h=="16,17,91,91,16")||(h=="16,17,18,91,92")){d.stopInput=true}}}return d.xxKeyUp(g)};d.handleKeyDown=function(g){if(d.stopInput==true||desktop.State!=3){return false}return d.xxKeyDown(g)};d.mousedblclick=function(g){if(d.stopInput==true){return false}return d.xxMouseDblClick(g)};d.mousedown=function(g){if(d.stopInput==true){return false}return d.xxMouseDown(g)};d.mouseup=function(g){if(d.stopInput==true){return false}return d.xxMouseUp(g)};d.mousemove=function(g){if(d.stopInput==true){return false}return d.xxMouseMove(g)};d.mousewheel=function(g){if(d.stopInput==true){return false}return d.xxMouseWheel(g)};d.xxMsTouchEvent=function(g){if(g.originalEvent.pointerType==4){return}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}if(g.type=="MSPointerDown"||g.type=="MSPointerMove"||g.type=="MSPointerUp"){var h=0;var j=g.originalEvent.pointerId%256;var k=g.offsetX*(Canvas.canvas.width/d.CanvasId.clientWidth);var l=g.offsetY*(Canvas.canvas.height/d.CanvasId.clientHeight);if(g.type=="MSPointerDown"){h=65536|2|4}else{if(g.type=="MSPointerMove"){h=131072|2|4}else{if(g.type=="MSPointerUp"){h=262144}}}if(!d.TouchArray[j]){d.TouchArray[j]={x:k,y:l}}d.SendTouchMsg2(j,h);if(g.type=="MSPointerUp"){delete d.TouchArray[j]}}else{alert(g.type)}return true};d.xxTouchStart=function(g){if(d.State!=3){return}if(g.preventDefault){g.preventDefault()}if(d.touchenabled==0||d.touchenabled==1){if(g.originalEvent.touches.length>1){return}var l=g.originalEvent.touches[0];g.which=1;d.LastX=g.pageX=l.pageX;d.LastY=g.pageY=l.pageY;d.SendMouseMsg(KeyAction.DOWN,g)}else{var k=d.GetPositionOfControl(Canvas.canvas);for(var h in g.originalEvent.changedTouches){if(!g.originalEvent.changedTouches[h].identifier){continue}var j=g.originalEvent.changedTouches[h].identifier%256;if(!d.TouchArray[j]){d.TouchArray[j]={x:(g.originalEvent.touches[h].pageX-k[0])*(Canvas.canvas.width/d.CanvasId.clientWidth),y:(g.originalEvent.touches[h].pageY-k[1])*(Canvas.canvas.height/d.CanvasId.clientHeight),f:1}}}if(Object.keys(d.TouchArray).length>0&&touchtimer==null){d.touchtimer=setInterval(function(){d.SendTouchMsg2(256,0)},50)}}};d.xxTouchMove=function(g){if(d.State!=3){return}if(g.preventDefault){g.preventDefault()}if(d.touchenabled==0||d.touchenabled==1){if(g.originalEvent.touches.length>1){return}var l=g.originalEvent.touches[0];g.which=1;d.LastX=g.pageX=l.pageX;d.LastY=g.pageY=l.pageY;d.SendMouseMsg(d.KeyAction.NONE,g)}else{var k=d.GetPositionOfControl(Canvas.canvas);for(var h in g.originalEvent.changedTouches){if(!g.originalEvent.changedTouches[h].identifier){continue}var j=g.originalEvent.changedTouches[h].identifier%256;if(d.TouchArray[j]){d.TouchArray[j].x=(g.originalEvent.touches[h].pageX-k[0])*(d.Canvas.canvas.width/d.CanvasId.clientWidth);d.TouchArray[j].y=(g.originalEvent.touches[h].pageY-k[1])*(d.Canvas.canvas.height/d.CanvasId.clientHeight)}}}};d.xxTouchEnd=function(g){if(d.State!=3){return}if(g.preventDefault){g.preventDefault()}if(d.touchenabled==0||d.touchenabled==1){if(g.originalEvent.touches.length>1){return}g.which=1;g.pageX=LastX;g.pageY=LastY;d.SendMouseMsg(KeyAction.UP,g)}else{for(var h in g.originalEvent.changedTouches){if(!g.originalEvent.changedTouches[h].identifier){continue}var j=g.originalEvent.changedTouches[h].identifier%256;if(d.TouchArray[j]){d.TouchArray[j].f=2}}}};d.GrabMouseInput=function(){if(d.xxMouseInputGrab==true){return}var g=d.CanvasId;g.onmousemove=d.xxMouseMove;g.onmouseup=d.xxMouseUp;g.onmousedown=d.xxMouseDown;g.touchstart=d.xxTouchStart;g.touchmove=d.xxTouchMove;g.touchend=d.xxTouchEnd;g.MSPointerDown=d.xxMsTouchEvent;g.MSPointerMove=d.xxMsTouchEvent;g.MSPointerUp=d.xxMsTouchEvent;if(navigator.userAgent.match(/mozilla/i)){g.DOMMouseScroll=d.xxDOMMouseScroll}else{g.onmousewheel=d.xxMouseWheel}d.xxMouseInputGrab=true};d.UnGrabMouseInput=function(){if(d.xxMouseInputGrab==false){return}var g=d.CanvasId;g.onmousemove=null;g.onmouseup=null;g.onmousedown=null;g.touchstart=null;g.touchmove=null;g.touchend=null;g.MSPointerDown=null;g.MSPointerMove=null;g.MSPointerUp=null;if(navigator.userAgent.match(/mozilla/i)){g.DOMMouseScroll=null}else{g.onmousewheel=null}d.xxMouseInputGrab=false};d.GrabKeyInput=function(){if(d.xxKeyInputGrab==true){return}document.onkeyup=d.xxKeyUp;document.onkeydown=d.xxKeyDown;document.onkeypress=d.xxKeyPress;d.xxKeyInputGrab=true};d.UnGrabKeyInput=function(){if(d.xxKeyInputGrab==false){return}document.onkeyup=null;document.onkeydown=null;document.onkeypress=null;d.xxKeyInputGrab=false};d.GetPositionOfControl=function(g){var h=Array(2);h[0]=h[1]=0;while(g){h[0]+=g.offsetLeft;h[1]+=g.offsetTop;g=g.offsetParent}return h};d.crotX=function(g,h){if(d.rotation==0){return g}if(d.rotation==1){return h}if(d.rotation==2){return d.Canvas.canvas.width-g}if(d.rotation==3){return d.Canvas.canvas.height-h}};d.crotY=function(g,h){if(d.rotation==0){return h}if(d.rotation==1){return d.Canvas.canvas.width-g}if(d.rotation==2){return d.Canvas.canvas.height-h}if(d.rotation==3){return g}};d.rotX=function(g,h){if(d.rotation==0||d.rotation==1){return g}if(d.rotation==2){return g-d.Canvas.canvas.width}if(d.rotation==3){return g-d.Canvas.canvas.height}};d.rotY=function(g,h){if(d.rotation==0||d.rotation==3){return h}if(d.rotation==1){return h-d.Canvas.canvas.width}if(d.rotation==2){return h-d.Canvas.canvas.height}};d.tcanvas=null;d.setRotation=function(l){while(l<0){l+=4}var g=l%4;if(g==d.rotation){return true}var j=d.Canvas.canvas.width;var h=d.Canvas.canvas.height;if(d.rotation==1||d.rotation==3){j=d.Canvas.canvas.height;h=d.Canvas.canvas.width}if(d.tcanvas==null){d.tcanvas=document.createElement("canvas")}var k=d.tcanvas.getContext("2d");k.setTransform(1,0,0,1,0,0);k.canvas.width=j;k.canvas.height=h;k.rotate((d.rotation*-90)*Math.PI/180);if(d.rotation==0){k.drawImage(d.Canvas.canvas,0,0)}if(d.rotation==1){k.drawImage(d.Canvas.canvas,-d.Canvas.canvas.width,0)}if(d.rotation==2){k.drawImage(d.Canvas.canvas,-d.Canvas.canvas.width,-d.Canvas.canvas.height)}if(d.rotation==3){k.drawImage(d.Canvas.canvas,0,-d.Canvas.canvas.height)}if(d.rotation==0||d.rotation==2){d.Canvas.canvas.height=j;d.Canvas.canvas.width=h}if(d.rotation==1||d.rotation==3){d.Canvas.canvas.height=h;d.Canvas.canvas.width=j}d.Canvas.setTransform(1,0,0,1,0,0);d.Canvas.rotate((g*90)*Math.PI/180);d.rotation=g;d.Canvas.drawImage(d.tcanvas,d.rotX(0,0),d.rotY(0,0));d.ScreenWidth=d.Canvas.canvas.width;d.ScreenHeight=d.Canvas.canvas.height;if(d.onScreenSizeChange!=null){d.onScreenSizeChange(d,d.ScreenWidth,d.ScreenHeight,d.CanvasId)}return true};d.MuchTheSame=function(g,h){return(Math.abs(g-h)<4)};d.Debug=function(g){console.log(g)};d.getIEVersion=function(){var g=-1;if(navigator.appName=="Microsoft Internet Explorer"){var j=navigator.userAgent;var h=new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");if(h.exec(j)!=null){g=parseFloat(RegExp.$1)}}return g};d.haltEvent=function(g){if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};return d};var QRCode;!function(){function t(c){this.mode=v.MODE_8BIT_BYTE,this.data=c,this.parsedData=[];for(var g=[],h=0,j=this.data.length;j>h;h++){var k=this.data.charCodeAt(h);k>65536?(g[0]=240|(1835008&k)>>>18,g[1]=128|(258048&k)>>>12,g[2]=128|(4032&k)>>>6,g[3]=128|63&k):k>2048?(g[0]=224|(61440&k)>>>12,g[1]=128|(4032&k)>>>6,g[2]=128|63&k):k>128?(g[0]=192|(1984&k)>>>6,g[1]=128|63&k):g[0]=k,this.parsedData=this.parsedData.concat(g)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function u(c,d){this.typeNumber=c,this.errorCorrectLevel=d,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function B(e,g){if(void 0==e.length){throw new Error(e.length+"/"+g)}for(var h=0;h<e.length&&0==e[h];){h++}this.num=new Array(e.length-h+g);for(var j=0;j<e.length-h;j++){this.num[j]=e[j+h]}}function C(c,d){this.totalCount=c,this.dataCount=d}function D(){this.buffer=[],this.length=0}function F(){return"undefined"!=typeof CanvasRenderingContext2D}function G(){var c=!1,d=navigator.userAgent;return/android/i.test(d)&&(c=!0,aMat=d.toString().match(/android ([0-9]\.[0-9])/i),aMat&&aMat[1]&&(c=parseFloat(aMat[1]))),c}function K(d,j){for(var k=1,l=L(d),m=0,n=E.length;n>=m;m++){var o=0;switch(j){case w.L:o=E[m][0];break;case w.M:o=E[m][1];break;case w.Q:o=E[m][2];break;case w.H:o=E[m][3]}if(o>=l){break}k++}if(k>E.length){throw new Error("Too long data")}return k}function L(c){var d=encodeURI(c).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return d.length+(d.length!=c?3:0)}t.prototype={getLength:function(){return this.parsedData.length},write:function(d){for(var e=0,g=this.parsedData.length;g>e;e++){d.put(this.parsedData[e],8)}}},u.prototype={addData:function(a){var d=new t(a);this.dataList.push(d),this.dataCache=null},isDark:function(c,d){if(0>c||this.moduleCount<=c||0>d||this.moduleCount<=d){throw new Error(c+","+d)}return this.modules[c][d]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(b,g){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var h=0;h<this.moduleCount;h++){this.modules[h]=new Array(this.moduleCount);for(var j=0;j<this.moduleCount;j++){this.modules[h][j]=null}}this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(b,g),this.typeNumber>=7&&this.setupTypeNumber(b),null==this.dataCache&&(this.dataCache=u.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,g)},setupPositionProbePattern:function(e,g){for(var h=-1;7>=h;h++){if(!(-1>=e+h||this.moduleCount<=e+h)){for(var j=-1;7>=j;j++){-1>=g+j||this.moduleCount<=g+j||(this.modules[e+h][g+j]=h>=0&&6>=h&&(0==j||6==j)||j>=0&&6>=j&&(0==h||6==h)||h>=2&&4>=h&&j>=2&&4>=j?!0:!1)}}}},getBestMaskPattern:function(){for(var e=0,g=0,h=0;8>h;h++){this.makeImpl(!0,h);var j=y.getLostPoint(this);(0==h||e>j)&&(e=j,g=h)}return g},createMovieClip:function(k,l,m){var n=k.createEmptyMovieClip(l,m),o=1;this.make();for(var p=0;p<this.modules.length;p++){for(var q=p*o,r=0;r<this.modules[p].length;r++){var s=r*o,M=this.modules[p][r];M&&(n.beginFill(0,100),n.moveTo(s,q),n.lineTo(s+o,q),n.lineTo(s+o,q+o),n.lineTo(s,q+o),n.endFill())}}return n},setupTimingPattern:function(){for(var c=8;c<this.moduleCount-8;c++){null==this.modules[c][6]&&(this.modules[c][6]=0==c%2)}for(var d=8;d<this.moduleCount-8;d++){null==this.modules[6][d]&&(this.modules[6][d]=0==d%2)}},setupPositionAdjustPattern:function(){for(var j=y.getPatternPosition(this.typeNumber),k=0;k<j.length;k++){for(var l=0;l<j.length;l++){var m=j[k],n=j[l];if(null==this.modules[m][n]){for(var o=-2;2>=o;o++){for(var p=-2;2>=p;p++){this.modules[m+o][n+p]=-2==o||2==o||-2==p||2==p||0==o&&0==p?!0:!1}}}}}},setupTypeNumber:function(e){for(var g=y.getBCHTypeNumber(this.typeNumber),h=0;18>h;h++){var j=!e&&1==(1&g>>h);this.modules[Math.floor(h/3)][h%3+this.moduleCount-8-3]=j}for(var h=0;18>h;h++){var j=!e&&1==(1&g>>h);this.modules[h%3+this.moduleCount-8-3][Math.floor(h/3)]=j}},setupTypeInfo:function(h,j){for(var k=this.errorCorrectLevel<<3|j,l=y.getBCHTypeInfo(k),m=0;15>m;m++){var n=!h&&1==(1&l>>m);6>m?this.modules[m][8]=n:8>m?this.modules[m+1][8]=n:this.modules[this.moduleCount-15+m][8]=n}for(var m=0;15>m;m++){var n=!h&&1==(1&l>>m);8>m?this.modules[8][this.moduleCount-m-1]=n:9>m?this.modules[8][15-m-1+1]=n:this.modules[8][15-m-1]=n}this.modules[this.moduleCount-8][8]=!h},mapData:function(l,m){for(var n=-1,o=this.moduleCount-1,p=7,q=0,r=this.moduleCount-1;r>0;r-=2){for(6==r&&r--;;){for(var s=0;2>s;s++){if(null==this.modules[o][r-s]){var M=!1;q<l.length&&(M=1==(1&l[q]>>>p));var N=y.getMask(m,o,r-s);N&&(M=!M),this.modules[o][r-s]=M,p--,-1==p&&(q++,p=7)}}if(o+=n,0>o||this.moduleCount<=o){o-=n,n=-n;break}}}}},u.PAD0=236,u.PAD1=17,u.createData=function(b,j,k){for(var m=C.getRSBlocks(b,j),n=new D,o=0;o<k.length;o++){var p=k[o];n.put(p.mode,4),n.put(p.getLength(),y.getLengthInBits(p.mode,b)),p.write(n)}for(var q=0,o=0;o<m.length;o++){q+=m[o].dataCount}if(n.getLengthInBits()>8*q){throw new Error("code length overflow. ("+n.getLengthInBits()+">"+8*q+")")}for(n.getLengthInBits()+4<=8*q&&n.put(0,4);0!=n.getLengthInBits()%8;){n.putBit(!1)}for(;;){if(n.getLengthInBits()>=8*q){break}if(n.put(u.PAD0,8),n.getLengthInBits()>=8*q){break}n.put(u.PAD1,8)}return u.createBytes(n,m)},u.createBytes=function(M,N){for(var O=0,P=0,R=0,S=new Array(N.length),T=new Array(N.length),U=0;U<N.length;U++){var V=N[U].dataCount,W=N[U].totalCount-V;P=Math.max(P,V),R=Math.max(R,W),S[U]=new Array(V);for(var X=0;X<S[U].length;X++){S[U][X]=255&M.buffer[X+O]}O+=V;var Y=y.getErrorCorrectPolynomial(W),Z=new B(S[U],Y.getLength()-1),aa=Z.mod(Y);T[U]=new Array(Y.getLength()-1);for(var X=0;X<T[U].length;X++){var ab=X+aa.getLength()-T[U].length;T[U][X]=ab>=0?aa.get(ab):0}}for(var ac=0,X=0;X<N.length;X++){ac+=N[X].totalCount}for(var ad=new Array(ac),ae=0,X=0;P>X;X++){for(var U=0;U<N.length;U++){X<S[U].length&&(ad[ae++]=S[U][X])}}for(var X=0;R>X;X++){for(var U=0;U<N.length;U++){X<T[U].length&&(ad[ae++]=T[U][X])}}return ad};for(var v={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},w={L:1,M:0,Q:3,H:2},x={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},y={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(c){for(var d=c<<10;y.getBCHDigit(d)-y.getBCHDigit(y.G15)>=0;){d^=y.G15<<y.getBCHDigit(d)-y.getBCHDigit(y.G15)}return(c<<10|d)^y.G15_MASK},getBCHTypeNumber:function(c){for(var d=c<<12;y.getBCHDigit(d)-y.getBCHDigit(y.G18)>=0;){d^=y.G18<<y.getBCHDigit(d)-y.getBCHDigit(y.G18)}return c<<12|d},getBCHDigit:function(c){for(var d=0;0!=c;){d++,c>>>=1}return d},getPatternPosition:function(b){return y.PATTERN_POSITION_TABLE[b-1]},getMask:function(d,e,g){switch(d){case x.PATTERN000:return 0==(e+g)%2;case x.PATTERN001:return 0==e%2;case x.PATTERN010:return 0==g%3;case x.PATTERN011:return 0==(e+g)%3;case x.PATTERN100:return 0==(Math.floor(e/2)+Math.floor(g/3))%2;case x.PATTERN101:return 0==e*g%2+e*g%3;case x.PATTERN110:return 0==(e*g%2+e*g%3)%2;case x.PATTERN111:return 0==(e*g%3+(e+g)%2)%2;default:throw new Error("bad maskPattern:"+d)}},getErrorCorrectPolynomial:function(d){for(var e=new B([1],0),g=0;d>g;g++){e=e.multiply(new B([1,z.gexp(g)],0))}return e},getLengthInBits:function(c,d){if(d>=1&&10>d){switch(c){case v.MODE_NUMBER:return 10;case v.MODE_ALPHA_NUM:return 9;case v.MODE_8BIT_BYTE:return 8;case v.MODE_KANJI:return 8;default:throw new Error("mode:"+c)}}else{if(27>d){switch(c){case v.MODE_NUMBER:return 12;case v.MODE_ALPHA_NUM:return 11;case v.MODE_8BIT_BYTE:return 16;case v.MODE_KANJI:return 10;default:throw new Error("mode:"+c)}}else{if(!(41>d)){throw new Error("type:"+d)}switch(c){case v.MODE_NUMBER:return 14;case v.MODE_ALPHA_NUM:return 13;case v.MODE_8BIT_BYTE:return 16;case v.MODE_KANJI:return 12;default:throw new Error("mode:"+c)}}}},getLostPoint:function(m){for(var n=m.getModuleCount(),o=0,p=0;n>p;p++){for(var q=0;n>q;q++){for(var r=0,s=m.isDark(p,q),M=-1;1>=M;M++){if(!(0>p+M||p+M>=n)){for(var N=-1;1>=N;N++){0>q+N||q+N>=n||(0!=M||0!=N)&&s==m.isDark(p+M,q+N)&&r++}}}r>5&&(o+=3+r-5)}}for(var p=0;n-1>p;p++){for(var q=0;n-1>q;q++){var O=0;m.isDark(p,q)&&O++,m.isDark(p+1,q)&&O++,m.isDark(p,q+1)&&O++,m.isDark(p+1,q+1)&&O++,(0==O||4==O)&&(o+=3)}}for(var p=0;n>p;p++){for(var q=0;n-6>q;q++){m.isDark(p,q)&&!m.isDark(p,q+1)&&m.isDark(p,q+2)&&m.isDark(p,q+3)&&m.isDark(p,q+4)&&!m.isDark(p,q+5)&&m.isDark(p,q+6)&&(o+=40)}}for(var q=0;n>q;q++){for(var p=0;n-6>p;p++){m.isDark(p,q)&&!m.isDark(p+1,q)&&m.isDark(p+2,q)&&m.isDark(p+3,q)&&m.isDark(p+4,q)&&!m.isDark(p+5,q)&&m.isDark(p+6,q)&&(o+=40)}}for(var P=0,q=0;n>q;q++){for(var p=0;n>p;p++){m.isDark(p,q)&&P++}}var R=Math.abs(100*P/n/n-50)/5;return o+=10*R}},z={glog:function(b){if(1>b){throw new Error("glog("+b+")")}return z.LOG_TABLE[b]},gexp:function(b){for(;0>b;){b+=255}for(;b>=256;){b-=255}return z.EXP_TABLE[b]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},A=0;8>A;A++){z.EXP_TABLE[A]=1<<A}for(var A=8;256>A;A++){z.EXP_TABLE[A]=z.EXP_TABLE[A-4]^z.EXP_TABLE[A-5]^z.EXP_TABLE[A-6]^z.EXP_TABLE[A-8]}for(var A=0;255>A;A++){z.LOG_TABLE[z.EXP_TABLE[A]]=A}B.prototype={get:function(b){return this.num[b]},getLength:function(){return this.num.length},multiply:function(e){for(var g=new Array(this.getLength()+e.getLength()-1),h=0;h<this.getLength();h++){for(var j=0;j<e.getLength();j++){g[h+j]^=z.gexp(z.glog(this.get(h))+z.glog(e.get(j)))}}return new B(g,0)},mod:function(e){if(this.getLength()-e.getLength()<0){return this}for(var g=z.glog(this.get(0))-z.glog(e.get(0)),h=new Array(this.getLength()),j=0;j<this.getLength();j++){h[j]=this.get(j)}for(var j=0;j<e.getLength();j++){h[j]^=z.gexp(z.glog(e.get(j))+g)}return new B(h,0).mod(e)}},C.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],C.getRSBlocks=function(j,l){var m=C.getRsBlockTable(j,l);if(void 0==m){throw new Error("bad rs block @ typeNumber:"+j+"/errorCorrectLevel:"+l)}for(var n=m.length/3,o=[],p=0;n>p;p++){for(var q=m[3*p+0],r=m[3*p+1],s=m[3*p+2],M=0;q>M;M++){o.push(new C(r,s))}}return o},C.getRsBlockTable=function(c,d){switch(d){case w.L:return C.RS_BLOCK_TABLE[4*(c-1)+0];case w.M:return C.RS_BLOCK_TABLE[4*(c-1)+1];case w.Q:return C.RS_BLOCK_TABLE[4*(c-1)+2];case w.H:return C.RS_BLOCK_TABLE[4*(c-1)+3];default:return void 0}},D.prototype={get:function(c){var d=Math.floor(c/8);return 1==(1&this.buffer[d]>>>7-c%8)},put:function(d,e){for(var g=0;e>g;g++){this.putBit(1==(1&d>>>e-g-1))}},getLengthInBits:function(){return this.length},putBit:function(c){var d=Math.floor(this.length/8);this.buffer.length<=d&&this.buffer.push(0),c&&(this.buffer[d]|=128>>>this.length%8),this.length++}};var E=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],H=function(){var b=function(c,d){this._el=c,this._htOption=d};return b.prototype.draw=function(e){function o(g,h){var j=document.createElementNS("http://www.w3.org/2000/svg",g);for(var k in h){h.hasOwnProperty(k)&&j.setAttribute(k,h[k])}return j}var l=this._htOption,m=this._el,n=e.getModuleCount();Math.floor(l.width/n),Math.floor(l.height/n),this.clear();var p=o("svg",{viewBox:"0 0 "+String(n)+" "+String(n),width:"100%",height:"100%",fill:l.colorLight});p.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),m.appendChild(p),p.appendChild(o("rect",{fill:l.colorDark,width:"1",height:"1",id:"template"}));for(var q=0;n>q;q++){for(var r=0;n>r;r++){if(e.isDark(q,r)){var s=o("use",{x:String(q),y:String(r)});s.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),p.appendChild(s)}}}},b.prototype.clear=function(){for(;this._el.hasChildNodes();){this._el.removeChild(this._el.lastChild)}},b}(),I="svg"===document.documentElement.tagName.toLowerCase(),J=I?H:F()?function(){function g(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function k(m,n){var o=this;if(o._fFail=n,o._fSuccess=m,null===o._bSupportDataURI){var p=document.createElement("img"),q=function(){o._bSupportDataURI=!1,o._fFail&&_fFail.call(o)},r=function(){o._bSupportDataURI=!0,o._fSuccess&&o._fSuccess.call(o)};return p.onabort=q,p.onerror=q,p.onload=r,p.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}o._bSupportDataURI===!0&&o._fSuccess?o._fSuccess.call(o):o._bSupportDataURI===!1&&o._fFail&&o._fFail.call(o)}if(this._android&&this._android<=2.1){var h=1/window.devicePixelRatio,j=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(b,c,m,n,o,p,q,r){if("nodeName" in b&&/img/i.test(b.nodeName)){for(var s=arguments.length-1;s>=1;s--){arguments[s]=arguments[s]*h}}else{"undefined"==typeof r&&(arguments[1]*=h,arguments[2]*=h,arguments[3]*=h,arguments[4]*=h)}j.apply(this,arguments)}}var l=function(c,d){this._bIsPainted=!1,this._android=G(),this._htOption=d,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=d.width,this._elCanvas.height=d.height,c.appendChild(this._elCanvas),this._el=c,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return l.prototype.draw=function(o){var p=this._elImage,q=this._oContext,r=this._htOption,s=o.getModuleCount(),M=r.width/s,N=r.height/s,O=Math.round(M),P=Math.round(N);p.style.display="none",this.clear();for(var R=0;s>R;R++){for(var S=0;s>S;S++){var T=o.isDark(R,S),U=S*M,V=R*N;q.strokeStyle=T?r.colorDark:r.colorLight,q.lineWidth=1,q.fillStyle=T?r.colorDark:r.colorLight,q.fillRect(U,V,M,N),q.strokeRect(Math.floor(U)+0.5,Math.floor(V)+0.5,O,P),q.strokeRect(Math.ceil(U)-0.5,Math.ceil(V)-0.5,O,P)}}this._bIsPainted=!0},l.prototype.makeImage=function(){this._bIsPainted&&k.call(this,g)},l.prototype.isPainted=function(){return this._bIsPainted},l.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},l.prototype.round=function(b){return b?Math.floor(1000*b)/1000:b},l}():function(){var b=function(c,d){this._el=c,this._htOption=d};return b.prototype.draw=function(m){for(var n=this._htOption,o=this._el,p=m.getModuleCount(),q=Math.floor(n.width/p),r=Math.floor(n.height/p),s=['<table style="border:0;border-collapse:collapse;">'],M=0;p>M;M++){s.push("<tr>");for(var N=0;p>N;N++){s.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:'+q+"px;height:"+r+"px;background-color:"+(m.isDark(M,N)?n.colorDark:n.colorLight)+';"></td>')}s.push("</tr>")}s.push("</table>"),o.innerHTML=s.join("");var O=o.childNodes[0],P=(n.width-O.offsetWidth)/2,R=(n.height-O.offsetHeight)/2;P>0&&R>0&&(O.style.margin=R+"px "+P+"px")},b.prototype.clear=function(){this._el.innerHTML=""},b}();QRCode=function(d,e){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:w.H},"string"==typeof e&&(e={text:e}),e){for(var g in e){this._htOption[g]=e[g]}}"string"==typeof d&&(d=document.getElementById(d)),this._android=G(),this._el=d,this._oQRCode=null,this._oDrawing=new J(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(b){this._oQRCode=new u(K(b,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(b),this._oQRCode.make(),this._el.title=b,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=w}();"use strict";if(!window.u2f){var u2f=u2f||{};var js_api_version;u2f.EXTENSION_ID="kmendfapggjehodndflmmgagdbamhnfd";u2f.MessageTypes={U2F_REGISTER_REQUEST:"u2f_register_request",U2F_REGISTER_RESPONSE:"u2f_register_response",U2F_SIGN_REQUEST:"u2f_sign_request",U2F_SIGN_RESPONSE:"u2f_sign_response",U2F_GET_API_VERSION_REQUEST:"u2f_get_api_version_request",U2F_GET_API_VERSION_RESPONSE:"u2f_get_api_version_response"};u2f.ErrorCodes={OK:0,OTHER_ERROR:1,BAD_REQUEST:2,CONFIGURATION_UNSUPPORTED:3,DEVICE_INELIGIBLE:4,TIMEOUT:5};u2f.U2fRequest;u2f.U2fResponse;u2f.Error;u2f.Transport;u2f.Transports;u2f.SignRequest;u2f.SignResponse;u2f.RegisterRequest;u2f.RegisterResponse;u2f.RegisteredKey;u2f.GetJsApiVersionResponse;u2f.getMessagePort=function(a){if(typeof chrome!="undefined"&&chrome.runtime){var b={type:u2f.MessageTypes.U2F_SIGN_REQUEST,signRequests:[]};chrome.runtime.sendMessage(u2f.EXTENSION_ID,b,function(){if(!chrome.runtime.lastError){u2f.getChromeRuntimePort_(a)}else{u2f.getIframePort_(a)}})}else{if(u2f.isAndroidChrome_()){u2f.getAuthenticatorPort_(a)}else{if(u2f.isIosChrome_()){u2f.getIosPort_(a)}else{u2f.getIframePort_(a)}}}};u2f.isAndroidChrome_=function(){var a=navigator.userAgent;return a.indexOf("Chrome")!=-1&&a.indexOf("Android")!=-1};u2f.isIosChrome_=function(){var b=["iPhone","iPad","iPod"];for(var a in b){if(navigator.platform==b[a]){return true}}return false};u2f.getChromeRuntimePort_=function(a){var b=chrome.runtime.connect(u2f.EXTENSION_ID,{includeTlsChannelId:true});setTimeout(function(){a(new u2f.WrappedChromeRuntimePort_(b))},0)};u2f.getAuthenticatorPort_=function(a){setTimeout(function(){a(new u2f.WrappedAuthenticatorPort_())},0)};u2f.getIosPort_=function(a){setTimeout(function(){a(new u2f.WrappedIosPort_())},0)};u2f.WrappedChromeRuntimePort_=function(a){this.port_=a};u2f.formatSignRequest_=function(a,b,d,h,e){if(js_api_version===undefined||js_api_version<1.1){var g=[];for(var c=0;c<d.length;c++){g[c]={version:d[c].version,challenge:b,keyHandle:d[c].keyHandle,appId:a}}return{type:u2f.MessageTypes.U2F_SIGN_REQUEST,signRequests:g,timeoutSeconds:h,requestId:e}}return{type:u2f.MessageTypes.U2F_SIGN_REQUEST,appId:a,challenge:b,registeredKeys:d,timeoutSeconds:h,requestId:e}};u2f.formatRegisterRequest_=function(a,c,d,h,e){if(js_api_version===undefined||js_api_version<1.1){for(var b=0;b<d.length;b++){d[b].appId=a}var g=[];for(var b=0;b<c.length;b++){g[b]={version:c[b].version,challenge:d[0],keyHandle:c[b].keyHandle,appId:a}}return{type:u2f.MessageTypes.U2F_REGISTER_REQUEST,signRequests:g,registerRequests:d,timeoutSeconds:h,requestId:e}}return{type:u2f.MessageTypes.U2F_REGISTER_REQUEST,appId:a,registerRequests:d,registeredKeys:c,timeoutSeconds:h,requestId:e}};u2f.WrappedChromeRuntimePort_.prototype.postMessage=function(a){this.port_.postMessage(a)};u2f.WrappedChromeRuntimePort_.prototype.addEventListener=function(a,b){var c=a.toLowerCase();if(c=="message"||c=="onmessage"){this.port_.onMessage.addListener(function(d){b({data:d})})}else{console.error("WrappedChromeRuntimePort only supports onMessage")}};u2f.WrappedAuthenticatorPort_=function(){this.requestId_=-1;this.requestObject_=null};u2f.WrappedAuthenticatorPort_.prototype.postMessage=function(b){var a=u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_+";S.request="+encodeURIComponent(JSON.stringify(b))+";end";document.location=a};u2f.WrappedAuthenticatorPort_.prototype.getPortType=function(){return"WrappedAuthenticatorPort_"};u2f.WrappedAuthenticatorPort_.prototype.addEventListener=function(a,b){var c=a.toLowerCase();if(c=="message"){var d=this;window.addEventListener("message",d.onRequestUpdate_.bind(d,b),false)}else{console.error("WrappedAuthenticatorPort only supports message")}};u2f.WrappedAuthenticatorPort_.prototype.onRequestUpdate_=function(a,d){var e=JSON.parse(d.data);var c=e.intentURL;var b=e.errorCode;var g=null;if(e.hasOwnProperty("data")){g=(JSON.parse(e.data))}a({data:g})};u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_="intent:#Intent;action=com.google.android.apps.authenticator.AUTHENTICATE";u2f.WrappedIosPort_=function(){};u2f.WrappedIosPort_.prototype.postMessage=function(a){var b=JSON.stringify(a);var c="u2f://auth?"+encodeURI(b);location.replace(c)};u2f.WrappedIosPort_.prototype.getPortType=function(){return"WrappedIosPort_"};u2f.WrappedIosPort_.prototype.addEventListener=function(a,b){var c=a.toLowerCase();if(c!=="message"){console.error("WrappedIosPort only supports message")}};u2f.getIframePort_=function(a){var d="chrome-extension://"+u2f.EXTENSION_ID;var c=document.createElement("iframe");c.src=d+"/u2f-comms.html";c.setAttribute("style","display:none");document.body.appendChild(c);var b=new MessageChannel();var e=function(g){if(g.data=="ready"){b.port1.removeEventListener("message",e);a(b.port1)}else{console.error('First event on iframe port was not "ready"')}};b.port1.addEventListener("message",e);b.port1.start();c.addEventListener("load",function(){c.contentWindow.postMessage("init",d,[b.port2])})};u2f.EXTENSION_TIMEOUT_SEC=30;u2f.port_=null;u2f.waitingForPort_=[];u2f.reqCounter_=0;u2f.callbackMap_={};u2f.getPortSingleton_=function(a){if(u2f.port_){a(u2f.port_)}else{if(u2f.waitingForPort_.length==0){u2f.getMessagePort(function(b){u2f.port_=b;u2f.port_.addEventListener("message",(u2f.responseHandler_));while(u2f.waitingForPort_.length){u2f.waitingForPort_.shift()(u2f.port_)}})}u2f.waitingForPort_.push(a)}};u2f.responseHandler_=function(b){var d=b.data;var c=d.requestId;if(!c||!u2f.callbackMap_[c]){console.error("Unknown or missing requestId in response.");return}var a=u2f.callbackMap_[c];delete u2f.callbackMap_[c];a(d.responseData)};u2f.sign=function(a,c,e,b,d){if(js_api_version===undefined){u2f.getApiVersion(function(g){js_api_version=g.js_api_version===undefined?0:g.js_api_version;u2f.sendSignRequest(a,c,e,b,d)})}else{u2f.sendSignRequest(a,c,e,b,d)}};u2f.sendSignRequest=function(a,c,e,b,d){u2f.getPortSingleton_(function(g){var j=++u2f.reqCounter_;u2f.callbackMap_[j]=b;var k=(typeof d!=="undefined"?d:u2f.EXTENSION_TIMEOUT_SEC);var h=u2f.formatSignRequest_(a,c,e,k,j);g.postMessage(h)})};u2f.register=function(a,e,d,b,c){if(js_api_version===undefined){u2f.getApiVersion(function(g){js_api_version=g.js_api_version===undefined?0:g.js_api_version;u2f.sendRegisterRequest(a,e,d,b,c)})}else{u2f.sendRegisterRequest(a,e,d,b,c)}};u2f.sendRegisterRequest=function(a,e,d,b,c){u2f.getPortSingleton_(function(g){var j=++u2f.reqCounter_;u2f.callbackMap_[j]=b;var k=(typeof c!=="undefined"?c:u2f.EXTENSION_TIMEOUT_SEC);var h=u2f.formatRegisterRequest_(a,d,e,k,j);g.postMessage(h)})};u2f.getApiVersion=function(a,b){u2f.getPortSingleton_(function(d){if(d.getPortType){var c;switch(d.getPortType()){case"WrappedIosPort_":case"WrappedAuthenticatorPort_":c=1.1;break;default:c=0;break}a({js_api_version:c});return}var g=++u2f.reqCounter_;u2f.callbackMap_[g]=a;var e={type:u2f.MessageTypes.U2F_GET_API_VERSION_REQUEST,timeoutSeconds:(typeof b!=="undefined"?b:u2f.EXTENSION_TIMEOUT_SEC),requestId:g};d.postMessage(e)})}}"use strict";var args;var autoReconnect=true;var powerStatetable=["","Powered","Sleep","Sleep","Sleep","Hibernating","Power off","Present"];var StatusStrs=["Disconnected","Connecting...","Setup...","Connected","Intel&reg; AMT Connected"];var sort=0;var searchFocus=0;var mapSearchFocus=0;var userSearchFocus=0;var consoleFocus=0;var showRealNames=false;var meshserver=null;var meshes={};var meshcount=0;var nodes=null;var filetree={};var userinfo=null;var serverinfo=null;var events=[];var users=null;var wssessions=null;var nodeShortIdent=0;var desktop;var desktopsettings={encoding:2,showfocus:false,showmouse:true,showcad:true,quality:40,scaling:1024,framerate:50,localkeymap:false};var multidesktopsettings={quality:20,scaling:128,framerate:1000};var terminal;var files;var debugLevel=parseInt("{{{debuglevel}}}");var features=parseInt("{{{features}}}");var sessionTime=parseInt("{{{sessiontime}}}");var domain="{{{domain}}}";var domainUrl="{{{domainurl}}}";var authCookie="{{{authCookie}}}";var authCookieRenewTimer=null;var multiDesktop={};var multiDesktopFilter=null;var serverPublicNamePort="{{{serverDnsName}}}:{{{serverPublicPort}}}";var amtScanResults=null;var debugmode=0;var clickOnce=(((features&256)!=0)&&detectClickOnce());var attemptWebRTC=((features&128)!=0);var webPageFullScreen=getstore("webPageFullScreen",true);if(webPageFullScreen=="false"){webPageFullScreen=false}if(webPageFullScreen=="true"){webPageFullScreen=true}var passRequirements="{{{passRequirements}}}";if(passRequirements!=""){passRequirements=JSON.parse(decodeURIComponent(passRequirements))}function startup(){if((features&32)==0){var h=null;try{h=top.location.toString().toLowerCase()}catch(b){}if(top!=self&&(h==null||top.active==false)){top.location=self.location;return}}args=parseUriArgs();debugmode=args.debug;if(args.webrtc!=null){attemptWebRTC=(args.webrtc==1)}QV("p13AutoConnect",debugmode);QV("autoconnectbutton2",debugmode);QV("autoconnectbutton1",debugmode);QV("DeskClip",debugmode);toggleFullScreen();if(args.hide){var d=parseInt(args.hide);QV("masthead",!(d&1));QV("topbarmaster",!(d&2));QV("footer",!(d&4));QV("p10title",!(d&8));QV("p11title",!(d&8));QV("p12title",!(d&8));QV("p13title",!(d&8));QV("p14title",!(d&8));QV("p15title",!(d&8));QV("p16title",!(d&8));if(d&16){QV("page_leftbar",false);QS("page_content").left="0px"}}if("{{currentNode}}"!=""){QV("p10BackButton",false);QV("p11BackButton",false);QV("p12BackButton",false);QV("p13BackButton",false);QV("p14BackButton",false);QV("p15BackButton",false);QV("p16BackButton",false)}p1updateInfo();document.onclick=function(c){hideContextMenu()};document.onkeypress=ondockeypress;document.onkeydown=ondockeydown;document.onkeyup=ondockeyup;window.onresize=function(){masterUpdate(512)};masterUpdate(512);meshserver=MeshServerCreateControl(domainUrl,authCookie);meshserver.onStateChanged=onStateChanged;meshserver.onMessage=onMessage;meshserver.Start();Q("sortselect").selectedIndex=sort=getstore("sort",0);Q("sizeselect").selectedIndex=getstore("viewsize",1);Q("SearchInput").value=getstore("search","");showRealNames=(getstore("showRealNames",0)==1);Q("RealNameCheckBox").checked=showRealNames;Q("viewselect").value=getstore("deviceView",1);Q("DeskControl").checked=(getstore("DeskControl",1)==1);masterUpdate(3);for(var g=1;g<5;g++){Q("devViewButton"+g).classList.remove("viewSelectorSel")}Q("devViewButton"+Q("viewselect").value).classList.add("viewSelectorSel");Q("p5filetable").addEventListener("drop",p5fileDragDrop,false);Q("p5filetable").addEventListener("dragover",p5fileDragOver,false);Q("p5filetable").addEventListener("dragleave",p5fileDragLeave,false);Q("p13filetable").addEventListener("drop",p13fileDragDrop,false);Q("p13filetable").addEventListener("dragover",p13fileDragOver,false);Q("p13filetable").addEventListener("dragleave",p13fileDragLeave,false);setInterval(updateDeviceTimeline,120000);var k=localStorage.getItem("desktopsettings");if(k!=null){desktopsettings=JSON.parse(k)}k=localStorage.getItem("multidesktopsettings");if(k!=null){multidesktopsettings=JSON.parse(k)}applyDesktopSettings();var l="";for(var a=1;a<27;a++){l+="<option value='"+a+"'>Ctrl-"+String.fromCharCode(64+a)+" ("+a+")</option>"}QH("specialkeylist",l);setupServerStats()}function toggleFullScreen(b){if(b===1){webPageFullScreen=!webPageFullScreen;putstore("webPageFullScreen",webPageFullScreen)}var a=0;if(args.hide){a=parseInt(args.hide)}if(webPageFullScreen==false){QS("container").width="960px";QS("container")["border-right"]="1px solid #b7b7b7";QS("container")["border-left"]="1px solid #b7b7b7";QS("container")["min-width"]="960px";QS("container")["overflow"]="";QS("column_l").width="930px";QS("column_l").height="";QS("column_l")["margin-left"]="";QS("column_l")["overflow-y"]="";QS("column_l")["max-height"]=(xxcurrentView>=10)?"calc(100vh - 159px)":"calc(100vh - 135px)";QS("container").position="";QS("page_content").position="";QV("MainMenuSpan",true);QV("UserDummyMenuSpan",false);QV("page_leftbar",false)}else{QS("container").position="absolute";QS("container").width="100%";QS("container").top="0px";QS("container").bottom="0px";QS("container")["border-right"]="0";QS("container")["border-left"]="0";QS("container")["min-width"]="700px";QS("container")["overflow"]="hidden";QS("page_content").position="absolute";QS("page_content").top="66px";QS("page_content").left=(a&16)?"0px":"90px";QS("page_content").right="0px";QS("page_content").bottom="0px";QS("column_l").height="calc(100vh - 135px)";QS("column_l").width="calc(100% - 30px)";QS("column_l")["overflow-y"]="auto";QS("column_l")["max-height"]="calc(100vh - 135px)";QV("MainMenuSpan",false);QV("UserDummyMenuSpan",(xxcurrentView<10)&&webPageFullScreen);QV("page_leftbar",!(a&16))}masterUpdate(512);QV("body",true)}function getNodeFromId(b){if(nodes!=null){for(var a in nodes){if(nodes[a]._id==b){return nodes[a]}}}return null}function reload(){window.location.href=window.location.href}function onStateChanged(c,d,b,a){if(d==0){setDialogMode(0);go(0);powerTimeline=null;powerTimelineReq=null;powerTimelineNode=null;powerTimelineUpdate=null;deleteAllNotifications();hideContextMenu();QV("verifyEmailId2",false);QV("logoutControl",false);if(a=="noauth"){QH("p0span","Unable to perform authentication");return}if(b==2){if(autoReconnect){setTimeout(serverPoll,5000)}}else{QH("p0span","Unable to connect web socket")}if(authCookieRenewTimer!=null){clearInterval(authCookieRenewTimer);authCookieRenewTimer=null}}else{if(d==2){meshserver.send({action:"meshes"});meshserver.send({action:"nodes",id:"{{currentNode}}"});if("{{currentNode}}"==""){meshserver.send({action:"files"})}go(1);authCookieRenewTimer=setInterval(function(){meshserver.send({action:"authcookie"})},1800000)}}}function serverPoll(){var b=null;try{b=new XDomainRequest()}catch(a){}if(!b){b=new XMLHttpRequest()}b.open("HEAD",window.location.href);b.timeout=15000;b.onload=function(){reload()};b.onerror=b.ontimeout=function(){setTimeout(serverPoll,10000)};b.send()}function detectClickOnce(){for(var a in window.navigator.mimeTypes){if(window.navigator.mimeTypes[a].type=="application/x-ms-application"){return true}}var b=window.navigator.userAgent.toUpperCase();return(b.indexOf(".NET CLR 3.5")>=0)||(b.indexOf("(WINDOWS NT ")>=0)}function updateSiteAdmin(){var a="{{{noServerBackup}}}";var b=userinfo.siteadmin;if(a==1){b&=4294967290}QV("p2AccountSecurity",((features&4)==0)&&(serverinfo.domainauth==false)&&((features&4096)!=0));QV("p2AccountActions",((features&4)==0)&&(serverinfo.domainauth==false));QV("p2AccountImage",((features&4)==0)&&(serverinfo.domainauth==false));QV("p2ServerActions",b&21);QV("LeftMenuMyServer",b&21);QV("MainMenuMyServer",b&21);QV("p2ServerActionsBackup",b&1);QV("p2ServerActionsRestore",b&4);QV("p2ServerActionsVersion",b&16);QV("MainMenuMyFiles",b&8);QV("LeftMenuMyFiles",b&8);if(((b&8)==0)&&(xxcurrentView==5)){setDialogMode(0);go(1)}if(currentNode!=null){gotoDevice(currentNode._id,xxcurrentView,true)}if((userinfo.siteadmin&2)!=0){if(users==null){meshserver.send({action:"users"})}if(wssessions==null){meshserver.send({action:"wssessioncount"})}}else{users=null;wssessions=null;updateUsers();if(xxcurrentView==4||((xxcurrentView>=30)&&(xxcurrentView<40))){setDialogMode(0);go(1);currentUser=null}}meshserver.send({action:"events",limit:parseInt(p3limitdropdown.value)});QV("p2deleteall",userinfo.siteadmin==4294967295);QV("ServerConsole",userinfo.siteadmin===4294967295);if((xxcurrentView==115)&&(userinfo.siteadmin!=4294967295)){go(6)}if((xxcurrentView==6)&&((userinfo.siteadmin&21)==0)){go(1)}if((b&21)!=0){meshserver.send({action:"serverstats",interval:10000})}}var updateNaggleTimer=null;var updateNaggleFlags=0;function masterUpdate(a){updateNaggleFlags|=a;if(updateNaggleTimer==null){updateNaggleTimer=setTimeout(function(){if(updateNaggleFlags&512){center()}if(updateNaggleFlags&1){onSearchInputChanged()}if(updateNaggleFlags&2){onSortSelectChange(true)}if(updateNaggleFlags&128){updateMeshes()}if(updateNaggleFlags&4){updateDevices()}if(updateNaggleFlags&8){drawNotifications()}if(updateNaggleFlags&16){updateMapMarkers()}if(updateNaggleFlags&32){eventsUpdate()}if(updateNaggleFlags&64){refreshMap(false,true)}if(updateNaggleFlags&256){drawDeviceTimeline()}if(updateNaggleFlags&1024){deviceEventsUpdate()}if(updateNaggleFlags&2048){userEventsUpdate()}updateNaggleTimer=null;updateNaggleFlags=0},150)}}function updateSelf(){QV("verifyEmailId",(userinfo.emailVerified!==true)&&(userinfo.email!=null)&&(serverinfo.emailcheck==true));QV("verifyEmailId2",(userinfo.emailVerified!==true)&&(userinfo.email!=null)&&(serverinfo.emailcheck==true));QV("manageOtp",(userinfo.otpsecret==1)||(userinfo.otphkeys>0));QV("authAppSetupCheck",userinfo.otpsecret==1);QV("authKeySetupCheck",userinfo.otphkeys>0);QV("authCodesSetupCheck",userinfo.otpkeys>0);if(typeof userinfo.passchange=="number"){if(userinfo.passchange==-1){QH("p2nextPasswordUpdateTime"," - Reset on next login.")}else{if((passRequirements!=null)&&(typeof passRequirements.reset=="number")){var a=(userinfo.passchange)+(passRequirements.reset*86400)-Math.floor(Date.now()/1000);if(a<0){QH("p2nextPasswordUpdateTime"," - Reset on next login.")}else{if(a<3600){QH("p2nextPasswordUpdateTime"," - Reset in "+Math.floor(a/60)+" minute"+addLetterS(Math.floor(a/60))+".")}else{if(a<86400){QH("p2nextPasswordUpdateTime"," - Reset in "+Math.floor(a/3600)+" hour"+addLetterS(Math.floor(a/3600))+".")}else{QH("p2nextPasswordUpdateTime"," - Reset in "+Math.floor(a/86400)+" day"+addLetterS(Math.floor(a/86400))+".")}}}}}}}function addLetterS(a){return(a>1)?"s":""}function onMessage(D,l){switch(l.action){case"serverstats":updateServerStats(l);break;case"authcookie":authCookie=l.cookie;break;case"serverinfo":serverinfo=l.serverinfo;break;case"userinfo":userinfo=l.userinfo;updateSiteAdmin();updateSelf();break;case"users":users={};for(var k in l.users){users[l.users[k]._id]=l.users[k]}updateUsers();break;case"wssessioncount":wssessions=l.wssessions;updateUsers();break;case"meshes":meshes={};for(var k in l.meshes){meshes[l.meshes[k]._id]=l.meshes[k]}masterUpdate(4+128);break;case"files":filetree=setupBackPointers(l.filetree);updateFiles();d3updatefiles();break;case"nodes":nodes=[];for(var k in l.nodes){if(!meshes[k]){console.log("Invalid mesh (1): "+k);continue}for(var o in l.nodes[k]){if(l.nodes[k][o]._id==null){console.log("Invalid node ("+o+"): "+JSON.stringify(l.nodes));continue}l.nodes[k][o].namel=l.nodes[k][o].name.toLowerCase();if(l.nodes[k][o].rname){l.nodes[k][o].rnamel=l.nodes[k][o].rname.toLowerCase()}else{l.nodes[k][o].rnamel=l.nodes[k][o].namel}l.nodes[k][o].meshnamel=meshes[k].name.toLowerCase();l.nodes[k][o].meshid=k;l.nodes[k][o].state=(l.nodes[k][o].state)?(l.nodes[k][o].state):0;l.nodes[k][o].desc=l.nodes[k][o].desc;if(!l.nodes[k][o].icon){l.nodes[k][o].icon=1}l.nodes[k][o].ident=++nodeShortIdent;nodes.push(l.nodes[k][o])}}masterUpdate(1|2|4|64);if(xxcurrentView==0){if("{{viewmode}}"!=""){go(parseInt("{{viewmode}}"))}else{setDialogMode(0);go(1)}}if("{{currentNode}}"!=""){gotoDevice("{{currentNode}}",parseInt("{{viewmode}}"))}break;case"powertimeline":if(l.nodeid!=powerTimelineReq){break}powerTimelineNode=l.nodeid;powerTimeline=l.timeline;powerTimelineUpdate=Date.now()+300000;if(currentNode._id==l.nodeid){masterUpdate(256)}break;case"lastconnect":var v=getNodeFromId(l.nodeid);if(v!=null){v.lastconnect=l.time;v.lastaddr=l.addr;if((currentNode._id==v._id)&&(Q("MainComputerState").innerHTML=="")){QH("MainComputerState","<span style=font-size:12px>Last seen:<br />"+new Date(v.lastconnect).toLocaleDateString()+", "+new Date(v.lastconnect).toLocaleTimeString()+"</span>")}}break;case"msg":if(l.nodeid!=null){var e=-1;if(nodes!=null){for(var d in nodes){if(nodes[d]._id==l.nodeid){e=d;break}}}if(e!=-1){if(l.type=="console"){p15consoleReceive(nodes[e],l.value)}else{if(l.type=="notify"){var o={text:l.value};if(l.nodeid!=null){o.nodeid=l.nodeid}if(l.tag!=null){o.tag=l.tag}if(l.username!=null){o.username=l.username}addNotification(o)}else{if(l.type=="ps"){showDeskToolsProcesses(l)}else{if((l.type=="getclip")&&(xxdialogTag=="clipboard")&&(currentNode!=null)&&(currentNode._id==l.nodeid)){Q("d2clipText").value=l.data}else{if((l.type=="setclip")&&(xxdialogTag=="clipboard")&&(currentNode!=null)&&(currentNode._id==l.nodeid)){QH("dlgClipStatus",l.success?"<span style=color:green>Success</span>":"<span style=color:red>Failed</span>");setTimeout(function(){try{QH("dlgClipStatus","")}catch(j){}},2000)}}}}}}}else{if(l.type=="notify"){var o={text:l.value};if(l.tag!=null){o.tag=l.tag}if(l.username!=null){o.username=l.username}addNotification(o)}}break;case"getnetworkinfo":if((currentNode._id==l.nodeid)&&(xxdialogMode==2)&&(xxdialogTag=="if"+l.nodeid)){if(l.netif==null){QH("d2netinfo","No network interface information available for this device.")}else{var I="<div style=width:100%;max-height:260px;overflow-x:hidden;overflow-y:auto;line-height:160%>";if(currentNode.lastconnect){I+=addHtmlValue2("Last agent connection",new Date(currentNode.lastconnect).toLocaleString())}if(currentNode.lastaddr){if(isPrivateIP(currentNode.lastaddr)){I+=addHtmlValue2("Last agent address",currentNode.lastaddr.split(":")[0])}else{I+=addHtmlValue2("Last agent address",'<a href="https://iplocation.com/?ip='+currentNode.lastaddr.split(":")[0]+'" rel="noreferrer noopener" target="MeshIPLoopup">'+currentNode.lastaddr.split(":")[0]+"</a>")}}I+=addHtmlValue2("Last interfaces update",new Date(l.updateTime).toLocaleString());for(var d in l.netif){var q=l.netif[d];I+="<hr />";if(q.name){I+=addHtmlValue2("Name","<b>"+EscapeHtml(q.name)+"</b>")}if(q.desc){I+=addHtmlValue2("Description",EscapeHtml(q.desc).replace("(R)","&reg;").replace("(r)","&reg;"))}if(q.dnssuffix){I+=addHtmlValue2("DNS suffix",EscapeHtml(q.dnssuffix))}if(q.mac){I+=addHtmlValue2("MAC address",'<a href="https://dnslytics.com/mac-address-lookup/'+q.mac.substring(0,6)+'" rel="noreferrer noopener" target="MeshMACLoopup">'+EscapeHtml(q.mac.toLowerCase())+"</a>")}if(q.v4addr){I+=addHtmlValue2("IPv4 address",EscapeHtml(q.v4addr))}if(q.v4mask){I+=addHtmlValue2("IPv4 mask",EscapeHtml(q.v4mask))}if(q.v4gateway){I+=addHtmlValue2("IPv4 gateway",EscapeHtml(q.v4gateway))}if(q.gatewaymac){I+=addHtmlValue2("Gateway MAC",'<a href="https://dnslytics.com/mac-address-lookup/'+q.gatewaymac.substring(0,6)+'" rel="noreferrer noopener" target="MeshMACLoopup">'+EscapeHtml(q.gatewaymac.toLowerCase())+"</a>")}}I+="</div>";QH("d2netinfo",I)}}break;case"serverversion":if((xxdialogMode==2)&&(xxdialogTag=="MeshCentralServerUpdate")){var I="<div style=width:100%;max-height:260px;overflow-x:hidden;overflow-y:auto;line-height:160%>";if(!l.current){l.current="Unknown"}if(!l.latest){l.latest="Unknown"}I+=addHtmlValue2("Current Version","<b>"+EscapeHtml(l.current)+"</b>");I+=addHtmlValue2("Latest Version","<b>"+EscapeHtml(l.latest)+"</b>");I+="</div>";if((l.latest.indexOf(".")==-1)||(l.current==l.latest)||((features&2048)==0)){setDialogMode(2,"MeshCentral Version",1,null,I)}else{setDialogMode(2,"MeshCentral Version",3,server_showVersionDlgEx,I+"<br /><label><input id=d2updateCheck type=checkbox onclick=server_showVersionDlgUpdate() /> Check and click OK to start server self-update.</label>");server_showVersionDlgUpdate()}}break;case"servererrors":if((xxdialogMode==2)&&(xxdialogTag=="MeshCentralServerErrors")){if(l.data==null){setDialogMode(2,"MeshCentral Server Errors",1,null,"Server has no error log.")}else{var I="<div style=width:100%;max-height:260px;overflow-x:hidden;overflow:auto;line-height:160%;font-size:10px><pre>"+l.data+"<pre></div>";setDialogMode(2,"MeshCentral Server Errors",3,server_showErrorsDlgEx,I+"<br /><label><input id=d2updateCheck type=checkbox onclick=server_showVersionDlgUpdate() /> Check and click OK to clear error log.</label>");server_showVersionDlgUpdate()}}break;case"serverconsole":p15consoleReceive("serverconsole",l.value);break;case"events":if((l.nodeid!=null)&&(l.nodeid==currentNode._id)){currentDeviceEvents=l.events;masterUpdate(1024)}else{if((l.user!=null)&&(l.user==currentUser.name)){currentUserEvents=l.events;masterUpdate(2048)}else{events=l.events;masterUpdate(32)}}break;case"getcookie":if(l.tag=="clickonce"){var a="{{{serverRedirPort}}}"==""?"{{{serverPublicPort}}}":"{{{serverRedirPort}}}";var A="http://"+window.location.hostname+":"+a+"/clickonce/minirouter/MeshMiniRouter.application?WS=wss%3A%2F%2F"+window.location.hostname+"%2Fmeshrelay.ashx%3Fauth="+l.cookie+"&CH={{{webcerthash}}}&AP="+l.protocol+((debugmode==1)?"":"&HOL=1");var u=window.open(A,"_blank");u.opener=null}break;case"getNotes":var o=Q("d2devNotes");if(o&&(l.id==decodeURIComponent(o.attributes.noteid.value))){if(l.notes){QH("d2devNotes",decodeURIComponent(l.notes))}else{QH("d2devNotes","")}var B=o.attributes.ro.value=="true";if(B==false){o.removeAttribute("readonly");QE("idx_dlgOkButton",true);QV("idx_dlgOkButton",true);focusTextBox("d2devNotes")}}break;case"otpauth-request":if((xxdialogMode==2)&&(xxdialogTag=="otpauth-request")){var C=l.secret;if(C.length==52){C=C.split(/(.............)/).filter(Boolean).join(" ")}else{if(C.length==32){C=C.split(/(....)/).filter(Boolean).join(" ");C=C.substring(0,20)+"<br/>"+C.substring(20)}}QH("d2optinfo",'<table style=width:380px><tr><td style=vertical-align:top>Install <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" rel="noreferrer noopener" target=_blank>Google Authenticator</a> or a compatible application and scan the barcode, use <a href="'+l.url+'" rel="noreferrer noopener" target=_blank> this link</a> or enter the secret. Then, enter the current 6 digit token below to activate 2-Step login.<br /><br />Secret<br /><tt id=d2optsecret secret="'+l.secret+'" style=font-size:12px>'+C+'</tt><br /><br /></td><td style=width:1px;vertical-align:top><a href="'+l.url+'" rel="noreferrer noopener" target=_blank><div id="qrcode"></div></a></td><tr><td colspan=2 style="text-align:center;border-top:1px solid black"><br />Enter the token here for 2-step login: <input type=text onkeypress="return (event.keyCode == 8) || (event.charCode >= 48 && event.charCode <= 57)" onkeyup=account_addOtpCheck(event) onkeydown=account_addOtpCheck() maxlength=6 id=d2otpauthinput type=text></td></table>');new QRCode(Q("qrcode"),{text:l.url,width:128,height:128,colorDark:"#000000",colorLight:"#EEE",correctLevel:QRCode.CorrectLevel.H});QV("idx_dlgOkButton",true);QE("idx_dlgOkButton",false);Q("d2otpauthinput").focus()}break;case"otpauth-setup":if(xxdialogMode){return}setDialogMode(2,"Authenticator App",1,null,l.success?"<b style=color:green>Authenticator app activation successful</b>. You will now need a valid token to login again.":"<b style=color:red>2-step login activation failed</b>. Clear the secret from the application and try again. You only have a few minutes to enter the proper code.");break;case"otpauth-clear":if(xxdialogMode){return}setDialogMode(2,"Authenticator App",1,null,l.success?"<b>Authenticator application removed</b>. You can reactivate this feature at any time.":"<b style=color:red>2-step login activation removal failed</b>. Try again.");break;case"otpauth-getpasswords":if(xxdialogMode){return}var I="One time tokens can be used as secondary authentication. Generate a set, print them and keep them in a safe place.";I+="<div style='border-radius:6px;border: 2px dashed #888;width:100%;margin-top:8px'><div style='padding:8px;font-family:Arial, Helvetica, sans-serif;font-size:20px;font-weight:bold'><table style=width:100%;text-align:center>";if(l.passwords){var g=0;for(var d in l.passwords){if(++g%2){I+="<tr>"}var y=""+l.passwords[d].p;while(y.length<8){y="0"+y}if(l.passwords[d].u===true){I+="<td>"+y.substring(0,4)+"&nbsp;"+y.substring(4)}else{I+="<td><strike style=color:#BBB>"+y.substring(0,4)+"&nbsp;"+y.substring(4);+"</strike>"}}}else{I+="<tr><td>No Active Tokens"}I+="</table></div></div><br />";I+="<div><input type=button value='Close' onclick=setDialogMode(0) style=float:right></input>";I+="<input type=button value='Generate New Tokens' onclick='account_manageOtp(1);'></input>";if(l.passwords!=null){I+="<input type=button value='Clear Tokens' onclick='account_manageOtp(2);'></input>"}I+="</div><br />";setDialogMode(2,"Manage Backup Codes",8,null,I,"otpauth-manage");break;case"otp-hkey-get":if(xxdialogMode&&(xxdialogTag!="otpauth-hardware-manage")){return}var F="<div style='border-radius:6px;border:2px solid #CCC;background-color:#BBB;width:100%;box-sizing:border-box;margin-bottom:6px'><div style='margin:3px;font-family:Arial, Helvetica, sans-serif;font-size:16px;font-weight:bold'><table style=width:100%;text-align:left>";var b="</table></div></div>";var I="<a href='https://www.yubico.com/' rel='noreferrer noopener' target='_blank'>Hardware keys</a> are used as secondary login authentication.";I+="<div style='max-height:150px;overflow-y:auto;overflow-x:hidden;margin-top:6px;margin-bottom:6px'>";if(l.keys&&l.keys.length>0){for(var d in l.keys){var h=l.keys[d],H=(h.type==1)?"U2F":"OTP";I+=F+'<tr style=margin:5px><td style=width:30px><img width=24 height=18 src="images/hardware-key-'+H+'-24.png" style=margin-top:4px><td style=width:250px>'+h.name+"<td><input type=button value='Remove' onclick=account_removehkey("+h.i+")></input>"+b}}else{I+=F+"<tr style=text-align:center><td>No Keys Configured"+b}I+="</div>";I+="<div><input type=button value='Close' onclick=setDialogMode(0) style=float:right></input>";I+="<input id=d2addkey1 type=button value='Add U2F Key' onclick='account_addhkey(1);'></input>";if((features&16384)!=0){I+="<input id=d2addkey2 type=button value='Add OTP Key' onclick='account_addhkey(2);'></input>"}I+="</div><br />";setDialogMode(2,"Manage Security Keys",8,null,I,"otpauth-hardware-manage");if(u2fSupported()==false){QE("d2addkey1",false)}break;case"otp-hkey-yubikey-add":if(l.result){meshserver.send({action:"otp-hkey-get"})}else{setDialogMode(2,"Add Security Key",1,null,"<br />Error, Unable to add key.<br /><br />")}break;case"otp-hkey-setup-request":if(xxdialogMode&&(xxdialogTag!="otpauth-hardware-manage")){return}var I="Press the key button now.<br /><br /><div style=width:100%;text-align:center><img width=120 height=117 src='images/hardware-keypress-120.png' /></div><input id=dp1keyname style=display:none value="+l.name+" />";setDialogMode(2,"Add Security Key",2,null,I);window.u2f.register(l.request.appId,l.request.registerRequests,l.request.registeredKeys,function(m){if(m.registrationData){meshserver.send({action:"otp-hkey-setup-response",response:m,name:Q("dp1keyname").value});setDialogMode(2,"Add Security Key",0,null,"<br />Checking...<br /><br /><br />","otpauth-hardware-manage")}else{var j=["","Unknown error","Bad request","Unsupported configuration","This key was already registered","Timeout"];setDialogMode(2,"Add Security Key",1,null,"<br />"+j[m.errorCode]+".<br /><br />")}},l.request.timeoutSeconds);break;case"otp-hkey-setup-response":if(xxdialogMode&&(xxdialogTag!="otpauth-hardware-manage")){return}if(l.result==true){meshserver.send({action:"otp-hkey-get"})}else{setDialogMode(2,"Add Security Key",1,null,"<br />ERROR: Unable to add key.<br /><br />","otpauth-hardware-manage")}break;case"event":if(!l.event.nolog){events.unshift(l.event);var c=parseInt(p3limitdropdown.value);while(events.length>c){events.pop()}masterUpdate(32)}switch(l.event.action){case"accountcreate":case"accountchange":if(userinfo.name==l.event.account.name){var t=l.event.account.siteadmin?l.event.account.siteadmin:0;var w=userinfo.siteadmin?userinfo.siteadmin:0;if((l.event.account.quota!=userinfo.quota)||(((userinfo.siteadmin&8)==0)&&((l.event.account.siteadmin&8)!=0))){meshserver.send({action:"files"})}userinfo=l.event.account;if(w!=t){updateSiteAdmin()}updateSelf()}if(users==null){break}users[l.event.account._id]=l.event.account;updateUsers();break;case"accountremove":if(users==null){break}delete users["user/"+domain+"/"+l.event.username.toLowerCase()];updateUsers();break;case"createmesh":if(l.event.links["user/"+domain+"/"+userinfo.name.toLowerCase()]!=null){meshes[l.event.meshid]={_id:l.event.meshid,name:l.event.name,mtype:l.event.mtype,desc:l.event.desc,links:l.event.links};masterUpdate(4+128);meshserver.send({action:"files"})}break;case"meshchange":if(meshes[l.event.meshid]==null){meshes[l.event.meshid]={_id:l.event.meshid,name:l.event.name,mtype:l.event.mtype,desc:l.event.desc,links:l.event.links};meshserver.send({action:"nodes"})}else{if(l.event.name){meshes[l.event.meshid].name=l.event.name}if(l.event.desc){meshes[l.event.meshid].desc=l.event.desc}if(l.event.flags!=null){meshes[l.event.meshid].flags=l.event.flags}if(l.event.links){meshes[l.event.meshid].links=l.event.links}if(l.event.amt){meshes[l.event.meshid].amt=l.event.amt}if(meshes[l.event.meshid].links["user/"+domain+"/"+userinfo.name.toLowerCase()]==null){if((xxcurrentView==20)&&(currentMesh==meshes[l.event.meshid])){go(2)}delete meshes[l.event.meshid];var s=[];for(var d in nodes){if(nodes[d].meshid!=l.event.meshid){s.push(nodes[d])}}nodes=s;if(xxcurrentView>=10&&xxcurrentView<20&&currentNode&&currentNode.meshid==l.event.meshid){setDialogMode(0);go(1)}}}masterUpdate(4+128);if(xxcurrentView==20&&currentMesh._id==l.event.meshid){p20updateMesh()}break;case"deletemesh":if(meshes[l.event.meshid]){delete meshes[l.event.meshid];masterUpdate(128);meshserver.send({action:"files"})}var s=[];if(nodes!=null){for(var d in nodes){if(nodes[d].meshid!=l.event.meshid){s.push(nodes[d])}}}nodes=s;masterUpdate(4);if(xxcurrentView>=20&&xxcurrentView<30&&currentMesh._id==l.event.meshid){setDialogMode(0);go(2)}if(xxcurrentView>=10&&xxcurrentView<20&&currentNode&&currentNode.meshid==l.event.meshid){setDialogMode(0);go(1)}break;case"addnode":var v=l.event.node;if(!meshes[v.meshid]){break}v.namel=v.name.toLowerCase();if(v.rname){v.rnamel=v.rname.toLowerCase()}else{v.rnamel=v.namel}v.meshnamel=meshes[v.meshid].name.toLowerCase();v.state=0;if(!v.icon){v.icon=1}v.ident=++nodeShortIdent;if(nodes==null){}nodes.push(v);masterUpdate(1|2|4|16);break;case"removenode":var e=-1;for(var d in nodes){if(nodes[d]._id==l.event.nodeid){e=d;break}}if(e!=-1){var v=nodes[e];if(currentNode==v){if(xxcurrentView>=10&&xxcurrentView<20){setDialogMode(0);go(1)}currentNode=null}nodes.splice(e,1);masterUpdate(4|16)}break;case"changenode":var e=-1;for(var d in nodes){if(nodes[d]._id==l.event.nodeid){e=d;break}}if(e!=-1){var v=nodes[e];v.name=l.event.node.name;v.rname=l.event.node.rname;v.users=l.event.node.users;v.host=l.event.node.host;v.desc=l.event.node.desc;v.osdesc=l.event.node.osdesc;v.publicip=l.event.node.publicip;v.iploc=l.event.node.iploc;v.wifiloc=l.event.node.wifiloc;v.gpsloc=l.event.node.gpsloc;v.tags=l.event.node.tags;v.userloc=l.event.node.userloc;if(l.event.node.agent!=null){if(v.agent==null){v.agent={}}if(l.event.node.agent.ver!=null){v.agent.ver=l.event.node.agent.ver}if(l.event.node.agent.id!=null){v.agent.id=l.event.node.agent.id}if(l.event.node.agent.caps!=null){v.agent.caps=l.event.node.agent.caps}if(l.event.node.agent.core!=null){v.agent.core=l.event.node.agent.core}else{if(v.agent.core){delete v.agent.core}}v.agent.tag=l.event.node.agent.tag}if(l.event.node.intelamt!=null){if(v.intelamt==null){v.intelamt={}}if(l.event.node.intelamt.host!=null){v.intelamt.user=l.event.node.intelamt.host}if(l.event.node.intelamt.user!=null){v.intelamt.user=l.event.node.intelamt.user}if(l.event.node.intelamt.tls!=null){v.intelamt.tls=l.event.node.intelamt.tls}if(l.event.node.intelamt.ver!=null){v.intelamt.ver=l.event.node.intelamt.ver}if(l.event.node.intelamt.state!=null){v.intelamt.state=l.event.node.intelamt.state}}v.namel=v.name.toLowerCase();if(v.rname){v.rnamel=v.rname.toLowerCase()}else{v.rnamel=v.namel}if(l.event.node.icon){v.icon=l.event.node.icon}masterUpdate(2|4|8|16);refreshDevice(v._id);if((currentNode==v)&&(xxdialogMode!=null)&&(xxdialogTag=="@xxmap")){p10showNodeLocationDialog()}}break;case"nodemeshchange":var e=-1;for(var d in nodes){if(nodes[d]._id==l.event.nodeid){e=d;break}}if(e!=-1){var v=nodes[e];if(meshes[l.event.newMeshId]==null){if(currentNode==v){if(xxcurrentView>=10&&xxcurrentView<20){setDialogMode(0);go(1)}currentNode=null}nodes.splice(e,1);masterUpdate(4|16)}else{v.meshid=l.event.newMeshId;v.meshnamel=meshes[l.event.newMeshId].name.toLowerCase();masterUpdate(1|2|4)}refreshDevice(l.event.nodeid)}else{var v=l.event.node;if(!meshes[v.meshid]){break}v.namel=v.name.toLowerCase();if(v.rname){v.rnamel=v.rname.toLowerCase()}else{v.rnamel=v.namel}v.meshnamel=meshes[v.meshid].name.toLowerCase();v.state=0;if(!v.icon){v.icon=1}v.ident=++nodeShortIdent;if(nodes==null){}nodes.push(v);masterUpdate(1|2|4|16)}break;case"nodeconnect":var e=-1;for(var d in nodes){if(nodes[d]._id==l.event.nodeid){e=d;break}}if(e!=-1){var v=nodes[e];v.conn=l.event.conn;v.pwr=l.event.pwr;masterUpdate(4|16);refreshDevice(v._id)}break;case"wssessioncount":if(wssessions!=null){if(l.event.count==0&&wssessions["user/"+domain+"/"+l.event.username.toLowerCase()]){delete wssessions["user/"+domain+"/"+l.event.username.toLowerCase()]}else{wssessions["user/"+domain+"/"+l.event.username.toLowerCase()]=l.event.count}updateUsers()}break;case"clearevents":events=[];masterUpdate(32);break;case"login":if(users!=null&&users["user/"+domain+"/"+l.event.username.toLowerCase()]){users["user/"+domain+"/"+l.event.username.toLowerCase()].login=Math.floor(new Date(l.event.time).getTime()/1000)}break;case"scanamtdevice":if((xxdialogMode==null)||(!Q("dp1range"))||(Q("dp1range").value!=l.event.range)){return}var I="";if(l.event.results==null){I="<div style=width:100%;text-align:center;margin-top:12px>Unable to scan this address range.</div><div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>Sample IP range values<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>"}else{amtScanResults=l.event.results;for(var d in l.event.results){var z=l.event.results[d],E=z.hostname;if(E.length>20){E=E.substring(0,20)+"..."}var G='<b title="'+EscapeHtml(z.hostname)+'">'+EscapeHtml(E)+"</b> - v"+z.ver;if(z.state==2){if(z.tls==1){G+=" with TLS."}else{G+=" without TLS."}}else{G+=" not activated."}I+='<div style=width:100%;margin-bottom:2px;background-color:lightgray><div style=padding:4px><div style=display:inline-block;margin-right:5px><input class=DevScanCheckbox name=dp1checkbox tag="'+EscapeHtml(d)+'" type=checkbox onclick=addAmtScanToMeshCheckbox() /></div><div class=j1 style=display:inline-block></div><div style=display:inline-block;margin-left:5px;overflow-x:auto;white-space:nowrap>'+G+"</div></div></div>"}if(I==""){I="<div style=width:100%;text-align:center;margin-top:12px>Scan returned no results.</div><div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>Sample IP range values<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>"}}QH("dp1results",I);QE("dp1range",true);QE("dp1rangebutton",true);break;case"notify":var o={text:l.event.value};if(l.event.tag!=null){o.tag=l.event.tag}addNotification(o);break;case"stopped":break;default:break}break;case"stopped":autoReconnect=false;QH("p0span",l.msg);break;default:console.log("Unknown message.action",l.action);break}}function onRealNameCheckBox(){showRealNames=Q("RealNameCheckBox").checked;putstore("showRealNames",showRealNames?1:0);masterUpdate(6);return}function onDeviceViewChange(a){if(a!=null){Q("viewselect").value=a}for(var b=1;b<5;b++){Q("devViewButton"+b).classList.remove("viewSelectorSel")}Q("devViewButton"+Q("viewselect").value).classList.add("viewSelectorSel");putstore("deviceView",Q("viewselect").value);putstore("viewsize",Q("sizeselect").value);masterUpdate(4)}function ondockeypress(a){if(!xxdialogMode&&xxcurrentView==11&&desktop&&Q("DeskControl").checked){if(currentNode!=null){var d=meshes[currentNode.meshid];var g=d.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;var b=((g==4294967295)||(((g&8)!=0)&&((g&256)==0)));if(b==false){return false}var c=((g!=4294967295)||(((g&8)!=0)&&((g&256)==0)&&((g&4096)!=0)));if(c==true){if((a.altKey==true)||(a.ctrlKey==true)||(a.keyCode<32)||(a.keyCode>90)){return false}}}return desktop.m.handleKeys(a)}if(!xxdialogMode&&xxcurrentView==12&&terminal&&terminal.State==3){return terminal.m.TermHandleKeys(a)}if(!xxdialogMode&&((xxcurrentView==15)||(xxcurrentView==115))){return agentConsoleHandleKeys(a)}if(!xxdialogMode&&xxcurrentView==4){if(a.ctrlKey==true||a.altKey==true||a.metaKey==true){return}var h=0;if(a.key){if(a.key.length===1&&userSearchFocus==0){Q("UserSearchInput").value=((Q("UserSearchInput").value+a.key));h=1}if(a.keyCode==8&&userSearchFocus==0){var j=Q("UserSearchInput").value;Q("UserSearchInput").value=j.substring(0,j.length-1);h=1}if(a.keyCode==27){Q("UserSearchInput").value="";h=1}}else{if(a.charCode!=0&&userSearchFocus==0){Q("UserSearchInput").value=((Q("UserSearchInput").value+String.fromCharCode(a.charCode)));h=1}}if(h>0){if(h==1){onUserSearchInputChanged()}return haltEvent(a)}}if(xxdialogMode||xxcurrentView!=1){return}if(a.ctrlKey==true&&a.charCode==96){showRealNames=!showRealNames;Q("RealNameCheckBox").value=showRealNames;putstore("showRealNames",showRealNames?1:0);masterUpdate(6);return}if(a.ctrlKey==true||a.altKey==true||a.metaKey==true){return}if(Q("viewselect").value<3){var h=0;if(a.key){if(a.key.length===1&&searchFocus==0){Q("SearchInput").value=((Q("SearchInput").value+a.key));h=1}if(a.keyCode==8&&searchFocus==0){var j=Q("SearchInput").value;Q("SearchInput").value=j.substring(0,j.length-1);h=1}if(a.keyCode==27){Q("SearchInput").value="";h=1}}else{if(a.charCode!=0&&searchFocus==0){Q("SearchInput").value=((Q("SearchInput").value+String.fromCharCode(a.charCode)));h=1}}if(h>0){if(h==1){masterUpdate(5)}return haltEvent(a)}}if(Q("viewselect").value==3){if(a.key){if(a.key.length===1&&mapSearchFocus==0){Q("mapSearchLocation").value=((Q("mapSearchLocation").value+a.key));h=1}if(a.keyCode==27){Q("mapSearchLocation").value="";mapCloseSearchWindow();h=1}if(a.keyCode==13){getSearchLocation()}}else{if(a.charCode!=0&&mapSearchFocus==0){Q("mapSearchLocation").value=((Q("mapSearchLocation").value+String.fromCharCode(a.charCode)));h=1}}}}function ondockeydown(a){if(!xxdialogMode&&xxcurrentView==11&&desktop&&Q("DeskControl").checked){if(currentNode!=null){var d=meshes[currentNode.meshid];var g=d.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;var b=((g==4294967295)||(((g&8)!=0)&&((g&256)==0)));if(b==false){return false}var c=((g!=4294967295)||(((g&8)!=0)&&((g&256)==0)&&((g&4096)!=0)));if(c==true){if((a.altKey==true)||(a.ctrlKey==true)||(a.keyCode<32)||(a.keyCode>90)){return false}}}return desktop.m.handleKeyDown(a)}if(!xxdialogMode&&xxcurrentView==12&&terminal&&terminal.State==3){return terminal.m.TermHandleKeyDown(a)}if(!xxdialogMode&&xxcurrentView==13&&a.keyCode==116&&p13filetree!=null){haltEvent(a);return false}if(!xxdialogMode&&((xxcurrentView==15)||(xxcurrentView==115))){return agentConsoleHandleKeys(a)}if(!xxdialogMode&&xxcurrentView==4){if(a.keyCode===8&&userSearchFocus==0){var j=Q("UserSearchInput").value;Q("UserSearchInput").value=(j.substring(0,j.length-1));h=1}if(a.keyCode===27){Q("UserSearchInput").value="";h=1}if(h>0){if(h==1){masterUpdate(5)}return haltEvent(a)}}if(xxdialogMode||xxcurrentView!=1||a.ctrlKey==true||a.altKey==true||a.metaKey==true){return}var h=0;if(Q("viewselect").value<3){if(a.keyCode===8&&searchFocus==0){var j=Q("SearchInput").value;Q("SearchInput").value=(j.substring(0,j.length-1));h=1}if(a.keyCode===27){Q("SearchInput").value="";h=1}if(h>0){if(h==1){masterUpdate(5)}return haltEvent(a)}}if(Q("viewselect").value==3){if(a.keyCode===8&&mapSearchFocus==0){var j=Q("mapSearchLocation").value;Q("mapSearchLocation").value=(j.substring(0,j.length-1));h=1}if(a.keyCode===27){Q("mapSearchLocation").value="";mapCloseSearchWindow();h=1}}}function ondockeyup(a){if(!xxdialogMode&&xxcurrentView==11&&desktop&&Q("DeskControl").checked){if(currentNode!=null){var d=meshes[currentNode.meshid];var g=d.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;var b=((g==4294967295)||(((g&8)!=0)&&((g&256)==0)));if(b==false){return false}var c=((g!=4294967295)||(((g&8)!=0)&&((g&256)==0)&&((g&4096)!=0)));if(c==true){if((a.altKey==true)||(a.ctrlKey==true)||(a.keyCode<32)||(a.keyCode>90)){return false}}}return desktop.m.handleKeyUp(a)}if(!xxdialogMode&&xxcurrentView==12&&terminal&&terminal.State==3){return terminal.m.TermHandleKeyUp(a)}if(!xxdialogMode&&xxcurrentView==13&&a.keyCode==116&&p13filetree!=null){p13folderup(9999);haltEvent(a);return false}if(!xxdialogMode&&xxcurrentView==4){if((a.keyCode===8&&searchFocus==0)||a.keyCode===27){return haltEvent(a)}}if(xxdialogMode&&a.keyCode==27){dialogclose(0)}if(xxdialogMode||xxcurrentView!=0||a.ctrlKey==true||a.altKey==true||a.metaKey==true){return}if(Q("viewselect").value<3){if((a.keyCode===8&&searchFocus==0)||a.keyCode===27){return haltEvent(a)}}if(Q("viewselect").value==3){if((a.keyCode===8&&mapSearchFocus==0)||a.keyCode===27){return haltEvent(a)}}}function devMouseHover(b,c){var d=Q("viewselect").value;if(d==1){var a=b.children[1].children[1];a.children[0].classList.remove("g1s");a.children[1].classList.remove("e2s");a.children[2].classList.remove("g2s");if(c==1){a.children[0].classList.add("g1s");a.children[1].classList.add("e2s");a.children[2].classList.add("g2s")}}else{if(d==2){var a=b;a.children[2].classList.remove("g1s");a.children[4].classList.remove("e2s");a.children[3].classList.remove("g2s");if(c==1){a.children[2].classList.add("g1s");a.children[4].classList.add("e2s");a.children[3].classList.add("g2s")}}}}var deviceHeaderId=0;var deviceHeaderTotal=0;var deviceHeadersTitles={};var deviceHeaderCount;var deviceHeaders={};var oldviewmode=0;function updateDevices(){if(nodes==null){return}var H="",a=0,g=null,e=0,l={},O=Q("viewselect").value,s={},p={};QV("xdevices",O<4);QV("xdevicesmap",O==4);QV("devListToolbar",O<3);QV("kvmListToolbar",O==3);QV("devMapToolbar",O==4);QV("devListToolbarSize",O==3);QV("NoMeshesPanel",meshcount==0);QV("devListToolbarViewIcons",(meshcount!=0)&&(nodes.length>0));QV("devListToolbarSort",(meshcount!=0)&&(nodes.length>0)&&(O<4));if((meshcount==0)||(nodes.length==0)){O=1;sort=0}if(O==4){setTimeout(function(){if(xxmap.map!=null){xxmap.map.updateSize()}},200)}else{deviceHeaderId=0;deviceHeaderCount={};deviceHeaderTotal=0;deviceHeaders={};deviceHeadersTitles={};var x=[];if(sort==0){nodes.sort(meshSort)}else{if(sort==1){nodes.sort(powerSort)}else{if(sort==2){if(showRealNames==true){nodes.sort(deviceHostSort)}else{nodes.sort(deviceSort)}}}}var d=[],m=document.getElementsByClassName("DeviceCheckbox"),b=0;for(var t=0;t<m.length;t++){if(m[t].checked){d.push(m[t].value)}}if((oldviewmode<3)&&(O==3)){multiDesktopFilter=d}else{if((oldviewmode==3)&&(O<3)){d=multiDesktopFilter}}var M=Q("column_l").clientWidth-60;var k=Math.floor(M/301);k=301+Math.floor((M-(k*301))/k);for(var t in nodes){if(nodes[t].v==false){continue}var z=meshes[nodes[t].meshid],B=z.links["user/"+domain+"/"+userinfo.name.toLowerCase()];if(B==null){continue}var C=B.rights;if((O==3)&&(z.mtype==1)){continue}if(sort==0){if(nodes[t].meshid!=g){deviceHeaderSet();var o="";if(meshes[nodes[t].meshid].mtype==1){o="<span class=devHeaderx>, Intel&reg; AMT only</span>"}if((O==1)&&(g!=null)){if(a==2){H+="<td><div style=width:301px></div></td>"}if(H!=""){H+="</tr></table>"}}H+="<div class=DevSt style=width:100%;padding-top:4px><span style=float:right>";H+=getMeshActions(z,C);H+='</span><span id=MxMESH style=cursor:pointer onclick=gotoMesh("'+nodes[t].meshid+'")>'+EscapeHtml(meshes[nodes[t].meshid].name)+"</span>"+o+"<span id=DevxHeader"+deviceHeaderId+" class=devHeaderx></span></div>";g=nodes[t].meshid;l[g]=1;a=0}}else{if(sort==1){var G=nodes[t].pwr?nodes[t].pwr:0;if(G!==g){deviceHeaderSet();if((O==1)&&(g!==null)){if(a==2){H+="<td><div style=width:301px></div></td>"}if(H!=""){H+="</tr></table>"}}H+="<div class=DevSt style=width:100%;padding-top:4px><span>"+PowerStateStr2(nodes[t].pwr)+"</span><span id=DevxHeader"+deviceHeaderId+' class="devHeaderx"></span></div>';g=G;a=0}}else{if(sort==2){if(g==null){g="1"}}}}e++;var L=EscapeHtml(nodes[t].name);if(L.length==0){L="<i>None</i>"}if((nodes[t].rname!=null)&&(nodes[t].rname.length>0)){L+=" / "+EscapeHtml(nodes[t].rname)}var D=EscapeHtml(nodes[t].name);if(showRealNames==true&&nodes[t].rname!=null){D=EscapeHtml(nodes[t].rname)}if(D.length==0){D="<i>None</i>"}var u=nodes[t].icon;var F=NodeStateStr(nodes[t]);if((!nodes[t].conn)||(nodes[t].conn==0)){u+=" gray"}if(O==1){H+="<div id=devs onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=display:inline-block;width:"+k+'px;height:50px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:12px><input class="'+nodes[t].meshid+' DeviceCheckbox" onclick=p1updateInfo() value=devid_'+nodes[t]._id+" type=checkbox></div><div style=height:100%;cursor:pointer onclick=gotoDevice('"+nodes[t]._id+"',null,null,event)><div class=\"i"+u+'" style=width:50px;float:left></div><div style=height:100%><div class=g1></div><div class=e2><div class=e1 style=width:'+(k-100)+'px title="'+L+'">'+D+"</div><div>"+F+"</div></div><div class=g2></div></div></div></div>"}else{if(O==2){H+="<tr><td><div id=devs class=bar18 onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=height:18px;width:100%;font-size:medium>";H+='<div style=width:22px;float:left;background-color:white><input class="'+nodes[t].meshid+' DeviceCheckbox" onclick=p1updateInfo() value=devid_'+nodes[t]._id+" type=checkbox></div>";H+="<div style=float:left;height:18px;width:18px;background-color:white onclick=gotoDevice('"+nodes[t]._id+"',null,null,event)><div class=j"+u+" style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>";H+="<div class=g1 style=height:18px;float:left></div><div class=g2 style=height:18px;float:right></div>";H+='<div style=cursor:pointer;font-size:14px title="'+L+"\" onclick=gotoDevice('"+nodes[t]._id+"',null,null,event)><span style=float:right>"+F+"</span><span style=width:300px>"+D+"</span></div></div></td></tr>"}else{if((O==3)&&(nodes[t].conn&1)&&(((C&8)||(C&256))!=0)&&((nodes[t].agent.caps&1)!=0)){if((multiDesktopFilter.length==0)||(multiDesktopFilter.indexOf("devid_"+nodes[t]._id)>=0)){H+="<div id=devs style=display:inline-block;margin:1px;background-color:lightgray;border-radius:5px;position:relative><div style=padding:3px;cursor:pointer onclick=gotoDevice('"+nodes[t]._id+"',11,null,event)>";H+='<div class="j'+u+'" style=width:16px;float:left></div>&nbsp;'+D+"</div>";H+="<span onclick=gotoDevice('"+nodes[t]._id+"',null,null,event)></span><div id=xkvmid_"+nodes[t]._id.split("/")[2]+"><div id=skvmid_"+nodes[t]._id.split("/")[2]+' style="position:absolute;color:white;left:5px;top:27px;text-shadow:0px 0px 5px #000;z-index:1000;cursor:default" onclick=toggleKvmDevice(\''+nodes[t]._id+"')>Disconnected</div></div>";H+="</div>";x.push(nodes[t]._id)}}}}if((sort==3)&&(H!="")){if(nodes[t].tags){for(var w in nodes[t].tags){var K=nodes[t].tags[w];if(s[K]==null){s[K]=H;p[K]=1}else{s[K]+=H;p[K]+=1}if(O==3){break}}}H=""}deviceHeaderTotal++;if(typeof deviceHeaderCount[nodes[t].state]=="undefined"){deviceHeaderCount[nodes[t].state]=1}else{deviceHeaderCount[nodes[t].state]++}}if(sort==3){var q=[];for(var t in s){q.push(t)}q.sort(function(c,j){return c.toLowerCase().localeCompare(j.toLowerCase())});for(var w in q){var t=q[w];H+="<div class=DevSt style=width:100%;padding-top:4px><span>"+t+'</span><span class="devHeaderx">, '+p[t]+" device"+((p[t]>1)?"s":"")+"</span></div>"+s[t]}}if((H=="")&&(meshcount>0)&&(Q("SearchInput").value!="")){if(sort==3){H='<div style="margin:30px">No devices are included in any groups, click on a device\'s "Groups" to add to a group.</div>'}else{H='<div style="margin:30px">No devices matching this search.</div>'}}if((O==1)&&(a==2)){H+="<td><div style=width:301px></div></td>"}if((sort==0)&&(Q("SearchInput").value=="")&&(O<3)){for(var t in meshes){var y=meshes[t],A=y.links["user/"+domain+"/"+userinfo.name.toLowerCase()];if(A!=null){var C=A.rights;if(l[y._id]==null){if((g!="")&&(H!="")){H+="</tr></table>"}H+="<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt><span style=float:right>";H+=getMeshActions(y,C);H+='</span><span id=MxMESH style=cursor:pointer onclick=gotoMesh("'+y._id+'")>'+EscapeHtml(y.name)+"</span></td></tr><tr>";if(y.mtype==1){H+="<td><div style=padding:10px><i>No Intel&reg; AMT devices in this mesh";if((C&4)!=0){H+=', <a style=cursor:pointer onclick=addDeviceToMesh("'+y._id+'")>add one</a>'}}if(y.mtype==2){H+="<td><div style=padding:10px><i>No devices in this mesh";if((C&4)!=0){H+=', <a style=cursor:pointer onclick=addAgentToMesh("'+y._id+'")>add one</a>'}}H+=".</i></div></td>";g=y._id;e++}}}}H+="</tr></table><div style=height:1px></div>";H+="<div style=border-top-style:solid;border-top-width:1px;border-top-color:#DDDDDD;cursor:pointer;font-size:10px>";if((O<3)&&(sort==0)&&(meshcount>0)){H+='<a onclick=account_createMesh() title="Create a new group of devices." style=cursor:pointer>Add Device Group</a>&nbsp'}H+='<a onclick=p10showMeshCmdDialog(0) style=cursor:pointer title="Download MeshCmd, a command line tool that performs many functions.">MeshCmd</a></div>';H+="</div><br/>";QH("xdevices",H);deviceHeaderSet();var m=document.getElementsByClassName("DeviceCheckbox"),b=0;for(var t=0;t<m.length;t++){m[t].checked=(d.indexOf(m[t].value)>=0)}for(var t in deviceHeaders){QH(t,deviceHeaders[t])}for(var t in deviceHeadersTitles){Q(t).title=deviceHeadersTitles[t]}p1updateInfo();if(O==3){var P=[{x:180,y:101},{x:302,y:169},{x:454,y:255}][Q("sizeselect").selectedIndex];var I=P.x+2,N=M-5,R=Math.floor(N/I);R=I+Math.floor((N-(R*I))/R);P.y=P.y*(R/P.x);P.x=R;for(var t in multiDesktop){multiDesktop[t].xxdelete=true}for(var t in x){var v=x[t],J=v.split("/")[2],h=multiDesktop[v];if(h!=null){h.m.CanvasId.setAttribute("style","background-color:black;width:"+P.x+"px;height:"+P.y+"px");Q("xkvmid_"+J).appendChild(h.m.CanvasId);delete h.xxdelete;QH("skvmid_"+J,["Disconnected","Connecting...","Setup...","",""][((h.m.State==null)?h.m.state:h.m.State)])}else{var E=getNodeFromId(v);if((desktopNode==E)&&(desktop!=null)){var a=desktop.m.CanvasId;a.setAttribute("id","kvmid_"+J);a.setAttribute("style","background-color:black;width:"+P.x+"px;height:"+P.y+"px");a.setAttribute("onclick","toggleKvmDevice('"+v+"')");a.removeAttribute("onmousedown");a.removeAttribute("onmouseup");a.removeAttribute("onmousemove");Q("xkvmid_"+J).appendChild(a);QH("skvmid_"+J,["Disconnected","Connecting...","Setup...","",""][((desktop.m.State==null)?desktop.m.state:desktop.m.State)]);if(desktop.m.SendCompressionLevel){desktop.m.SendCompressionLevel(1,multidesktopsettings.quality,multidesktopsettings.scaling,multidesktopsettings.framerate)}desktop.shortid=J;desktop.onStateChanged=onMultiDesktopStateChange;multiDesktop[v]=desktop;desktop=desktopNode=currentNode=null;QH("DeskParent",'<canvas id="Desk" width="640" height="480" style="width:100%;-ms-touch-action:none;margin-left:0px" oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></canvas>')}else{var a=document.createElement("canvas");a.setAttribute("id","kvmid_"+J);a.setAttribute("width",640);a.setAttribute("height",480);a.setAttribute("oncontextmenu","return false");a.setAttribute("style","background-color:black;width:"+P.x+"px;height:"+P.y+"px");a.setAttribute("onclick","toggleKvmDevice('"+v+"')");try{Q("xkvmid_"+J).appendChild(a)}catch(n){}if(Q("autoConnectDesktopCheckbox").checked==true){setTimeout(function(){connectMultiDesktop(E,1)},100)}}}}for(var t in multiDesktop){if(multiDesktop[t].xxdelete==true){multiDesktop[t].Stop();delete multiDesktop[t]}else{if(debugmode&&multiDesktop[t].m&&multiDesktop[t].m.onScreenSizeChange){mdeskAdjust(multiDesktop[t].m,multiDesktop[t].m.ScreenWidth,multiDesktop[t].m.ScreenHeight,multiDesktop[t].m.CanvasId)}}}deskAdjust()}else{disconnectAllKvmFunction();Q("autoConnectDesktopCheckbox").checked=false}}oldviewmode=O}function toggleKvmDevice(d){var c=getNodeFromId(d),a=meshes[c.meshid],b=a.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;if((b&8)||(b&256)){if(c.conn&1){connectMultiDesktop(c,1)}}}function autoConnectDesktops(){if(Q("autoConnectDesktopCheckbox").checked==true){connectAllKvmFunction()}}function connectAllKvmFunction(){for(var a in nodes){if(multiDesktop[nodes[a]._id]==null){toggleKvmDevice(nodes[a]._id)}}}function disconnectAllKvmFunction(){for(var a in multiDesktop){multiDesktop[a].Stop()}multiDesktop={}}function onMultiDesktopStateChange(a,c){try{QH("skvmid_"+a.shortid,["Disconnected","Connecting...","Setup...","",""][c])}catch(b){}}function showMultiDesktopSettings(){QV("d7amtkvm",false);QV("d7meshkvm",true);d7bitmapquality.value=multidesktopsettings.quality;d7bitmapscaling.value=multidesktopsettings.scaling;if(multidesktopsettings.framerate){d7framelimiter.value=multidesktopsettings.framerate}else{d7framelimiter.value=1000}setDialogMode(7,"Remote Desktop Settings",3,showMultiDesktopSettingsChanged)}function showMultiDesktopSettingsChanged(){multidesktopsettings.quality=d7bitmapquality.value;multidesktopsettings.scaling=d7bitmapscaling.value;multidesktopsettings.framerate=d7framelimiter.value;localStorage.setItem("multidesktopsettings",JSON.stringify(multidesktopsettings));for(var a in multiDesktop){multiDesktop[a].m.SendCompressionLevel(1,multidesktopsettings.quality,multidesktopsettings.scaling,multidesktopsettings.framerate)}}function connectMultiDesktop(c,a){var d=c._id,e=d.split("/")[2];var b=multiDesktop[d];if(b==null){if(Q("kvmid_"+e)==null){return}if(a==2){if((c.intelamt.user==null)||(c.intelamt.user=="")){return}b=CreateAmtRedirect(CreateAmtRemoteDesktop("kvmid_"+e),authCookie);b.shortid=e;b.onStateChanged=onMultiDesktopStateChange;b.m.bpp=1;b.m.useZRLE=true;b.m.showmouse=true;b.m.onKvmData=function(g){console.log("KVM Data received in multi-desktop mode, this is not supported.")};if(debugmode>0){b.m.onScreenSizeChange=mdeskAdjust}b.Start(d,16994,"*","*",0);b.contype=2;multiDesktop[d]=b}else{if(a==1){b=CreateAgentRedirect(meshserver,CreateAgentRemoteDesktop("kvmid_"+e),serverPublicNamePort,authCookie);b.shortid=e;b.attemptWebRTC=attemptWebRTC;b.onStateChanged=onMultiDesktopStateChange;b.m.CompressionLevel=multidesktopsettings.quality;b.m.ScalingLevel=multidesktopsettings.scaling;b.m.FrameRateTimer=multidesktopsettings.framerate;if(debugmode>0){b.m.onScreenSizeChange=mdeskAdjust}b.Start(d);b.contype=1;multiDesktop[d]=b}}}else{b.Stop();delete multiDesktop[d]}}function getMeshActions(a,b){if((b&4)==0){return""}var c="";if((features&1024)==0){c+=' <a style=cursor:pointer;font-size:10px title="Add a new Intel&reg; AMT computer that is located on the internet." onclick=addCiraDeviceToMesh("'+a._id+'")>Add CIRA</a>'}if(a.mtype==1){if((features&1)==0){c+=' <a style=cursor:pointer;font-size:10px title="Add a new Intel&reg; AMT computer that is located on the local network." onclick=addDeviceToMesh("'+a._id+'")>Add Local</a>';c+=' <a style=cursor:pointer;font-size:10px title="Add a new Intel&reg; AMT computer by scanning the local network." onclick=addAmtScanToMesh("'+a._id+'")>Scan Network</a>'}}if(a.mtype==2){c+=' <a style=cursor:pointer;font-size:10px title="Add a new computer to this mesh by installing the mesh agent." onclick=addAgentToMesh("'+a._id+'")>Add Agent</a>';if(features&64){c+=' <a style=cursor:pointer;font-size:10px title="Invite someone to install the mesh agent on this mesh." onclick=inviteAgentToMesh("'+a._id+'")>Invite</a>'}}return c}function addDeviceToMesh(b){if(xxdialogMode){return}var a=meshes[b];var c='Add a new Intel&reg; AMT device to device group "'+EscapeHtml(a.name)+'".<br /><br />';c+=addHtmlValue("Device Name","<input id=dp1devicename style=width:230px maxlength=32 autocomplete=off onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />");c+=addHtmlValue("Hostname",'<input id=dp1hostname style=width:230px maxlength=32 autocomplete=off placeholder="Same as device name" onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');c+=addHtmlValue("Username",'<input id=dp1username style=width:230px maxlength=32 autocomplete=off placeholder="admin" onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');c+=addHtmlValue("Password","<input id=dp1password type=password style=width:230px autocomplete=off maxlength=32 onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />");c+=addHtmlValue("Security","<select id=dp1tls style=width:236px><option value=0>No TLS security</option><option value=1>TLS security required</option></select>");setDialogMode(2,"Add Intel&reg; AMT device",3,addDeviceToMeshEx,c,b);validateDeviceToMesh();Q("dp1devicename").focus()}function addAmtScanToMesh(a){if(xxdialogMode){return}var b="Enter a range of IP addresses to scan for Intel AMT devices.<br /><br />";b+=addHtmlValue("IP Range",'<input id=dp1range style=width:184px value="192.168.1.0/24" onkeyup=addAmtScanToMeshKeyUp(event) /><input id=dp1rangebutton type=button value=Scan onclick=addAmtScanToMeshButton()></input>');b+='<div id=dp1results style="width:100%;height:200px;background-color:white;border:1px gray solid;overflow-y:scroll"></div>';setDialogMode(2,"Scan for Intel&reg; AMT devices",3,addAmtScanToMeshEx,b,a);QE("idx_dlgOkButton",false);QH("dp1results","<div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>Sample IP range values<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>");focusTextBox("dp1range")}function addAmtScanToMeshKeyUp(a){if(a.keyCode==13){haltEvent(a);addAmtScanToMeshButton()}}function addAmtScanToMeshEx(b,h){var d=document.getElementsByClassName("DevScanCheckbox"),c=0;for(var e=0;e<d.length;e++){if(d[e].checked){var g=d[e].getAttribute("tag");var a=amtScanResults[g];meshserver.send({action:"addamtdevice",meshid:h,devicename:g,hostname:a.hostname,amtusername:"",amtpassword:"",amttls:a.tls})}}}function addAmtScanToMeshButton(){QE("dp1range",false);QE("dp1rangebutton",false);QH("dp1results","<div style=width:100%;text-align:center;margin-top:12px>Scanning...</div>");meshserver.send({action:"scanamtdevice",range:Q("dp1range").value})}function addAmtScanToMeshCheckbox(){var b=document.getElementsByClassName("DevScanCheckbox"),a=0;for(var c=0;c<b.length;c++){if(b[c].checked){a++}}QE("idx_dlgOkButton",a>0)}function addCiraDeviceToMesh(b){if(xxdialogMode){return}var a=meshes[b];var c=b.split("/")[2].replace(/\@/g,"X").replace(/\$/g,"X");var e="<select id=dlgAddCiraSel onclick=dlgAddCiraSelClick() style=width:230px><option value=0>MeshCommander Script</option><option value=1>Manual Username/Password</option>";if((features&16)==0){e+="<option value=2>Manual Certificate</option></select>"}var d="";d+=addHtmlValue("Setup Method",e);d+="<hr>";d+='<div id=dlgAddCira0>To add a new Intel&reg; AMT device to device group "'+EscapeHtml(a.name)+"\" with CIRA, download the following script files and use <a href='http://meshcommander.com' rel='noreferrer noopener' target='_blank'>MeshCommander</a> to run the script to configure computers.<br /><br />";d+=addHtmlValue("Setup CIRA",'<a style=cursor:pointer onclick=fileDownload("mescript.ashx?type=1&meshid='+c.substring(0,16)+'","cira_setup.mescript")>cira_setup.mescript</a>');d+=addHtmlValue("Cleanup CIRA",'<a style=cursor:pointer onclick=fileDownload("mescript.ashx?type=2","cira_clean.mescript")>cira_clean.mescript</a>');d+="</div>";d+='<div id=dlgAddCira1 style=display:none>To add a new Intel&reg; AMT device to device group "'+EscapeHtml(a.name)+'" with CIRA, load the following certificate as trusted root within Intel AMT';if(serverinfo.mpspass){d+=" and authenticate to the server using this username and password.<br /><br />"}else{d+=" and authenticate to the server using this username and any password.<br /><br />"}d+=addHtmlValue("Root Certificate",'<a style=cursor:pointer onclick=fileDownload("MeshServerRootCert.cer","MeshServerRootCert.cer")>Root Certificate File</a>');d+=addHtmlValue("Username",'<input style=width:230px readonly value="'+c.substring(0,16)+'" />');if(serverinfo.mpspass){d+=addHtmlValue("Password",'<input style=width:230px readonly value="'+EscapeHtml(serverinfo.mpspass)+'" />')}if(serverinfo!=null){d+=addHtmlValue("MPS Server",'<input style=width:230px readonly value="'+EscapeHtml(serverinfo.mpsname)+":"+serverinfo.mpsport+'" />')}d+="</div>";if((features&16)==0){d+='<div id=dlgAddCira2 style=display:none>To add a new Intel&reg; AMT device to device group "'+EscapeHtml(a.name)+'" with CIRA, load the following certificate as trusted root within Intel AMT, authenticate using a client certificate with the following common name and connect to the following server.<br /><br />';d+=addHtmlValue("Root Certificate",'<a style=cursor:pointer onclick=fileDownload("MeshServerRootCert.cer","MeshServerRootCert.cer")>Root Certificate File</a>');d+=addHtmlValue("Organization",'<input style=width:230px readonly value="'+c+'" />');if(serverinfo!=null){d+=addHtmlValue("MPS Server",'<input style=width:230px readonly value="'+EscapeHtml(serverinfo.mpsname)+":"+serverinfo.mpsport+'" />')}d+="</div>"}setDialogMode(2,"Add Intel&reg; AMT CIRA device",2,null,d,"fileDownload")}function dlgAddCiraSelClick(){var a=Q("dlgAddCiraSel").value;QV("dlgAddCira0",a==0);QV("dlgAddCira1",a==1);QV("dlgAddCira2",a==2)}function checkEmail(c){var d=c.split("@");var b=((d.length==2)&&(d[0].length>0)&&(d[1].split(".").length>1)&&(d[1].length>2));if(b==true){var e=d[1].split(".");for(var a in e){if(e[a].length==0){b=false}}}return b}function inviteAgentToMesh(b){if(xxdialogMode){return}var a=meshes[b];var c="Invite someone to install the mesh agent. An email with be sent with the link to the mesh agent installation for "+EscapeHtml(a.name)+".<br /><br />";c+=addHtmlValue("Name (optional)",'<input id=agentInviteName value="" style=width:230px maxlength=64 />');c+=addHtmlValue("Email",'<input id=agentInviteEmail style=width:230px placeholder="example@email.com" onkeyup=validateAgentInvite()></input>');c+=addHtmlValue("Operating System","<select id=agentInviteNameOs style=width:236px><option value=0>Any supported</option><option value=1>Windows only</option><option value=3>Apple OSX only</option><option value=2>Linux only</option></select>");c+=addHtmlValue("Installation Type","<select id=agentInviteType style=width:236px><option value=0>Background and interactive</option><option value=2>Background only</option><option value=1>Interactive only</option></select>");c+=addHtmlValue("Message<br />(optional)",'<textarea id=agentInviteMessage value="" style=width:230px;height:100px;resize:none maxlength=1024 /></textarea>');setDialogMode(2,"Invite",3,performAgentInvite,c,b);validateAgentInvite()}function validateAgentInvite(){QE("idx_dlgOkButton",checkEmail(Q("agentInviteEmail").value))}function performAgentInvite(a,b){meshserver.send({action:"inviteAgent",meshid:b,email:Q("agentInviteEmail").value,name:Q("agentInviteName").value,os:Q("agentInviteNameOs").value,flags:Q("agentInviteType").value,msg:Q("agentInviteMessage").value})}function addAgentToMesh(d){if(xxdialogMode){return}var b=meshes[d],j="",a=0;j+=addHtmlValue("Operating System","<select id=aginsSelect onchange=addAgentToMeshClick() style=width:236px><option value=0>Windows</option><option value=1>Linux</option><option value=2>Apple OSX</option><option value=3>Windows (UnInstall)</option><option value=4>Linux (UnInstall)</option></select>");j+="<div id=aginsTypeDiv>";j+=addHtmlValue("Installation Type","<select id=aginsType onchange=addAgentToMeshClick() style=width:236px><option value=0>Background & interactive</option><option value=2>Background only</option><option value=1>Interactive only</option></select>");j+="</div><hr>";var c=b.name;c=c.split("\\").join("").split("/").join("").split(":").join("").split("*").join("").split("?").join("").split('"').join("").split("<").join("").split(">").join("").split("|").join("").split(" ").join("").split("'").join("");j+='<div id=agins_windows>To add a new computer to device group "'+EscapeHtml(b.name)+'", download the mesh agent and install it the computer to manage. This agent has server and mesh information embedded within it.<br /><br />';j+=addHtmlValue("Mesh Agent",'<a id=aginsw32lnk style=cursor:pointer onclick=fileDownload("meshagents?id=3&meshid='+d.split("/")[2]+'&installflags=","MeshAgent-'+c+'.exe",1) title="32bit version of the MeshAgent">Windows (.exe)</a>');j+=addHtmlValue("Mesh Agent",'<a id=aginsw64lnk style=cursor:pointer onclick=fileDownload("meshagents?id=4&meshid='+d.split("/")[2]+'&installflags=","MeshAgent-'+c+'.exe",1) title="64bit version of the MeshAgent">Windows x64 (.exe)</a>');if(debugmode>0){j+=addHtmlValue("Settings File",'<a id=aginswmshlnk href="meshsettings?id='+d.split("/")[2]+'&installflags=0" rel="noreferrer noopener" target="_blank">'+EscapeHtml(b.name)+" settings (.msh)</a>")}j+="</div>";j+="<div id=agins_linux style=display:none>To add a computer to "+EscapeHtml(b.name)+" run the following command. Root credentials will be needed.<br />";j+="<textarea id=agins_linux_area rows=2 cols=20 readonly=readonly style=width:100%;resize:none;height:120px;overflow:scroll;font-size:12px readonly></textarea>";j+="</div>";j+='<div id=agins_osx style=display:none>To add a new computer to device group "'+EscapeHtml(b.name)+'", download the mesh agent and install it the computer to manage. This agent installer has server and mesh information embedded within it.<br /><br />';j+=addHtmlValue("Mesh Agent",'<a href="meshosxagent?id=16&meshid='+d.split("/")[2]+'" rel="noreferrer noopener" target="_blank" title="64bit version of OSX Mesh Agent">OSX Agent (64bit)</a>');j+="</div>";j+='<div id=agins_windows_un style=display:none>To remove a mesh agent, download the file below, run it and click "uninstall".<br /><br />';j+=addHtmlValue("Mesh Agent",'<a style=cursor:pointer onclick=fileDownload("meshagents?id=3","MeshAgent.exe") title="32bit version of the MeshAgent">Windows (.exe)</a>');j+=addHtmlValue("Mesh Agent",'<a style=cursor:pointer onclick=fileDownload("meshagents?id=4","MeshAgent.exe") title="64bit version of the MeshAgent">Windows x64 (.exe)</a>');j+="</div>";j+="<div id=agins_linux_un style=display:none>To remove a mesh agent, run the following command. Root credentials will be needed.<br />";j+="<textarea id=agins_linux_area_un rows=2 cols=20 readonly=readonly style=width:100%;resize:none;height:120px;overflow:scroll;font-size:12px readonly></textarea>";j+="</div>";setDialogMode(2,"Add Mesh Agent",2,null,j,"fileDownload");var h=serverinfo.name;if((h.indexOf(".")==-1)||((features&2)!=0)){h=window.location.hostname}var e=((features&8192)!=0)?"--no-proxy ":"";if(serverinfo.https==true){var g=(serverinfo.port==443)?"":(":"+serverinfo.port);Q("agins_linux_area").value="wget https://"+h+g+"/meshagents?script=1 "+e+"--no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://"+h+g+" '"+d.split("/")[2]+"'\r\n";Q("agins_linux_area_un").value="wget https://"+h+g+"/meshagents?script=1 "+e+"--no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n"}else{var g=(serverinfo.port==80)?"":(":"+serverinfo.port);Q("agins_linux_area").value="wget http://"+h+g+"/meshagents?script=1 "+e+"-O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://"+h+g+" '"+d.split("/")[2]+"'\r\n";Q("agins_linux_area_un").value="wget http://"+h+g+"/meshagents?script=1 "+e+"-O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n"}Q("aginsSelect").focus();addAgentToMeshClick()}function fileDownload(g,d,a){var h=null,c="";if(a==1){c=Q("aginsType").value}else{if(a==2){c=Q("aginsSelect").value;if(parseInt(c)>=5){d=d.toLowerCase()}else{d+=".exe"}}}try{h=new XDomainRequest()}catch(b){}if(!h){h=new XMLHttpRequest()}h.open("GET",window.location.href+g+c);h.timeout=15000;h.responseType="blob";h.onprogress=function(e){};h.onload=function(j){saveAs(new Blob([j.target.response],{type:"application/octet-stream"}),d);if(xxdialogTag=="fileDownload"){setDialogMode(0)}};h.onerror=function(){if(xxdialogTag=="fileDownload"){setDialogMode(0)}alert("Agent downloads timeout.")};h.ontimeout=function(){if(xxdialogTag=="fileDownload"){setDialogMode(0)}alert("Unable to download agent.")};h.send()}function addAgentToMeshClick(){var a=Q("aginsSelect").value;QV("agins_windows",a==0);QV("agins_linux",a==1);QV("agins_osx",a==2);QV("agins_windows_un",a==3);QV("agins_linux_un",a==4);QV("aginsTypeDiv",a==0);if(debugmode>0){Q("aginswmshlnk").href=(Q("aginswmshlnk").href.split("installflags=")[0])+"installflags="+Q("aginsType").value}}function validateDeviceToMesh(){QE("idx_dlgOkButton",(Q("dp1devicename").value.length>0)&&(passwordcheck(Q("dp1password").value)))}function addDeviceToMeshEx(b,d){var a=Q("dp1username").value;if(a==""){a="admin"}var c=Q("dp1hostname").value;if(c==""){c=Q("dp1devicename").value}meshserver.send({action:"addamtdevice",meshid:d,devicename:Q("dp1devicename").value,hostname:c,amtusername:a,amtpassword:Q("dp1password").value,amttls:Q("dp1tls").value})}function deviceHeaderSet(){if(deviceHeaderId==0){deviceHeaderId=1;return}deviceHeaders["DevxHeader"+deviceHeaderId]=", "+deviceHeaderTotal+((deviceHeaderTotal==1)?" node":" nodes");deviceHeaderId++;deviceHeaderCount={};deviceHeaderTotal=0}var powerStateStrings=["",'<span title="Device is powered on.">Powered</span>','<span title="Device is in sleep state (S1).">Sleeping</span>','<span title="Device is in sleep state (S2).">Sleeping</span>','<span title="Device is in deep sleep state (S3).">Deep Sleep</span>','<span title="Device is in hibernating state (S4).">Hibernating</span>','<span title="Device is in powered off state (S5).">Soft-Off</span>','<span title="Device is detected but power state could not be obtained.">Present</span>'];var powerStateStrings2=["","Device is powered","Device is in sleep state (S1)","Device is in sleep state (S2)","Device is in deep sleep state (S3)","Device is hibernating (S4)","Device is in soft-off state (S5)","Device is present, but power state cannot be determined"];var powerColorTable=["#00000000","black","blue","blue","lightblue","blueviolet","darkgreen","lightseagreen","lightseagreen"];function NodeStateStr(a){var b=[];if(a.state>0&&a.state<powerStatetable.length){state.push(powerStatetable[a.state])}if(a.conn){if((a.conn&1)!=0){b.push('<span title="Mesh agent is connected and ready for use.">Agent</span>')}if((a.conn&2)!=0){b.push('<span title="Intel&reg; AMT CIRA is connected and ready for use.">CIRA</span>')}else{if((a.conn&4)!=0){b.push('<span title="Intel&reg; AMT is routable.">Intel&reg; AMT</span>')}}if((a.conn&8)!=0){b.push('<span title="Mesh agent is reachable using another agent as relay.">Relay</span>')}}if((a.pwr!=null)&&(a.pwr!=0)){b.push(powerStateStrings[a.pwr])}return b.join(", ")}function PowerStateStr(a){if(a<powerStatetable.length){return powerStatetable[a]}return""}function PowerStateStr2(a){if((a!=0)&&(a<powerStatetable.length)){return powerStatetable[a]}return"Unknown"}function selectallButtonFunction(){var b=document.getElementsByClassName("DeviceCheckbox"),a=0;for(var c=0;c<b.length;c++){if(b[c].checked===true){a++}}for(var c=0;c<b.length;c++){b[c].checked=(a==0)}p1updateInfo()}function p1updateInfo(){var b=document.getElementsByClassName("DeviceCheckbox"),a=0;for(var c=0;c<b.length;c++){if(b[c].checked===true){a++}}if(a>0){QE("GroupActionButton",true);Q("SelectAllButton").value="Select None";QV("cxmgroupsplit",true);QV("cxmdesktop",true)}else{QE("GroupActionButton",false);Q("SelectAllButton").value="Select All";QV("cxmgroupsplit",false);QV("cxmdesktop",false)}}function groupActionFunction(){var a="Select an operation to perform on all selected devices. Actions will be performed only with proper rights.<br /><br />";a+=addHtmlValue("Operation","<select id=d2groupop style=float:right;width:250px><option value=100>Wake-up devices</option><option value=4>Sleep devices</option><option value=3>Reset devices</option><option value=2>Power off devices</option><option value=102>Move to device group</option><option value=101>Delete devices</option></select>");setDialogMode(2,"Group Action",3,groupActionFunctionEx,a)}function getCheckedDevices(){var e=[],b=document.getElementsByClassName("DeviceCheckbox"),a=0;for(var c=0;c<b.length;c++){if(b[c].checked){if(b[c].value){var d=b[c].value.substring(6);if(e.indexOf(d)==-1){e.push(d)}}}}return e}function groupActionFunctionEx(){var a=Q("d2groupop").value;if(a==100){meshserver.send({action:"wakedevices",nodeids:getCheckedDevices()})}else{if(a==101){var b="Confirm delete selected devices(s)?<br /><br />";b+="<label><input id=d2check type=checkbox onchange=d2groupActionFunctionDelEx() />Confirm</label>";setDialogMode(2,"Delete Nodes",3,groupActionFunctionDelEx,b);QE("idx_dlgOkButton",false)}else{if(a==102){p10showChangeGroupDialog(getCheckedDevices())}else{meshserver.send({action:"poweraction",nodeids:getCheckedDevices(),actiontype:a})}}}}function d2groupActionFunctionDelEx(){QE("idx_dlgOkButton",Q("d2check").checked)}function groupActionFunctionDelEx(){meshserver.send({action:"removedevices",nodeids:getCheckedDevices()})}function onSortSelectChange(a){sort=document.getElementById("sortselect").selectedIndex;if(!a){putstore("sort",sort)}}function meshSort(c,d){if(c.meshnamel>d.meshnamel){return 1}if(c.meshnamel<d.meshnamel){return -1}if(c.meshid==d.meshid){if(showRealNames==true){if(c.rnamel>d.rnamel){return 1}if(c.rnamel<d.rnamel){return -1}return 0}else{if(c.namel>d.namel){return 1}if(c.namel<d.namel){return -1}return 0}}return 0}function powerSort(c,e){var d=c.pwr?c.pwr:0;var g=e.pwr?e.pwr:0;if(d>g){return -1}if(d<g){return 1}if(d==g){if(showRealNames==true){if(c.rnamel>e.rnamel){return 1}if(c.rnamel<e.rnamel){return -1}return 0}else{if(c.namel>e.namel){return 1}if(c.namel<e.namel){return -1}return 0}}return 0}function deviceSort(c,d){if(c.namel>d.namel){return 1}if(c.namel<d.namel){return -1}return 0}function deviceHostSort(c,d){if(c.rnamel>d.rnamel){return 1}if(c.rnamel<d.rnamel){return -1}return 0}function onSearchFocus(a){searchFocus=a}function onMapSearchFocus(a){mapSearchFocus=a}function onUserSearchFocus(a){userSearchFocus=a}function onConsoleFocus(a){consoleFocus=a}function onSearchInputChanged(){var h=Q("SearchInput").value.toLowerCase().trim();putstore("search",h);if(h==""){for(var a in nodes){nodes[a].v=true}}else{try{var c=h.split(/\s+/).join("|"),e=new RegExp(c);for(var a in nodes){nodes[a].v=(e.test(nodes[a].name.toLowerCase()))||(nodes[a].rnamel!=null&&e.test(nodes[a].rnamel.toLowerCase()));if((nodes[a].v==false)&&nodes[a].tags){for(var g in nodes[a].tags){if(e.test(nodes[a].tags[g].toLowerCase())){nodes[a].v=true;break}else{nodes[a].v=false}}}}}catch(b){for(var a in nodes){nodes[a].v=true}}}}var contextelement=null;function handleContextMenu(d){hideContextMenu();var m=(window.pageXOffset!==null)?window.pageXOffset:(document.documentElement||document.body.parentNode||document.body).scrollLeft;var n=(window.pageYOffset!==null)?window.pageYOffset:(document.documentElement||document.body.parentNode||document.body).scrollTop;var c=document.elementFromPoint(d.pageX-m,d.pageY-n);if(c&&c!=null&&c.id=="MxMESH"){contextelement=c;var b=document.getElementById("meshContextMenu");b.style.left=d.pageX+"px";b.style.top=d.pageY+"px";b.style.display="block"}else{while(c&&c!=null&&c.id!="devs"){c=c.parentElement}if(!c||c==null){return true}contextelement=c;var b=document.getElementById("contextMenu");b.style.left=d.pageX+"px";b.style.top=d.pageY+"px";b.style.display="block"}var l=contextelement.children[1].attributes.onclick.value;var k=getNodeFromId(l.substring(12,l.length-18));var g=meshes[k.meshid];var h=g.links["user/"+domain+"/"+userinfo.name.toLowerCase()];var j=h.rights;var a=((j&16)!=0);var o=((j==4294967295)||((j&512)==0));var e=((j==4294967295)||((j&1024)==0));QV("cxdesktop",((g.mtype==1)||(k.agent==null)||(k.agent.caps==null)||((k.agent.caps&1)!=0)||(k.intelamt&&(k.intelamt.state==2)))&&((j&8)||(j&256)));QV("cxterminal",((g.mtype==1)||(k.agent==null)||(k.agent.caps==null)||((k.agent.caps&2)!=0)||(k.intelamt&&(k.intelamt.state==2)))&&(j&8)&&o);QV("cxfiles",((g.mtype==2)&&((k.agent==null)||(k.agent.caps==null)||((k.agent.caps&4)!=0)))&&(j&8)&&e);QV("cxevents",(k.intelamt!=null)&&((k.intelamt.state==2)||(k.conn&2))&&(j&8));QV("cxconsole",(a&&(g.mtype==2)&&((k.agent==null)||(k.agent.caps==null)||((k.agent.caps&8)!=0)))&&(j&8));return haltEvent(d)}function cmaction(a,b){var c=contextelement.children[1].attributes.onclick.value;c=c.substring(12,c.length-18);if(a==7){Q("viewselect").value=3;Q("viewselect").onchange();Q("autoConnectDesktopCheckbox").checked=true;Q("autoConnectDesktopCheckbox").onclick()}if((a>0)&&(a<7)){var d=[0,10,12,11,13,16,15][a];if(b&&(b.shiftKey==true)){window.open(window.location.origin+"?node="+c.split("/")[2]+"&viewmode="+d+"&hide=16","meshcentral:"+c)}else{gotoDevice(c,d)}}}function cmmeshaction(a){var d=contextelement.attributes.onclick.value.substring(32,(32+69));var b=document.getElementsByClassName("DeviceCheckbox");if(a==1){for(var c=0;c<b.length;c++){if((b[c].attributes)&&(b[c].attributes["class"]["value"].substring(0,69)==d)){b[c].checked=true}}}if(a==2){for(var c=0;c<b.length;c++){if((b[c].attributes)&&(b[c].attributes["class"]["value"].substring(0,69)==d)){b[c].checked=false}}}p1updateInfo()}function hideContextMenu(){QV("contextMenu",false);QV("meshContextMenu",false);contextelement=null}var xxmap={map:null,contextmenu:null,activeInteractions:[],showindex:0,markersSource:null,markersLayer:null,mapLayer:null,mapView:null,};function updateMapMarkers(j){if((xxmap!=null)&&(xxmap.map==null)){try{loadmap()}catch(b){console.error("loadmap() exception",b)}}if(xxmap==null){return}var a=null;for(var d in nodes){try{var g=map_parseNodeLoc(nodes[d]),c=xxmap.markersSource.getFeatureById(nodes[d]._id);if((g!=null)&&((nodes[d].meshid==j)||(j==null))){var e=g[0],h=g[1],k=g[2];if(a==null){a=[e,h,e,h,0]}else{if(e<a[0]){a[0]=e}if(h<a[1]){a[1]=h}if(e>a[2]){a[2]=e}if(h>a[3]){a[3]=h}}if(c==null){addFeature(nodes[d]);a[4]=1}else{updateFeature(nodes[d],c);c.setStyle(markerStyle(nodes[d],g[2]))}}else{if(c){xxmap.markersSource.removeFeature(c)}}}catch(b){console.error("updateMapMarkers() exception",b,JSON.stringify(nodes[d]))}}return a}var map_cm_popup=new ol.Overlay({element:Q("xmap-info-window"),positioning:"bottom-center",stopEvent:false});var map_cm_editMarker={text:"Modify node location",callback:function(a){modifyMarkerloc(a.data)}};var map_cm_clearMarker={text:"Remove node location",callback:function(a){meshserver.send({action:"changedevice",nodeid:a.data.a,userloc:[]})}};var map_cm_saveMarker={text:"Save node location",callback:function(a){saveMarkerloc(a.data)}};var map_cm_nodemenu_items=[{text:"General information",callback:function(a){if(a.data!=null){gotoDevice(a.data,10)}}},{text:"Desktop",callback:function(a){if(a.data!=null){gotoDevice(a.data,11)}}},{text:"Terminal",callback:function(a){if(a.data!=null){gotoDevice(a.data,12)}}},{text:"Intel&reg; AMT",callback:function(a){if(a.data!=null){gotoDevice(a.data,14)}}},"-",{text:"Zoom-in to extent",callback:function(b){var a=b.data.getGeometry().getCoordinates();zoomToLocation(a,19)}},{text:"Zoom-out to extent",callback:function(b){var a=b.data.getGeometry().getCoordinates();zoomToLocation(a,2)}}];var contextmenu_items=[{text:"Refresh",callback:function(){refreshMap(true,true)}},{text:"Zoom to fit extent",callback:function(){zoomToFitExtent()}},{text:"Center map here",callback:function(a){xxmap.mapView.animate({center:a.coordinate})}},{text:"Place node here",callback:function(a){placeNode(a.coordinate)}}];function stringToIntHash(c){var a=0,b;for(b=0;b<c.length;b++){a=((a<<5)-a)+c.charCodeAt(b);a|=0}return a}function map_parseNodeLoc(b){var a=null,c=0;if(b.iploc){a=b.iploc;c=1}if(b.wifiloc){a=b.wifiloc;c=2}if(b.gpsloc){a=b.gpsloc;c=3}if(b.userloc){a=b.userloc;c=4}if((a==null)||(typeof a!="string")){return null}a=a.split(",");if(c==1){return[parseFloat(a[0])+(stringToIntHash(b._id.substring(0,20))/100000000000),parseFloat(a[1])+(stringToIntHash(b._id.substring(20))/100000000000),c]}else{return[parseFloat(a[0]),parseFloat(a[1]),c]}}function loadmap(){if(xxmap==null){return}if((features&32768)==0){QV("viewselectmapoption",false);QV("devViewButton4",false);xxmap=null;return}try{xxmap.markersSource=new ol.source.Vector();xxmap.markersLayer=new ol.layer.Vector({source:xxmap.markersSource});xxmap.mapLayer=new ol.layer.Tile({source:new ol.source.OSM()});xxmap.mapView=new ol.View({center:ol.proj.transform([0,0],"EPSG:4326","EPSG:3857"),zoom:2,minZoom:2,maxZoom:20,extent:ol.proj.transformExtent([-100000,-69.55,100000,69.55],"EPSG:4326","EPSG:3857")});xxmap.map=new ol.Map({target:"xdevicesmap",layers:[xxmap.mapLayer,xxmap.markersLayer],view:xxmap.mapView});xxmap.map.addOverlay(map_cm_popup);xxmap.map.on("click",function(c){var d=xxmap.map.forEachFeatureAtPixel(c.pixel,function(h,j){return h});if(d){var g=d.getId();if(g!=null){gotoDevice(g,10)}else{var e=getCorrespondingFeature(d);gotoDevice(e.getId(),10)}}});xxmap.map.on("pointermove",function(d){var g=xxmap.map.forEachFeatureAtPixel(d.pixel,function(j,k){return j});if(g){xxmap.map.getTargetElement().style.cursor="pointer";var c=g.getGeometry().getCoordinates();map_cm_popup.setPosition(c);var e=g.getId();if(e){QH("xmap-info-window",g.get("name"))}else{var h=getCorrespondingFeature(g);QH("xmap-info-window",h.get("name"))}}else{xxmap.map.getTargetElement().style.cursor="";QH("xmap-info-window","")}});var a=new ContextMenu({width:160,defaultItems:false,items:contextmenu_items});a.on("open",function(c){var e=xxmap.map.forEachFeatureAtPixel(c.pixel,function(h,j){return h});xxmap.contextmenu.clear();if(e){var d=e.getId();if(d){addContextMenuItems(e)}else{var g=getCorrespondingFeature(e);if(g){addContextMenuItems(g)}else{xxmap.contextmenu.extend(contextmenu_items)}}}else{xxmap.contextmenu.extend(contextmenu_items)}});if(xxmap.contextmenu==null){xxmap.contextmenu=a}xxmap.map.addControl(xxmap.contextmenu)}catch(b){console.log(b);QV("viewselectmapoption",false);QV("devViewButton4",false);xxmap=null}}function addFeature(g,c,e){var a=getModifiedFeature(g._id);if(a){xxmap.markersSource.addFeature(a)}else{if(!c&&!e){var d=map_parseNodeLoc(g);c=d[0];e=d[1]}if(e>180){e=180-e;meshserver.send({action:"changedevice",nodeid:g._id,userloc:[c,e]})}if((c<90)&&(c>-90)&&(e<180)&&(e>-180)){var b=new ol.Feature({geometry:new ol.geom.Point(ol.proj.transform([e,c],"EPSG:4326","EPSG:3857")),name:g.name,status:g.conn,lat:c,lon:e});b.setId(g._id);b.setStyle(markerStyle(g));xxmap.markersSource.addFeature(b)}}}function removeFeature(b){var a=xxmap.markersSource.getFeatureById(b._id);if(a){xxmap.markersSource.removeFeature(a)}}function updateFeature(g,a){if(g.conn!=a.get("status")){a.set("status",g.conn);a.setStyle(markerStyle(g))}var c=map_parseNodeLoc(g);if(c!=null){var b=c[0],d=c[1];if((b!=a.get("lat"))||(d!=a.get("lon"))){a.set("lat",b);a.set("lon",d);var e=ol.proj.transform([parseFloat(d),parseFloat(b)],"EPSG:4326","EPSG:3857");a.getGeometry().setCoordinates(e)}}if(g.name!=a.get("name")){a.set("name",g.name)}}function modifyMarkerloc(c){var b=c.getId();if(b){c.setStyle(markerStyle(getNodeFromId(c.a),4));if(!getActiveInteractions(c)){var a=new ol.interaction.Modify({features:new ol.Collection([c]),pixelTolerance:10});xxmap.activeInteractions.push({featureid:b,feature:c,interaction:a});xxmap.map.addInteraction(a)}}}function saveMarkerloc(d){var c=d.getId();if(c){var a=getActiveInteractions(d);if(a){xxmap.map.removeInteraction(a);removeInteraction(c);var b=d.getGeometry().getCoordinates();var e=ol.proj.transform(b,"EPSG:3857","EPSG:4326");if(e[0]>180){e[0]=180-e[0]}var g=[e[1],e[0]];meshserver.send({action:"changedevice",nodeid:c,userloc:g})}}}function markerStyle(b,d){if(d==null){d=0;if(b.iploc){d=1}if(b.wifiloc){d=2}if(b.gpsloc){d=3}if(b.userloc){d=4}}var e=["","-ip","-wifi","-gps","-user"];var a=connStateColor(b);var c=new ol.style.Style({image:new ol.style.Icon({color:a,anchor:[0.5,1],src:"images/mapmarker"+e[d]+".png"})});return[c]}function connStateColor(a){if(a.conn==1||a.conn==3||a.conn==5){return"#00ffdd"}return"#C70039"}function addContextMenuItems(a){if(getActiveInteractions(a)){map_cm_saveMarker.data=a;xxmap.contextmenu.push(map_cm_saveMarker)}else{map_cm_editMarker.data=a;xxmap.contextmenu.push(map_cm_editMarker);var b=getNodeFromId(a.a);if(b.userloc){map_cm_clearMarker.data=a;xxmap.contextmenu.push(map_cm_clearMarker)}}map_cm_nodemenu_items.forEach(function(c){if(c.text=="Zoom-in to extent"||c.text=="Zoom-out to extent"){c.data=a}else{if(c!="-"){c.data=a.getId()}}});xxmap.contextmenu.extend(map_cm_nodemenu_items)}function getActiveInteractions(b){var a=b.getId();for(var c=0;c<xxmap.activeInteractions.length;c++){if(xxmap.activeInteractions[c].featureid==a){return xxmap.activeInteractions[c].interaction}}return false}function getModifiedFeature(a){if(a){for(var b=0;b<xxmap.activeInteractions.length;b++){if(xxmap.activeInteractions[b].featureid==a){return xxmap.activeInteractions[b].feature}}}return null}function removeInteraction(a){var c=-1;for(var b=0;b<xxmap.activeInteractions.length;b++){if(xxmap.activeInteractions[b].featureid===a){c=b;break}}if(c>=0){xxmap.activeInteractions.splice(c,1)}}function getCorrespondingFeature(e){var d=e.getGeometry().getCoordinates();for(var b=0;b<xxmap.activeInteractions.length;b++){var c=xxmap.activeInteractions[b].feature;var a=c.getGeometry().getCoordinates();if(a[0].toFixed(5)==d[0].toFixed(5)&&a[1].toFixed(5)==d[1].toFixed(5)){return c}}return null}function refreshMap(k,h){if(k){xxmap.map.setTarget(null);xxmap.map=null;xxmap.markersSource=null;xxmap.mapView=null;xxmap.mapLayer=null;xxmap.activeInteractions=[]}var a=updateMapMarkers();if((a!=null)&&(h||(a[4]==1))){var b=(a[0]+a[2])/2;var c=(a[1]+a[3])/2;var d=Math.max(Math.abs(a[0]-a[2]),Math.abs(a[1]-a[3]));var l=xxmap.map.getView();l.setCenter(ol.proj.transform([c,b],"EPSG:4326","EPSG:3857"));var e=360,g=-2;while(e>d){g++;e=e/2}l.setZoom(g)}}function placeNode(a){if(xxdialogMode){return}var c='<div style=margin-bottom:6px><label for=selectnode-search>Search</label>&nbsp&nbsp<input type=text placeholder="Device name" id="selectnode-search" onchange=onPlaceNodeInputChange() onkeyup=onPlaceNodeInputChange() autocomplete=off style=width:120px></div><div id=placenode style="height:254px;overflow-y:auto;width:100%;margin:12px 1px 4px 1px;"><div id=noNodesMapPlace style=text-align:center;width:100%;display:none>No devices found.</div>';for(var b in nodes){c+="<div class=noselect id="+nodes[b]._id+"-rowid onclick=selectNodeToPlace(event,'"+nodes[b]._id+"') style=background-color:lightgray;margin-bottom:4px;border-radius:2px><input name=PlaceMapDeviceCheckbox id="+nodes[b]._id+"-checkid type=checkbox style=width:16px;display:inline />";c+="<div class=j"+nodes[b].icon+" style=width:16px;height:16px;margin-top:2px;margin-right:4px;display:inline-block></div><div style=width:16px;display:inline>"+nodes[b].name+"</div></div>"}setDialogMode(2,"Select a node to place",3,placeNodeEx,c+"</div>",a);onPlaceNodeInputChange()}function placeNodeEx(b,c){var d=document.getElementsByName("PlaceMapDeviceCheckbox");for(var g in d){if(d[g].checked){var h=getNodeFromId(d[g].id.substring(0,d[g].id.length-8));if(h){var e=xxmap.markersSource.getFeatureById(g);var j=ol.proj.transform(c,"EPSG:3857","EPSG:4326");var k=[j[1],j[0]];if(e){e.getGeometry().setCoordinates(c);var a=getActiveInteractions(e);if(a){saveMarkerloc(e)}else{meshserver.send({action:"changedevice",nodeid:h._id,userloc:k})}}else{meshserver.send({action:"changedevice",nodeid:h._id,userloc:k})}}}}}function onPlaceNodeInputChange(){updatePlaceNodeTable(Q("selectnode-search").value.trim().toLowerCase())}function updatePlaceNodeTable(d){var b=document.getElementsByName("PlaceMapDeviceCheckbox"),a=0;for(var c in nodes){var e=((nodes[c].namel.indexOf(d)>=0||d=="")||(nodes[c].rnamel!=null&&nodes[c].rnamel.indexOf(d)>=0));if(e){a++}QV(nodes[c]._id+"-rowid",e)}QV("noNodesMapPlace",a==0)}function selectNodeToPlace(b,g){if(b.target.name!="PlaceMapDeviceCheckbox"){var h=Q(g+"-checkid");h.checked=!h.checked}var c=document.getElementsByName("PlaceMapDeviceCheckbox"),a=0;for(var d in c){if(c[d].checked){a++}}QE("idx_dlgOkButton",a>0)}function addMeshOptions(a,b){}function meshOptionRmvMod(a,b){}function meshExists(){for(var a in meshes){if(meshes[a]){return true}}return false}function setMeshView(a){var c=Q("select-mesh");var b=c.selectedIndex;if(c[b].value==a){c[0].selected=true;onSelectMeshChange()}}function clearMeshOptions(){}function getSearchLocation(){try{var b=Q("mapSearchLocation").value.trim();if(b.length>0){var c=new XMLHttpRequest();c.onreadystatechange=function(){if(c.readyState==4&&c.status==200){formatSearchData(c.responseText)}};c.open("GET","https://nominatim.openstreetmap.org/search?q="+b+"&format=json",true);c.send()}}catch(a){}}function formatSearchData(c){try{QH("xmapSearchResults","");var d=JSON.parse(c),b=0,k='<div style="overflow-y:auto;width:100%;max-height:240px">';for(var j=0;j<d.length;j++){if(d[j].display_name&&d[j].boundingbox[0]&&d[j].boundingbox[1]&&d[j].boundingbox[2]&&d[j].boundingbox[3]){b++;var a=(j%2==0)?"F5F5F5":"EBEBEB";k+="<div style=cursor:pointer;padding:5px;background-color:#"+a+" onclick=mapGotoSelectedLocation(this)><div>"+d[j].display_name+"</div><div style=display:none>"+d[j].boundingbox[0]+"!#!"+d[j].boundingbox[1]+"!#!"+d[j].boundingbox[2]+"!#!"+d[j].boundingbox[3]+"</div></div>"}}k+="</div>";if(b==1){var h=[parseFloat(d[0].boundingbox[2]),parseFloat(d[0].boundingbox[0]),parseFloat(d[0].boundingbox[3]),parseFloat(d[0].boundingbox[1])];zoomToExtent(h)}else{if(b==0){k="<div style=width:200px>No location found.<div>"}QV("xmapSearchResultsDlg",true)}QH("xmapSearchResults",k)}catch(g){}}function mapGotoSelectedLocation(c){var d=c.children;var a=d[1].innerHTML.split("!#!");var b=[parseFloat(a[2]),parseFloat(a[0]),parseFloat(a[3]),parseFloat(a[1])];zoomToExtent(b);mapCloseSearchWindow()}function mapCloseSearchWindow(){QH("xmapSearchResults","");QV("xmapSearchResultsDlg",false)}function zoomToLocation(a,c){var b=xxmap.map.getView();b.setCenter(a);b.setZoom(c)}function zoomToFitExtent(){var b=xxmap.markersSource.getFeatures();if(b.length>0){var a=xxmap.markersSource.getExtent();xxmap.map.getView().fit(a,xxmap.map.getSize())}}function zoomToExtent(b){var a=ol.proj.transformExtent(b,ol.proj.get("EPSG:4326"),ol.proj.get("EPSG:3857"));xxmap.map.getView().fit(a,xxmap.map.getSize())}function refreshDevice(a){if(!currentNode||currentNode._id!=a){return}gotoDevice(a,xxcurrentView,true)}function getNodeRights(c){var b=getNodeFromId(c),a=meshes[b.meshid];return a.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights}var currentNode;var powerTimelineNode=null;var powerTimelineReq=null;var powerTimelineUpdate=null;var powerTimeline=null;function getCurrentNode(){return currentNode}function gotoDevice(r,t,w,j){if((userinfo.emailVerified!==true)&&(serverinfo.emailcheck==true)&&(userinfo.siteadmin!=4294967295)){setDialogMode(2,"New Device Group",1,null,'Unable to create a new device group until a email address is verified. This is required for password recovery. Go to the "My Account" tab to change and verify an email address.');return}if(j&&(j.shiftKey==true)){window.open(window.location.origin+"?node="+r.split("/")[2]+"&viewmode=10&hide=16","meshcentral:"+r);return}var q=getNodeFromId(r);var n=meshes[q.meshid];var o=n.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;if(!currentNode||currentNode._id!=q._id||w==true){currentNode=q;var p=EscapeHtml(q.name);if(p.length==0){p="<i>None</i>"}if((o&4)!=0){p='<span title="Click here to edit the server-side device name" onclick=showEditNodeValueDialog(0) style=cursor:pointer>'+p+' <img class=hoverButton width=10 height=10 src="images/link5.png" /></span>'}QH("p10deviceName",p);QH("p11deviceName",p);QH("p12deviceName",p);QH("p13deviceName",p);QH("p14deviceName",p);QH("p15deviceName","Console - "+p);QH("p16deviceName",p);var B="<table style=width:100%>";B+=addDeviceAttribute('<span title="The name of the device group this computer belong to.">Group</span>','<a title="The name of the device group this computer belong to" onclick=gotoMesh("'+q.meshid+'") style=cursor:pointer>'+EscapeHtml(meshes[q.meshid].name)+"</a>");if((q.rname!=null)&&(q.name!=q.rname)){B+=addDeviceAttribute('<span title="The name of this computer as set in the operating system">Name</span>','<span title="The name of this computer as set in the operating system">'+EscapeHtml(q.rname)+"</span>")}if((features&1)==0){if((o&4)!=0){if(q.host){B+=addDeviceAttribute("Hostname","<span onclick=showEditNodeValueDialog(1) style=cursor:pointer>"+EscapeHtml(q.host)+"</span>")}else{B+=addDeviceAttribute("Hostname","<span onclick=showEditNodeValueDialog(1) style=cursor:pointer><i>None</i></span>")}}else{B+=addDeviceAttribute("Hostname",EscapeHtml(q.host))}}var h=q.desc?EscapeHtml(q.desc):"<i>None</i>";if((o&4)!=0){B+=addDeviceAttribute("Description","<span onclick=showEditNodeValueDialog(2) style=cursor:pointer>"+h+' <img class=hoverButton width=10 height=10 src="images/link5.png" /></span>')}else{B+=addDeviceAttribute("Description",h)}var a=["Unknown","Windows 32bit console","Windows 64bit console","Windows 32bit service","Windows 64bit service","Linux 32bit","Linux 64bit","MIPS","XENx86","Android ARM","Linux ARM","OSX 32bit","Android x86","PogoPlug ARM","Android APK","Linux Poky x86-32bit","OSX 64bit","ChromeOS","Linux Poky x86-64bit","Linux NoKVM x86-32bit","Linux NoKVM x86-64bit","Windows MinCore console","Windows MinCore service","NodeJS","ARM-Linaro","ARMv6l / ARMv7l"];if((q.agent!=null)&&(q.agent.id!=null)&&(q.agent.ver!=null)){var y="";if(q.agent.id<=a.length){y=a[q.agent.id]}else{y=a[0]}if(q.agent.ver!=0){y+=" v"+q.agent.ver}B+=addDeviceAttribute("Mesh Agent",y)}if(q.intelamt!=null){var y="";var v={0:"Not Activated (Pre)",1:"Not Activated (In)",2:"Activated"};if(q.intelamt.ver!=null&&q.intelamt.state==null){y+="<i>Unknown State</i>, v"+q.intelamt.ver}else{if((q.intelamt.ver==null)&&(q.intelamt.state==2)){y+="<i>Activated</i>"}else{if((q.intelamt.ver==null)||(q.intelamt.state==null)){y+="<i>Unknown Version & State</i>"}else{y+=v[q.intelamt.state];if((q.intelamt.state==2)&&q.intelamt.flags){if(q.intelamt.flags&2){y+=' <span title="Intel AMT is activated in Client Control Mode">CCM</span>'}else{if(q.intelamt.flags&4){y+=' <span title="Intel AMT is activated in Admin Control Mode">ACM</span>'}}}y+=(", v"+q.intelamt.ver)}}}if(q.intelamt.tls==1){y+=', <span title="Intel AMT is setup with TLS network security">TLS</span>'}if(q.intelamt.state==2){if(q.intelamt.user==null||q.intelamt.user==""){if((o&4)!=0){y+=', <i style=color:#FF0000;cursor:pointer title="Edit Intel&reg; AMT credentials" onclick=editDeviceAmtSettings("'+q._id+'")>No Credentials</i>'}else{y+=", <i style=color:#FF0000>No Credentials</i>"}}y+=" ";if((o&4)!=0){y+='<img src=images/link4.png height=10 width=10 title="Edit Intel&reg; AMT credentials" style=cursor:pointer onclick=editDeviceAmtSettings("'+q._id+'")>'}}B+=addDeviceAttribute("Intel&reg; AMT",y)}if((q.agent!=null)&&(q.agent.tag!=null)&&(q.agent.tag!="mailto:")){var z=EscapeHtml(q.agent.tag);if(z.startsWith("mailto:")){z='<a href="'+z+'">'+z.substring(7)+"</a>"}B+=addDeviceAttribute("Agent Tag",z)}if(q.osdesc){B+=addDeviceAttribute("Operating System",q.osdesc)}if(q.users&&q.conn&&(q.users.length>0)&&(q.conn&1)){B+=addDeviceAttribute("Active User"+((q.users.length>1)?"s":""),q.users.join(", "))}var d=q.conn;if(d&&d>1){var g=[];if((q.conn&1)!=0){g.push('<span title="Mesh agent is connected and ready for use.">Mesh Agent</span>')}if((q.conn&2)!=0){g.push('<span title="Intel&reg; AMT CIRA is connected and ready for use.">Intel&reg; AMT CIRA</span>')}else{if((q.conn&4)!=0){g.push('<span title="Intel&reg; AMT is routable and ready for use.">Intel&reg; AMT</span>')}}if((q.conn&8)!=0){g.push('<span title="Mesh agent is reachable using another agent as relay.">Mesh Relay</span>')}B+=addDeviceAttribute("Connectivity",g.join(", "))}var l="<i>None</i>";if(q.tags!=null){l="";for(var m in q.tags){l+='<span style="background-color:lightgray;padding:3px;margin-right:4px;border-radius:5px">'+q.tags[m]+"</span>"}}B+=addDeviceAttribute("Tags","<span onclick=showEditNodeValueDialog(3) style=cursor:pointer>"+l+' <img class=hoverButton width=10 height=10 src="images/link5.png" /></span>');B+="</table><br />";if((o&76)!=0){B+='<input type=button value=Actions title="Perform power actions on the device" onclick=deviceActionFunction() />'}B+='<input type=button value=Notes title="View notes about this device" onclick=showNotes('+((o&128)==0)+',"'+encodeURIComponent(q._id)+'") />';QH("p10html",B);masterUpdate(256);B="<div style=float:right;font-size:x-small>";if((o&4)!=0){B+='&nbsp;<a style=cursor:pointer onclick=p10showChangeGroupDialog(["'+q._id+'"]) title="Move this device to a different device group">Change Group</a>';B+='&nbsp;<a style=cursor:pointer onclick=p10showDeleteNodeDialog("'+q._id+'") title="Remove this device">Delete Device</a>'}B+="</div><div style=font-size:x-small>";if(n.mtype==2){B+='<a style=cursor:pointer onclick=p10showNodeNetInfoDialog("'+q._id+'") title="Show device network interface information">Interfaces</a>&nbsp;'}if(xxmap!=null){B+='<a style=cursor:pointer onclick=p10showNodeLocationDialog("'+q._id+'") title="Show device locations information">Location</a>&nbsp;'}if(((o&8)!=0)&&(n.mtype==2)){B+='<a style=cursor:pointer onclick=p10showMeshCmdDialog(1,"'+q._id+'") title="Traffic router used to connect to a device thru this server.">Router</a>&nbsp;'}if(((d&1)!=0)&&(clickOnce==true)&&(n.mtype==2)&&((o&8)!=0)){if((q.agent.id>0)&&(q.agent.id<5)){B+='<a style=cursor:pointer onclick=p10clickOnce("'+q._id+'","RDP2",3389) title="Requires Microsoft ClickOnce support in your browser.">RDP</a>&nbsp;'}if(q.agent.id>4){B+='<a style=cursor:pointer onclick=p10clickOnce("'+q._id+'","PSSH",22) title="Requires Microsoft ClickOnce support in your browser.">Putty</a>&nbsp;';B+='<a style=cursor:pointer onclick=p10clickOnce("'+q._id+'","WSCP",22) title="Requires Microsoft ClickOnce support in your browser.">WinSCP</a>&nbsp;'}}B+="</div><br>";QH("p10html3",B);var u=PowerStateStr(q.state);if((d&1)!=0){if(u.length>0){u+="<br/>"}u+='<span style=font-size:12px title="Agent connected">Agent connected</span>'}if((d&2)!=0){if(u.length>0){u+="<br/>"}u+='<span style=font-size:12px title="Intel&reg; AMT connected">Intel&reg; AMT connected</span>'}else{if((d&4)!=0){if(u.length>0){u+="<br/>"}u+='<span style=font-size:12px title="Intel&reg; AMT detected">Intel&reg; AMT detected</span>'}}if((u=="")&&q.lastconnect){u="<span style=font-size:12px>Last seen:<br />"+new Date(q.lastconnect).toLocaleDateString()+", "+new Date(q.lastconnect).toLocaleTimeString()+"</span>"}QH("MainComputerState",u);Q("MainComputerImage").setAttribute("src","images/icons200-"+q.icon+"-1.jpg");Q("MainComputerImage").className=((!q.conn)||(q.conn==0)?"gray":"");var A=((o==4294967295)||((o&512)==0));var k=((o==4294967295)||((o&1024)==0));var b=((o==4294967295)||((o&2048)==0));if(A){setupTerminal()}if(k){setupFiles()}var e=((o&16)!=0);if(e){setupConsole()}else{if(t==15){t=10}}QV("MainDevDesktop",((n.mtype==1)||(q.agent==null)||(q.agent.caps==null)||((q.agent.caps&1)!=0)||(q.intelamt&&(q.intelamt.state==2)))&&((o&8)||(o&256)));QV("MainDevTerminal",((n.mtype==1)||(q.agent==null)||(q.agent.caps==null)||((q.agent.caps&2)!=0)||(q.intelamt&&(q.intelamt.state==2)))&&(o&8)&&A);QV("MainDevFiles",((n.mtype==2)&&((q.agent==null)||(q.agent.caps==null)||((q.agent.caps&4)!=0)))&&(o&8)&&k);QV("MainDevAmt",(q.intelamt!=null)&&((q.intelamt.state==2)||(q.conn&2))&&(o&8)&&b);QV("MainDevConsole",(e&&(n.mtype==2)&&((q.agent==null)||(q.agent.caps==null)||((q.agent.caps&8)!=0)))&&(o&8));QV("p15uploadCore",(q.agent!=null)&&(q.agent.caps!=null)&&((q.agent.caps&16)!=0));QH("p15coreName",((q.agent!=null)&&(q.agent.core!=null))?q.agent.core:"");var c=Q("p14iframe").contentWindow.getCurrentMeshNode();if((c!=null)&&(c._id!=currentNode._id)){Q("p14iframe").contentWindow.disconnect()}var s=((q.conn&6)!=0)?true:false;Q("p14iframe").contentWindow.setConnectionState(s);Q("p14iframe").contentWindow.setFrameHeight("650px");Q("p14iframe").contentWindow.setAuthCallback(updateAmtCredentials);QV("deskActionsBtn",(o&72)!=0);QV("termActionsBtn",(o&72)!=0);QV("filesActionsBtn",(o&72)!=0);if((powerTimelineNode!=currentNode._id)&&(powerTimelineReq!=currentNode._id)){QH("p10html2","");powerTimelineReq=currentNode._id;meshserver.send({action:"powertimeline",nodeid:currentNode._id});meshserver.send({action:"lastconnect",nodeid:currentNode._id})}QV("DeskTools",false);showDeskToolsProcesses();refreshDeviceEvents();if((currentNode)&&(xxcurrentView>=10)&&(xxcurrentView<20)){document.title="MeshCentral - "+currentNode.name}else{document.title="MeshCentral"}}setupDesktop();if(!t){t=10}go(t)}function showNotes(b,a){if(xxdialogMode){return}setDialogMode(2,"Notes",2,showNotesEx,"<textarea id=d2devNotes ro="+b+" noteid="+a+" readonly style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll></textarea><span style=font-size:10px>Notes can be viewed and changed by other administrators.<span>",a);meshserver.send({action:"getNotes",id:decodeURIComponent(a)})}function showNotesEx(a,b){meshserver.send({action:"setNotes",id:decodeURIComponent(b),notes:encodeURIComponent(Q("d2devNotes").value)})}function deviceChat(){if(xxdialogMode){return}var a="/messenger?id=meshmessenger/"+encodeURIComponent(currentNode._id)+"/"+encodeURIComponent(userinfo._id)+"&title="+currentNode.name;if((authCookie!=null)&&(authCookie!="")){a+="&auth="+authCookie}window.open(a,"meshmessenger:"+currentNode._id);meshserver.send({action:"meshmessenger",nodeid:decodeURIComponent(currentNode._id)})}function deviceUrlFunction(){if(xxdialogMode){return}setDialogMode(2,"Open Page on Device",3,deviceUrlFunctionEx,'<input id=d2devurl placeholder="http://server.com" style=width:100%;overflow-y:scroll></input>')}function deviceUrlFunctionEx(){meshserver.send({action:"msg",type:"openUrl",nodeid:currentNode._id,url:Q("d2devurl").value})}function deviceToastFunction(){if(xxdialogMode){return}setDialogMode(2,"Device Notification",3,deviceToastFunctionEx,"<textarea id=d2devToast style=width:100%;height:80px;resize:none;overflow-y:scroll></textarea>")}function deviceToastFunctionEx(){meshserver.send({action:"toast",nodeids:[currentNode._id],title:"MeshCentral",msg:Q("d2devToast").value})}function deviceActionFunction(){if(xxdialogMode){return}var a=meshes[currentNode.meshid].links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;var b="Select an operation to perform on this device.<br /><br />";var c="<select id=d2deviceop style=float:right;width:250px>";if((a&64)!=0){c+="<option value=100>Wake-up</option>"}if((a&8)!=0){c+="<option value=4>Sleep</option><option value=3>Reset</option><option value=2>Power off</option>"}c+="</select>";b+=addHtmlValue("Operation",c);setDialogMode(2,"Device Action",3,deviceActionFunctionEx,b)}function deviceActionFunctionEx(){var a=Q("d2deviceop").value;if(a==100){meshserver.send({action:"wakedevices",nodeids:[currentNode._id]})}else{meshserver.send({action:"poweraction",nodeids:[currentNode._id],actiontype:a})}}function updateAmtCredentials(a){var b=getNodeFromId(currentNode._id);if((a==true)||(b.intelamt.user==null)||(b.intelamt.user=="")){editDeviceAmtSettings(currentNode._id,updateAmtCredentialsEx)}else{Q("p14iframe").contentWindow.connectButtonfunctionEx()}}function updateAmtCredentialsEx(a,b){Q("p14iframe").contentWindow.connectButtonfunctionEx()}function updateDeviceTimeline(){if((meshserver.State!=2)||(powerTimelineNode==null)||(powerTimelineUpdate==null)||(currentNode==null)){return}if((powerTimelineNode==powerTimelineReq)&&(currentNode._id==powerTimelineNode)&&(powerTimelineUpdate<Date.now())){powerTimelineUpdate=null;meshserver.send({action:"powertimeline",nodeid:currentNode._id});meshserver.send({action:"lastconnect",nodeid:currentNode._id})}}function drawDeviceTimeline(){if((currentNode==null)||(xxcurrentView<10)||(xxcurrentView>19)){return}var s=null,o=Date.now();if(currentNode._id==powerTimelineNode){s=powerTimeline}var e=new Date();e.setHours(0,0,0,0);e=new Date(e.getTime()-(1000*60*60*24*6));var u=e.getTime();var t=[];if(s!=null&&s.length>1){t.push([0,s[1],s[0]]);var c=s[1];for(var m=2;m<s.length;m+=2){var p=s[m],k=o;if(s.length>(m+1)){k=s[m+1]}t.push([c,c+k,p]);c=c+k}}var A="",b=1,h=new Date();var w=Q("masthead").offsetWidth-(160+9+9+14);h.setHours(0,0,0,0);for(var m=0;m<7;m++){var g="",q=h.getTime(),l=q+(1000*60*60*24);for(var n in t){var a=t[n];if(isTimeBlockInside(q,l,a[0],a[1])==true){var y=Math.max(q,a[0]);var r=Math.min(Math.min(l,a[1]),o);var z=Math.round(((r-y)*w)/86400000);if(z>0){var v=powerStateStrings2[a[2]]+" from "+new Date(y).toLocaleTimeString()+" to "+new Date(r).toLocaleTimeString()+".";g+='<div title="'+v+'" style=display:table-cell;width:'+z+"px;background-color:"+powerColor(a[2])+";height:16px></div>"}}}A+="<tr style="+(((b%2)==0)?"background-color:#DDD":"")+"><td><div>&nbsp;"+h.toLocaleDateString()+"<div></div></div></td><td><div>"+g+"</div></td></tr>";++b;h=new Date(h.getTime()-(1000*60*60*24))}QH("p10html2",'<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:center;width:150px>Day</th><th scope=col style=text-align:center>7 Day Power State</th></tr>'+A+"</tbody></table>")}function powerColor(a){if(a<powerColorTable.length){return powerColorTable[a]}return"yellow"}function isTimeBlockInside(d,c,b,a){if((b<d)&&(a>c)){return true}if((b>d)&&(b<c)){return true}if((a>d)&&(a<c)){return true}return false}function addDeviceAttribute(a,b){return"<tr><td class=style7 style=width:180px>"+a+"</td><td class=style9 style=max-width:400px;overflow:hidden>"+b+"</td></tr>"}function editDeviceAmtSettings(e,b){if(xxdialogMode){return}var g="",d=getNodeFromId(e),a=3,c=getNodeRights(e);if((c&4)==0){return}g+=addHtmlValue("Username",'<input id=dp10username style=width:230px maxlength=32 autocomplete=nope placeholder="admin" onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />');g+=addHtmlValue("Password","<input id=dp10password type=password style=width:230px autocomplete=nope maxlength=32 onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />");g+=addHtmlValue("Security","<select id=dp10tls style=width:236px><option value=0>No TLS security</option><option value=1>TLS security required</option></select>");if((d.intelamt.user!=null)&&(d.intelamt.user!="")){a=7}setDialogMode(2,"Edit Intel&reg; AMT credentials",a,editDeviceAmtSettingsEx,g,{node:d,func:b});if((d.intelamt.user!=null)&&(d.intelamt.user!="")){Q("dp10username").value=d.intelamt.user}else{Q("dp10username").value="admin"}Q("dp10tls").value=d.intelamt.tls;validateDeviceAmtSettings()}function validateDeviceAmtSettings(){QE("idx_dlgOkButton",passwordcheck(Q("dp10password").value))}function editDeviceAmtSettingsEx(c,d){if(c==2){meshserver.send({action:"changedevice",nodeid:d.node._id,intelamt:{user:"",pass:""}})}else{var b=Q("dp10username").value;if(b==""){b="admin"}var a=Q("dp10password").value;if(a==""){b=""}meshserver.send({action:"changedevice",nodeid:d.node._id,intelamt:{user:b,pass:a,tls:Q("dp10tls").value}});d.node.intelamt.user=b;d.node.intelamt.tls=Q("dp10tls").value;if(d.func){setTimeout(d.func,300)}}}function p10showChangeGroupDialog(e){if(xxdialogMode){return}var g=null;if(e.length==1){try{g=meshes[getNodeFromId(e[0])]._id}catch(b){}}var j="<select id=p10newGroup style=width:236px>",a=0;for(var c in meshes){var d=meshes[c].links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;if((meshes[c]._id!=g)&&(d&4)){a++;j+="<option value='"+meshes[c]._id+"'>"+meshes[c].name+"</option>"}}j+="</select>";if(a>0){var h=(e.length==1)?"Select a new group for this device<br /><br />":"Select a new group for selected devices<br /><br />";h+=addHtmlValue("New Device Group",j);setDialogMode(2,"Change Group",3,p10showChangeGroupDialogEx,h,e)}else{setDialogMode(2,"Change Group",1,null,"No other device group of same type exists.")}}function p10showChangeGroupDialogEx(a,c){meshserver.send({action:"changeDeviceMesh",nodeids:c,meshid:Q("p10newGroup").value})}function p10showDeleteNodeDialog(a){if(xxdialogMode){return}var b='Are you sure you want to delete node "'+EscapeHtml(currentNode.name)+'"?<br /><br />';b+="<label><input id=p10check type=checkbox onchange=p10validateDeleteNodeDialog() />Confirm</label>";setDialogMode(2,"Delete Node",3,p10showDeleteNodeDialogEx,b,a);p10validateDeleteNodeDialog()}function p10validateDeleteNodeDialog(){QE("idx_dlgOkButton",Q("p10check").checked)}function p10showDeleteNodeDialogEx(a,b){meshserver.send({action:"removedevices",nodeids:[b]})}function p10clickOnce(a,c,b){meshserver.send({action:"getcookie",nodeid:a,tcpport:b,tag:"clickonce",protocol:c})}var d2map=null;function p10showNodeLocationDialog(){if((xxdialogMode!=null)&&(xxdialogTag=="@xxmap")){setDialogMode(0)}else{if(xxdialogMode){return}}var m=[],n=["iploc","wifiloc","gpsloc","userloc"],a=null;for(var k in n){if(currentNode[n[k]]!=null){var j=currentNode[n[k]].split(","),h=parseFloat(j[0]),l=parseFloat(j[1]);if((h<90)&&(h>-90)&&(l<180)&&(l>-180)){var e=new ol.Feature({geometry:new ol.geom.Point(ol.proj.fromLonLat([l,h]))});e.setStyle(markerStyle(currentNode,parseInt(k)+1));m.push(e);if(a==null){a=[h,l,h,l,0]}else{if(h<a[0]){a[0]=h}if(l<a[1]){a[1]=l}if(h>a[2]){a[2]=h}if(l>a[3]){a[3]=l}}}}}var p=new ol.source.Vector({features:m});var o=new ol.layer.Vector({source:p});var q="<div id=d2map style=width:100%;height:300px></div>";setDialogMode(2,"Device Location",1,null,q,"@xxmap");var c=0,b=0,r=8;if(a!=null){var b=(a[0]+a[2])/2;var c=(a[1]+a[3])/2;var d=Math.max(Math.abs(a[0]-a[2]),Math.abs(a[1]-a[3]));var g=360,r=-2;while(g>d){r++;g=g/2}}if(m.length==1){r=8}d2map=new ol.Map({target:"d2map",interactions:ol.interaction.defaults({dragPan:false,mouseWheelZoom:false}),layers:[new ol.layer.Tile({source:new ol.source.OSM()}),o],view:new ol.View({center:ol.proj.fromLonLat([c,b]),zoom:r})})}function p10showNodeNetInfoDialog(){if(xxdialogMode){return}setDialogMode(2,"Network Interfaces",1,null,"<div id=d2netinfo>Loading...</div>","if"+currentNode._id);meshserver.send({action:"getnetworkinfo",nodeid:currentNode._id})}function p10showMeshCmdDialog(a,b){if(xxdialogMode){return}var d="<select id=aginsSelect onclick=meshCmdOsClick() style=width:236px>";d+="<option value=3>Windows (32bit)</option>";d+="<option value=4>Windows (64bit)</option>";d+="<option value=5>Linux x86 (32bit)</option>";d+="<option value=6>Linux x86 (64bit)</option>";d+="<option value=25>Linux ARM, Raspberry Pi (32bit)</option>";d+="</select>";var c="";if(a==0){c+="<div>MeshCmd is a command line tool that performs lots of different operations. The action file can optionally be downloaded and edited to provide server information and credentials.<br /><br />"}if(a==1){c+='<div>Download "meshcmd" with an action file to route traffic thru this server to this device. Make sure to edit meshaction.txt and add your account password or make any changes needed.<br /><br />'}c+=addHtmlValue("Operating System",d);c+=addHtmlValue("MeshCmd",'<a id=meshcmddownloadid style=cursor:pointer onclick=fileDownload("meshagents?meshcmd=","MeshCmd",2)></a>');if(a==0){c+=addHtmlValue("Action File",'<a style=cursor:pointer onclick=fileDownload("meshagents?meshaction=generic","MeshAction.txt")>MeshAction (.txt)</a>')}if(a==1){c+=addHtmlValue("Action File",'<a style=cursor:pointer onclick=fileDownload("meshagents?meshaction=route&nodeid='+b+'","MeshAction.txt")>MeshAction (.txt)</a>')}c+="</div>";setDialogMode(2,["Download MeshCmd","Network Router"][a],9,null,c,"fileDownload");meshCmdOsClick()}function meshCmdOsClick(){var a=Q("aginsSelect").value,b="";if(a==3){b="MeshCmd (Win32 executable)"}if(a==4){b="MeshCmd (Win64 executable)"}if(a==5){b="MeshCmd (Linux x86, 32bit)"}if(a==6){b="MeshCmd (Linux x86, 64bit)"}if(a==25){b="MeshCmd (Linux ARM, 32bit)"}QH("meshcmddownloadid",b)}function p10showiconselector(){if(xxdialogMode){return}var a=meshes[currentNode.meshid];var b=a.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;if((b&4)==0){return}var c="<br><div style=display:inline-block;width:40px></div>";c+="<div style=display:inline-block class=i1 onclick=p10setIcon(1)></div>";c+="<div style=display:inline-block class=i2 onclick=p10setIcon(2)></div>";c+="<div style=display:inline-block class=i3 onclick=p10setIcon(3)></div>";c+="<div style=display:inline-block class=i4 onclick=p10setIcon(4)></div>";c+="<div style=display:inline-block class=i5 onclick=p10setIcon(5)></div>";c+="<div style=display:inline-block class=i6 onclick=p10setIcon(6)></div><br><br>";setDialogMode(2,"Icon Selection",0,null,c);QV("id_dialogclose",true)}function p10setIcon(a){setDialogMode(0);meshserver.send({action:"changedevice",nodeid:currentNode._id,icon:a})}var showEditNodeValueDialog_modes=["Device Name","Hostname","Description","Tags"];var showEditNodeValueDialog_modes2=["name","host","desc","tags"];var showEditNodeValueDialog_modes3=["","","","Tag1, Tag2, Tag3"];function showEditNodeValueDialog(a){if(xxdialogMode){return}var c=addHtmlValue(showEditNodeValueDialog_modes[a],'<input id=dp10devicevalue style=width:230px maxlength=64 placeholder="'+showEditNodeValueDialog_modes3[a]+'" onchange=p10editdevicevalueValidate('+a+",event) onkeyup=p10editdevicevalueValidate("+a+",event) />");setDialogMode(2,"Edit Device",3,showEditNodeValueDialogEx,c,a);var b=currentNode[showEditNodeValueDialog_modes2[a]];if(b==null){b=""}if(Array.isArray(b)){b=b.join(", ")}Q("dp10devicevalue").value=b;p10editdevicevalueValidate();Q("dp10devicevalue").focus()}function showEditNodeValueDialogEx(a,b){var c={action:"changedevice",nodeid:currentNode._id};c[showEditNodeValueDialog_modes2[b]]=Q("dp10devicevalue").value;meshserver.send(c)}function p10editdevicevalueValidate(b,a){var c=((b>1)||(Q("dp10devicevalue").value.length>0));QE("idx_dlgOkButton",c);if((a!=null)&&(c==true)&&(a.keyCode==13)){dialogclose(1)}}var desktopNode;function setupDesktop(){if((desktopNode!=currentNode)&&(desktop!=null)){desktop.Stop();desktopNode=null;desktop=null}if((desktopNode!=currentNode)||(desktop==null)){var b=multiDesktop[currentNode._id];if(b!=null){QH("DeskParent","");var a=b.m.CanvasId;a.setAttribute("id","Desk");a.setAttribute("style","width:100%;-ms-touch-action:none;margin-left:0px");a.setAttribute("onmousedown","dmousedown(event)");a.setAttribute("onmouseup","dmouseup(event)");a.setAttribute("onmousemove","dmousemove(event)");a.removeAttribute("onclick");Q("DeskParent").appendChild(a);desktop=b;if(desktop.m.SendCompressionLevel){desktop.m.SendCompressionLevel(1,desktopsettings.quality,desktopsettings.scaling,desktopsettings.framerate)}desktop.onStateChanged=onDesktopStateChange;desktopNode=currentNode;onDesktopStateChange(desktop,desktop.State);delete multiDesktop[currentNode._id]}else{QH("DeskParent",'<canvas id=Desk width=640 height=480 style="width:100%;-ms-touch-action:none;margin-left:0px" oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></canvas>');desktopNode=currentNode}Q("Desk").addEventListener("DOMMouseScroll",function(c){return dmousewheel(c)});Q("Desk").addEventListener("mousewheel",function(c){return dmousewheel(c)})}desktopNode=currentNode;updateDesktopButtons();deskAdjust();if(!Q("Desk")["toBlob"]){QV("deskSaveBtn",false)}}function updateDesktopButtons(){var d=meshes[currentNode.meshid];var a=0;if(desktop!=null){a=desktop.State}var e=d.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;QV("disconnectbutton1span",(a!=0));QV("connectbutton1span",(a==0)&&((e&8)||(e&256))&&(d.mtype==2)&&(currentNode.agent.caps&1));QV("connectbutton1hspan",(a==0)&&(e&8)&&((currentNode.intelamt!=null)&&(d.mtype==1||currentNode.intelamt.state==2)&&((currentNode.intelamt.ver!=null)||(d.mtype==1))));QV("d7amtkvm",(currentNode.intelamt!=null&&((currentNode.intelamt.ver!=null)||(d.mtype==1)))&&((a==0)||(desktop.contype==2)));QV("d7meshkvm",(webRtcDesktop)||((d.mtype==2)&&(currentNode.agent.caps&1)&&((a==false)||(desktop.contype==1))));var c=(e==4294967295)||(((e&8)!=0)&&((e&256)==0)&&((e&4096)==0));var g=((currentNode.conn&1)!=0);QE("connectbutton1",g);var b=((currentNode.conn&6)!=0);QE("connectbutton1h",b);QE("deskSaveBtn",a==3);QV("deskFocusBtn",(desktop!=null)&&(desktop.contype==2)&&(a!=0)&&(desktopsettings.showfocus));QV("DeskCAD",c);QE("DeskCAD",a==3);QE("DeskClip",a==3);QV("DeskWD",(currentNode.agent)&&(currentNode.agent.id<5)&&c);QE("DeskWD",a==3);QV("deskkeys",(currentNode.agent)&&(currentNode.agent.id<5)&&c);QE("deskkeys",a==3);QV("DeskToolsButton",(c)&&(d.mtype==2)&&g);QV("DeskChatButton",(browserfullscreen==false)&&(c)&&(d.mtype==2)&&g);QV("DeskNotifyButton",(browserfullscreen==false)&&(currentNode.agent)&&(currentNode.agent.id<5)&&(c)&&(d.mtype==2)&&g);QV("DeskOpenWebButton",(browserfullscreen==false)&&(c)&&(d.mtype==2)&&g);QV("DeskControlSpan",c);QV("deskActionsBtn",(browserfullscreen==false));QV("deskActionsSettings",(browserfullscreen==false));if(e&8){Q("DeskControl").checked=(getstore("DeskControl",1)==1)}else{Q("DeskControl").checked=false}if(g==false){QV("DeskTools",false)}}var autoConnectDesktopTimer=null;function autoConnectDesktop(a){if(autoConnectDesktopTimer==null){autoConnectDesktopTimer=setInterval(connectDesktop,100)}else{clearInterval(autoConnectDesktopTimer);autoConnectDesktopTimer=null}}function connectDesktop(b,a){if(desktop==null){desktopNode=currentNode;if(a==2){if((desktopNode.intelamt.user==null)||(desktopNode.intelamt.user=="")){editDeviceAmtSettings(desktopNode._id,connectDesktop);return}desktop=CreateAmtRedirect(CreateAmtRemoteDesktop("Desk"),authCookie);desktop.debugmode=debugmode;desktop.onStateChanged=onDesktopStateChange;desktop.m.bpp=(desktopsettings.encoding==1||desktopsettings.encoding==3)?1:2;desktop.m.useZRLE=(desktopsettings.encoding<3);desktop.m.localKeyMap=desktopsettings.localkeymap;desktop.m.showmouse=desktopsettings.showmouse;desktop.m.onScreenSizeChange=deskAdjust;desktop.m.onKvmData=function(h){if(h.length==0){if(!desktop.m._sentPresence){desktop.m._sentPresence=true;desktop.m.sendKvmData(JSON.stringify({action:"present",ver:1}))}return}var d=null;try{d=JSON.parse(h)}catch(g){}if((d!=null)&&(d.action!=null)){if(d.action=="restart"){webRtcDesktopReset();desktop.m.sendKvmData(JSON.stringify({action:"present",ver:1}))}else{if((d.action=="present")&&(webRtcDesktop==null)){webRtcDesktop={platform:d.platform};var c=null;if(typeof RTCPeerConnection!=="undefined"){webRtcDesktop.webrtc=new RTCPeerConnection(c)}else{if(typeof webkitRTCPeerConnection!=="undefined"){webRtcDesktop.webrtc=new webkitRTCPeerConnection(c)}}webRtcDesktop.webchannel=webRtcDesktop.webrtc.createDataChannel("DataChannel",{});webRtcDesktop.webchannel.onopen=function(){console.log("WebRTC Data Channel Open");Q("deskstatus").textContent=StatusStrs[desktop.State]+", Soft-KVM";desktop.m.hold(true);webRtcDesktop.webRtcActive=true;webRtcDesktop.softdesktop=CreateKvmDataChannel(webRtcDesktop.webchannel,CreateAgentRemoteDesktop("Desk",Q("id_mainarea")),desktop.m);webRtcDesktop.softdesktop.m.setRotation(desktop.m.rotation);webRtcDesktop.softdesktop.m.onScreenSizeChange=deskAdjust;if(desktopsettings.quality){webRtcDesktop.softdesktop.m.CompressionLevel=desktopsettings.quality}if(desktopsettings.scaling){webRtcDesktop.softdesktop.m.ScalingLevel=desktopsettings.scaling}webRtcDesktop.softdesktop.Start()};webRtcDesktop.webchannel.onclose=function(e){console.log("WebRTC Data Channel Closed");webRtcDesktopReset()};webRtcDesktop.webrtc.onicecandidate=function(j){if(j.candidate==null){desktop.m.sendKvmData(JSON.stringify({action:"offer",ver:1,sdp:webRtcDesktop.webrtcoffer.sdp}))}else{webRtcDesktop.webrtcoffer.sdp+=("a="+j.candidate.candidate+"\r\n")}};webRtcDesktop.webrtc.oniceconnectionstatechange=function(){if((webRtcDesktop!=null)&&(webRtcDesktop.webrtc!=null)&&((webRtcDesktop.webrtc.iceConnectionState=="disconnected")||(webRtcDesktop.webrtc.iceConnectionState=="failed"))){webRtcDesktopReset()}};webRtcDesktop.webrtc.createOffer(function(e){webRtcDesktop.webrtcoffer=e;webRtcDesktop.webrtc.setLocalDescription(e,function(){},webRtcDesktopReset)},webRtcDesktopReset,{mandatory:{OfferToReceiveAudio:false,OfferToReceiveVideo:false}})}else{if((d.action=="answer")&&(webRtcDesktop!=null)){webRtcDesktop.webrtc.setRemoteDescription(new RTCSessionDescription({type:"answer",sdp:d.sdp}),function(){},webRtcDesktopReset)}}}}};desktop.Start(desktopNode._id,16994,"*","*",0);desktop.contype=2}else{desktop=CreateAgentRedirect(meshserver,CreateAgentRemoteDesktop("Desk"),serverPublicNamePort,authCookie);desktop.debugmode=debugmode;desktop.m.debugmode=debugmode;desktop.attemptWebRTC=attemptWebRTC;desktop.onStateChanged=onDesktopStateChange;desktop.m.CompressionLevel=desktopsettings.quality;desktop.m.ScalingLevel=desktopsettings.scaling;desktop.m.FrameRateTimer=desktopsettings.framerate;desktop.m.onDisplayinfo=deskDisplayInfo;desktop.m.onScreenSizeChange=deskAdjust;desktop.Start(desktopNode._id);desktop.contype=1}}else{desktop.Stop();webRtcDesktopReset();desktopNode=desktop=null}}var webRtcDesktop=null;function webRtcDesktopReset(){if(webRtcDesktop==null){return}if(webRtcDesktop.softdesktop!=null){webRtcDesktop.softdesktop.Stop();webRtcDesktop.softdesktop=null}if(webRtcDesktop.webchannel!=null){try{webRtcDesktop.webchannel.close()}catch(a){}webRtcDesktop.webchannel=null}if(webRtcDesktop.webrtc!=null){try{webRtcDesktop.webrtc.close()}catch(a){}webRtcDesktop.webrtc=null}webRtcDesktop=null;if(desktop&&desktop.m){desktop.m.hold(false);Q("deskstatus").textContent=StatusStrs[desktop.State]}}function onDesktopStateChange(c,a){var d=a;if((d==3)&&(c.contype==2)){d++}var b=StatusStrs[d];if((desktop!=null)&&(desktop.webRtcActive==true)){b+=", WebRTC"}QH("deskstatus",b);switch(a){case 0:desktop.Stop();desktopNode=desktop=null;QV("DeskFocus",false);QV("termdisplays",false);deskFocusBtn.value="All Focus";if(fullscreen==true){deskToggleFull()}webRtcDesktopReset();break;case 2:break;default:break}updateDesktopButtons();deskAdjust();setTimeout(deskAdjust,50)}function showDesktopSettings(){if(xxdialogMode){return}applyDesktopSettings();updateDesktopButtons();setDialogMode(7,"Remote Desktop Settings",3,showDesktopSettingsChanged)}function showDesktopSettingsChanged(){desktopsettings.encoding=d7desktopmode.value;desktopsettings.showfocus=d7showfocus.checked;desktopsettings.showmouse=d7showcursor.checked;desktopsettings.quality=d7bitmapquality.value;desktopsettings.scaling=d7bitmapscaling.value;desktopsettings.framerate=d7framelimiter.value;desktopsettings.localkeymap=d7localKeyMap.checked;localStorage.setItem("desktopsettings",JSON.stringify(desktopsettings));applyDesktopSettings();if(desktop){if(desktop.contype==1){if(desktop.State!=0){desktop.m.SendCompressionLevel(1,desktopsettings.quality,desktopsettings.scaling,desktopsettings.framerate)}}if(desktop.contype==2){if(desktopsettings.showfocus==false){desktop.m.focusmode=0;deskFocusBtn.value="All Focus"}if(desktop.State!=0){desktop.Stop();setTimeout(function(){connectDesktop(null,2)},50)}}}}function applyDesktopSettings(){var c="",b=(features&512)?[90,80,70,60,50,40,30,20,10,5,1]:[60,50,40,30,20,10,5,1];for(var a in b){c+="<option value="+b[a]+">"+b[a]+"%</option>"}QH("d7bitmapquality",c);d7desktopmode.value=desktopsettings.encoding;d7showfocus.checked=desktopsettings.showfocus;d7showcursor.checked=desktopsettings.showmouse;d7bitmapquality.value=40;if(b.indexOf(parseInt(desktopsettings.quality))>=0){d7bitmapquality.value=desktopsettings.quality}d7bitmapscaling.value=desktopsettings.scaling;if(desktopsettings.framerate){d7framelimiter.value=desktopsettings.framerate}if(desktopsettings.localkeymap){d7localKeyMap.checked=desktopsettings.localkeymap}QV("deskFocusBtn",(desktop!=null)&&(desktop.contype==2)&&(desktop.state!=0)&&(desktopsettings.showfocus))}function enterBrowserFullscreen(a){if(a.requestFullscreen){a.requestFullscreen()}else{if(a.msRequestFullscreen){a.msRequestFullscreen()}else{if(a.mozRequestFullScreen){a.mozRequestFullScreen()}else{if(a.webkitRequestFullscreen){a.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}}}}}function exitBrowserFullscreen(){if(document.exitFullscreen){document.exitFullscreen()}else{if(document.msExitFullscreen){document.msExitFullscreen()}else{if(document.mozCancelFullScreen){document.mozCancelFullScreen()}else{if(document.webkitExitFullscreen){document.webkitExitFullscreen()}}}}}function isBrowserFullscreen(){if(!document.fullscreenElement&&!document.mozFullScreenElement&&!document.webkitFullscreenElement&&!document.msFullscreenElement){return false}else{return true}}var fullscreen=false;var browserfullscreen=false;function deskToggleFull(a){fullscreen=!fullscreen;QV("mastheadx",!fullscreen);QV("masthead",!fullscreen);QV("topbar",!fullscreen);QV("p11deviceNameHeader",!fullscreen);QV("footer",!fullscreen);QV("column_l_bottomgap",!fullscreen);QV("idx_deskFullBtn2",fullscreen);QV("deskFullBtn",!fullscreen);QV("page_leftbar",!fullscreen);if(fullscreen){if(a.shiftKey==true){enterBrowserFullscreen(Q("deskarea0"));browserfullscreen=true}QS("column_l").width="930px";QS("column_l").height="";QS("column_l")["margin-left"]="";QS("column_l")["overflow-y"]="";QS("container").position="";QS("page_content").position="";QV("MainMenuSpan",true);QS("container").width="100%";QS("container")["border-right"]="0";QS("container")["border-left"]="0";QS("column_l").padding="0";QS("column_l").width="100%";QS("column_l")["max-height"]=""}else{exitBrowserFullscreen();browserfullscreen=false;QS("container").width="960px";QS("container")["border-right"]="1px solid #b7b7b7";QS("container")["border-left"]="1px solid #b7b7b7";QS("column_l").padding="0 15px";QS("column_l").width="930px";toggleFullScreen()}deskAdjust();deskAdjust();updateDesktopButtons()}function deskToggleFocus(){desktop.m.focusmode=(desktop.m.focusmode+64)%192;Q("deskFocusBtn").value=["All Focus","Small Focus","Large Focus"][desktop.m.focusmode/64]}function deskAdjust(){var c=(Math.max(document.documentElement.clientHeight,window.innerHeight||0)-(Q("deskarea1").clientHeight+Q("deskarea2").clientHeight+Q("Desk").clientHeight+Q("deskarea4").clientHeight+2))/2;if(fullscreen){document.documentElement.style.overflow="hidden";QS("deskarea3x").height=null;if(c<0){var a=(Math.max(document.documentElement.clientHeight,window.innerHeight||0)-(Q("deskarea1").clientHeight+Q("deskarea2").clientHeight+Q("deskarea4").clientHeight));var b=9999;if(desktop){b=(desktop.m.width/desktop.m.height)*a}if(webRtcDesktop&&webRtcDesktop.softdesktop){b=(webRtcDesktop.softdesktop.m.width/webRtcDesktop.softdesktop.m.height)*a}QS("Desk")["max-height"]=a+"px";QS("Desk")["max-width"]=b+"px";c=0}else{QS("Desk")["max-height"]=null;QS("Desk")["max-width"]=null}QS("Desk")["margin-top"]=c+"px";QS("Desk")["margin-bottom"]=c+"px"}else{var b=9999,a=(Math.max(document.documentElement.clientHeight,window.innerHeight||0)-(webPageFullScreen?276:290));if(desktop){b=(desktop.m.width/desktop.m.height)*a}if(webRtcDesktop&&webRtcDesktop.softdesktop){b=(webRtcDesktop.softdesktop.m.width/webRtcDesktop.softdesktop.m.height)*a}document.documentElement.style.overflow="auto";QS("Desk")["max-height"]=a+"px";QS("Desk")["max-width"]=b+"px";QS("Desk")["margin-top"]="0";QS("Desk")["margin-bottom"]="0"}}function mdeskAdjust(c,h,g,a){if(!c||!h||!g||!a){return}if(a.id=="Desk"){deskAdjust();return}var k=[{x:180,y:101},{x:302,y:169},{x:454,y:255}][Q("sizeselect").selectedIndex];var e=k.x+2,j=Q("xdevices").clientWidth-30,l=Math.floor(j/e);l=e+Math.floor((j-(l*e))/l);k.y=k.y*(l/k.x);k.x=l;var b=k.y,d=k.x;if(c.State!=0){b=k.y;d=(h/g)*k.y}QS(a.id)["max-height"]=b+"px";QS(a.id)["max-width"]=d+"px";QS(a.id)["margin-top"]="0";QS(a.id)["margin-bottom"]="0"}function deskSendKeys(){if(xxdialogMode||desktop==null||desktop.State!=3){return}var a=Q("deskkeys").value;if(a==0){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[65364,1],[65364,0],[65511,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.DOWN,40],[desktop.m.KeyAction.UP,40],[desktop.m.KeyAction.EXUP,91]])}}else{if(a==1){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[65362,1],[65362,0],[65511,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.DOWN,38],[desktop.m.KeyAction.UP,38],[desktop.m.KeyAction.EXUP,91]])}}else{if(a==2){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[108,1],[108,0],[65511,0]])}else{desktop.sendCtrlMsg('{"action":"lock"}')}}else{if(a==3){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[109,1],[109,0],[65511,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.DOWN,77],[desktop.m.KeyAction.UP,77],[desktop.m.KeyAction.EXUP,91]])}}else{if(a==4){if(desktop.contype==2){desktop.m.sendkey([[65505,1],[65511,1],[109,1],[109,0],[65511,0],[65505,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.DOWN,16],[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.DOWN,77],[desktop.m.KeyAction.UP,77],[desktop.m.KeyAction.EXUP,91],[desktop.m.KeyAction.UP,16]])}}else{if(a==5){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[65511,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.EXUP,91]])}}else{if(a==6){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[114,1],[114,0],[65511,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.DOWN,82],[desktop.m.KeyAction.UP,82],[desktop.m.KeyAction.EXUP,91]])}}}}}}}}}function showDeskClip(){if(xxdialogMode||desktop==null||desktop.State!=3){return}Q("DeskClip").blur();var a='<input id=dlgClipGet type=button value="Get Clipboard" style=width:120px onclick=showDeskClipGet()>';a+='<input id=dlgClipSet type=button value="Set Clipboard" style=width:120px onclick=showDeskClipSet()>';a+='<div id=dlgClipStatus style="display:inline-block;margin-left:8px" ></div>';a+='<textarea id=d2clipText style="width:100%;height:184px;resize:none" maxlength=65535></textarea>';a+='<input type=button value="Close" style=width:80px;float:right onclick=dialogclose(0)><div style=height:26px>&nbsp;</div>';setDialogMode(2,"Remote Clipboard",8,null,a,"clipboard");Q("d2clipText").focus()}function showDeskClipGet(){if(desktop==null||desktop.State!=3){return}meshserver.send({action:"msg",type:"getclip",nodeid:currentNode._id})}function showDeskClipSet(){if(desktop==null||desktop.State!=3){return}meshserver.send({action:"msg",type:"setclip",nodeid:currentNode._id,data:Q("d2clipText").value})}function sendCAD(){if(xxdialogMode||desktop==null||desktop.State!=3){return}desktop.m.sendcad()}function toggleDeskTools(){if(xxdialogMode){return}if(QS("DeskTools").display=="none"){QV("DeskTools",true);Q("DeskTools").nodeid=currentNode._id;refreshDeskTools()}else{QV("DeskTools",false)}}function refreshDeskTools(){QV("DeskToolsRefreshButton",false);setTimeout(refreshDeskToolsEx,500);meshserver.send({action:"msg",type:"ps",nodeid:currentNode._id})}function refreshDeskToolsEx(){QV("DeskToolsRefreshButton",true)}var deskTools={sort:1,msg:null};function sortProcess(a){deskTools.sort=a;showDeskToolsProcesses(deskTools.msg)}function sortProcessPid(c,d){if(c.p>d.p){return 1}if(c.p<d.p){return(-1)}return 0}function sortProcessName(c,d){if(c.d>d.d){return 1}if(c.d<d.d){return(-1)}return 0}function showDeskToolsProcesses(c){deskTools.msg=c;if(c==null){QH("DeskToolsProcesses","");return}if(Q("DeskTools").nodeid!=c.nodeid){return}var d=[],h=null;try{h=JSON.parse(c.value)}catch(a){}if(h!=null){for(var g in h){d.push({p:parseInt(g),c:h[g].cmd,d:h[g].cmd.toLowerCase(),u:h[g].user})}if(deskTools.sort==0){d.sort(sortProcessPid)}else{if(deskTools.sort==1){d.sort(sortProcessName)}}var j="";for(var b in d){if(d[b].p!=0){j+="<div class=deskToolsBar><div style=width:50px;float:left;text-align:right;padding-right:5px>"+d[b].p+'</div><a style=float:right;padding-right:5px;cursor:pointer title="Stop process" onclick=stopProcess('+d[b].p+',"'+d[b].c+'")><img width=10 height=10 src="images/trash.png"></a><div style=float:right;padding-right:5px>'+(d[b].u?d[b].u:"")+"</div><div>"+d[b].c+"</div></div>"}}QH("DeskToolsProcesses",j)}}function toggleKvmControl(){putstore("DeskControl",(Q("DeskControl").checked?1:0))}function deskSaveImage(){if(xxdialogMode||desktop==null||desktop.State!=3){return}var a=new Date(),b="Desktop-"+currentNode.name+"-"+a.getFullYear()+"-"+("0"+(a.getMonth()+1)).slice(-2)+"-"+("0"+a.getDate()).slice(-2)+"-"+("0"+a.getHours()).slice(-2)+"-"+("0"+a.getMinutes()).slice(-2);Q("Desk")["toBlob"](function(c){saveAs(c,b+".jpg")})}function deskDisplayInfo(e,a,c,d){var g=Q("termdisplays").value;if(a.length>0){var b="";for(var h in a){b+="<option"+((g==a[h])?" selected":"")+">"+a[h]+"</option>"}QH("termdisplays",b)}QV("termdisplays",a.length>0)}function deskGetDisplayNumbers(a){desktop.m.GetDisplayNumbers()}function deskSetDisplay(b){var a=0,c=Q("termdisplays").value;if(c=="All Displays"){a=65535}else{a=parseInt(c.substring(8))}desktop.m.SetDisplay(a)}var dblClickDetectArgs={t:0,x:0,y:0};function dblClickDetect(a){if(a.buttons!=1){return}var b=Date.now();if(((b-dblClickDetectArgs.t)<250)&&(Math.abs(a.clientX-dblClickDetectArgs.x)<2)&&(Math.abs(a.clientY-dblClickDetectArgs.y)<2)){if(!xxdialogMode&&desktop!=null&&Q("DeskControl").checked){if((webRtcDesktop!=null)&&(webRtcDesktop.softdesktop!=null)){webRtcDesktop.softdesktop.m.mousedblclick(a);desktop.m.sendKeepAlive()}else{desktop.m.mousedblclick(a)}}}dblClickDetectArgs.t=b;dblClickDetectArgs.x=a.clientX;dblClickDetectArgs.y=a.clientY}function dmousedown(a){if(!xxdialogMode&&desktop!=null&&Q("DeskControl").checked){if((webRtcDesktop!=null)&&(webRtcDesktop.softdesktop!=null)){webRtcDesktop.softdesktop.m.mousedown(a);desktop.m.sendKeepAlive()}else{desktop.m.mousedown(a)}}dblClickDetect(a)}function dmouseup(a){if(!xxdialogMode&&desktop!=null&&Q("DeskControl").checked){if((webRtcDesktop!=null)&&(webRtcDesktop.softdesktop!=null)){webRtcDesktop.softdesktop.m.mouseup(a);desktop.m.sendKeepAlive()}else{desktop.m.mouseup(a)}}}function dmousemove(a){if(!xxdialogMode&&desktop!=null&&Q("DeskControl").checked){if((webRtcDesktop!=null)&&(webRtcDesktop.softdesktop!=null)){webRtcDesktop.softdesktop.m.mousemove(a);desktop.m.sendKeepAlive()}else{desktop.m.mousemove(a)}}}function dmousewheel(a){if(!xxdialogMode&&desktop!=null&&Q("DeskControl").checked){if((webRtcDesktop!=null)&&(webRtcDesktop.softdesktop!=null)){webRtcDesktop.softdesktop.m.mousewheel(a);desktop.m.sendKeepAlive()}else{if(desktop.m.mousewheel){desktop.m.mousewheel(a)}}haltEvent(a);return true}return false}function drotate(a){if(!xxdialogMode&&desktop!=null){desktop.m.setRotation(desktop.m.rotation+a);deskAdjust();deskAdjust()}}function stopProcess(a,b){setDialogMode(2,"Process Control",3,stopProcessEx,"Stop process #"+a+' "'+b+'"?',a)}function stopProcessEx(a,b){meshserver.send({action:"msg",type:"pskill",nodeid:currentNode._id,value:b});setTimeout(refreshDeskTools,300)}var terminalNode;function setupTerminal(){if((terminalNode!=currentNode)&&(terminal!=null)){terminal.Stop();terminal=null}terminalNode=currentNode;updateTerminalButtons()}function updateTerminalButtons(){var b=meshes[terminalNode.meshid];var d=((terminal!=null)&&(terminal.state!=0));QV("disconnectbutton2span",(d==true));QV("connectbutton2span",(d==false)&&(b.mtype==2)&&(currentNode.agent.caps&2));QV("connectbutton2hspan",(d==false)&&((terminalNode.intelamt!=null)&&(b.mtype==1||terminalNode.intelamt.state==2)&&((terminalNode.intelamt.ver!=null)||(b.mtype==1))));var c=((terminalNode.conn&1)!=0);QE("connectbutton2",c);var a=((terminalNode.conn&6)!=0);QE("connectbutton2h",a);QE("ctrlcbutton",d);QE("ctrlxbutton",d);QE("escbutton",d);QE("bsbutton",d);QE("pastebutton",d);QE("specialkeylist",d);QE("specialkeylistinput",d);QV("terminalSettingsButtons",(terminal)&&(terminal.contype==2));if(terminal){Q("id_ttypebutton").value=terminalEmulations[terminal.m.terminalEmulation];Q("id_tfxkeysbutton").value=fxEmulations[terminal.m.fxEmulation];Q("id_tcrbutton").value=(terminal.m.lineFeed=="\r\n")?"CR+LF":"LF"}}function onTerminalStateChange(d,a){var c=a;if((c==3)&&(d.contype==2)){c++}var b=StatusStrs[c];if(terminal.webRtcActive==true){b+=", WebRTC"}QH("termstatus",b);switch(a){case 0:d.m.TermResetScreen();d.m.TermDraw();if(terminal!=null){terminal.Stop();terminal=null}break;case 3:break;default:break}updateTerminalButtons()}var autoConnectTerminalTimer=null;function autoConnectTerminal(a){if(autoConnectTerminalTimer==null){autoConnectTerminalTimer=setInterval(connectTerminal,100)}else{clearInterval(autoConnectTerminalTimer);autoConnectTerminalTimer=null}}function connectTerminal(b,a){if(!terminal){if(a==2){if((terminalNode.intelamt.user==null)||(terminalNode.intelamt.user=="")){editDeviceAmtSettings(terminalNode._id,connectTerminal);return}terminal=CreateAmtRedirect(CreateAmtRemoteTerminal("Term"),authCookie);terminal.debugmode=debugmode;terminal.m.debugmode=debugmode;terminal.onStateChanged=onTerminalStateChange;terminal.Start(terminalNode._id,16994,"*","*",0);terminal.contype=2;Q("id_ttypebutton").value=terminalEmulations[terminal.m.terminalEmulation]}else{terminal=CreateAgentRedirect(meshserver,CreateAmtRemoteTerminal("Term"),serverPublicNamePort,authCookie);terminal.debugmode=debugmode;terminal.m.debugmode=debugmode;terminal.m.lineFeed=([1,2,3,4,21,22].indexOf(currentNode.agent.id)>=0)?"\r\n":"\n";terminal.attemptWebRTC=attemptWebRTC;terminal.onStateChanged=onTerminalStateChange;terminal.Start(terminalNode._id);terminal.contype=1;terminal.m.terminalEmulation=0;terminal.m.fxEmulation=0;Q("id_ttypebutton").value=terminalEmulations[0]}}else{terminal.Stop();terminal=null}Q("connectbutton2").blur()}var terminalEmulations=["UTF8 Terminal","Extended ASCII","Intel ASCII"];function termToggleType(){if(!terminal||xxdialogMode){return}terminal.m.terminalEmulation=(terminal.m.terminalEmulation+1)%3;Q("id_ttypebutton").value=terminalEmulations[terminal.m.terminalEmulation];Q("id_ttypebutton").blur()}var fxEmulations=["Intel (F10 = ESC+[OM)","Alternate (F10 = ESC+0)","VT100+ (F10 = ESC+[OY)"];function termToggleFx(){if(!terminal||xxdialogMode){return}terminal.m.fxEmulation=(terminal.m.fxEmulation+1)%3;Q("id_tfxkeysbutton").value=fxEmulations[terminal.m.fxEmulation];Q("id_tfxkeysbutton").blur()}function termToggleCr(){if(!terminal||xxdialogMode){return}if(terminal.m.lineFeed=="\n"){terminal.m.lineFeed="\r\n"}else{terminal.m.lineFeed="\n"}Q("id_tcrbutton").value=(terminal.m.lineFeed=="\r\n")?"CR+LF":"LF"}function termSendKey(b,a){if(!terminal||xxdialogMode){return}terminal.m.TermSendKey(b);Q(a).blur()}function showTermPasteDialog(){if(!terminal||xxdialogMode){return}Q("pastebutton").blur();setDialogMode(2,"Paste",3,showTermPasteDialogEx,'<textarea id=d2pasteText style="width:100%;height:184px;resize:none"></textarea>');Q("d2pasteText").focus()}function showTermPasteDialogEx(){if(!terminal){return}terminal.m.TermSendKeys(Q("d2pasteText").value)}function sendSpecialKey(){terminal.m.TermSendKey(Q("specialkeylist").value);Q("specialkeylist").blur();Q("specialkeylistinput").blur()}var filesNode;function setupFiles(){var b=(filesNode==currentNode);filesNode=currentNode;var a=((filesNode.conn&1)!=0)?true:false;QE("p13Connect",a);if(((b==false)||(a==false))&&files){files.Stop();files=null}}function onFilesStateChange(c,a){p13Connect.value=(a==0)?"Connect":"Disconnect";var b=StatusStrs[a];if(files.webRtcActive==true){b+=", WebRTC"}Q("p13Status").textContent=b;switch(a){case 0:QH("p13files","");p13filetree=null;p13filetreelocation=[];QH("p13currentpath","");QE("p13FolderUp",false);p13setActions();if(files!=null){files.Stop();files=null}break;case 3:p13targetpath="";files.sendText({action:"ls",reqid:1,path:""});break;default:break}}function CreateRemoteFiles(b){var a={protocol:5};a.onFileUpdate=b;a.xxStateChange=function(c){};a.ProcessData=function(c){a.onFileUpdate(c)};return a}var autoConnectFilesTimer=null;function autoConnectFiles(a){if(autoConnectFilesTimer==null){autoConnectFilesTimer=setInterval(connectFiles,100)}else{clearInterval(autoConnectFilesTimer);autoConnectFilesTimer=null}}function connectFiles(a){if(!files){files=CreateAgentRedirect(meshserver,CreateRemoteFiles(p13gotFiles),serverPublicNamePort,authCookie);files.attemptWebRTC=attemptWebRTC;files.onStateChanged=onFilesStateChange;files.Start(filesNode._id)}else{files.Stop();files=null}p13clipboard=p13clipboardFolder=null;p13clipboardCut=0;p13updateClipview()}var p13filetree=null;var p13targetpath=null;var p13filetreelocation=[];function p13gotFiles(b){if((b.length>0)&&(b.charCodeAt(0)!=123)){p13gotDownloadBinaryData(b);return}b=JSON.parse(decode_utf8(b));if(b.action=="download"){p13gotDownloadCommand(b);return}b.path=b.path.replace(/\//g,"\\");if((p13filetree!=null)&&(b.path==p13filetree.path)){var a=p13getCheckedNames();p13filetree=b;p13updateFiles(a)}else{var c=b.path.replace(/\//g,"\\"),d=p13targetpath.replace(/\//g,"\\");while((c.length>0)&&(c[0]=="\\")){c=c.substring(1)}while((d.length>0)&&(d[0]=="\\")){d=d.substring(1)}if((c==d)||((b.path=="\\")&&(p13targetpath==""))){p13filetree=b;p13updateFiles()}}}function p13getCheckedNames(){var b=[],a=document.getElementsByName("fd");for(var c=0;c<a.length;c++){if(a[c].checked){b.push(p13filetree.dir[a[c].value].n)}}return b}function p13updateFiles(b){var n="",o="",c="<a style=cursor:pointer onclick=p13folderup(0)>Root</a>",l="Root";var w=p13filetree.path.split("\\");p13filetreelocation=[];for(var p in w){if(w[p]!=""){p13filetreelocation.push(w[p])}}for(var p in p13filetreelocation){c+=" / <a style=cursor:pointer onclick=p13folderup("+(parseInt(p)+1)+")>"+p13filetreelocation[p]+"</a>"}var s=p13filetreelocation.join("/");var j=p13sort_files(p13filetree.dir);for(var p in j){var d=j[p],r=d.n,u;u=r;if(r.length>70){u='<span title="'+EscapeHtml(r)+'">'+EscapeHtml(r.substring(0,70))+"...</span>"}else{u=EscapeHtml(r)}r=EscapeHtml(r);var g="";if(d.d!=null){var e=new Date(d.d),g=(e.getMonth()+1)+"/"+(e.getDate())+"/"+e.getFullYear()+" "+e.toLocaleTimeString()+"&nbsp;"}var k="";if(d.s!=null){k=getFileSizeStr(d.s)}var m="";if(d.t<3){var t="",v="";m="<div class=filelist file=999><input file=999 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value='"+d.nx+"'>&nbsp;<span style=float:right title=\""+v+'">'+t+"</span><span><div class=fileIcon"+d.t+' onclick=p13folderset("'+encodeURIComponent(d.nx)+'")></div><a style=cursor:pointer onclick=p13folderset("'+encodeURIComponent(d.nx)+'")>'+u+"</a></span></div>"}else{var q=u;if(d.s>0){q='<a rel="noreferrer noopener" target="_blank" style=cursor:pointer onclick="p13downloadfile(\''+encodeURIComponent(s+"/"+r)+"','"+encodeURIComponent(r)+"',"+d.s+')">'+u+"</a>"}m="<div class=filelist file=3><input file=3 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value='"+d.nx+"'>&nbsp;<span class=fsize>"+g+"</span><span style=float:right>"+k+"</span><span><div class=fileIcon"+d.t+"></div>"+q+"</span></div>"}if(d.t<3){n+=m}else{o+=m}}QH("p13files",n+o);QH("p13currentpath",c);QE("p13FolderUp",p13filetreelocation.length!=0);if(b!=null){var a=document.getElementsByName("fd");for(var p=0;p<a.length;p++){if(b.indexOf(p13filetree.dir[a[p].value].n)>=0){a[p].checked=true}}}p13setActions()}function p13folderset(a){p13targetpath=joinPaths(p13filetree.path,p13filetree.dir[a].n).split("\\").join("/");files.sendText({action:"ls",reqid:1,path:p13targetpath})}function p13folderup(a){if(a==null){p13filetreelocation.pop()}else{while(p13filetreelocation.length>a){p13filetreelocation.pop()}}p13targetpath=p13filetreelocation.join("/");files.sendText({action:"ls",reqid:1,path:p13targetpath})}var p13sortorder;function p13sort_filename(c,d){if(c.ln>d.ln){return(1*p13sortorder)}if(c.ln<d.ln){return(-1*p13sortorder)}return 0}function p13sort_timestamp(c,d){if(c.d>d.d){return(1*p13sortorder)}if(c.d<d.d){return(-1*p13sortorder)}return 0}function p13sort_bysize(c,d){if(c.s==d.s){return p13sort_filename(c,d)}return(((c.s-d.s))*p13sortorder)}function p13sort_files(a){var c=[],d=Q("p13sortdropdown").value;for(var b in a){a[b].nx=b;if(a[b].s==null){a[b].s=0}if(a[b].n==null){a[b].n=b}a[b].ln=a[b].n.toLowerCase();c.push(a[b])}p13sortorder=1;if(d>3){p13sortorder=-1;d-=3}if(d==1){c.sort(p13sort_filename)}else{if(d==2){c.sort(p13sort_bysize)}else{if(d==3){c.sort(p13sort_timestamp)}}}return c}function p13setActions(){if(p13filetree==null){QE("p13DeleteFileButton",false);QE("p13NewFolderButton",false);QE("p13UploadButton",false);QE("p13RenameFileButton",false);QE("p13SelectAllButton",false);Q("p13SelectAllButton").value="Select All";QE("p13RefreshButton",false);QE("p13CutButton",false);QE("p13CopyButton",false);QE("p13PasteButton",false)}else{var a=p13getFileSelCount(),c=p13getFileCount(),b=p13getFileSelCount(false);var d=((currentNode.agent.id>0)&&(currentNode.agent.id<5));QE("p13DeleteFileButton",(a>0)&&((p13filetreelocation.length>0)||(d==false)));QE("p13NewFolderButton",((p13filetreelocation.length>0)||(d==false)));QE("p13UploadButton",((p13filetreelocation.length>0)||(d==false)));QE("p13RenameFileButton",(a==1)&&((p13filetreelocation.length>0)||(d==false)));QE("p13SelectAllButton",c>0);Q("p13SelectAllButton").value=(a>0?"Select None":"Select All");QE("p13RefreshButton",true);QE("p13CutButton",(a>0)&&(a==b)&&((p13filetreelocation.length>0)||(d==false)));QE("p13CopyButton",(a>0)&&(a==b)&&((p13filetreelocation.length>0)||(d==false)));QE("p13PasteButton",((p13filetreelocation.length>0)||(d==false))&&((p13clipboard!=null)&&(p13clipboard.length>0)))}}function p13getFileSelCount(d){var a=0;var b=document.getElementsByName("fd");for(var c=0;c<b.length;c++){if((b[c].checked)&&((d!=false)||(b[c].attributes.file.value=="3"))){a++}}return a}function p13getFileSelDirCount(){var a=0,b=document.getElementsByName("fd");for(var c=0;c<b.length;c++){if((b[c].checked)&&(b[c].attributes.file.value=="999")){a++}}return a}function p13getFileCount(){var a=0;var b=document.getElementsByName("fd");return b.length}function p13selectallfile(){var c=(p13getFileSelCount()==0),a=document.getElementsByName("fd");for(var b=0;b<a.length;b++){a[b].checked=c}p13setActions()}function p13createfolder(){setDialogMode(2,"New Folder",3,p13createfolderEx,"<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% />");focusTextBox("p13renameinput");p13fileNameCheck()}function p13createfolderEx(){files.sendText({action:"mkdir",reqid:1,path:p13filetreelocation.join("/")+"/"+Q("p13renameinput").value});p13folderup(999)}function p13deletefile(){var a=p13getFileSelCount(),b=(p13getFileSelDirCount()>0)?"<br /><br /><input type=checkbox id=p13recdeleteinput>Recursive delete<br>":"<input type=checkbox id=p13recdeleteinput style='display:none'>";setDialogMode(2,"Delete",3,p13deletefileEx,(a>1)?("Delete "+a+" selected items?"+b):("Delete selected item?"+b))}function p13deletefileEx(){var b=[],a=document.getElementsByName("fd");for(var c=0;c<a.length;c++){if(a[c].checked){b.push(p13filetree.dir[a[c].value].n)}}files.sendText({action:"rm",reqid:1,path:p13filetreelocation.join("/"),delfiles:b,rec:Q("p13recdeleteinput").checked});p13folderup(999)}function p13renamefile(){var c,a=document.getElementsByName("fd");for(var b=0;b<a.length;b++){if(a[b].checked){c=p13filetree.dir[a[b].value].n}}setDialogMode(2,"Rename",3,p13renamefileEx,'<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% value="'+c+'" />',{action:"rename",path:p13filetreelocation.join("/"),oldname:c});focusTextBox("p13renameinput");p13fileNameCheck()}function p13renamefileEx(a,c){c.newname=Q("p13renameinput").value;files.sendText(c);p13folderup(999)}function p13fileNameCheck(a){var b=isFilenameValid(Q("p13renameinput").value);QE("idx_dlgOkButton",b);if((b==true)&&(a!=null)&&(a.keyCode==13)){dialogclose(1)}}function p13uploadFile(){setDialogMode(2,"Upload File",3,p13uploadFileEx,"<input type=file name=files id=p13uploadinput style=width:100% multiple=multiple onchange=\"updateUploadDialogOk('p13uploadinput')\" />");updateUploadDialogOk("p13uploadinput")}function p13uploadFileEx(){p13doUploadFiles(Q("p13uploadinput").files)}var p13clipboard=null,p13clipboardFolder=null,p13clipboardCut=0;function p13copyFile(b){var a=document.getElementsByName("fd");p13clipboard=[];p13clipboardCut=b,p13clipboardFolder=p13targetpath;for(var c=0;c<a.length;c++){if((a[c].checked)&&(a[c].attributes.file.value=="3")){p13clipboard.push(p13filetree.dir[a[c].value].n)}}p13updateClipview()}function p13pasteFile(){var a="";if((p13clipboard!=null)&&(p13clipboard.length>0)){a="Confim "+(p13clipboardCut==0?"copy":"move")+" of "+p13clipboard.length+" entrie"+((p13clipboard.length>1)?"s":"")+" to this location?"}setDialogMode(2,"Paste",3,p13pasteFileEx,a)}function p13pasteFileEx(){files.sendText({action:(p13clipboardCut==0?"copy":"move"),reqid:1,scpath:p13clipboardFolder,dspath:p13targetpath,names:p13clipboard});p13folderup(999);if(p13clipboardCut==1){p13clipboard=null,p13clipboardFolder=null,p13clipboardCut=0;p13updateClipview()}}function p13updateClipview(){var a="";if((p13clipboard!=null)&&(p13clipboard.length>0)){a="Holding "+p13clipboard.length+" entrie"+((p13clipboard.length>1)?"s":"")+" for "+(p13clipboardCut==0?"copy":"move")+", <a onclick=p13clearClip() style=cursor:pointer>Clear</a>."}QH("p13bottomstatus",a);p13setActions()}function p13clearClip(){p13clipboard=null;p13clipboardFolder=null;p13clipboardCut=0;p13updateClipview()}function p13fileDragDrop(a){haltEvent(a);QV("p13bigfail",false);QV("p13bigok",false);if(a.dataTransfer==null||a.dataTransfer.files.length==0||p13filetree==null){return}p13doUploadFiles(a.dataTransfer.files)}var p13dragtimer=null;function p13fileDragOver(b){haltEvent(b);if(p13dragtimer!=null){clearTimeout(p13dragtimer);p13dragtimer=null}var a=(p13filetree!=null);QV("p13bigok",a);QV("p13bigfail",!a)}function p13fileDragLeave(a){haltEvent(a);if(a.target.id!="p13filetable"){QV("p13bigfail",false);QV("p13bigok",false)}else{p13dragtimer=setTimeout(function(){QV("p13bigfail",false);QV("p13bigok",false);p13dragtimer=null},10)}}var downloadFile;function p13downloadfile(a,b,c){if(xxdialogMode||downloadFile||!files){return}downloadFile={path:decodeURIComponent(a),file:decodeURIComponent(b),size:c,tsize:0,data:"",state:0,id:Math.random()};files.sendText({action:"download",sub:"start",id:downloadFile.id,path:downloadFile.path});setDialogMode(2,"Download File",10,p13downloadFileCancel,"<div>"+downloadFile.file+"</div><br /><progress id=d2progressBar style=width:100% value=0 max="+c+" />")}function p13downloadFileCancel(){setDialogMode(0);files.sendText({action:"download",sub:"cancel",id:downloadFile.id});downloadFile=null}function p13gotDownloadCommand(a){if((downloadFile==null)||(a.id!=downloadFile.id)){return}if(a.sub=="start"){downloadFile.state=1;files.sendText({action:"download",sub:"startack",id:downloadFile.id})}else{if(a.sub=="cancel"){downloadFile=null;setDialogMode(0)}}}function p13gotDownloadBinaryData(a){if(!downloadFile||downloadFile.state==0){return}if(a.length>4){downloadFile.tsize+=(a.length-4);downloadFile.data+=a.substring(4);Q("d2progressBar").value=downloadFile.tsize}if((ReadInt(a,0)&1)!=0){saveAs(data2blob(downloadFile.data),downloadFile.file);downloadFile=null;setDialogMode(0)}else{files.sendText({action:"download",sub:"ack",id:downloadFile.id})}}var uploadFile;function p13doUploadFiles(a){if(xxdialogMode){return}uploadFile={};uploadFile.xpath=p13filetreelocation.join("/");uploadFile.xfiles=a;uploadFile.xfilePtr=-1;setDialogMode(2,"Upload File",10,p13uploadFileCancel,"<div id=p13dfileName>Connecting...</div><br /><progress id=d2progressBar style=width:100% value=0 max=0 />");p13uploadReconnect()}function onFileUploadStateChange(b,a){switch(a){case 0:p13folderup(9999);break;case 3:p13uploadNextFile();break;default:console.log("Unknown onFileUploadStateChange state",a);break}}function p13uploadReconnect(){uploadFile.ws=CreateAgentRedirect(meshserver,CreateRemoteFiles(p13gotUploadData),serverPublicNamePort,authCookie);uploadFile.ws.attemptWebRTC=false;uploadFile.ws.ctrlMsgAllowed=false;uploadFile.ws.onStateChanged=onFileUploadStateChange;uploadFile.ws.Start(filesNode._id)}function p13uploadNextFile(){uploadFile.xfilePtr++;if(uploadFile.xfiles.length>uploadFile.xfilePtr){uploadFile.xptr=0;var a=uploadFile.xfiles[uploadFile.xfilePtr];QH("p13dfileName",a.name);Q("d2progressBar").max=a.size;Q("d2progressBar").value=0;uploadFile.xreader=new FileReader();uploadFile.xreader.onload=function(){uploadFile.xdata=uploadFile.xreader.result;uploadFile.ws.sendText(JSON.stringify({action:"upload",reqid:uploadFile.xfilePtr,path:uploadFile.xpath,name:a.name,size:uploadFile.xdata.byteLength}))};uploadFile.xreader.readAsArrayBuffer(a)}else{p13uploadFileCancel()}}function p13uploadFileCancel(a,b){if(uploadFile!=null){if(uploadFile.ws!=null){uploadFile.ws.Stop();uploadFile.ws=null}uploadFile=null}setDialogMode(0)}function p13gotUploadData(b){var a=JSON.parse(b);if((uploadFile==null)||(parseInt(uploadFile.xfilePtr)!=parseInt(a.reqid))){return}if(a.action=="uploadstart"){p13uploadNextPart(false);for(var c=0;c<8;c++){p13uploadNextPart(true)}}else{if(a.action=="uploadack"){p13uploadNextPart(false)}else{if(a.action=="uploaderror"){p13uploadFileCancel()}}}}function p13uploadNextPart(c){var a=uploadFile.xdata;var e=uploadFile.xptr;var d=uploadFile.xptr+4096;if(d>a.byteLength){if(c==true){return}d=a.byteLength}if(e==a.byteLength){if(uploadFile.ws!=null){uploadFile.ws.Stop();uploadFile.ws=null}if(uploadFile.xfiles.length>uploadFile.xfilePtr+1){p13uploadReconnect()}else{p13uploadFileCancel()}}else{var b=a.slice(e,d);uploadFile.ws.send(b);uploadFile.xptr=d;Q("d2progressBar").value=d}}var currentDeviceEvents=null;function deviceEventsUpdate(){var h="",a=null;for(var c in currentDeviceEvents){var b=currentDeviceEvents[c];var g=new Date(b.time);if(g.toLocaleDateString()!=a){if(a!=null){h+="</table>"}h+="<table style=width:100% cellpadding=0 cellspacing=0><tr><td class=DevSt colspan=4>"+g.toLocaleDateString()+"</td></tr>";a=g.toLocaleDateString()}var d="si3";if(b.etype=="user"){d="m2"}if(b.etype=="server"){d="si3"}var e=b.msg.split("(R)").join("&reg;");h+="<tr><td style=width:18px><div class="+d+"></div></td><td class=g1 style=float:none>&nbsp;</td><td style=background-color:#C9C9C9>"+g.toLocaleTimeString()+" - "+e+"</td><td class=g2 style=float:none>&nbsp;</td></tr><tr style=height:2px></tr>"}if(a!=null){h+="</table>"}if(h==""){h="<br><i>No Events Found</i><br><br>"}QH("p16events",h)}function refreshDeviceEvents(){meshserver.send({action:"events",nodeid:currentNode._id,limit:parseInt(p16limitdropdown.value)})}function agentConsoleHandleKeys(b){if((b.ctrlKey)||(b.altKey)){return true}var d=0,a=Q("p15consoleText");if(b.key){if(b.keyCode==13&&consoleFocus==0){p15consoleSend(b);d=1}else{if(b.keyCode==8&&consoleFocus==0){var g=a.value;a.value=g.substring(0,g.length-1);d=1}else{if(b.keyCode==27){a.value="";d=1}else{if((b.keyCode==38)||(b.keyCode==40)){var c=consoleHistory.indexOf(a.value);if((b.keyCode==38)&&((consoleHistory.length-1)>c)){a.value=consoleHistory[c+1]}else{if((b.keyCode==40)&&(c>0)){a.value=consoleHistory[c-1]}else{if((b.keyCode==40)&&(c==0)){a.value=""}}}d=1}else{if(b.key.length===1){insertTextAtCursor(a,b.key);d=1}}}}}}else{if(b.charCode!=0&&consoleFocus==0){a.value=((a.value+String.fromCharCode(b.charCode)));d=1}}if(d>0){return haltEvent(b)}}function insertTextAtCursor(a,d){if(document.selection){a.focus();sel=document.selection.createRange();sel.text=d}else{if(a.selectionStart||a.selectionStart=="0"){var c=a.selectionStart,b=a.selectionEnd;a.value=a.value.substring(0,c)+d+a.value.substring(b,a.value.length);a.setSelectionRange(b+1,b+1)}else{a.value+=myValue}}}var consoleNode;var consoleServerText="";function setupConsole(){if(xxcurrentView==115){var d=(consoleNode=="server");consoleNode="server";QH("p15deviceName","My Server Console");QE("p15consoleText",true);QH("p15statetext","");QH("p15coreName","");if(d==false){QH("p15agentConsoleText",consoleServerText);Q("p15agentConsoleText").scrollTop=Q("p15agentConsoleText").scrollHeight}}else{var d=(consoleNode==currentNode);consoleNode=currentNode;var a=meshes[consoleNode.meshid];var b=a.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;if((b&16)!=0){if(consoleNode.consoleText==null){consoleNode.consoleText=""}if(d==false){QH("p15agentConsoleText",consoleNode.consoleText);Q("p15agentConsoleText").scrollTop=Q("p15agentConsoleText").scrollHeight}var c=((consoleNode.conn&1)!=0)?true:false;QH("p15statetext",c?"Agent is online":"Agent is offline");QE("p15consoleText",c);QE("p15uploadCore",c)}else{QH("p15statetext","Access Denied");QE("p15consoleText",false);QE("p15uploadCore",false)}}}function p15consoleClear(){QH("p15agentConsoleText","");Q("id_p15consoleClear").blur();if(xxcurrentView==115){consoleServerText=""}else{consoleNode.consoleText=""}}var consoleHistory=[];function p15consoleSend(a){if(a&&a.keyCode!=13){return}var d=Q("p15consoleText").value,c="<div style=color:green>&gt; "+EscapeHtml(Q("p15consoleText").value)+"<br/></div>";Q("p15agentConsoleText").innerHTML+=c;Q("p15agentConsoleText").scrollTop=Q("p15agentConsoleText").scrollHeight;Q("p15consoleText").value="";if(xxcurrentView==115){consoleServerText+=c;meshserver.send({action:"serverconsole",value:d})}else{consoleNode.consoleText+=c;meshserver.send({action:"msg",type:"console",nodeid:consoleNode._id,value:d})}if(d.length>0){var b=consoleHistory.indexOf(d);if(b>=0){consoleHistory.splice(b,1)}consoleHistory.unshift(d);consoleHistory.splice(10)}}function p15consoleReceive(b,a){a="<div>"+a+"</div>";if(b==="serverconsole"){consoleServerText+=a;if(consoleNode=="server"){Q("p15agentConsoleText").innerHTML+=a;Q("p15agentConsoleText").scrollTop=Q("p15agentConsoleText").scrollHeight}}else{if(b.consoleText==null){b.consoleText=a}else{b.consoleText+=a}if(consoleNode==b){Q("p15agentConsoleText").innerHTML+=a;Q("p15agentConsoleText").scrollTop=Q("p15agentConsoleText").scrollHeight}}}function p15uploadCore(a){if(xxdialogMode){return}if(a.shiftKey==true){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"default"})}else{if(a.altKey==true){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"clear"})}else{if(a.ctrlKey==true){p15uploadCore2()}else{setDialogMode(2,"Change Mesh Agent Core",3,p15uploadCoreEx,"<select id=d3coreMode style=float:right;width:260px><option value=1>Upload default server core</option><option value=2>Clear the core</option><option value=6>Upload recovery core</option><option value=3>Upload a core file</option><option value=4>Soft disconnect agent</option><option value=5>Hard disconnect agent</option></select><div>Change Core</div>")}}}}function p15uploadCoreEx(){if(Q("d3coreMode").value==1){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"default"})}else{if(Q("d3coreMode").value==2){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"clear"})}else{if(Q("d3coreMode").value==3){p15uploadCore2()}else{if(Q("d3coreMode").value==4){meshserver.send({action:"agentdisconnect",nodeid:consoleNode._id,disconnectMode:1})}else{if(Q("d3coreMode").value==5){meshserver.send({action:"agentdisconnect",nodeid:consoleNode._id,disconnectMode:2})}else{if(Q("d3coreMode").value==6){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"recovery"})}}}}}}}function p15uploadCore2(){if(xxdialogMode){return}Q("d3localmodeform").action="uploadmeshcorefile.ashx";Q("d3attrib").value=currentNode._id;setDialogMode(3,"Upload Mesh Agent Core",3,p15uploadCoreEx2);d3init()}function p15uploadCoreEx2(){var b=Q("d3uploadMode").value;if(b==1){Q("d3submit").click()}else{var a=d3getFileSel();if(a.length==1){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"custom",path:d3filetreelocation.join("/")+"/"+a[0]})}}}function account_manageAuthApp(){if(xxdialogMode||((features&4096)==0)){return}if(userinfo.otpsecret==1){account_removeOtp()}else{account_addOtp()}}function account_addOtp(){if(xxdialogMode||(userinfo.otpsecret==1)||((features&4096)==0)){return}setDialogMode(2,"Authenticator App",2,function(){meshserver.send({action:"otpauth-setup",secret:Q("d2optsecret").attributes.secret.value,token:Q("d2otpauthinput").value})},"<div id=d2optinfo>Loading...</div>","otpauth-request");meshserver.send({action:"otpauth-request"})}function account_addOtpCheck(a){var b=(Q("d2otpauthinput").value.length==6);QE("idx_dlgOkButton",b);if(a&&(a.keyCode==13)&&b){dialogclose(1)}}function account_removeOtp(){if(xxdialogMode||(userinfo.otpsecret!=1)||((features&4096)==0)){return}setDialogMode(2,"Authenticator App",3,function(){meshserver.send({action:"otpauth-clear"})},"Confirm removal of authenticator application 2-step login?")}function account_manageOtp(a){if((xxdialogMode==2)&&(xxdialogTag=="otpauth-manage")){dialogclose(0)}if(xxdialogMode||((features&4096)==0)){return}if((userinfo.otpsecret==1)||(userinfo.otphkeys>0)){meshserver.send({action:"otpauth-getpasswords",subaction:a})}}function account_manageHardwareOtp(){if((xxdialogMode==2)&&(xxdialogTag=="otpauth-hardware-manage")){dialogclose(0)}if(xxdialogMode||((features&4096)==0)){return}meshserver.send({action:"otp-hkey-get"})}function account_addhkey(a){if(a==1){var b="Type in the name of the key to add.<br /><br />";b+=addHtmlValue("Key Name",'<input id=dp1keyname style=width:230px maxlength=20 autocomplete=off placeholder="MyKey" onkeyup=account_addhkeyValidate(event,2) />')}else{if(a==2){var b="Type in a key name, select the OTP box and press the button on the YubiKey&trade;.<br /><br />";b+=addHtmlValue("Key Name",'<input id=dp1keyname style=width:230px maxlength=20 autocomplete=off placeholder="MyKey" onkeyup=account_addhkeyValidate(event,1) />');b+=addHtmlValue("YubiKey&trade; OTP","<input id=dp1key style=width:230px autocomplete=off onkeyup=account_addhkeyValidate(event,2) />")}}setDialogMode(2,"Add Security Key",3,account_addhkeyEx,b,a);Q("dp1keyname").focus()}function account_addhkeyValidate(b,a){if((b!=null)&&(b.keyCode==13)){if(a==2){dialogclose(1)}else{Q("dp1key").focus()}}}function account_addhkeyEx(a,c){var b=Q("dp1keyname").value;if(b==""){b="MyKey"}if(c==1){meshserver.send({action:"otp-hkey-setup-request",name:b})}else{if(c==2){meshserver.send({action:"otp-hkey-yubikey-add",name:b,otp:Q("dp1key").value});setDialogMode(2,"Add Security Key",0,null,"<br />Checking...<br /><br /><br />","otpauth-hardware-manage")}}}function account_removehkey(a){meshserver.send({action:"otp-hkey-remove",index:a});meshserver.send({action:"otp-hkey-get"})}function account_showVerifyEmail(){if(xxdialogMode||(userinfo.emailVerified==true)||(serverinfo.emailcheck!=true)){return}var a="Click ok to send a verification mail to:<br /><div style=padding:8px><b>"+EscapeHtml(userinfo.email)+"</b></div>Please wait a few minute to receive the verification.";setDialogMode(2,"Email Verification",3,account_showVerifyEmailEx,a)}function account_showVerifyEmailEx(){meshserver.send({action:"verifyemail",email:userinfo.email})}function account_showChangeEmail(){if(xxdialogMode){return}var a="Change your account email address here.<br /><br />";a+=addHtmlValue("Email","<input id=dp2email style=width:230px maxlength=256 onchange=account_validateEmail() onkeyup=account_validateEmail(event) />");setDialogMode(2,"Email Address Change",3,account_changeEmail,a);if(userinfo.email!=null){Q("dp2email").value=userinfo.email}account_validateEmail();Q("dp2email").focus()}function account_validateEmail(a,b){QE("idx_dlgOkButton",validateEmail(Q("dp2email").value)&&(Q("dp2email").value!=userinfo.email));if((a!=null)&&(a.keyCode==13)){dialogclose(1)}}function account_changeEmail(){meshserver.send({action:"changeemail",email:Q("dp2email").value})}function account_showDeleteAccount(){if(xxdialogMode){return}var a="To delete this account, type in the account password in both boxes below and hit ok.<br /><br />";a+="<form action='"+domainUrl+"deleteaccount' method=post><table style=margin-left:80px><tr>";a+="<td align=right>Password:</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateDeleteAccount() onkeyup=account_validateDeleteAccount() /></td>";a+="</tr><tr><td align=right>Password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateDeleteAccount() onkeyup=account_validateDeleteAccount() /></td>";a+="</tr></table><br /><div style=padding:10px;margin-bottom:4px>";a+="<input id=account_dlgCancelButton type=button value=Cancel style=float:right;width:80px;margin-left:5px onclick=dialogclose(0)>";a+='<input id=account_dlgOkButton type=submit value=OK style="float:right;width:80px" onclick=dialogclose(1)>';a+="</div><br /></form>";setDialogMode(2,"Delete Account",0,null,a);account_validateDeleteAccount();Q("apassword1").focus()}function account_showChangePassword(){if(xxdialogMode){return}var d="Change your account password by entering the old password and new password twice in the boxes below. Password hint can be used but is not recommanded.<br /><br />";d+="<table style=margin-left:60px>";d+="<tr><td align=right>Old password:</td><td><input id=apassword0 type=password name=apassword0 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b></b></td></tr>";d+="<tr><td align=right>New password:</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b><span id=dxPassWarn></span></b></td></tr>";d+="<tr><td align=right>New password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td></tr>";if(features&65536){d+="<tr><td align=right>Password hint:</td><td><input id=apasswordhint name=apasswordhint maxlength=250 type=text autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td></tr>"}d+="</table>";if(passRequirements){var b=[],c=0;for(var a in passRequirements){if((a!="reset")&&(a!="hint")){b.push(a+":"+passRequirements[a]);c++}}if(c>0){d+="<br /><span style=font-size:x-small>Requirements: "+b.join(", ")+".</span>"}}d+="<br />";setDialogMode(2,"Change Password",3,account_showChangePasswordEx,d);Q("apassword0").focus();account_validateNewPassword()}function account_showChangePasswordEx(){if(Q("apassword1").value==Q("apassword2").value){var a={action:"changepassword",oldpass:Q("apassword0").value,newpass:Q("apassword1").value};if(features&65536){a.hint=Q("apasswordhint").value}meshserver.send(a)}}function account_createMesh(){if(xxdialogMode){return}if((userinfo.emailVerified!==true)&&(serverinfo.emailcheck==true)&&(userinfo.siteadmin!=4294967295)){setDialogMode(2,"New Device Group",1,null,'Unable to create a new device group until a email address is verified. This is required for password recovery. Go to the "My Account" tab to change and verify an email address.');return}var a="Create a new device group using the options below.<br /><br />";a+=addHtmlValue("Name","<input id=dp2meshname style=width:230px maxlength=64 onchange=account_validateMeshCreate() onkeyup=account_validateMeshCreate() />");a+=addHtmlValue("Type","<div style=width:230px;margin:0;padding:0><select id=dp2meshtype style=width:100% onchange=account_validateMeshCreate() ><option value=2>Manage using a software agent</option><option value=1>Intel&reg; AMT only, no agent</option></select></div>");a+=addHtmlValue("Description","<div style=width:230px;margin:0;padding:0><textarea id=dp2meshdesc maxlength=1024 style=width:100%;resize:none></textarea></div>");setDialogMode(2,"New Device Group",3,account_createMeshEx,a);account_validateMeshCreate();Q("dp2meshname").focus()}function account_validateMeshCreate(){QE("idx_dlgOkButton",Q("dp2meshname").value.length>0)}function account_createMeshEx(a,b){meshserver.send({action:"createmesh",meshname:Q("dp2meshname").value,meshtype:Q("dp2meshtype").value,desc:Q("dp2meshdesc").value})}function account_validateDeleteAccount(){QE("account_dlgOkButton",(Q("apassword1").value.length>0)&&(Q("apassword1").value==Q("apassword2").value))}function account_validateNewPassword(){var d="",a=(Q("apassword0").value.length>0)&&(Q("apassword1").value.length>0)&&(Q("apassword1").value==Q("apassword2").value)&&(Q("apassword0").value!=Q("apassword1").value)&&(Q("apasswordhint").value!=Q("apassword1").value);if(Q("apassword1").value!=""){if(passRequirements==null||passRequirements==""){var c=checkPasswordStrength(Q("apassword1").value);if(c>=80){d="<span style=color:green>Strong<span>"}else{if(c>=60){d="<span style=color:blue>Good<span>"}else{d="<span style=color:red>Weak<span>"}}}else{var b=checkPasswordRequirements(Q("apassword1").value,passRequirements);if(b==false){a=false;d="<span style=color:red>Policy<span>"}}}QH("dxPassWarn",d);QE("idx_dlgOkButton",a)}function checkPasswordStrength(e){var g=0,d={},h=0,j={digits:/\d/.test(e),lower:/[a-z]/.test(e),upper:/[A-Z]/.test(e),nonWords:/\W/.test(e)};if(!e){return 0}for(var b=0;b<e.length;b++){d[e[b]]=(d[e[b]]||0)+1;g+=5/d[e[b]]}for(var a in j){h+=(j[a]==true)?1:0}return parseInt(g+(h-1)*10)}function checkPasswordRequirements(e,g){if((g==null)||(g=="")||(typeof g!="object")){return true}if(g.min){if(e.length<g.min){return false}}if(g.max){if(e.length>g.max){return false}}var d=0,b=0,h=0,c=0;for(var a=0;a<e.length;a++){if(/\d/.test(e[a])){d++}if(/[a-z]/.test(e[a])){b++}if(/[A-Z]/.test(e[a])){h++}if(/\W/.test(e[a])){c++}}if(g.num&&(d<g.num)){return false}if(g.lower&&(b<g.lower)){return false}if(g.upper&&(h<g.upper)){return false}if(g.nonalpha&&(c<g.nonalpha)){return false}return true}function updateMeshes(){var e="";var a=0,b=0;for(i in meshes){if(a>1){e+="</tr><tr>";a=0}a++;b++;var d=0;if(meshes[i].links["user/"+domain+"/"+userinfo.name.toLowerCase()]){d=meshes[i].links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights}var g="Partial Rights";if(d==4294967295){g="Full Administrator"}else{if(d==0){g="No Rights"}}e+="<div onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=display:inline-block;width:431px;height:50px;padding-top:1px;padding-bottom:1px;float:left><div style=float:left;width:30px;height:100%></div><div style=height:100%;cursor:pointer onclick=gotoMesh('"+i+"')><div class=mi style=float:left;width:50px;height:50px></div><div style=height:100%><div class=g1></div><div class=e2 style=width:300px><div class=e1>"+EscapeHtml(meshes[i].name)+"</div><div>"+g+"</div></div><div class=g2 style=float:left></div></div></div></div>"}meshcount=b;QH("p2meshes",e);QV("p2noMeshFound",b==0)}function gotoMesh(a){currentMesh=meshes[a];p20updateMesh();go(20)}function server_showRestoreDlg(){if(xxdialogMode){return}var a="Restore the server using a backup, <span style=color:red>this will delete the existing server data</span>. Only do this if you know what you are doing.<br /><br />";a+='<form action="/restoreserver.ashx" enctype="multipart/form-data" method="post"><div>';a+='<input id=account_dlgFileInput type=file name=datafile style=width:100% accept=".zip,application/octet-stream,application/zip,application/x-zip,application/x-zip-compressed" onchange=account_validateServerRestore()>';a+="<input id=account_dlgCancelButton type=button value=Cancel style=float:right;width:80px;margin-left:5px onclick=dialogclose(0)>";a+="<input id=account_dlgOkButton type=submit value=OK style=float:right;width:80px onclick=dialogclose(1)>";a+="</div><br /><br /></form>";setDialogMode(2,"Restore Server",0,null,a);account_validateServerRestore()}function account_validateServerRestore(){QE("account_dlgOkButton",Q("account_dlgFileInput").files.length==1)}function server_showVersionDlg(){if(xxdialogMode){return}setDialogMode(2,"MeshCentral Version",1,null,"Loading...","MeshCentralServerUpdate");meshserver.send({action:"serverversion"})}function server_showVersionDlgUpdate(){QE("idx_dlgOkButton",Q("d2updateCheck").checked)}function server_showVersionDlgEx(){meshserver.send({action:"serverupdate"})}function server_showErrorsDlg(){if(xxdialogMode){return}setDialogMode(2,"MeshCentral Errors",1,null,"Loading...","MeshCentralServerErrors");meshserver.send({action:"servererrors"})}function server_showErrorsDlgUpdate(){QE("idx_dlgOkButton",Q("d2updateCheck").checked)}function server_showErrorsDlgEx(){meshserver.send({action:"serverclearerrorlog"})}var currentMesh;function p20updateMesh(){if(currentMesh==null){return}QH("p20meshName",EscapeHtml(currentMesh.name));var j="Unknown #"+currentMesh.mtype;var h=0;try{h=currentMesh.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights}catch(c){}if(currentMesh.mtype==1){j="Intel&reg; AMT only, no agent"}if(currentMesh.mtype==2){j="Managed using a software agent"}var o="";o+=addHtmlValue("Name",addLinkConditional(EscapeHtml(currentMesh.name),"p20editmesh(1)",(h&1)!=0));o+=addHtmlValue("Description",addLinkConditional(((currentMesh.desc&&currentMesh.desc!="")?EscapeHtml(currentMesh.desc):"<i>None</i>"),"p20editmesh(2)",(h&1)!=0));var g=[];if(currentMesh.flags){if(currentMesh.flags&1){g.push("Auto-Remove")}}g=g.join(", ");if(g==""){g="<i>None</i>"}o+=addHtmlValue("Features",addLinkConditional(g,"p20editmeshfeatures()",(h&1)!=0));o+=addHtmlValue("Type",j);if(currentMesh.mtype==2){var e="No Policy";if(currentMesh.amt){if(currentMesh.amt.type==1){e="Deactivate Client Control Mode (CCM)"}else{if(currentMesh.amt.type==2){e="Simple Client Control Mode (CCM)";if(currentMesh.amt.cirasetup==2){e+=" + CIRA"}}}}o+=addHtmlValue("Intel&reg; AMT",addLinkConditional(e,"p20editMeshAmt()",(h&4294967295)!=0))}if(h&1){o+='<br><input type=button value=Notes title="View notes about this device group" onclick=showNotes(false,"'+encodeURIComponent(currentMesh._id)+'") />'}o+="<br style=clear:both><br>";var b=currentMesh.links["user/"+domain+"/"+userinfo.name.toLowerCase()];if(b&&((b.rights&2)!=0)){o+="<a onclick=p20showAddMeshUserDialog() style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> Add User</a>"}if((h&4)!=0){if(currentMesh.mtype==1){o+='<a onclick=addCiraDeviceToMesh("'+currentMesh._id+'") style=cursor:pointer;margin-right:10px title="Add a new Intel&reg; AMT computer that is located on the internet."><img src=images/icon-installmesh.png border=0 height=12 width=12> Install CIRA</a>';o+='<a onclick=addDeviceToMesh("'+currentMesh._id+'") style=cursor:pointer;margin-right:10px title="Add a new Intel&reg; AMT computer that is located on the local network."><img src=images/icon-installmesh.png border=0 height=12 width=12> Install local</a>'}if(currentMesh.mtype==2){o+='<a onclick=addAgentToMesh("'+currentMesh._id+'") style=cursor:pointer;margin-right:10px title="Add a new computer to this mesh by installing the mesh agent."><img src=images/icon-addnew.png border=0 height=12 width=12> Install</a>';if(features&64){o+='<a onclick=inviteAgentToMesh("'+currentMesh._id+'") style=cursor:pointer;margin-right:10px title="Invite someone to install the mesh agent on this mesh."><img src=images/icon-addnew.png border=0 height=12 width=12> Invite</a>'}}}o+='<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:left;width:430px>User Authorizations</th><th scope=col style=text-align:left></th></tr>';var a=1,m=[];for(var d in currentMesh.links){m.push({id:d,name:d.split("/")[2],rights:currentMesh.links[d].rights})}m.sort(function(p,q){if(p.name>q.name){return 1}if(p.name<q.name){return -1}return 0});for(var d in m){var n="",l="Partial Rights",k=m[d].rights;if(k==4294967295){l="Full Administrator"}else{if(k==0){l="No Rights"}}if((d!=userinfo._id)&&(h==4294967295||(((h&2)!=0)))){n='<a onclick=p20deleteUser(event,"'+encodeURIComponent(m[d].id)+'") title="Remote user rights to this mesh" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>'}o+='<tr onclick=p20viewuser("'+encodeURIComponent(m[d].id)+'") style=cursor:pointer'+(((a%2)==0)?";background-color:#DDD":"")+'><td><div title="User" class=m2></div><div>&nbsp;'+EscapeHtml(decodeURIComponent(m[d].name))+"<div></div></div></td><td><div style=float:right>"+n+"</div><div>"+l+"</div></td></tr>";++a}o+="</tbody></table>";if(h==4294967295){o+="<div style=font-size:x-small;text-align:right><span><a onclick=p20showDeleteMeshDialog() style=cursor:pointer>Delete Group</a></span></div>"}QH("p20info",o)}function p20editMeshAmt(){if(xxdialogMode){return}var a="";a+=addHtmlValue("Type","<select id=dp20amtpolicy style=width:230px onchange=p20editMeshAmtChange()><option value=0>No Policy</option><option value=1>Deactivate Client Control Mode (CCM)</option><option value=2>Simple Client Control Mode (CCM)</option></select>");a+="<div id=dp20amtpolicydiv></div>";setDialogMode(2,"Intel&reg; AMT Policy",3,p20editMeshAmtEx,a);if(currentMesh.amt){Q("dp20amtpolicy").value=currentMesh.amt.type}p20editMeshAmtChange();if(currentMesh.amt&&currentMesh.amt.type==2){Q("dp20amtpolicypass").value=currentMesh.amt.password;Q("dp20amtbadpass").value=currentMesh.amt.badpass;if((features&1024)==0){Q("dp20amtcira").value=currentMesh.amt.cirasetup}}dp20amtValidatePolicy()}function p20editMeshAmtChange(){var a=Q("dp20amtpolicy").value,b="";if(a==2){b=addHtmlValue("Password*","<input id=dp20amtpolicypass style=width:230px maxlength=32 onchange=dp20amtValidatePolicy() onkeyup=dp20amtValidatePolicy() />");b+=addHtmlValue("Password mismatch","<select id=dp20amtbadpass style=width:230px><option value=0>Do nothing</option><option value=1>Reactivate Intel&reg; AMT</option></select>");if((features&1024)==0){b+=addHtmlValue('<span title="Client Initiated Remote Access">CIRA</span>',"<select id=dp20amtcira style=width:230px><option value=0>Don't configure</option><option value=1>Don't connect to server</option><option value=2>Connect to server</option></select>")}b+='<br/><span style="font-size:10px">* Recommanded, leave blank to assign a random password to each device.</span><br/>';b+='<span style="font-size:10px">This policy will not impact devices with Intel&reg; AMT in ACM mode.</span><br/>';b+='<span style="font-size:10px">This is not a secure policy as agents will be performing activation.</span>'}QH("dp20amtpolicydiv",b)}function dp20amtValidatePolicy(){var a=true,c=Q("dp20amtpolicy").value;if(c==2){var b=Q("dp20amtpolicypass").value;a=(b=="")?true:passwordcheck(b)}QE("idx_dlgOkButton",a)}function p20editMeshAmtEx(){var b=parseInt(Q("dp20amtpolicy").value),a={type:b};if(b==2){a={type:b,password:Q("dp20amtpolicypass").value,badpass:parseInt(Q("dp20amtbadpass").value)};if((features&1024)==0){a.cirasetup=parseInt(Q("dp20amtcira").value)}else{a.cirasetup=1}}meshserver.send({action:"meshamtpolicy",meshid:currentMesh._id,amtpolicy:a})}function p20showDeleteMeshDialog(){if(xxdialogMode){return}var a='Are you sure you want to delete group "'+EscapeHtml(currentMesh.name)+'"? Deleting the device group will also delete all information about devices within this group.<br /><br />';a+="<input id=p20check type=checkbox onchange=p20validateDeleteMeshDialog() />Confirm";setDialogMode(2,"Delete Group",3,p20showDeleteMeshDialogEx,a);p20validateDeleteMeshDialog()}function p20validateDeleteMeshDialog(){QE("idx_dlgOkButton",Q("p20check").checked)}function p20showDeleteMeshDialogEx(a,b){meshserver.send({action:"deletemesh",meshid:currentMesh._id,meshname:currentMesh.name})}function p20editmesh(a){if(xxdialogMode){return}var b=addHtmlValue("Name","<input id=dp20meshname style=width:230px maxlength=32 onchange=p20editmeshValidate() onkeyup=p20editmeshValidate() />");b+=addHtmlValue("Description","<div style=width:230px;margin:0;padding:0><textarea id=dp20meshdesc maxlength=1024 style=width:100%;resize:none></textarea></div>");setDialogMode(2,"Edit Device Group",3,p20editmeshEx,b);Q("dp20meshname").value=currentMesh.name;if(currentMesh.desc){Q("dp20meshdesc").value=currentMesh.desc}p20editmeshValidate();if(a==2){Q("dp20meshdesc").focus()}else{Q("dp20meshname").focus()}}function p20editmeshEx(){meshserver.send({action:"editmesh",meshid:currentMesh._id,meshname:Q("dp20meshname").value,desc:Q("dp20meshdesc").value})}function p20editmeshValidate(){QE("idx_dlgOkButton",Q("dp20meshname").value.length>0)}function p20editmeshfeatures(){if(xxdialogMode){return}var a=(currentMesh.flags)?currentMesh.flags:0;var b="<div><input type=checkbox id=d20flag1 "+((a&1)?"checked":"")+">Remove device on disconnect<br></div>";setDialogMode(2,"Edit Device Group Features",3,p20editmeshfeaturesEx,b)}function p20editmeshfeaturesEx(){var a=0;if(Q("d20flag1").checked){a+=1}meshserver.send({action:"editmesh",meshid:currentMesh._id,flags:a})}function p20showAddMeshUserDialog(){if(xxdialogMode){return}var a="Allow a user to manage this device group and devices in this group<br /><br />";a+=addHtmlValue("User Name","<input id=dp20username style=width:230px maxlength=32 onchange=p20validateAddMeshUserDialog() onkeyup=p20validateAddMeshUserDialog() />");a+='<br><div style="height:120px;overflow-y:scroll;border:1px solid gray">';a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20fulladmin>Full Administrator<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20editmesh>Edit Device Group<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20manageusers>Manage Device Group Users<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20managecomputers>Manage Device Group Computers<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotecontrol>Remote Control<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remoteview style=margin-left:12px>Remote View Only<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotelimitedinput style=margin-left:12px>Limited Input Only<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20noterminal style=margin-left:12px>No Terminal Access<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20nofiles style=margin-left:12px>No File Access<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20noamt style=margin-left:12px>No Intel&reg; AMT<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshagentconsole>Mesh Agent Console<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshserverfiles>Server Files<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20wakedevices>Wake Devices<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20editnotes>Edit Device Notes<br>";a+="</div>";setDialogMode(2,"Add User to Device Group",3,p20showAddMeshUserDialogEx,a);p20validateAddMeshUserDialog();Q("dp20username").focus()}function p20validateAddMeshUserDialog(){var a=currentMesh.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;QE("idx_dlgOkButton",(Q("dp20username").value.length>0));QE("p20fulladmin",a==4294967295);QE("p20editmesh",(!Q("p20fulladmin").checked)&&(a==4294967295));QE("p20manageusers",!Q("p20fulladmin").checked);QE("p20managecomputers",!Q("p20fulladmin").checked);QE("p20remotecontrol",!Q("p20fulladmin").checked);QE("p20meshagentconsole",!Q("p20fulladmin").checked);QE("p20meshserverfiles",!Q("p20fulladmin").checked);QE("p20wakedevices",!Q("p20fulladmin").checked);QE("p20editnotes",!Q("p20fulladmin").checked);QE("p20remoteview",!Q("p20fulladmin").checked&&Q("p20remotecontrol").checked);QE("p20remotelimitedinput",!Q("p20fulladmin").checked&&Q("p20remotecontrol").checked&&!Q("p20remoteview").checked);QE("p20noterminal",!Q("p20fulladmin").checked&&Q("p20remotecontrol").checked);QE("p20nofiles",!Q("p20fulladmin").checked&&Q("p20remotecontrol").checked);QE("p20noamt",!Q("p20fulladmin").checked&&Q("p20remotecontrol").checked)}function p20showAddMeshUserDialogEx(){var a=0;if(Q("p20fulladmin").checked==true){a=4294967295}else{if(Q("p20editmesh").checked==true){a+=1}if(Q("p20manageusers").checked==true){a+=2}if(Q("p20managecomputers").checked==true){a+=4}if(Q("p20remotecontrol").checked==true){a+=8}if(Q("p20meshagentconsole").checked==true){a+=16}if(Q("p20meshserverfiles").checked==true){a+=32}if(Q("p20wakedevices").checked==true){a+=64}if(Q("p20editnotes").checked==true){a+=128}if(Q("p20remoteview").checked==true){a+=256}if(Q("p20noterminal").checked==true){a+=512}if(Q("p20nofiles").checked==true){a+=1024}if(Q("p20noamt").checked==true){a+=2048}if(Q("p20remotelimitedinput").checked==true){a+=4096}}meshserver.send({action:"addmeshuser",meshid:currentMesh._id,meshname:currentMesh.name,username:Q("dp20username").value,meshadmin:a})}function p20viewuser(e){if(xxdialogMode){return}e=decodeURIComponent(e);var d="",b=currentMesh.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights,c=currentMesh.links[e].rights;if(c==4294967295){d=", Full Administrator (all rights)"}else{if((c&1)!=0){d+=", Edit Device Group"}if((c&2)!=0){d+=", Manage Device Group Users"}if((c&4)!=0){d+=", Manage Device Group Computers"}if((c&8)!=0){d+=", Remote Control"}if((c&16)!=0){d+=", Agent Console"}if((c&32)!=0){d+=", Server Files"}if((c&64)!=0){d+=", Wake Devices"}if((c&128)!=0){d+=", Edit Notes"}if(((c&8)!=0)&&(c&256)!=0){d+=", Remote View Only"}if(((c&8)!=0)&&(c&512)!=0){d+=", No Terminal"}if(((c&8)!=0)&&(c&1024)!=0){d+=", No Files"}if(((c&8)!=0)&&(c&2048)!=0){d+=", No Intel&reg; AMT"}if(((c&8)!=0)&&((c&4096)!=0)&&((c&256)==0)){d+=", Limited Input"}}d=d.substring(2);if(d==""){d="No Rights"}var a=1,g=addHtmlValue("User Name",EscapeHtml(decodeURIComponent(e.split("/")[2])));g+=addHtmlValue("Permissions",d);if((("user/"+domain+"/"+userinfo.name.toLowerCase())!=e)&&(b==4294967295||(((b&2)!=0)&&(c!=4294967295)))){a+=4}setDialogMode(2,"Device Group User",a,p20viewuserEx,g,e)}function p20viewuserEx(a,b){if(a!=2){return}setDialogMode(2,"Remote Mesh User",3,p20viewuserEx2,"Confirm removal of user "+b.split("/")[2]+"?",b)}function p20deleteUser(a,b){haltEvent(a);p20viewuserEx(2,decodeURIComponent(b))}function p20viewuserEx2(a,b){meshserver.send({action:"removemeshuser",meshid:currentMesh._id,meshname:currentMesh.name,userid:b})}var filetreelinkpath;var filetreelocation=[];function updateFiles(){QV("MainMenuMyFiles",((features&8)==0));if((features&8)!=0){return}var q="",r="",c="<a style=cursor:pointer onclick=p5folderup(0)>Root</a>",o="Root",y,k=filetree,m=1;var j=[],v=filetreelinkpath,b=[],a=document.getElementsByName("fc");for(var s=0;s<a.length;s++){if(a[s].checked){b.push(a[s].value)}}filetreelinkpath="";for(var s in filetreelocation){if((k.f!=null)&&(k.f[filetreelocation[s]]!=null)){j.push(filetreelocation[s]);o+=" / "+filetreelocation[s];if((m==1)){var B=filetreelocation[s].split("/");y=window.location+B[0]+"files/"+B[2];filetreelinkpath+=filetreelocation[s]}else{if(filetreelinkpath!=""){filetreelinkpath+="/"+filetreelocation[s];if(m>2){y+="/"+filetreelocation[s]}}}k=k.f[filetreelocation[s]];c+=" / <a style=cursor:pointer onclick=p5folderup("+m+")>"+(k.n!=null?k.n:filetreelocation[s])+"</a>";m++}else{break}}filetreelocation=j;var w=o.toLowerCase().startsWith("root / "+userinfo._id+" / public");var l=p5sort_files(k.f);for(var s in l){var d=l[s],u=d.n,A;A=u;if(u.length>70){A='<span title="'+EscapeHtml(u)+'">'+EscapeHtml(u.substring(0,70))+"...</span>"}else{A=EscapeHtml(u)}u=EscapeHtml(u);var g="";if(d.d!=null){var e=new Date(d.d),g=(e.getMonth()+1)+"/"+(e.getDate())+"/"+e.getFullYear()+" "+e.toLocaleTimeString()+"&nbsp;"}var n="";if(d.s!=null){n=getFileSizeStr(d.s)}var p="";if(d.t<3||d.t==4){var z=(d.t==1||d.t==4)?p5getQuotabar(d):"",C="";p="<div class=filelist file=999><input file=999 style=float:left name=fc class=fcb type=checkbox onchange=p5setActions() value='"+u+"'>&nbsp;<span style=float:right title=\""+C+'">'+z+"</span><span><div class=fileIcon"+d.t+' onclick=p5folderset("'+encodeURIComponent(d.nx)+'")></div><a style=cursor:pointer onclick=p5folderset("'+encodeURIComponent(d.nx)+'")>'+A+"</a></span></div>"}else{var t=A;var x="";if(w){x=' (<a style=cursor:pointer title="Display public link" onclick=\'p5showPublicLink("'+y+"/"+d.nx+"\")'>Link</a>)"}if(d.s>0){t='<a rel="noreferrer noopener" target="_blank" href="downloadfile.ashx?link='+encodeURIComponent(filetreelinkpath+"/"+d.nx)+'">'+A+"</a>"+x}p="<div class=filelist file=3><input file=3 style=float:left name=fc class=fcb type=checkbox onchange=p5setActions() value='"+d.nx+"'>&nbsp;<span class=fsize>"+g+"</span><span style=float:right>"+n+"</span><span><div class=fileIcon"+d.t+"></div>"+t+"</span></div>"}if(d.t<3){q+=p}else{r+=p}}QH("p5rightOfButtons",p5getQuotabar(k));QH("p5files",q+r);QH("p5currentpath",c);QE("p5FolderUp",filetreelocation.length!=0);QV("p5PublicShare",w);if(v==filetreelinkpath){a=document.getElementsByName("fc");for(var s=0;s<a.length;s++){a[s].checked=(b.indexOf(a[s].value)>=0)}}p5setActions()}function getNiceSize(a){if(a<=0){return"Storage limit exceed"}if(a<2048){return a+" bytes remaining"}if(a<2097152){return Math.round(a/1024)+" kilobytes remaining"}if(a<2147483648){return Math.round(a/1024/1024)+" megabytes remaining"}return Math.round(a/1024/1024/1024)+" gigabytes remaining"}function getNiceSize2(a){if(a<=0){return"None"}if(a<2048){return a+" b"}if(a<2097152){return Math.round(a/1024)+" Kb"}if(a<2147483648){return Math.round(a/1024/1024)+" Mb"}return Math.round(a/1024/1024/1024)+" Gb"}function p5getQuotabar(a){while(a.t>1&&a.t!=4){a=a.parent}if((a.t!=1&&a.t!=4)||(a.maxbytes==null)){return""}var b=Math.floor(a.s/1024),c=(a.maxbytes-a.s);return'<span title="'+b+"k in "+a.c+" file"+(a.c>1?"s":"")+". "+(Math.floor(a.maxbytes/1024/1024))+'k maxinum">'+getNiceSize(c)+" <progress style=height:10px;width:100px value="+a.s+" max="+a.maxbytes+" /></span>"}function p5showPublicLink(a){setDialogMode(2,"Public Link",1,null,'<input type=text style=width:100% value="'+a+'" readonly />')}var sortorder;function p5sort_filename(c,d){if(c.ln>d.ln){return(1*sortorder)}if(c.ln<d.ln){return(-1*sortorder)}return 0}function p5sort_timestamp(c,d){if(c.d>d.d){return(1*sortorder)}if(c.d<d.d){return(-1*sortorder)}return 0}function p5sort_bysize(c,d){if(c.s==d.s){return p5sort_filename(c,d)}return(((c.s-d.s))*sortorder)}function p5sort_files(a){var c=[],d=Q("p5sortdropdown").value;for(var b in a){a[b].nx=b;if(a[b].n==null){a[b].n=b}a[b].ln=a[b].n.toLowerCase();c.push(a[b])}sortorder=1;if(d>3){sortorder=-1;d-=3}if(d==1){c.sort(p5sort_filename)}else{if(d==2){c.sort(p5sort_bysize)}else{if(d==3){c.sort(p5sort_timestamp)}}}return c}function p5setActions(){var a=getFileSelCount(),c=getFileCount(),b=getFileSelCount(false);QE("p5DeleteFileButton",(a>0)&&(filetreelocation.length>0));QE("p5NewFolderButton",filetreelocation.length>0);QE("p5UploadButton",filetreelocation.length>0);QE("p5RenameFileButton",(a==1)&&(filetreelocation.length>0));QE("p5SelectAllButton",c>0);Q("p5SelectAllButton").value=(a>0?"Select None":"Select All");QE("p5CutButton",(b>0)&&(a==b));QE("p5CopyButton",(b>0)&&(a==b));QE("p5PasteButton",(p5clipboard!=null)&&(p5clipboard.length>0)&&(filetreelocation.length>0))}function getFileSelCount(d){var a=0,b=document.getElementsByName("fc");for(var c=0;c<b.length;c++){if((b[c].checked)&&((d!=false)||(b[c].attributes.file.value=="3"))){a++}}return a}function getFileSelDirCount(){var a=0,b=document.getElementsByName("fc");for(var c=0;c<b.length;c++){if((b[c].checked)&&(b[c].attributes.file.value=="999")){a++}}return a}function getFileCount(){var a=0;var b=document.getElementsByName("fc");return b.length}function p5selectallfile(){var c=(getFileSelCount()==0),a=document.getElementsByName("fc");for(var b=0;b<a.length;b++){a[b].checked=c}p5setActions()}function setupBackPointers(d){if(d.f!=null){var b=0,a=0;for(var c in d.f){setupBackPointers(d.f[c]);d.f[c].parent=d;if(d.f[c].s){b+=d.f[c].s}if(d.f[c].c){a+=d.f[c].c}if(d.f[c].t==3){a++}}d.s=b;d.c=a}return d}function getFileSizeStr(a){if(a==1){return"1 byte"}return""+a+" bytes"}function p5folderup(a){if(a==null){filetreelocation.pop()}else{while(filetreelocation.length>a){filetreelocation.pop()}}updateFiles()}function p5folderset(a){filetreelocation.push(decodeURIComponent(a));updateFiles()}function p5createfolder(){setDialogMode(2,"New Folder",3,p5createfolderEx,"<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% />");focusTextBox("p5renameinput");p5fileNameCheck()}function p5createfolderEx(){meshserver.send({action:"fileoperation",fileop:"createfolder",path:filetreelocation,newfolder:Q("p5renameinput").value})}function p5deletefile(){var a=getFileSelCount(),b=(getFileSelDirCount()>0)?"<br /><br /><input type=checkbox id=p5recdeleteinput>Recursive delete<br>":"<input type=checkbox id=p5recdeleteinput style='display:none'>";setDialogMode(2,"Delete",3,p5deletefileEx,(a>1)?("Delete "+a+" selected items?"+b):("Delete selected item?"+b))}function p5deletefileEx(){var b=[],a=document.getElementsByName("fc");for(var c=0;c<a.length;c++){if(a[c].checked){b.push(a[c].value)}}meshserver.send({action:"fileoperation",fileop:"delete",path:filetreelocation,delfiles:b,rec:Q("p5recdeleteinput").checked})}function p5renamefile(){var c,a=document.getElementsByName("fc");for(var b=0;b<a.length;b++){if(a[b].checked){c=a[b].value}}setDialogMode(2,"Rename",3,p5renamefileEx,'<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% value="'+c+'" />',{action:"fileoperation",fileop:"rename",path:filetreelocation,oldname:c});focusTextBox("p5renameinput");p5fileNameCheck()}function p5renamefileEx(a,c){c.newname=Q("p5renameinput").value;meshserver.send(c)}function p5fileNameCheck(a){var b=isFilenameValid(Q("p5renameinput").value);QE("idx_dlgOkButton",b);if((b==true)&&(a&&a.keyCode==13)){dialogclose(1)}}var isFilenameValid=(function(){var b=/^[^\\/:\*\?"<>\|]+$/,c=/^\./,d=/^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i;return function a(e){return b.test(e)&&!c.test(e)&&!d.test(e)&&(e[0]!=".")}})();function p5uploadFile(){setDialogMode(2,"Upload File",3,p5uploadFileEx,'<form method=post enctype=multipart/form-data action=uploadfile.ashx target=fileUploadFrame><input type=text name=link style=display:none id=p5uploadpath value="'+encodeURIComponent(filetreelinkpath)+'" /><input type=file name=files id=p5uploadinput style=width:100% multiple=multiple onchange="updateUploadDialogOk(\'p5uploadinput\')" /><input type=submit id=p5loginSubmit style=display:none /></form>');updateUploadDialogOk("p5uploadinput")}function p5uploadFileEx(){Q("p5loginSubmit").click()}function updateUploadDialogOk(a){QE("idx_dlgOkButton",Q(a).value!="")}var p5clipboard=null,p5clipboardFolder=null,p5clipboardCut=0;function p5copyFile(b){var a=document.getElementsByName("fc");p5clipboard=[];p5clipboardCut=b,p5clipboardFolder=Clone(filetreelocation);for(var c=0;c<a.length;c++){if((a[c].checked)&&(a[c].attributes.file.value=="3")){p5clipboard.push(a[c].value)}}p5updateClipview()}function p5pasteFile(){var a="";if((p5clipboard!=null)&&(p5clipboard.length>0)){a="Confim "+(p5clipboardCut==0?"copy":"move")+" of "+p5clipboard.length+" entrie"+((p5clipboard.length>1)?"s":"")+" to this location?"}setDialogMode(2,"Paste",3,p5pasteFileEx,a)}function p5pasteFileEx(){meshserver.send({action:"fileoperation",fileop:(p5clipboardCut==0?"copy":"move"),scpath:p5clipboardFolder,path:filetreelocation,names:p5clipboard});p5folderup(999);if(p5clipboardCut==1){p5clipboard=null,p5clipboardFolder=null,p5clipboardCut=0;p5updateClipview()}}function p5updateClipview(){var a="";if((p5clipboard!=null)&&(p5clipboard.length>0)){a="Holding "+p5clipboard.length+" entrie"+((p5clipboard.length>1)?"s":"")+" for "+(p5clipboardCut==0?"copy":"move")+", <a onclick=p5clearClip() style=cursor:pointer>Clear</a>."}QH("p5bottomstatus",a);p5setActions()}function p5clearClip(){p5clipboard=null;p5clipboardFolder=null;p5clipboardCut=0;p5updateClipview()}function p5fileDragDrop(b){if(xxdialogMode){return}haltEvent(b);QV("bigfail",false);QV("bigok",false);var c=0;p5uploadFile();try{Q("p5uploadinput").files=b.dataTransfer.files}catch(d){c=1}if(c==0){p5uploadFileEx()}setDialogMode(0);if(c==1){if(b.dataTransfer==null||b.dataTransfer.files.length==0||filetreelocation.length==0){return}var j=[],m=[],o=[],a=[],l=b.dataTransfer.files.length,n=0;for(var h=0;h<b.dataTransfer.files.length;h++){n+=b.dataTransfer.files[h].size}if(n>1300000){p5uploadFile();return}for(var h=0;h<b.dataTransfer.files.length;h++){var k=new FileReader(),g=b.dataTransfer.files[h];j.push(g.name);m.push(g.size);o.push(g.type);k.onload=function(e){a.push(e.target.result);if(--l==0){Q("p5fileDragName").value=j.join("*");Q("p5fileDragSize").value=m.join("*");Q("p5fileDragType").value=o.join("*");Q("p5fileDragData").value=a.join("*");Q("p5fileDragLink").value=encodeURIComponent(filetreelinkpath);Q("p5loginSubmit2").click()}};k.readAsDataURL(g)}}}var p5dragtimer=null;function p5fileDragOver(b){if(xxdialogMode){return}haltEvent(b);if(p5dragtimer!=null){clearTimeout(p5dragtimer);p5dragtimer=null}var a=true;if(filetreelocation.length==0){a=false}QV("bigok",a);QV("bigfail",!a)}function p5fileDragLeave(a){if(xxdialogMode){return}haltEvent(a);if(a.target.id!="p5filetable"){QV("bigfail",false);QV("bigok",false)}else{p5dragtimer=setTimeout(function(){QV("bigfail",false);QV("bigok",false);p5dragtimer=null},10)}}function eventMouseHover(a,b){a.children[1].classList.remove("g1s");a.children[2].style["background-color"]=((b==0)?"#c9c9c9":"#b9b9b9");a.children[3].classList.remove("g2s");if(b==1){a.children[1].classList.add("g1s");a.children[3].classList.add("g2s")}}function eventsUpdate(){var h="",a=null;for(var c in events){var b=events[c],g=new Date(b.time);if(g.toLocaleDateString()!=a){if(a!=null){h+="</table>"}h+="<table style=width:100% cellpadding=0 cellspacing=0><tr><td colspan=4 class=DevSt>"+g.toLocaleDateString()+"</td></tr>";a=g.toLocaleDateString()}var d="si3";if(b.etype=="user"){d="m2"}if(b.etype=="server"){d="si3"}var e=b.msg.split("(R)").join("&reg;");if(b.username&&b.username!=userinfo.name){e+=": "+b.username}h+="<tr onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class="+d+"></div></td><td class=g1 style=float:none>&nbsp;</td><td style=background-color:#C9C9C9>"+g.toLocaleTimeString()+" - "+e+"</td><td class=g2 style=float:none>&nbsp;</td></tr><tr style=height:2px></tr>"}if(a!=null){h+="</table>"}if(h==""){h="<br><i>No Events Found</i><br><br>"}QH("p3events",h)}function showDeleteAllEventsDialog(){if(xxdialogMode){return}var a="Delete all events in the server event log?<br /><br />";a+="<input id=p3check type=checkbox onchange=validateDeleteAllEventsDialog() />Confirm";setDialogMode(2,"Delete All Events",3,showDeleteAllEventsDialogEx,a);validateDeleteAllEventsDialog()}function validateDeleteAllEventsDialog(){QE("idx_dlgOkButton",Q("p3check").checked)}function showDeleteAllEventsDialogEx(a,b){meshserver.send({action:"clearevents"})}function refreshEvents(){meshserver.send({action:"events",limit:parseInt(p3limitdropdown.value)})}function updateUsers(){QV("MainMenuMyUsers",(users!=null)&&((features&4)==0));QV("LeftMenuMyUsers",(users!=null)&&((features&4)==0));QV("UserNewAccountButton",((features&4)==0)&&(serverinfo.domainauth==false));if((users==null)||((features&4)!=0)){QH("p3users","");return}var g=[],d=100,b=0;for(var c in users){g.push(c)}g.sort();var j=Q("UserSearchInput").value.toLowerCase();var k="<table style=width:100% cellpadding=0 cellspacing=0>",a=true;k+="<th style=color:gray>Name<th style=color:gray;width:80px>Groups<th style=color:gray;width:120px>Last&nbsp;Access<th style=color:gray;width:120px>Permissions";for(var c in g){var h=users[g[c]],e=null;if(wssessions!=null){e=wssessions[h._id]}if((e!=null)&&(h.name.toLowerCase().indexOf(j)>=0)){if(d>0){if(a){k+="<tr><td class=userTableHeader colspan=4>Online Users";a=false}k+=addUserHtml(h,e);d--}else{b++}}}a=true;for(var c in g){var h=users[g[c]],e=null;if(wssessions!=null){e=wssessions[h._id]}if((e==null)&&(h.name.toLowerCase().indexOf(j)>=0)){if(d>0){if(a){k+="<tr><td class=userTableHeader colspan=4>Offline Users";a=false}k+=addUserHtml(h,e);d--}else{b++}}}k+="</table>";if(b==1){k+="<br />1 more user not shown, use search box to look for users...<br />"}else{if(b>1){k+="<br />"+b+" more users not shown, use search box to look for users...<br />"}}if(d==100){k+="<br />No users found.<br />"}QH("p3users",k);if((currentUser!=null)&&(xxcurrentView==30)){gotoUser(encodeURIComponent(currentUser._id),true)}}function addUserHtml(m,l){var o="",b=" gray",e="m2",h="",k=(m.name!=userinfo.name),g="",j="";if(l!=null){b="";if(k){h='<span style=float:right;margin-top:1px;margin-right:4px title=Chat><a onclick=userChat(event,"'+encodeURIComponent(m._id)+'","'+encodeURIComponent(m.name)+"\")><img src='images/icon-chat.png' height=16 width=16 style=padding-top:2px /></a></span>";h+='<span style=float:right;margin-top:1px;margin-left:4px;margin-right:4px title=Notify><a onclick=showUserAlertDialog(event,"'+encodeURIComponent(m._id)+"\")><img src='images/icon-notify.png' height=16 width=16 style=padding-top:2px /></a></span>"}if(l==1){g+="1&nbsp;session"}else{g+=l+"&nbsp;sessions"}}else{if(m.login){g+='<span title="Last login: '+new Date(m.login*1000).toLocaleString()+'">'+new Date(m.login*1000).toLocaleDateString()+"</span>"}}if(k){j+='<a style=cursor:pointer onclick=showUserAdminDialog(event,"'+encodeURIComponent(m._id)+'")>'}if((m.siteadmin!=null)&&((m.siteadmin&32)!=0)&&(m.siteadmin!=4294967295)){j+="Locked,&nbsp;"}j+="<span title='Server Permissions'>";if((m.siteadmin==null)||(m.siteadmin==0)||(m.siteadmin==32)){j+="User"}else{if(m.siteadmin==8){j+="User + Files"}else{if(m.siteadmin==4294967295){j+="Administrator"}else{j+="Partial"}}}j+="</span>";if(k){j+="</a>"}var c=0;if(m.links){for(var d in m.links){c++}}var n=EscapeHtml(m.name),a="";if(serverinfo.emailcheck==true){a=((m.emailVerified!=true)?' <b style=color:red title="Email is not verified">&#x1F5F4</b>':' <b style=color:green title="Email is verified">&#x1F5F8</b>')}if(m.email!=null){n+=', <a onclick=doemail(event,"'+m.email+'")>'+m.email+"</a>"+a}if((m.otpsecret>0)||(m.otphkeys>0)){n+=' <img src="images/key12.png" height=12 width=11 title="2nd factor authentication enabled" style="margin-top:2px" />'}if((m.siteadmin!=null)&&((m.siteadmin&32)!=0)&&(m.siteadmin!=4294967295)){n+=' <img src="images/padlock12.png" height=12 width=8 title="Account is locked" style="margin-top:2px" />'}o+='<tr onmouseover=userMouseHover(this,1) onmouseout=userMouseHover(this,0)><td style=cursor:pointer onclick=gotoUser("'+encodeURIComponent(m._id)+'")>';o+="<div class=bar style=height:24px;width:100%;font-size:medium>";o+='<div style=float:left;height:24px;width:24px;background-color:white><div class="'+e+b+'" style=width:16px;margin-top:4px;margin-left:2px;height:16px></div></div>';o+="<div class=g1 style=height:24px;float:left></div><div class=g2 style=height:24px;float:right></div>";o+="<div><span>"+n+"</span>"+h+"</div></div><td style=text-align:center>"+c+"<td style=text-align:center>"+g+"<td style=text-align:center>"+j;return o}function userMouseHover(b,c){var a=b.children[0].children[0];a.children[1].classList.remove("g1s");a.children[2].classList.remove("g2s");if(c==1){a.children[1].classList.add("g1s");a.children[2].classList.add("g2s")}b.children[0].children[0].style["background-color"]=((c==0)?"#c9c9c9":"#b9b9b9")}function userChat(a,d,b){haltEvent(a);var c="/messenger?id=meshmessenger/"+d+"/"+encodeURIComponent(userinfo._id)+"&title="+b;if((authCookie!=null)&&(authCookie!="")){c+="&auth="+authCookie}window.open(c,"meshmessenger:"+d);meshserver.send({action:"meshmessenger",userid:decodeURIComponent(d)});return false}function showUserAlertDialog(a,b){if(xxdialogMode){return}haltEvent(a);setDialogMode(2,"Notify "+EscapeHtml(users[decodeURIComponent(b)].name),3,showUserAlertDialogEx,'Send a text notification to this user.<textarea id=d2notifyText maxlength=2048 style="width:100%;height:184px;resize:none"></textarea>',b);Q("d2notifyText").focus();return false}function showUserAlertDialogEx(a,b){meshserver.send({action:"notifyuser",userid:decodeURIComponent(b),msg:Q("d2notifyText").value})}function doemail(b,a){if(xxdialogMode){return}haltEvent(b);window.open("mailto:"+a);return false}function showUserBroadcastDialog(){if(xxdialogMode){return}var a='Broadcast a message to all connected users.<textarea id=broadcastMessage value="" style=width:370px;height:100px;resize:none maxlength=256 /></textarea>';setDialogMode(2,"Broadcast Message",3,showUserBroadcastDialogEx,a);Q("broadcastMessage").focus()}function showUserBroadcastDialogEx(){meshserver.send({action:"userbroadcast",msg:Q("broadcastMessage").value})}function showCreateNewAccountDialog(){if(xxdialogMode){return}var d="";d+=addHtmlValue("Name","<input id=p4name style=width:230px maxlength=64 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />");d+=addHtmlValue("Email","<input id=p4email style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />");d+=addHtmlValue("Password","<input id=p4pass1 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />");d+=addHtmlValue("Password","<input id=p4pass2 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />");d+="<div><input id=p4resetNextLogin type=checkbox />Force password reset on next login.</div>";if(passRequirements){var b=[],c=0;for(var a in passRequirements){if((a!="reset")&&(a!="hint")){b.push(a+":"+passRequirements[a]);c++}}if(c>0){d+="<div style=font-size:x-small;padding:6px>Requirements: "+b.join(", ")+".</div>"}}setDialogMode(2,"Create Account",3,showCreateNewAccountDialogEx,d);showCreateNewAccountDialogValidate();Q("p4name").focus()}function showCreateNewAccountDialogValidate(b){if((b==null)&&(Q("p4email").value.length>0)&&(validateEmail(Q("p4email").value))==false){QE("idx_dlgOkButton",false);return}var a=(!Q("p4name")||((Q("p4name").value.length>0)&&(Q("p4name").value.indexOf(" ")==-1)))&&Q("p4pass1").value.length>0&&Q("p4pass1").value==Q("p4pass2").value&&checkPasswordRequirements(Q("p4pass1").value,passRequirements);if(a&&passRequirements){if(checkPasswordRequirements(Q("p4pass1").value,passRequirements)==false){a=false}}QE("idx_dlgOkButton",a)}function showCreateNewAccountDialogEx(){meshserver.send({action:"adduser",username:Q("p4name").value,email:Q("p4email").value,pass:Q("p4pass1").value,resetNextLogin:Q("p4resetNextLogin").checked})}function showUserAdminDialog(a,c){if(xxdialogMode){return}haltEvent(a);c=decodeURIComponent(c);var d="<div>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_fileaccess>Server Files, <input type=number onchange=showUserAdminDialogValidate() maxlength=10 style=width:80px;text-align:right id=ua_fileaccessquota>k max, blank for default<br><hr/>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_fulladmin>Full Administrator<br>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_serverbackup>Server Backup<br>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_serverrestore>Server Restore<br>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_serverupdate>Server Updates<br>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_manageusers>Manage Users<br>";d+="<hr/><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_lockedaccount>Lock Account<br>";d+="</div>";var b=users[c.toLowerCase()];setDialogMode(2,"Server Permissions",3,showUserAdminDialogEx,d,b);if(b.siteadmin&&b.siteadmin!=0){Q("ua_fulladmin").checked=(b.siteadmin==4294967295);Q("ua_serverbackup").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&1)!=0));Q("ua_manageusers").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&2)!=0));Q("ua_serverrestore").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&4)!=0));Q("ua_fileaccess").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&8)!=0));Q("ua_serverupdate").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&16)!=0));Q("ua_lockedaccount").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&32)!=0))}QE("ua_fulladmin",userinfo.siteadmin==4294967295);QE("ua_serverbackup",userinfo.siteadmin==4294967295);QE("ua_manageusers",userinfo.siteadmin==4294967295);QE("ua_serverrestore",userinfo.siteadmin==4294967295);QE("ua_fileaccess",userinfo.siteadmin==4294967295);QE("ua_serverupdate",userinfo.siteadmin==4294967295);Q("ua_fileaccessquota").value=(b.quota!=null)?(b.quota/1024):"";showUserAdminDialogValidate();return false}function showUserAdminDialogValidate(){if(userinfo.siteadmin==4294967295){QE("ua_serverbackup",!Q("ua_fulladmin").checked);QE("ua_manageusers",!Q("ua_fulladmin").checked);QE("ua_serverrestore",!Q("ua_fulladmin").checked);QE("ua_fileaccess",!Q("ua_fulladmin").checked);QE("ua_serverupdate",!Q("ua_fulladmin").checked);QE("ua_fileaccessquota",Q("ua_fileaccess").checked&&!Q("ua_fulladmin").checked)}}function showUserAdminDialogEx(a,d){var c=0,b=parseInt(Q("ua_fileaccessquota").value);if(Q("ua_fulladmin").checked==true){c=4294967295}else{if(Q("ua_serverbackup").checked==true){c+=1}if(Q("ua_manageusers").checked==true){c+=2}if(Q("ua_serverrestore").checked==true){c+=4}if(Q("ua_fileaccess").checked==true){c+=8}if(Q("ua_serverupdate").checked==true){c+=16}if(Q("ua_lockedaccount").checked==true){c+=32}}var e={action:"edituser",name:d.name,siteadmin:c};if(isNaN(b)==false){e.quota=(b*1024)}meshserver.send(e)}function onUserSearchInputChanged(){updateUsers()}var currentUser=null;function gotoUser(q,g){if(xxdialogMode&&!g){return}var p=currentUser=users[decodeURIComponent(q)];if(p==null){setDialogMode(0);go(4);return}QH("p30userName",p.name);QH("p31userName",p.name);var o=(p.name==userinfo.name),a=0;if(wssessions!=null&&wssessions[p._id]){a=wssessions[p._id]}Q("MainUserImage").classList.remove("gray");if(a==0){Q("MainUserImage").classList.add("gray")}var l="",n="";if((p.siteadmin!=null)&&((p.siteadmin&32)!=0)&&(p.siteadmin!=4294967295)){n='<img src="images/padlock12.png" height=12 width=8 title="Account is locked" style="margin-top:2px" /> ';l+="Locked account, "}if((p.siteadmin==null)||(p.siteadmin==0)||(p.siteadmin==32)){l+="No server rights"}else{if(p.siteadmin==8){l+="Access to server files"}else{if(p.siteadmin==4294967295){l+="Full administrator"}else{l+="Partial rights"}}}var r="<div style=min-height:80px><table style=width:100%>";var c=p.email?EscapeHtml(p.email):"<i>Not set</i>",d="";if(serverinfo.emailcheck){d=((p.emailVerified==true)?'<b style=color:green;cursor:pointer title="Email is verified">&#x1F5F8</b> ':'<b style=color:red;cursor:pointer title="Email not verified">&#x1F5F4</b> ')}r+=addDeviceAttribute("Email",d+'<a style=cursor:pointer onclick=p30showUserEmailChangeDialog(event,"'+q+'")>'+c+'</a> <a style=cursor:pointer onclick=doemail(event,"'+p.email+'")><img class=hoverButton width=10 height=10 src="images/link1.png" /></a>');r+=addDeviceAttribute("Server Rights",n+'<a style=cursor:pointer onclick=showUserAdminDialog(event,"'+q+'")>'+l+"</a>");if(p.quota){r+=addDeviceAttribute("Server Quota",EscapeHtml(parseInt(p.quota)/1024)+" k")}r+=addDeviceAttribute("Creation",new Date(p.creation*1000).toLocaleString());if(p.login){r+=addDeviceAttribute("Last Login",new Date(p.login*1000).toLocaleString())}if(p.passchange==-1){r+=addDeviceAttribute("Password","Will be changed on next login.")}else{if(p.passchange){r+=addDeviceAttribute("Password","Last changed: "+new Date(p.passchange*1000).toLocaleString())}}var j=0,k="<i>None<i>";if(p.links){for(var h in p.links){j++}if(j==1){k="1 group"}else{if(j>1){k=j+" groups"}}}r+=addDeviceAttribute("Device Groups",k);var m=0;if((p.otpsecret>0)||(p.otphkeys>0)){m=1;var e=[];if(p.otpsecret>0){e.push("Authentication App")}if(p.otphkeys>0){e.push("Security Key")}if(p.otpkeys>0){e.push("Backup Codes")}r+=addDeviceAttribute("Security",'<img src="images/key12.png" height=12 width=11 title="2nd factor authentication enabled" style="margin-top:2px" /> '+e.join(", "))}r+="</table></div><br />";r+='<input type=button value=Notes title="View notes about this user" onclick=showNotes(false,"'+q+'") />';if(!o&&(a>0)){r+='<input type=button value=Notify title="Send user notification" onclick=showUserAlertDialog(event,"'+q+'") />'}QH("p30html",r);drawUserTimeline();var b=true;if(p._id==userinfo._id){b=false}if(p.siteadmin&&p.siteadmin>0&&userinfo.siteadmin!=4294967295){b=false}r="<div style=float:right;font-size:x-small>";if(b){r+='<a style=cursor:pointer onclick=p30showDeleteUserDialog() title="Remove this user">Delete User</a>'}r+="</div><div style=font-size:x-small>";if(userinfo.siteadmin==4294967295){r+="<a style=cursor:pointer onclick=p30showUserChangePassDialog("+m+') title="Change the password for this user">Change Password</a>'}r+="</div><br>";QH("p30html3",r);r="";if(a==1){r="1 active session"}else{if(a>1){r=a+" active sessions"}}QH("MainUserState",r);go(30);QH("p31events","");refreshUsersEvents()}function p30showUserEmailChangeDialog(a){if(xxdialogMode){return}var b="";b+=addHtmlValue("Email","<input id=dp30email style=width:230px maxlength=32 onchange=p30validateEmail() onkeyup=p30validateEmail() />");if(serverinfo.emailcheck){b+=addHtmlValue("Status","<select id=dp30verified style=width:230px onchange=p30validateEmail()><option value=0>Not verified</option><option value=1>Verified</option></select>")}setDialogMode(2,"Change Email for "+EscapeHtml(currentUser.name),3,p30showUserEmailChangeDialogEx,b);Q("dp30email").focus();Q("dp30email").value=currentUser.email;if(serverinfo.emailcheck){Q("dp30verified").value=currentUser.emailVerified?1:0}p30validateEmail()}function p30validateEmail(){var a=Q("dp30email").value,b=a.split("@");b=(b.length==2)&&(b[0].length>0)&&(b[1].split(".").length>1)&&(b[1].length>2)&&(a.length<1024)&&((a!=userinfo.email)||((serverinfo.emailcheck==true)&&(Q("dp30verified").value!=(userinfo.emailVerified?1:0))));QE("idx_dlgOkButton",b)}function p30showUserEmailChangeDialogEx(){var a={action:"edituser",name:currentUser.name,email:Q("dp30email").value};if(serverinfo.emailcheck){a.emailVerified=(Q("dp30verified").value==1)}meshserver.send(a)}function p30showUserChangePassDialog(b){if(xxdialogMode){return}var e="";e+=addHtmlValue("Password","<input id=p4pass1 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=showCreateNewAccountDialogValidate(1)></input>");e+=addHtmlValue("Password","<input id=p4pass2 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=showCreateNewAccountDialogValidate(1)></input>");if(features&65536){e+=addHtmlValue("Password hint","<input id=p4hint type=text style=width:230px maxlength=256></input>")}if(passRequirements){var c=[],d=0;for(var a in passRequirements){if((a!="reset")&&(a!="hint")){c.push(a+":"+passRequirements[a]);d++}}if(d>0){e+="<div style=font-size:x-small;padding:6px>Requirements: "+c.join(", ")+".</div>"}}e+="<div><input id=p4resetNextLogin type=checkbox />Force password reset on next login.</div>";if(b==1){e+="<div><input id=p4twoFactorRemove type=checkbox />Remove all 2nd factor authentication.</div>"}setDialogMode(2,"Change Password for "+EscapeHtml(currentUser.name),3,p30showUserChangePassDialogEx,e,b);showCreateNewAccountDialogValidate(1);Q("p4pass1").focus()}function p30showUserChangePassDialogEx(a,e){var d=false;if((e==1)&&(Q("p4twoFactorRemove").checked==true)){d=true}if(Q("p4pass1").value==Q("p4pass2").value){var c={action:"changeuserpass",user:currentUser.name,pass:Q("p4pass1").value,removeMultiFactor:d,resetNextLogin:Q("p4resetNextLogin").checked};if(features&65536){c.hint=Q("p4hint").value}meshserver.send(c)}}function p30showDeleteUserDialog(){if(xxdialogMode){return}setDialogMode(2,"Delete User "+EscapeHtml(currentUser.name),3,p30showDeleteUserDialogEx,"Confirm deletion of user "+EscapeHtml(currentUser.name)+"?")}function p30showDeleteUserDialogEx(){meshserver.send({action:"deleteuser",userid:currentUser._id,username:currentUser.name})}function drawUserTimeline(){var s=null,o=Date.now();s=[];var e=new Date();e.setHours(0,0,0,0);e=new Date(e.getTime()-(1000*60*60*24*6));var u=e.getTime();var t=[];if(s!=null&&s.length>1){t.push([0,s[1],s[0]]);var c=s[1];for(var m=2;m<s.length;m+=2){var p=s[m],k=o;if(s.length>(m+1)){k=s[m+1]}t.push([c,c+k,p]);c=c+k}}var z="",b=1,h=new Date();h.setHours(0,0,0,0);for(var m=0;m<7;m++){var g="",q=h.getTime(),l=q+(1000*60*60*24);for(var n in t){var a=t[n];if(isTimeBlockInside(q,l,a[0],a[1])==true){var w=Math.max(q,a[0]);var r=Math.min(Math.min(l,a[1]),o);var y=Math.round((r-w)/112794);if(y>0){var v=powerStateStrings2[a[2]]+" from "+new Date(w).toLocaleTimeString()+" to "+new Date(r).toLocaleTimeString()+".";g+='<div title="'+v+'" style=display:table-cell;width:'+y+"px;background-color:"+powerColor(a[2])+";height:16px></div>"}}}z+="<tr style="+(((b%2)==0)?"background-color:#DDD":"")+"><td><div>&nbsp;"+h.toLocaleDateString()+"<div></div></div></td><td><div>"+g+"</div></td></tr>";++b;h=new Date(h.getTime()-(1000*60*60*24))}QH("p30html2",'<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:center;width:150px>Day</th><th scope=col style=text-align:center>7 Day Login State</th></tr>'+z+"</tbody></table>")}var currentUserEvents=null;function userEventsUpdate(){var h="",a=null;for(var c in currentUserEvents){var b=currentUserEvents[c];var g=new Date(b.time);if(g.toLocaleDateString()!=a){if(a!=null){h+="</table>"}h+="<table style=width:100% cellpadding=0 cellspacing=0><tr><td class=DevSt>"+g.toLocaleDateString()+"</td></tr>";a=g.toLocaleDateString()}var d="si3";if(b.etype=="user"){d="m2"}if(b.etype=="server"){d="si3"}var e=b.msg.split("(R)").join("&reg;");if(b.username&&b.username!=userinfo.name){e+=": "+b.username}h+="<tr><td><div class=bar18 style=height:18px;width:100%;font-size:medium>";h+="<div style=float:left;height:18px;width:18px;background-color:white><div class="+d+" style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>";h+="<div class=g1 style=height:18px;float:left></div><div class=g2 style=height:18px;float:right></div>";h+="<div style=font-size:14px><span style=width:300px>"+g.toLocaleTimeString()+" - "+e+"</span></div></div></td></tr>"}if(a!=null){h+="</table>"}if(h==""){h="<br><i>No Events Found</i><br><br>"}QH("p31events",h)}function refreshUsersEvents(){meshserver.send({action:"events",limit:parseInt(p31limitdropdown.value),user:currentUser.name})}function d3init(){Q("d3localFile").value="";d3modechange()}function d3modechange(){var a=Q("d3uploadMode").value;QV("d3localmode",a==1);QV("d3servermode",a==2);if(a==1){d3setActions()}else{d3updatefiles()}}var d3filetreelinkpath;var d3filetreelocation=[];function d3updatefiles(){if(Q("d3uploadMode").value==1){return}var m="",n="",e=filetree,j=1;var c=[],r=d3filetreelinkpath,b=[],a=document.getElementsByName("fc");for(var o=0;o<a.length;o++){if(a[o].checked){b.push(a[o].value)}}d3filetreelinkpath="";for(var o in d3filetreelocation){if((e.f!=null)&&(e.f[d3filetreelocation[o]]!=null)){c.push(d3filetreelocation[o]);if((j==1)){var t=d3filetreelocation[o].split("/");publicPath=window.location+t[0]+"files/"+t[2];if(d3filetreelocation[o]===userinfo._id){d3filetreelinkpath+="self"}else{d3filetreelinkpath+=(t[0]+"/"+t[2])}}else{if(d3filetreelinkpath!=""){d3filetreelinkpath+="/"+d3filetreelocation[o];if(j>2){publicPath+="/"+d3filetreelocation[o]}}}e=e.f[d3filetreelocation[o]];j++}else{break}}d3filetreelocation=c;var g=p5sort_files(e.f);for(var o in g){var d=g[o],q=d.n,s;s=q;if(q.length>70){s='<span title="'+EscapeHtml(q)+'">'+EscapeHtml(q.substring(0,70))+"...</span>"}else{s=EscapeHtml(q)}q=EscapeHtml(q);var k="";if(d.s!=null){k=getFileSizeStr(d.s)}var l="";if(d.t<3){var u="";l='<div class=filelist file=999><span style=float:right title="'+u+'"></span><span><div class=fileIcon'+d.t+' onclick=d3folderset("'+encodeURIComponent(d.nx)+'")></div>&nbsp;<a style=cursor:pointer onclick=d3folderset("'+encodeURIComponent(d.nx)+'")>'+s+"</a></span></div>"}else{var p=s;l="<div class=filelist file=3><input style=float:left name=fcx class=fcb type=checkbox onchange=d3setActions() value='"+d.nx+"'>&nbsp;<span style=float:right>"+k+"</span><span><div class=fileIcon"+d.t+"></div>"+p+"</span></div>"}if(d.t<3){m+=l}else{n+=l}}QH("d3serverfiles",m+n);QE("p3FolderUp",d3filetreelocation.length>0);d3setActions()}function d3folderset(a){d3filetreelocation.push(decodeURIComponent(a));d3updatefiles()}function d3folderup(a){if(a==null){d3filetreelocation.pop()}else{while(d3filetreelocation.length>a){d3filetreelocation.pop()}}d3updatefiles()}function d3getFileSel(){var a=[];var b=document.getElementsByName("fcx");for(var c=0;c<b.length;c++){if(b[c].checked){a.push(b[c].value)}}return a}function d3setActions(){var a=Q("d3uploadMode").value;if(a==1){QE("idx_dlgOkButton",Q("d3localFile").value.length>0)}else{QE("idx_dlgOkButton",d3getFileSel().length==1)}}var notifications=[];function clickNotificationIcon(a){if(a==true){QV("notifiyBox",true)}else{if(a==false){QV("notifiyBox",false)}else{QV("notifiyBox",QS("notifiyBox")["display"]=="none")}}drawNotifications()}function setNotificationCount(a){if(parseInt(Q("notificationCount").innerHTML)==a){return}QH("notificationCount",a);QS("notificationCount")["background-color"]=(a==0)?"lightblue":"orange";QV("notificationCount",a>0)}function drawNotifications(){var j="";if(notifications.length==0){j="<div style=margin:5px>There are currently no notifications</div>"}else{for(var c in notifications){var g=notifications[c];var k="";var a=new Date(g.time);var e=0;if(g.nodeid!=null){var h=getNodeFromId(g.nodeid);if(h!=null){e=h.icon;k="<b>"+h.name+"</b>: "}}j+='<div title="Occured at '+a.toLocaleString()+'" id="notifyx'+g.id+'" class=notification style="cursor:pointer;border-top:1px solid '+((j=="")?"transparent":"orange")+'"><div class=j'+e+' onclick="notificationSelected('+g.id+')" style=margin:5px;float:left></div><div onclick="notificationDelete('+g.id+')" class=unselectable title="Clear this notification" style=margin:5px;float:right;color:orange><b>X</b></div><div onclick="notificationSelected('+g.id+')" style=margin:5px>'+k+g.text+"</div></div>"}}var b="";if(notifications.length>1){b='<div id="notifyRemoveAll" onclick="deleteAllNotifications()" style="cursor:pointer;border-top:1px solid orange;margin:5px;color:orange;text-align:right;padding-right:3px">Clear all</div>'}QH("notifiyBox",'<div class=customScroll style="max-height:170px;overflow-y:auto;margin:5px">'+j+"</div>"+b)}function notificationSelected(b){var c=-1;for(var a in notifications){if(notifications[a].id==b){c=a}}if(c!=-1){var d=notifications[c];if(d.nodeid!=null){if(d.tag=="desktop"){gotoDevice(d.nodeid,12)}else{if(d.tag=="terminal"){gotoDevice(d.nodeid,11)}else{if(d.tag=="files"){gotoDevice(d.nodeid,13)}else{if(d.tag=="intelamt"){gotoDevice(d.nodeid,14)}else{if(d.tag=="console"){gotoDevice(d.nodeid,15)}else{gotoDevice(d.nodeid,10)}}}}}}else{if(d.tag.startsWith("meshmessenger/")){window.open("/messenger?id="+d.tag+"&title="+encodeURIComponent(d.username),d.tag.split("/")[2]);notificationDelete(b)}}}}function notificationDelete(c){var d=-1,a=Q("notifyx"+c);if(a!=null){for(var b in notifications){if(notifications[b].id==c){d=b}}if(d!=-1){notifications.splice(d,1);a.parentNode.removeChild(a);setNotificationCount(notifications.length);if(notifications.length==0){QV("notifiyBox",false)}if(notifications.length==1){QV("notifyRemoveAll",false)}if((notifications.length>0)&&(d==0)){var g=notifications[0];QS("notifyx"+g.id)["border-top"]="1px solid transparent"}}}}function addNotification(a){if(a.time==null){a.time=Date.now()}if(a.id==null){a.id=Math.random()}notifications.unshift(a);setNotificationCount(notifications.length);Q("chimes").play();clickNotificationIcon(true)}function deleteAllNotifications(){notifications=[];setNotificationCount(0);drawNotifications();QV("notifiyBox",false)}function setupServerStats(){window.serverStatCpu=new Chart(document.getElementById("serverCpuChart").getContext("2d"),{type:"doughnut",data:{datasets:[{data:[0,0],backgroundColor:["#AAAAAA","#00AA00"]}],labels:["Used","Free"]},options:{responsive:true,legend:{position:"none",},animation:{animateScale:true,animateRotate:true},width:"60px"}});window.serverStatMemory=new Chart(document.getElementById("serverMemoryChart").getContext("2d"),{type:"doughnut",data:{datasets:[{data:[0,0],backgroundColor:["#AAAAAA","#00AA00"]}],labels:["Used","Free"]},options:{responsive:true,legend:{position:"none",},animation:{animateScale:true,animateRotate:true},width:"60px"}})}var lastServerStats=null;function updateServerStats(d){if(d!=null){lastServerStats=d}else{d=lastServerStats}if(d==null){return}if(typeof d.cpuavg=="object"){var c=Math.min(d.cpuavg[0],1);window.serverStatCpu.config.data.datasets[0].data=[c,1-c];QH("serverCpuChartText",'<div style=margin-bottom:5px>CPU Load</div><div><b title="CPU load in the last minute">'+(Math.round(d.cpuavg[0]*100)/100)+'</b>, <b title="CPU load in the last 5 minutes">'+(Math.round(d.cpuavg[1]*100)/100)+'</b>, <b title="CPU load in the 15 minutes">'+(Math.round(d.cpuavg[2]*100)/100)+"</b></div>");QS("serverCpuChartView")["display"]="inline-block";window.serverStatCpu.update()}if((typeof d.totalmem=="number")&&(typeof d.freemem=="number")){window.serverStatMemory.config.data.datasets[0].data=[d.totalmem-d.freemem,d.freemem];QH("serverMemoryChartText","<div style=margin-bottom:5px>Memory</div><div><b>"+getNiceSize2(d.freemem)+"</b> free, <b>"+getNiceSize2(d.totalmem)+"</b> total</div>");QS("serverMemoryChartView")["display"]="inline-block";window.serverStatMemory.update()}var e="<div style=width:100% cellpadding=0 cellspacing=0>";if(typeof d.values=="object"){for(var a in d.values){e+="<div class=userTableHeader style=margin-bottom:4px;width:200px>"+a+"</div>";for(var b in d.values[a]){e+="<div style=display:inline-block><table style=width:300px;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0><tr><td class=h1></td><td><span>"+b+"</span><span style=float:right>"+d.values[a][b]+"</span></td><td class=h2></td></tr></table></div>"}}}e+="</div>";QH("serverStatsTable",e)}var xxdialogMode;var xxdialogFunc;var xxdialogButtons;var xxdialogTag;var xxcurrentView=-1;function setDialogMode(j,k,a,e,d,h){xxdialogMode=j;xxdialogFunc=e;xxdialogButtons=a;xxdialogTag=h;QE("idx_dlgOkButton",true);QV("idx_dlgOkButton",a&1);QV("idx_dlgCancelButton",a&2);QV("id_dialogclose",(a&2)||(a&8));QV("idx_dlgDeleteButton",a&4);QV("idx_dlgButtonBar",a&7);if(k){QH("id_dialogtitle",k)}for(var g=1;g<24;g++){QV("dialog"+g,g==j)}QV("dialog",j);if(d){if(j==2){QH("id_dialogOptions",d)}else{QH("id_dialogMessage",d)}}}function dialogclose(e){var c=xxdialogFunc,a=xxdialogButtons,d=xxdialogTag;setDialogMode();if(((a&8)||e)&&c){c(e,d)}}function center(){if(xxcurrentView==11){deskAdjust()}else{if(xxcurrentView==10){masterUpdate(256)}else{if(xxcurrentView==1){masterUpdate(4)}}}}function messagebox(b,a){QH("id_dialogMessage",a);setDialogMode(1,b,1)}function statusbox(b,a){QH("id_dialogMessage",a);setDialogMode(1,b)}function goBack(){if(xxdialogMode){return}if((xxcurrentView>=10)&&(xxcurrentView<20)){go(1)}if((xxcurrentView>=20)&&(xxcurrentView<30)){go(2)}if((xxcurrentView>=30)&&(xxcurrentView<40)){go(4)}}function go(d){if(xxdialogMode||xxcurrentView==d){return}for(var a=0;a<32;a++){QV("p"+a,a==d)}xxcurrentView=d;var b=["LeftMenuMyDevices","LeftMenuMyAccount","LeftMenuMyEvents","LeftMenuMyFiles","LeftMenuMyUsers","LeftMenuMyServer"];for(var a in b){Q(b[a]).classList.remove("lbbuttonsel");Q(b[a]).classList.remove("lbbuttonsel2")}QV("topbar",d!=0);if(d>=10&&d<20){QS("MainMenuMyDevices").backgroundColor="#606060"}else{QS("MainMenuMyDevices").backgroundColor=((d==1)?"#003366":"#808080")}if(d==1||(d>=10&&d<20)){Q("LeftMenuMyDevices").classList.add("lbbuttonsel")}if(d==1){Q("LeftMenuMyDevices").classList.add("lbbuttonsel2")}if(d>=20&&d<30){QS("MainMenuMyAccount").backgroundColor="#606060"}else{QS("MainMenuMyAccount").backgroundColor=((d==2)?"#003366":"#808080")}if(d==2||(d>=20&&d<30)){Q("LeftMenuMyAccount").classList.add("lbbuttonsel")}if(d==2){Q("LeftMenuMyAccount").classList.add("lbbuttonsel2")}QS("MainMenuMyEvents").backgroundColor=((d==3)?"#003366":"#808080");if(d==3){Q("LeftMenuMyEvents").classList.add("lbbuttonsel","lbbuttonsel2")}if(d>=30&&d<40){QS("MainMenuMyUsers").backgroundColor="#606060"}else{QS("MainMenuMyUsers").backgroundColor=((d==4)?"#003366":"#808080")}if(d==4||(d>=30&&d<40)){Q("LeftMenuMyUsers").classList.add("lbbuttonsel")}if(d==4){Q("LeftMenuMyUsers").classList.add("lbbuttonsel2")}QS("MainMenuMyFiles").backgroundColor=((d==5)?"#003366":"#808080");if(d==5){Q("LeftMenuMyFiles").classList.add("lbbuttonsel","lbbuttonsel2")}QS("MainMenuMyServer").backgroundColor=(((d==6)||(d==115))?"#003366":"#808080");if(((d==6)||(d==115))){Q("LeftMenuMyServer").classList.add("lbbuttonsel","lbbuttonsel2")}if(webPageFullScreen){QS("column_l")["max-height"]="calc(100vh - 135px)"}else{QS("column_l")["max-height"]=(d>=10)?"calc(100vh - 159px)":"calc(100vh - 135px)"}if((d==0)&&(webPageFullScreen)){QS("page_content").position="";QV("page_leftbar",false);QS("column_l").height="calc(100vh - 110px)";QS("column_l")["max-height"]=""}QV("MainSubMenuSpan",d>=10&&d<20);QV("UserDummyMenuSpan",(d<10)&&(d!=6)&&webPageFullScreen);QV("MeshSubMenuSpan",d>=20&&d<30);QV("UserSubMenuSpan",d>=30&&d<40);QV("ServerSubMenuSpan",d==6||d==115);var c={10:"MainDev",11:"MainDevDesktop",12:"MainDevTerminal",13:"MainDevFiles",14:"MainDevAmt",15:"MainDevConsole",20:"MeshGeneral",30:"UserGeneral",31:"UserEvents",6:"ServerGeneral",115:"ServerConsole"};for(var a in c){Q(c[a]).classList.remove("style3x");Q(c[a]).classList.remove("style3sel");Q(c[a]).classList.add((d==a)?"style3sel":"style3x")}if(d==115){QV("p15",true)}QV("p15uploadCore",d!=115);QV("p15BackButton",d!=115);if((d==15)||(d==115)){setupConsole()}if(d==1){masterUpdate(4)}if((currentNode)&&(d>=10)&&(d<20)){document.title="MeshCentral - "+currentNode.name}else{document.title="MeshCentral"}}function joinPaths(){var c=[];for(var a in arguments){var b=arguments[a];if((b!=null)&&(b!="")){while(b.endsWith("/")||b.endsWith("\\")){b=b.substring(0,b.length-1)}while(b.startsWith("/")||b.startsWith("\\")){b=b.substring(1)}c.push(b)}}return c.join("/")}function putstore(b,c){try{if(typeof(localStorage)==="undefined"){return}localStorage.setItem(b,c)}catch(a){}}function getstore(b,d){try{if(typeof(localStorage)==="undefined"){return d}var c=localStorage.getItem(b);if((c==null)||(c==null)){return d}return c}catch(a){return d}}function addLink(b,a){return"<span style=cursor:pointer;text-decoration:none onclick='"+a+"'>"+b+" <img class=hoverButton width=10 height=10 src=images/link5.png></span>"}function addLinkConditional(d,b,a){if(a){return addLink(d,b)}return d}function haltEvent(a){if(a.preventDefault){a.preventDefault()}if(a.stopPropagation){a.stopPropagation()}return false}function addOption(c,d,a){var b=document.createElement("option");b.text=d;b.value=a;Q(c).add(b)}function passwordcheck(a){return(a.length>7)&&(/\d/.test(a))&&(/[a-z]/.test(a))&&(/[A-Z]/.test(a))&&(/\W/.test(a))}function methodcheck(a){if(a&&a!=null&&a.Body&&a.Body.ReturnValueStr!="SUCCESS"){messagebox("Call Error",a.Header.Method+": "+a.Body.ReturnValueStr.replace("_"," "));return true}return false}function TableStart(){return"<table cellpadding=0 cellspacing=0 style=width:100%;border-radius:8px><tr><td width=200px><p><td>"}function TableStart2(){return"<table cellpadding=0 cellspacing=0 style=width:100%;border-radius:8px><tr><td><p><td>"}function TableEntry(a,b){return"<tr><td><p>"+a+"<td>"+b}function FullTable(c,a){var b=TableStart();for(i in c){if(i&&c[i]){b+=TableEntry(i,c[i])}}return b+TableEnd(a)}function TableEnd(a){return"<tr><td colspan=2><p>"+(a?a:"")+"</table>"}function AddButton(b,a){return"<input type=button value='"+b+"' onclick='"+a+"' style=margin:4px>"}function AddButton2(b,a){return"<input type=button value='"+b+"' onclick='"+a+"'>"}function AddRefreshButton(a){return"<input type=button name=refreshbtn value=Refresh onclick='refreshButtons(false);"+a+"' style=margin:4px "+(refreshButtonsState==false?"disabled":"")+">"}function MoreStart(){return'<a style=cursor:pointer;color:blue id=morexxx1 onclick=QV("morexxx1",false);QV("morexxx2",true)>&#x25BC; More</a><div id=morexxx2 style=display:none><br><hr>'}function MoreEnd(){return'<a style=cursor:pointer;color:blue onclick=QV("morexxx2",false);QV("morexxx1",true)>&#x25B2; Less</a></div>'}function getSelectedOptions(e){var d=[],c;for(var a=0,b=e.options.length;a<b;a++){c=e.options[a];if(c.selected){d.push(c.value)}}return d}function getInstance(b,c){for(var a in b){if(b[a]["InstanceID"]==c){return b[a]}}return null}function getItem(b,c,d){for(var a in b){if(b[a][c]==d){return b[a]}}return null}function guidToStr(a){return a.substring(6,8)+a.substring(4,6)+a.substring(2,4)+a.substring(0,2)+"-"+a.substring(10,12)+a.substring(8,10)+"-"+a.substring(14,16)+a.substring(12,14)+"-"+a.substring(16,20)+"-"+a.substring(20)}function getUrlVars(){var d,a,e=[],b=window.location.href.slice(window.location.href.indexOf("?")+1).split("&");for(var c=0;c<b.length;c++){d=b[c].indexOf("=");if(d>0){e[b[c].substring(0,d)]=b[c].substring(d+1,b[c].length)}}return e}function addHtmlValue(a,b){return"<table><td style=width:120px>"+a+"<td><b>"+b+"</b></table>"}function addHtmlValue2(a,b){return"<div><div style=display:inline-block;float:right>"+b+"</div><div style=display:inline-block>"+a+"</div></div>"}function parseUriArgs(){var a,c={},b=window.document.location.href.split(/[\?&|\=]/);b.splice(0,1);for(d in b){switch(d%2){case 0:a=decodeURIComponent(b[d]);break;case 1:c[a]=decodeURIComponent(b[d]);var d=parseInt(c[a]);if(d==c[a]){c[a]=d}break;default:break}}return c}function focusTextBox(a){setTimeout(function(){Q(a).selectionStart=Q(a).selectionEnd=65535;Q(a).focus()},0)}function validateEmail(b){var a=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;return a.test(b)}function isPrivateIP(b){return(b.startsWith("10.")||b.startsWith("172.16.")||b.startsWith("192.168."))}function u2fSupported(){return(window.u2f&&((navigator.userAgent.indexOf("Chrome/")>0)||(navigator.userAgent.indexOf("Firefox/")>0)||(navigator.userAgent.indexOf("Opera/")>0)||(navigator.userAgent.indexOf("Safari/")>0)))};</script></body></html>
\ No newline at end of file
1 +<!DOCTYPE html> <html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> <meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="format-detection" content="telephone=no"> <style>body{margin:0;padding:0;border:0;color:black;font-size:13px;font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;background-color:#d3d9d6;}#container{background-color:#fff;width:960px;min-width:960px;margin:0 auto;border-top:0;border-right:1px solid #b7b7b7;border-bottom:0;border-left:1px solid #b7b7b7;padding:0;}#masthead{width:auto;margin:0;padding:0;overflow:auto;text-align:right;background-color:#036;width:960px;}#column_l{position:relative;float:left;width:930px;margin:0;padding:0 15px;background-color:#fff;}#footer{clear:both;overflow:auto;width:100%;text-align:center;background-color:#113962;padding-top:5px;padding-bottom:5px;}#masthead img{float:left;}#masthead p{font-size:11px;color:#fff;margin:10px 10px 0;}#footer a{color:#fff;text-decoration:underline;}#footer a:hover{color:#fff;text-decoration:none;}a{color:#036;text-decoration:underline;}.i1{background:url(../images/icons50.png) 0px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i2{background:url(../images/icons50.png) -50px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i3{background:url(../images/icons50.png) -100px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i4{background:url(../images/icons50.png) -150px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i5{background:url(../images/icons50.png) -200px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i6{background:url(../images/icons50.png) -250px 0px;height:50px;width:50px;cursor:pointer;border:none;}.j1{background:url(../images/icons16.png) 0px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j2{background:url(../images/icons16.png) -16px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j3{background:url(../images/icons16.png) -32px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j4{background:url(../images/icons16.png) -48px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j5{background:url(../images/icons16.png) -64px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j6{background:url(../images/icons16.png) -80px 0px;height:16px;width:16px;cursor:pointer;border:none;}.lbbutton{width:74px;height:74px;border-radius:5px;background-color:white;margin-left:8px;margin-top:8px;position:relative;cursor:pointer;opacity:0.5;}.lbbutton:hover{opacity:1;}.lbbuttonsel{opacity:0.9;}.lbbuttonsel2{width:82px;border-radius:5px 0px 0px 5px;opacity:1;}.lb1{background:url(../images/leftbar-62.jpg) -0px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb2{background:url(../images/leftbar-62.jpg) -75px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb3{background:url(../images/leftbar-62.jpg) -150px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb4{background:url(../images/leftbar-62.jpg) -225px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb5{background:url(../images/leftbar-62.jpg) -294px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb6{background:url(../images/leftbar-62.jpg) -360px 0px;height:62px;width:62px;cursor:pointer;border:none;}.m0{background :url(../images/images16.png) -32px 0px;height :16px;width :16px;border:none;float:left }.m1{background :url(../images/images16.png) -16px 0px;height :16px;width :16px;border:none;float:left }.m2{background :url(../images/images16.png) -96px 0px;height :16px;width :16px;border:none;float:left }.m3{background :url(../images/images16.png) -112px 0px;height :16px;width :16px;border:none;float:left }.si0{background :url(../images/icons16.png) 0px 0px;height :16px;width :16px;border:none;float:left }.si1{background :url(../images/icons16.png) -16px 0px;height :16px;width :16px;border:none;float:left }.si2{background :url(../images/icons16.png) -32px 0px;height :16px;width :16px;border:none;float:left }.si3{background :url(../images/icons16.png) -48px 0px;height :16px;width :16px;border:none;float:left }.si4{background :url(../images/icons16.png) -64px 0px;height :16px;width :16px;border:none;float:left }.mi{background :url(../images/meshicon50.png) 0px 0px;height:50px;width:50px;cursor:pointer;border:none }#floatframe{position:fixed;top:200px;height:300px;z-index:200;display:none;}.style1{text-align:center;}.style2{text-align:center;background-color:#808080;font-weight:bold;}.style3{text-align:center;color:white;background-color:#808080;font-weight:bold;}.style3x{text-align:center;color:white;background-color:#808080;font-weight:bold;}.style3x:hover{background-color:#606060;}.style3sel{text-align:center;color:white;background-color:#003366;font-weight:bold;}.style4{color:white;text-decoration:none;}.style5{text-align:center;background-color:#808080;font-weight:normal;}.style6{text-align:center;background-color:#D3D9D6;}.style7{font-size:large;background-color:#FFFFFF;}.style10{background-color:#C9C9C9;}.style11{font-size:large;background-color:#C9C9C9;}.style14{text-align:left;background-color:#D3D9D6;}.auto-style1{text-align:right;background-color:#D3D9D6;}.fileIcon1{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb49Y2Sj9LT2f///yH5BAEAAAMALAAAAAAQABAAAAImnI+py+1vhJwyUYAzHTL4D3qdlJWaIFJqmKod607sDKIiDUP63hQAOw==);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon2{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAM2xV/Xur+XPgP///yH5BAEAAAMALAAAAAAQABAAAAJD3ISZIGHWUGihznesYDYATFVM+D2hJ4lgN1olxALAtAlmPCJvuMmJd6PJckDYwicrHhTD5o7plJmg0Uc0asNMkphHAQA7);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon3{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb19IGBgbq6uv///yH5BAEAAAMALAAAAAAQABAAAAIy3ISpxgcPH2ouQgFEw1YmxnUXKEaaEZZnVWZk66JwzKpvuwZzwOgwb/C1gIOA8Yg8DgoAOw==);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon4{background:url(../images/meshicon16.png);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.filelist{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;cursor:default;-khtml-user-drag:element;background-color:white;clear:both;}.noselect{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.fsize{float:right;text-align:right;width:180px;}.g1{background-position:0% 0%;width:14px;height:100%;float:left; background-image:linear-gradient(to right, #ffffff 0%, #c9c9c9 100%);background-color:#c9c9c9;background-repeat:repeat;background-attachment:scroll;}.g1s{background-image:linear-gradient(to right, #ffffff 0%, #b9b9b9 100%);}.g2{background-position:0% 0%;width:14px;height:100%;float:right; background-image:linear-gradient(to right, #c9c9c9 0%, #ffffff 100%);background-color:#c9c9c9;background-repeat:repeat;background-attachment:scroll;}.g2s{background-image:linear-gradient(to right, #b9b9b9 0%, #ffffff 100%);}.h1{background-position:0% 0%;width:14px;height:100%; background-image:linear-gradient(to right, #ffffff 0%, #d3d9d6 100%);background-color:#d3d9d6;background-repeat:repeat;background-attachment:scroll;}.h2{background-position:0% 0%;width:14px;height:100%; background-image:linear-gradient(to right, #d3d9d6 0%, #ffffff 100%);background-color:#d3d9d6;background-repeat:repeat;background-attachment:scroll;}.e1{font-size:large;margin-top:4px;margin-bottom:3px;overflow:hidden;word-wrap:hyphenate;white-space:nowrap;text-overflow:ellipsis;}.e2{float:left;height:100%;background-color:#c9c9c9;}.e2s{background-color:#b9b9b9;}.bar{font-size:large;background-color:#C9C9C9;height:24px;float:left;margin-bottom:2px;}.bar2{font-size:large;height:24px;float:left;margin-bottom:2px;}.bar18{font-size:large;background-color:#C9C9C9;height:18px;float:left;margin-bottom:2px;}.bar182{font-size:large;height:18px;float:left;margin-bottom:2px;}.devHeaderx{color:lightgray;}.DevSt{border-bottom-style:solid;border-bottom-width:1px;border-bottom-color:#DDDDDD;}.contextMenu{background:#F9F9F9;box-shadow:0 0 12px rgba( 0, 0, 0, .3 );border:1px solid #ccc; display:none;position:absolute;top:0;left:0;list-style:none;margin:0;padding:5px;min-width:100px;max-width:150px;z-index:500;}.cmtext{color:#444;display:inline-block;padding-left:8px;padding-right:8px;padding-top:5px;padding-bottom:5px;text-decoration:none;width:85%;cursor:default;overflow:hidden;position:relative;}.cmtext:hover{color:#f9f9f9;background:#444;}.gray{ filter:gray; -webkit-filter:grayscale(100%) opacity(60%); }.unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.notifiyBox{position:absolute;z-index:1000;top:50px;right:26px;width:300px;text-align:left;background-color:#F0ECCD;border:4px solid #666;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:2px 2px 4px #888;-moz-box-shadow:2px 2px 4px #888;box-shadow:2px 2px 4px #888;max-height:200px;}.notifiyBox:before{content:' ';position:absolute;width:0;height:0;right:5px;top:-30px;border:15px solid;border-color:transparent #666 #666 transparent;}.notifiyBox:after{content:' ';position:absolute;width:0;height:0;right:7px;top:-24px;border:12px solid;border-color:transparent #F0ECCD #F0ECCD transparent;}.notification{width:100%;min-height:30px;}.notification:hover{background-color:#EFE8B6;}.deskToolsBar{padding:3px;}.deskToolsBar:hover{background-color:#EFE8B6;}.userTableHeader{border-bottom:1pt solid lightgray;padding-top:4px;padding-bottom:4px;}.viewSelector{width:32px;height:32px;background-color:#DDD;border-radius:3px;float:left;margin-left:5px;cursor:pointer;opacity:0.3;}.viewSelectorSel{background-color:#BBB;opacity:0.8;}.viewSelector:hover{opacity:0.5;background-color:#AAA;}.viewSelector1{margin-left:2px;margin-top:2px;background:url(../images/views.png) -0px 0px;height:28px;width:28px;}.viewSelector2{margin-left:2px;margin-top:2px;background:url(../images/views.png) -28px 0px;height:28px;width:28px;}.viewSelector3{margin-left:2px;margin-top:2px;background:url(../images/views.png) -56px 0px;height:28px;width:28px;}.viewSelector4{margin-left:2px;margin-top:2px;background:url(../images/views.png) -84px 0px;height:28px;width:28px;}.viewSelector5{margin-left:2px;margin-top:2px;background:url(../images/views.png) -112px 0px;height:28px;width:28px;}.backButtonEx{margin-left:2px;margin-top:2px;background:url(../images/views.png) -140px 0px;height:28px;width:28px;}.backButton{width:32px;height:32px;background-color:#DDD;border-radius:3px;float:left;margin-right:5px;cursor:pointer;opacity:0.3;}.backButton:hover{opacity:0.5;background-color:#AAA;}.hoverButton{opacity:0.5;}.hoverButton:hover{opacity:1;}</style> <style>.ol-box{box-sizing:border-box;border-radius:2px;border:2px solid #00f;}.ol-mouse-position{top:8px;right:8px;position:absolute;}.ol-scale-line{background:rgba(0,60,136,.3);border-radius:4px;bottom:8px;left:8px;padding:2px;position:absolute;}.ol-scale-line-inner{border:1px solid #eee;border-top:none;color:#eee;font-size:10px;text-align:center;margin:1px;will-change:contents,width;}.ol-overlay-container{will-change:left,right,top,bottom;}.ol-unsupported{display:none;}.ol-unselectable, .ol-viewport{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;}.ol-selectable{-webkit-touch-callout:default;-webkit-user-select:auto;-moz-user-select:auto;-ms-user-select:auto;user-select:auto;}.ol-grabbing{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing;}.ol-grab{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab;}.ol-control{position:absolute;background-color:rgba(255,255,255,.4);border-radius:4px;padding:2px;}.ol-control:hover{background-color:rgba(255,255,255,.6);}.ol-zoom{top:.5em;right:.5em;}.ol-rotate{top:.5em;right:.5em;transition:opacity .25s linear,visibility 0s linear;}.ol-rotate.ol-hidden{opacity:0;visibility:hidden;transition:opacity .25s linear,visibility 0s linear .25s;}.ol-zoom-extent{top:4.643em;left:.5em;}.ol-full-screen{right:.5em;top:.5em;}@media print{.ol-control{display:none;}}.ol-control button{display:block;margin:1px;padding:0;color:#fff;font-size:1.14em;font-weight:700;text-decoration:none;text-align:center;height:1.375em;width:1.375em;line-height:.4em;background-color:rgba(0,60,136,.5);border:none;border-radius:2px;}.ol-control button::-moz-focus-inner{border:none;padding:0;}.ol-zoom-extent button{line-height:1.4em;}.ol-compass{display:block;font-weight:400;font-size:1.2em;will-change:transform;}.ol-touch .ol-control button{font-size:1.5em;}.ol-touch .ol-zoom-extent{top:5.5em;}.ol-control button:focus, .ol-control button:hover{text-decoration:none;background-color:rgba(0,60,136,.7);}.ol-zoom .ol-zoom-in{border-radius:2px 2px 0 0;}.ol-zoom .ol-zoom-out{border-radius:0 0 2px 2px;}.ol-attribution{text-align:right;bottom:.5em;right:.5em;max-width:calc(100% - 1.3em);}.ol-attribution ul{margin:0;padding:0 .5em;font-size:.7rem;line-height:1.375em;color:#000;text-shadow:0 0 2px #fff;}.ol-attribution li{display:inline;list-style:none;line-height:inherit;}.ol-attribution li:not(:last-child):after{content:" ";}.ol-attribution img{max-height:2em;max-width:inherit;vertical-align:middle;}.ol-attribution button, .ol-attribution ul{display:inline-block;}.ol-attribution.ol-collapsed ul{display:none;}.ol-attribution.ol-logo-only ul{display:block;}.ol-attribution:not(.ol-collapsed){background:rgba(255,255,255,.8);}.ol-attribution.ol-uncollapsible{bottom:0;right:0;border-radius:4px 0 0;height:1.1em;line-height:1em;}.ol-attribution.ol-logo-only{background:0 0;bottom:.4em;height:1.1em;line-height:1em;}.ol-attribution.ol-uncollapsible img{margin-top:-.2em;max-height:1.6em;}.ol-attribution.ol-logo-only button, .ol-attribution.ol-uncollapsible button{display:none;}.ol-zoomslider{top:4.5em;left:.5em;height:200px;}.ol-zoomslider button{position:relative;height:10px;}.ol-touch .ol-zoomslider{top:5.5em;}.ol-overviewmap{left:.5em;bottom:.5em;}.ol-overviewmap.ol-uncollapsible{bottom:0;left:0;border-radius:0 4px 0 0;}.ol-overviewmap .ol-overviewmap-map, .ol-overviewmap button{display:inline-block;}.ol-overviewmap .ol-overviewmap-map{border:1px solid #7b98bc;height:150px;margin:2px;width:150px;}.ol-overviewmap:not(.ol-collapsed) button{bottom:1px;left:2px;position:absolute;}.ol-overviewmap.ol-collapsed .ol-overviewmap-map, .ol-overviewmap.ol-uncollapsible button{display:none;}.ol-overviewmap:not(.ol-collapsed){background:rgba(255,255,255,.8);}.ol-overviewmap-box{border:2px dotted rgba(0,60,136,.7);}.ol-overviewmap .ol-overviewmap-box:hover{cursor:move;}</style> <style> .ol-ctx-menu-container{position:absolute;padding:8px;background:#fff;color:#222;font-size:13px;border-radius:5px;box-shadow:3px 3px 5px rgba(0,0,0,.2);box-sizing:border-box}.ol-ctx-menu-container a,.ol-ctx-menu-container div,.ol-ctx-menu-container img,.ol-ctx-menu-container li,.ol-ctx-menu-container span,.ol-ctx-menu-container ul{margin:0;padding:0;border:0;font:inherit;font-size:100%;vertical-align:baseline}.ol-ctx-menu-container a img{border:none}.ol-ctx-menu-container *,.ol-ctx-menu-container :after,.ol-ctx-menu-container :before{box-sizing:inherit}.ol-ctx-menu-container.ol-ctx-menu-hidden{opacity:0;visibility:hidden;-webkit-transition:visibility 0s linear .3s,opacity .3s;transition:visibility 0s linear .3s,opacity .3s}.ol-ctx-menu-container ul{list-style:none}.ol-ctx-menu-container li{position:relative;line-height:20px;padding:2px 5px}.ol-ctx-menu-container li:not(.ol-ctx-menu-separator):hover{cursor:pointer;background-color:#333;color:#eee}.ol-ctx-menu-container li.ol-ctx-menu-submenu .ol-ctx-menu-container{border:1px solid #eee;padding:8px;top:0;opacity:0;visibility:hidden;-webkit-transition:visibility 0s linear .3s,opacity .3s;transition:visibility 0s linear .3s,opacity .3s}.ol-ctx-menu-container li.ol-ctx-menu-submenu:hover .ol-ctx-menu-container{opacity:1;visibility:visible;-webkit-transition-delay:0s;transition-delay:0s}.ol-ctx-menu-container li.ol-ctx-menu-submenu:after{position:absolute;top:7px;right:10px;content:"";display:inline-block;width:.6em;height:.6em;border-right:.3em solid #222;border-top:.3em solid #222;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ol-ctx-menu-container li.ol-ctx-menu-submenu:hover:after{border-color:#eee}.ol-ctx-menu-container li.ol-ctx-menu-separator{padding:0}.ol-ctx-menu-container li.ol-ctx-menu-separator hr{border:0;height:1px;background-image:-webkit-linear-gradient(right,transparent,rgba(0,0,0,.75),transparent);background-image:linear-gradient(270deg,transparent,rgba(0,0,0,.75),transparent)}.ol-ctx-menu-icon{text-indent:20px;background-size:20px auto;background-repeat:no-repeat;background-position:0}.ol-ctx-menu-zoom-in{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABaUlEQVQ4T72U7VHCQBCGn90GtAMuNGCswFiBWIFQgWMFxg6wArECsQKhArEBiB1Qwa1zgQn5IAYcxv13k71n3919L8KJQ07M47+BzgG9TRfZ/JBuWhS6BJFHRJICYrZGZIz3z5Ct2+B7gG6I6kt+wewdkQVwjtkAkR5mC8yu26A1oItR/cTsOweQBdgutD8G7jGm2PJ2n8oqUKIpIjd4HxTM8gvaT/F+AlmWnyWaIXKF95eNguFzTYFhNsdWu9kFgFlaFMANUH3D8wDLoLgSTSD2il8NCe2ZXQBxWDGwxmyUzzOMBZ7wy7Qb2K0wQfXjMOBuhlFpZtNty5sFaTQBuTusZdymeqs1SpYKcO9HkE3KbTd9WFijMHJQ5hBNEAYNq5Qd0dhyke0GiE4QzjqfW23mHT8Hl4DG4Lce3FPE7AtbBSdsbNqpoJLgYkRnNeUV+xwJDHTnUEkxHGbhBXUs5TjJjew/KPy94g+NRaIVRYmMXwAAAABJRU5ErkJggg==")}.ol-ctx-menu-container li:hover.ol-ctx-menu-zoom-in{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABc0lEQVQ4T71U21ECQRDsJgGdvQDECMQIxAjECMQILCPwzAAjECIQI0AiEDPQAPaWCBhrcKHuCUcV5f7dY3v6tUscefHIePhfwBBCF8CZqRCReRs1tQxDCH1VfQLQz4EsSY4AvIjIsgm8AhhCGKrqa9zwrqoLAKckB5HtguR1E2gBMITQU9VPAD8GICIGtl3e+xHJBwBT59xtHcsCYJZlUwA3kcGHbfDep51OZywi3/acZZm9vyJ5WR5o38uACmDunNt6ZwAkUxFZDwghDFT1jeSjiJinhVUBVNVJkiTDKO8CQA+AsbNQ7s1Ps0VVn5MkSfcCtmBoDZi1Bdx4eJ7zbBolrwPy3o9J3rWSHPs3A1BbjVKlYBaIyDgvu9LDXDU2RTZmXVW1oKyLxRD+OrkOrJLy5mVM0iaftDhuhVbsvBzMglzKUNW6IV/OOWtCM8MmVvEkmbwt83LaB19fdgOtVquUZJeknaDdobTwbOcvBzPcN/AXH1DFFWP7u9oAAAAASUVORK5CYII=")}.ol-ctx-menu-zoom-out{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABU0lEQVQ4T72U7VECMRRFz3sNaAdkacC1AtcKxApcKnCsQOwAK3CtQKxAqEBsANYOqCDPyTIC+8WCw5jfybn33dxEOPGSE/P4b6BzQG89RT47ZJoWhy5B5BGRZAMxWyEyxvtnyFdt8AagS1F9KQ6YvSMyB84xGyDSw2yO2XUbtAJ0MaqfmH0XAPIA2y7tj4F7jAm2uG1yWQZKNEHkBu+Dg2njWBJNEbnC+8uaIFRuWfuG2QxbbrOrUd0A1Tc8D7AIjkur7DAAsVf8MiWMZ3ZR2m02LPIMscATfjHqBnY7TFD9OAy4zTCCPG/MUKMM5O6wkXFr9dZq7FQqqHk/hDzbFa73cFONTZFDdRyiCcKg5rrSiLaXkiI6RjjrfG6VzDs+B5eAxuDXeYpmNRGzL2wZ/wof+du4GNFpBVqqz5HA4MM5VEYYDrOs+1I6Q9u/4Q8O9wN/AGgWjBVqQjjgAAAAAElFTkSuQmCC")}.ol-ctx-menu-container li:hover.ol-ctx-menu-zoom-out{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABYklEQVQ4T72U4VHCQBCF36tA91KAWIFYgViBWIFYgWMFYgdYgVCBWAFSgdiBFpAsFWSdxcDkQoBkhnF/ZjbfvX377ogjF4/Mw/8CVbUD4MynEJF5k2lqFapqz8yeAPRKkCXJEYAXEVnugm8BVXVgZq/FD+9mtgBwSrJfqF2QvN4FjYCq2jWzTwA/DhARh20qTdMRyQcA0xDCbZ3KCJhl2RTATaHgo+6HLMv8+xXJy+qB3l8FGoB5CKHsXcRV1b6ZvZF8FBH3NKotoJlNkiQZFONdlLtJ3rufbouZPSdJMjwIbKDQEzBrClx7eC4i33Uepmk6JnnXaOQifzMAtdGoRApugYiMI1uqKkrRWAfZo9MxM1+UZzFewl8mN4nYdVM83L7BkwbXLUrF3sfBLQDQBbDy08x8vOohXyEE71lVq9emuEk+3gZa3XYroCvwFyjP8yHJDsnxwaU08GxvS2uFhw78BbzWrxXgMbsHAAAAAElFTkSuQmCC")}</style> <script type="text/javascript" src="scripts/charts.js"></script> <script type="text/javascript" src="scripts/filesaver.1.1.20151003.js"></script> <script type="text/javascript" src="scripts/ol.js"></script> <script type="text/javascript" src="scripts/ol3-contextmenu.js"></script> <title>MeshCentral</title> </head> <body id="body" onload="if (typeof(startup) !== 'undefined') startup();" oncontextmenu="handleContextMenu(event)" style="display:none"> <div id="contextMenu" class="contextMenu noselect" style="display:none"> <div id="cxinfo" class="cmtext" onclick="cmaction(1,event)"><b>Information</b></div> <div id="cxdesktop" class="cmtext" onclick="cmaction(3,event)">Desktop</div> <div id="cxterminal" class="cmtext" onclick="cmaction(2,event)">Terminal</div> <div id="cxfiles" class="cmtext" onclick="cmaction(4,event)">Files</div> <div id="cxevents" class="cmtext" onclick="cmaction(5,event)">Events</div> <div id="cxconsole" class="cmtext" onclick="cmaction(6,event)">Console</div> <hr id="cxmgroupsplit"> <div id="cxmdesktop" class="cmtext" onclick="cmaction(7,event)" style="display:none">Multi-Desktop</div> </div> <div id="meshContextMenu" class="contextMenu,noselect" style="display:none;min-width:0px"> <div id="cxselectall" class="cmtext" onclick="cmmeshaction(1,event)">Select All</div> <div id="cxselectnone" class="cmtext" onclick="cmmeshaction(2,event)">Select None</div> <hr id="cxmgroupsplit2" style="display:none"> <div id="cxmmdesktop" class="cmtext" style="display:none" onclick="cmmeshaction(3,event)">Multi-Desktop</div> </div> <div id="container" style="max-height:100vh;position:relative"> <div id="notifiyBox" class="notifiyBox" style="display:none"></div> <div id="mastheadx"></div> <div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"> <div style="float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px"> <strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong> </div> <div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px"> <strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong> </div> <div style="float:right"> <div id="notificationCount" onclick="clickNotificationIcon()" class="unselectable" style="display:none;min-width:28px;font-size:20px;border-radius:5px;background-color:lightblue;text-align:center;margin:8px;cursor:pointer;padding:4px" title="Click to view current notifications">0</div> </div> <p id="logoutControl">{{{logoutControl}}}</p> </div> <div id="page_leftbar" style="height:calc(100vh - 66px);width:90px;position:absolute;z-index:1000;background:#113962;background:linear-gradient(to bottom, #104893 0%,#113962 100%);color:white;display:none"> <div style="height:16px"></div> <div id="LeftMenuMyDevices" class="lbbutton lbbuttonsel" title="My Devices" onclick="go(1)"> <div class="lb2" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyAccount" class="lbbutton" title="My Account" onclick="go(2)"> <div class="lb1" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyEvents" class="lbbutton" title="My Events" onclick="go(3)"> <div class="lb3" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyFiles" class="lbbutton" title="My Files" onclick="go(5)"> <div class="lb4" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyUsers" class="lbbutton" title="My Users" onclick="go(4)"> <div class="lb5" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyServer" class="lbbutton" title="My Server" onclick="go(6)" style="display:none"> <div class="lb6" style="position:absolute;top:6px;left:6px"></div> </div> </div> <div id="page_content" style="max-height:calc(100vh - 130px)"> <div id="topbarmaster"> <div id="topbar" class="noselect"> <div> <div style="position:relative"> <div style="position:absolute;top:3px;right:6px"> <span title="Toggle full width" style="cursor:pointer;color:white" onclick="toggleFullScreen(1)">&harr;</span> </div> <table id="MainMenuSpan" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="MainMenuMyDevices" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(1)">My Devices</td> <td id="MainMenuMyAccount" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(2)">My Account</td> <td id="MainMenuMyEvents" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(3)">My Events</td> <td id="MainMenuMyFiles" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(5)">My Files</td> <td id="MainMenuMyUsers" style="width:100px;height:24px;cursor:pointer;display:none" class="style3x" onclick="go(4)">My Users</td> <td id="MainMenuMyServer" style="width:100px;height:24px;cursor:pointer;display:none" class="style3x" onclick="go(6)">My Server</td> <td class="style3" style="text-align:right;height:24px">&nbsp;</td> </tr> </table> <div id="MainSubMenuSpan" style="display:none"> <table id="MainSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="MainDev" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(10)">General</td> <td id="MainDevDesktop" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(11)">Desktop</td> <td id="MainDevTerminal" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(12)">Terminal</td> <td id="MainDevFiles" style="width:100px;height:24px;cursor:pointer;display:none" class="style3x" onclick="go(13)">Files</td> <td id="MainDevEvents" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(16)">Events</td> <td id="MainDevAmt" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(14)">Intel&reg; AMT</td> <td id="MainDevConsole" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(15)">Console</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="MeshSubMenuSpan" style="display:none"> <table id="MeshSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="MeshGeneral" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(20)">General</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="UserSubMenuSpan" style="display:none"> <table id="UserSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="UserGeneral" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(30)">General</td> <td id="UserEvents" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(31)">Events</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="ServerSubMenuSpan" style="display:none"> <table id="ServerSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="ServerGeneral" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(6)">General</td> <td id="ServerConsole" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(115)">Console</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="UserDummyMenuSpan"> <table id="UserDummyMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr><td class="style3" style="text-align:right;height:24px">&nbsp;</td></tr> </table> </div> </div> </div> </div> </div> <div id="column_l"> <div id="p0" style="display:none"> <div id="p0message" style="margin:50px;text-align:center"><span id="p0span">Server disconnected</span>, <href onclick="reload()" style="cursor:pointer"><u>click to reconnect</u></href>.</div> </div> <div id="p1" style="display:none"> <div style="float:right;display:none" id="devListToolbarViewIcons"> <div id="devViewButton1" class="viewSelector" onclick="onDeviceViewChange(1)" title="Columns"><div class="viewSelector2"></div></div> <div id="devViewButton2" class="viewSelector" onclick="onDeviceViewChange(2)" title="List"><div class="viewSelector1"></div></div> <div id="devViewButton3" class="viewSelector" onclick="onDeviceViewChange(3)" title="Desktops"><div class="viewSelector3"></div></div> <div id="devViewButton4" class="viewSelector" onclick="onDeviceViewChange(4)" title="Map"><div class="viewSelector4"></div></div> </div><div><h1>My Devices</h1></div> <table class="noselect" style="width:100%;height:24px;background-color:#d3d9d6;vertical-align:middle;border-spacing:0"> <tr> <td class="h1"></td> <td id="devListToolbar" class="style14" style="display:none"> &nbsp;&nbsp;<input type="button" id="SelectAllButton" onclick="selectallButtonFunction();" value="Select All">&nbsp; <input type="button" id="GroupActionButton" disabled="disabled" value="Group Action" onclick="groupActionFunction()">&nbsp; <input id="SearchInput" type="text" style="width:120px" placeholder="Filter" onchange="masterUpdate(5)" onkeyup="masterUpdate(5)" autocomplete="off" onfocus="onSearchFocus(1)" onblur="onSearchFocus(0)">&nbsp; <label><input type="checkbox" id="RealNameCheckBox" onclick="onRealNameCheckBox()"><span title="Show devices operating system name">OS Name</span></label> </td> <td id="kvmListToolbar" class="style14" style="height:100%;display:none"> &nbsp;&nbsp;<input type="button" onclick="connectAllKvmFunction()" value="Connect All">&nbsp; <input type="button" onclick="disconnectAllKvmFunction()" value="Disconnect All">&nbsp; <label><input type="checkbox" id="autoConnectDesktopCheckbox" onclick="autoConnectDesktops(event)" title="Automatic connect">Auto&nbsp;</label> <input type="button" onclick="showMultiDesktopSettings()" value="Settings">&nbsp; </td> <td id="devMapToolbar" class="style14" style="height:100%;display:none"> &nbsp;&nbsp;<input type="text" id="mapSearchLocation" placeholder="Search Location" onfocus="onMapSearchFocus(1)" onblur="onMapSearchFocus(0)"> <input type="button" value="Search" title="Search for location" onclick="getSearchLocation()"> <input type="button" id="refreshmap" title="Reset map view" value="Reset" style="margin-left:5px" onclick="refreshMap(false,true)"> </td> <td class="auto-style1" style="height:100%"> <div style="float:right;display:none" id="devListToolbarView"> View <select id="viewselect" onchange="onDeviceViewChange()"> <option value="1">Columns <option value="2">List <option value="3">Desktops <option id="viewselectmapoption" value="4">Map </select> </div> <div style="float:right;display:none" id="devListToolbarSort"> Sort <select id="sortselect" onchange="masterUpdate(6)"> <option>Group <option>Power <option>Device <option>Tags </select> &nbsp; </div> <div style="float:right;display:none" id="devListToolbarSize"> Size <select id="sizeselect" onchange="onDeviceViewChange()"> <option value="0">Small <option value="1">Medium <option value="2">Large </select> &nbsp; </div> </td> <td class="h2"></td> </tr> </table> <div id="NoMeshesPanel" style="display:none"> <table style="width:100%;padding:20px"> <tr> <td valign="top" style="width:50px"> <img src="images/info.png" height="48" width="47"> </td> <td> To get started, <a onclick="account_createMesh()" style="cursor:pointer"><strong>click here to create a device group</strong></a>. </td> </tr> </table> </div> <div id="xdevices" class="noselect" style="max-height:calc(100vh - 239px);overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;display:none"></div> <div id="xdevicesmap" style="height:calc(100vh - 239px);width:100%;overflow:hidden;position:relative;display:none"> <div id="xmapSearchResultsDlg" style="position:absolute;display:none;max-height:280px;left:5px;top:5px;max-width:250px;z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666"> <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0"> <div id="xmapSearchClose" style="float:right;padding:5px;cursor:pointer" onclick="mapCloseSearchWindow()"><b>X</b></div> <div style="padding:5px">Location Results</div> <div style="width:100%;margin:6px"></div> </div> <div id="xmapSearchResults" style="margin:6px"></div> </div> </div> <div id="xmap-info-window" style="text-shadow:0px 0px 15px #FFF"></div> </div> <div id="p2" style="display:none"> <h1>My Account</h1> <img id="p2AccountImage" alt="" width="150" height="103" src="images/mainaccount.jpg" style="margin-bottom:10px;margin-right:20px;float:right"> <div id="p2AccountSecurity" style="display:none"> <p><strong>Account security</strong></p> <div style="margin-left:25px"> <div id="manageAuthApp"><div style="width:15px;display:inline-block"><span id="authAppSetupCheck" style="color:green;font-size:10px"><strong>&#x2713;</strong></span></div><span><a onclick="account_manageAuthApp()" style="cursor:pointer">Manage authenticator app</a><br></span></div> <div id="manageHardwareOtp"><div style="width:15px;display:inline-block"><span id="authKeySetupCheck" style="color:green;font-size:10px"><strong>&#x2713;</strong></span></div><span><a onclick="account_manageHardwareOtp(0)" style="cursor:pointer">Manage security keys</a><br></span></div> <div id="manageOtp"><div style="width:15px;display:inline-block"><span id="authCodesSetupCheck" style="color:green;font-size:10px"><strong>&#x2713;</strong></span></div><span><a onclick="account_manageOtp(0)" style="cursor:pointer">Manage backup codes</a><br></span></div> </div> </div> <div id="p2AccountActions"> <p><strong>Account actions</strong></p> <p style="margin-left:40px"> <span id="verifyEmailId" style="display:none"><a onclick="account_showVerifyEmail()" style="cursor:pointer">Verify email</a><br></span> <a onclick="account_showChangeEmail()" style="cursor:pointer">Change email address</a><br> <a onclick="account_showChangePassword()" style="cursor:pointer">Change password</a><span id="p2nextPasswordUpdateTime"></span><br> <a onclick="account_showDeleteAccount()" style="cursor:pointer">Delete account</a><br> </p> <br style="clear:both"> </div> <strong>Device Groups</strong> ( <a onclick="account_createMesh()" style="cursor:pointer"><img height="12" src="images/icon-addnew.png" width="12" border="0"> New</a> ) <br><br> <div id="p2meshes"></div> <div id="p2noMeshFound" style="margin-left:40px;display:none">No device groups. <a onclick="account_createMesh()" style="cursor:pointer"><strong>Get started here!</strong></a></div> <br style="clear:both"> </div> <div id="p3" style="display:none"> <h1>My Events</h1> <table style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0"> <tr> <td class="h1"></td> <td>&nbsp;<input id="p2deleteall" type="button" onclick="showDeleteAllEventsDialog()" style="display:none" value="Delete All..."></td> <td class="auto-style1"> Show <select id="p3limitdropdown" onchange="refreshEvents()"> <option value="60">Last 60 <option value="120">Last 120 <option value="250">Last 250 <option value="500">Last 500 <option value="1000">Last 1000 </select> </td> <td class="h2"></td> </tr> </table> <div id="p3events" style="height:calc(100vh - 243px);overflow-y:scroll"></div> </div> <div id="p4" style="display:none"> <h1>My Users</h1> <table style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0"> <tr> <td class="h1"></td> <td class="style14"> <div style="float:right"> <input type="button" onclick="showUserBroadcastDialog()" style="margin-right:6px" value="Broadcast"> </div> <div> <input id="UserNewAccountButton" type="button" style="margin-left:6px" onclick="showCreateNewAccountDialog()" value="New Account..."> <input id="UserSearchInput" type="text" style="width:120px;margin-left:6px" placeholder="Filter" onchange="onUserSearchInputChanged()" onkeyup="onUserSearchInputChanged()" autocomplete="off" onfocus="onUserSearchFocus(1)" onblur="onUserSearchFocus(0)"> </div> </td> <td class="h2"></td> </tr> </table> <div id="p3users" style="max-height:calc(100vh - 243px);overflow-y:auto"></div> </div> <div id="p5" style="display:none"> <h1>My Files</h1> <table id="p5toolbar" style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="width:100%;background-color:#d3d9d6;text-align:left;padding:4px" valign="bottom"> <div id="p5rightOfButtons" style="float:right;margin-top:3px"></div> <div> <input type="button" id="p5FolderUp" disabled="disabled" onclick="p5folderup();" value="Up">&nbsp; <input type="button" id="p5SelectAllButton" disabled="disabled" onclick="p5selectallfile();" value="Select All" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5RenameFileButton" disabled="disabled" value="Rename" onclick="p5renamefile();" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5DeleteFileButton" disabled="disabled" value="Delete" onclick="p5deletefile();" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5NewFolderButton" disabled="disabled" value="New Folder" onclick="p5createfolder();" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5UploadButton" disabled="disabled" value="Upload" onclick="p5uploadFile()" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5CutButton" disabled="disabled" value="Cut" onclick="p5copyFile(1)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p5CopyButton" disabled="disabled" value="Copy" onclick="p5copyFile(0)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p5PasteButton" disabled="disabled" value="Paste" onclick="p5pasteFile()" onkeypress="return false" onkeydown="return false">&nbsp; </div> </td> </tr> <tr> <td style="background-color:#E4E9E7;height:28px"> <div style="float:right"> <select id="p5sortdropdown" onchange="updateFiles()"> <option value="1" selected="selected">Sort by name <option value="2">Sort by size <option value="3">Sort by date <option value="4">Descend by name <option value="5">Descend by size <option value="6">Descend by date </select> </div> <div>&nbsp;&nbsp;<span id="p5currentpath"></span></div> </td> </tr> </table> <div id="p5filetable" style="width:100%;height:calc(100vh - 294px);overflow:auto;-webkit-user-select:none;position:relative"> <div id="p5PublicShare" style="display:none;width:100%;overflow:auto;-webkit-user-select:none;background-color:lightsteelblue"><div style="padding:4px">These files are shared publicly, click "link" to get public url.</div></div> <div id="bigok" style="width:256px;overflow:hidden;position:absolute;left:337px;top:20px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&checkmark;</b></div> <div id="bigfail" style="width:256px;overflow:hidden;position:absolute;left:337px;top:20px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&#10007;</b></div> <span id="p5files"></span> </div> <table id="p5toolbarBottom" style="width:100%" cellpadding="0" cellspacing="0"> <tr><td class="style6" style="text-align:left;padding:3px">&nbsp;<span id="p5bottomstatus"></span></td></tr> </table> </div> <div id="p6" style="display:none"> <img id="MainMeshImage" src="serverpic.ashx" style="border-width:0px;height:200px;width:200px;float:right"> <h1>My Server</h1> <p id="p2ServerActions"><strong>Server actions</strong></p> <p style="margin-left:40px"> <div id="p2ServerActionsBackup" style="margin-left:40px"><a href="/backup.zip" rel="noreferrer noopener" target="_blank" style="cursor:pointer">Download server backup</a></div> <div id="p2ServerActionsRestore" style="margin-left:40px"><a onclick="server_showRestoreDlg()" style="cursor:pointer">Restore server with backup</a></div> <div id="p2ServerActionsVersion" style="margin-left:40px"><a onclick="server_showVersionDlg()" style="cursor:pointer">Check server version</a></div> <div id="p2ServerActionsErrors" style="margin-left:40px"><a onclick="server_showErrorsDlg()" style="cursor:pointer">Show server error log</a></div> </p> <br><strong>Server Statistics</strong><br><br> <div id="serverStats" style="margin-left:40px"> <div id="serverCpuChartView" style="display:none"> <div style="width:60px;display:inline-block"><canvas id="serverCpuChart" style="width:60px;height:60px"></canvas></div> <div style="width:160px;display:inline-block" id="serverCpuChartText"></div> </div> <div id="serverMemoryChartView" style="display:none"> <div style="width:60px;display:inline-block"><canvas id="serverMemoryChart" style="width:60px;height:60px"></canvas></div> <div style="width:160px;display:inline-block" id="serverMemoryChartText"></div> </div><br><br> <div id="serverStatsTable"></div> </div> </div> <div id="p10" style="display:none"> <table style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="width:auto" valign="top"> <div id="p10title"> <div id="p10BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>General - <span id="p10deviceName"></span></h1> </div> <div id="p10html"></div> </td> <td style="width:20px"></td> <td style="width:200px"> <a style="cursor:pointer" onclick="p10showiconselector()"><img id="MainComputerImage" style="border-width:0px;height:200px;width:200px"></a> <div style="width:100%;text-align:center"><strong><span id="MainComputerState"></span></strong></div> </td> </tr> </table><br> <div id="p10html2"></div> <div id="p10html3"></div> </div> <div id="p11" class="noselect" style="display:none"> <div id="p11title"> <div id="p11deviceNameHeader"> <div id="p11BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <div style="float:right" id="devListToolbarViewIcons"><div class="viewSelector" onclick="deskToggleFull(event)" title="Full Screen. Hold shift to browser full screen."><div class="viewSelector5"></div></div></div> <h1>Desktop - <span id="p11deviceName"></span></h1> </div> </div> <div id="p14warning" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showFeaturesDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Intel&reg; AMT Redirection port or KVM feature is disabled<span id="p14warninga">, click here to enable it.</span></div> </div> <div id="p14warning2" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showPowerActionDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Remote computer is not powered on, click here to issue a power command.</div> </div> <table id="deskarea0" cellpadding="0" cellspacing="0" style="width:100%;padding:0px;padding:0px;margin-top:0px"> <tr id="deskarea1"> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <span id="p14power"></span>&nbsp; <div style='cursor:pointer;border:none;float:right;font-size:130%;margin-right:4px' title="Rotate Left" onclick="drotate(-1)">&olarr;</div> <div style='cursor:pointer;border:none;float:right;font-size:130%;margin-right:4px' title="Rotate Right" onclick="drotate(1)">&orarr;</div> <input id="deskFocusBtn" type="button" title="Toggle focus mode, when active only the region around the mouse is updated" onkeypress="return false" onkeydown="return false" value="Focus All" onclick="deskToggleFocus()" style="margin-right:3px;display:none"> <input id="deskSaveBtn" type="button" title="Save a screenshot of the remote desktop" onkeypress="return false" onkeydown="return false" value="Save..." onclick="deskSaveImage()" style="margin-right:3px"> <input id="deskActionsBtn" type="button" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value="Actions" onclick="deviceActionFunction()" style="margin-right:3px"> <input id="deskActionsSettings" type="button" value="Settings..." title="Edit remote desktop settings" onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()" style="margin-right:3px"> <input type="button" title="Change the power state of the remote machine" onkeypress="return false" onkeydown="return false" value="Power Actions..." onclick="showPowerActionDlg()" style="margin-right:3px;display:none"> </div> <div> <div id="idx_deskFullBtn2" onclick="deskToggleFull(event)" style="float:left;font-size:large;cursor:pointer;display:none">&nbsp;&#x2716;</div> <input type="button" id="autoconnectbutton1" value="AutoConnect" onclick="autoConnectDesktop(event)" onkeypress="return false" onkeydown="return false" style="display:none"> <span id="connectbutton1span">&nbsp;<input type="button" id="connectbutton1" value="Connect" onclick="connectDesktop(event,1)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="connectbutton1hspan">&nbsp;<input type="button" id="connectbutton1h" value="HW Connect" onclick="connectDesktop(event,2)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="disconnectbutton1span">&nbsp;<input type="button" id="disconnectbutton1" value="Disconnect" onclick="connectDesktop(event,0)" onkeypress="return false" onkeydown="return false"></span> &nbsp;<span id="deskstatus">Disconnected</span> </div> </td> </tr> <tr id="deskarea2"> <td> <div style="background-color:gray"><div id="progressbar" style="height:2px;width:0%;background-color:red"></div></div> </td> </tr> <tr id="deskarea3"> <td id="deskarea3x" style="background:black;text-align:center;position:relative;overflow:hidden"> <div id="DeskFocus" style="overflow:hidden;color:transparent;border:3px dotted rgba(255,0,0,.2);position:absolute;border-radius:5px" oncontextmenu="return false" onmousedown="dmousedown(event)" onmouseup="dmouseup(event)" onmousemove="dmousemove(event)"></div> <div id="DeskParent" style="overflow:hidden"> <canvas id="Desk" width="640" height="480" style="overflow:hidden;width:100%;-ms-touch-action:none;margin-left:0px" oncontextmenu="return false" onmousedown="dmousedown(event)" onmouseup="dmouseup(event)" onmousemove="dmousemove(event)" onmousewheel="dmousewheel(event)"></canvas> </div> <div id="DeskTools" style="position:absolute;width:400px;height:100%;background-color:gray;top:0;right:0;border-left:2px solid lightgray;display:none"> <a id="DeskToolsRefreshButton" style="float:right;padding:3px;cursor:pointer" onclick="refreshDeskTools()">Refresh</a> <div id="DeskToolsBar" style="position:absolute;padding:3px;border-radius:3px 3px 0px 0px;top:5px;left:4px;bottom:26px;background-color:lightgray;cursor:pointer">Processes</div> <div style="position:absolute;top:26px;left:4px;right:4px;bottom:4px;background-color:lightgray;text-align:left"> <div style="border-bottom:1px solid darkgray;padding:3px"><a style="width:50px;padding-right:5px;float:left;cursor:pointer" title="Sort by process id" onclick="sortProcess(0)">PID</a><a style="cursor:pointer" title="Sort by name" onclick="sortProcess(1)">Name</a></div> <div id="DeskToolsProcesses" style="overflow-y:scroll;position:absolute;top:24px;bottom:0px;width:100%"></div> </div> </div> </td> </tr> <tr id="deskarea4"> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <select id="termdisplays" style="display:none" onchange="deskSetDisplay(event)" onclick="deskGetDisplayNumbers(event)"></select>&nbsp; <input id="DeskToolsButton" type="button" value="Tools" title="Toggle tools view" onkeypress="return false" onkeydown="return false" onclick="toggleDeskTools()">&nbsp; <span id="DeskChatButton" style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Open chat window to this computer"><img src='images/icon-chat.png' onclick="deviceChat()" height="16" width="16" style="padding-top:2px"></span> <span id="DeskNotifyButton" style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Display a notification on the remote computer"><img src='images/icon-notify.png' onclick="deviceToastFunction()" height="16" width="16" style="padding-top:2px"></span> <span id="DeskOpenWebButton" style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Open a web address on remote computer"><img src='images/icon-url2.png' onclick="deviceUrlFunction()" height="16" width="16" style="padding-top:2px"></span> </div> <div> <select style="margin-left:6px" id="deskkeys"> <option value="5">Win <option value="0">Win+Down <option value="1">Win+Up <option value="2">Win+L <option value="3">Win+M <option value="4">Shift+Win+M <option value="6">Win+R </select> <input id="DeskWD" type="button" value="Send" onkeypress="return false" onkeydown="return false" onclick="deskSendKeys()"> <input id="DeskClip" style="margin-left:6px;display:none" type="button" value="Clipboard" onkeypress="return false" onkeydown="return false" onclick="showDeskClip()"> <input id="DeskCAD" type="button" value="Ctrl-Alt-Del" onkeypress="return false" onkeydown="return false" onclick="sendCAD()"> <label><span id="DeskControlSpan" style="margin-left:6px" title="Toggle mouse and keyboard input"><input id="DeskControl" type="checkbox" onkeypress="return false" onkeydown="return false" onclick="toggleKvmControl()">Input</span></label>&nbsp; </div> </td> </tr> </table> </div> <div id="p12" style="display:none"> <div id="p12title"> <div id="p12BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Terminal - <span id="p12deviceName"></span></h1> </div> <div id="p12warning" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showFeaturesDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Intel&reg; AMT Redirection port or KVM feature is disabled<span id="p14warninga">, click here to enable it.</span></div> </div> <div id="p12warning2" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showPowerActionDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Remote computer is not powered on, click here to issue a power command.</div> </div> <table cellpadding="0" cellspacing="0" style="width:100%;padding:0px;padding:0px;margin-top:0px"> <tr> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <input id="termActionsBtn" type="button" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value="Actions" onclick="deviceActionFunction()" style="margin-right:3px"> </div> <div> <input type="button" id="autoconnectbutton2" value="AutoConnect" onclick="autoConnectTerminal(event)" onkeypress="return false" onkeydown="return false" style="display:none"> <span id="connectbutton2span">&nbsp;<input type="button" id="connectbutton2" value="Connect" onclick="connectTerminal(event,1)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="connectbutton2hspan">&nbsp;<input type="button" id="connectbutton2h" value="HW Connect" onclick="connectTerminal(event,2)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="disconnectbutton2span">&nbsp;<input type="button" id="disconnectbutton2" value="Disconnect" onclick="connectTerminal(event,0)" onkeypress="return false" onkeydown="return false"></span> &nbsp;<span id="termstatus">Disconnected</span> </div> </td> </tr> <tr> <td> <div style="background-color:gray"><div id="termprogressbar" style="height:2px;width:0%;background-color:red"></div></div> </td> </tr> <tr> <td style="background:black;text-align:center;height:500px;position:relative"> <pre id="Term" style="background:black;margin:0;padding:0"></pre> </td> </tr> <tr> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <span id="terminalSettingsButtons" style="display:none"> <input id="id_tcrbutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="CR+LF" title="Toggle what the return key will send" onclick="termToggleCr()"> <input id="id_tfxkeysbutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Intel (F10 = ESC+[OM)" title="Toggle F1 to F10 keys emulation type" onclick="termToggleFx()"> <input id="id_ttypebutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Extended Ascii" title="Toggle terminal emulation type" onclick="termToggleType()"> </span> <select id="specialkeylist" onkeypress="return false" style="margin-left:5px"></select> <input id="specialkeylistinput" type="button" onkeypress="return false" class="bottombutton" value="Send" title="Send the selected special key" onclick="sendSpecialKey()"> </div> <div> &nbsp; <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="ctrlcbutton" value="Ctl-C" onclick="termSendKey(3,'ctrlcbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="ctrlxbutton" value="Ctl-X" onclick="termSendKey(24,'ctrlxbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="escbutton" value="ESC" onclick="termSendKey(27,'escbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="bsbutton" value="Backspace" onclick="termSendKey(8,'bsbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="pastebutton" value="Paste" title="Paste text into the terminal" onclick="showTermPasteDialog()"> </div> </td> </tr> </table> </div> <div id="p13" style="display:none"> <div id="p13title"> <div id="p13BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Files - <span id="p13deviceName"></span></h1> </div> <table id="p13toolbar" style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="background-color:#C0C0C0;border-bottom:2px solid black;padding:2px"> <div style="float:right;text-align:right"> <input id="filesActionsBtn" type="button" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value="Actions" onclick="deviceActionFunction()" style="margin-right:3px"> </div> <div> <input id="p13AutoConnect" value="AutoConnect" onclick="autoConnectFiles(event)" onkeypress="return false" onkeydown="return false" type="button" style="display:none"> <input id="p13Connect" value="Connect" onclick="connectFiles(event)" onkeypress="return false" onkeydown="return false" type="button"> <span id="p13Status">Disconnected</span> </div> </td> </tr> <tr> <td style="width:100%;background-color:#d3d9d6;text-align:left;padding:4px" valign="bottom"> <div id="p13rightOfButtons" style="float:right;margin-top:3px"></div> <div> <input type="button" id="p13FolderUp" disabled="disabled" onclick="p13folderup()" value="Up">&nbsp; <input type="button" id="p13SelectAllButton" disabled="disabled" onclick="p13selectallfile()" value="Select All" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13RenameFileButton" disabled="disabled" value="Rename" onclick="p13renamefile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13DeleteFileButton" disabled="disabled" value="Delete" onclick="p13deletefile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13NewFolderButton" disabled="disabled" value="New Folder" onclick="p13createfolder()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13UploadButton" disabled="disabled" value="Upload" onclick="p13uploadFile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13CutButton" disabled="disabled" value="Cut" onclick="p13copyFile(1)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13CopyButton" disabled="disabled" value="Copy" onclick="p13copyFile(0)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13PasteButton" disabled="disabled" value="Paste" onclick="p13pasteFile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13RefreshButton" disabled="disabled" value="Refresh" onclick="p13folderup(9999)" onkeypress="return false" onkeydown="return false">&nbsp; </div> </td> </tr> <tr> <td style="background-color:#E4E9E7;height:28px"> <div style="float:right"> <select id="p13sortdropdown" onchange="p13updateFiles()"> <option value="1" selected="selected">Sort by name <option value="2">Sort by size <option value="3">Sort by date <option value="4">Descend by name <option value="5">Descend by size <option value="6">Descend by date </select> </div> <div>&nbsp;&nbsp;<span id="p13currentpath"></span></div> </td> </tr> </table> <div id="p13filetable" style="width:100%;height:calc(100vh - 346px);overflow:auto;-webkit-user-select:none"> <div id="p13bigok" style="width:256px;overflow:hidden;position:absolute;left:337px;top:200px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&checkmark;</b></div> <div id="p13bigfail" style="width:256px;overflow:hidden;position:absolute;left:337px;top:200px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&#10007;</b></div> <span id="p13files"></span> </div> <table id="p13toolbarBottom" style="width:100%" cellpadding="0" cellspacing="0"> <tr><td class="style6" style="text-align:left;padding:3px">&nbsp;<span id="p13bottomstatus"></span></td></tr> </table> </div> <div id="p14" style="display:none"> <div id="p14title"> <div id="p14BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Intel&reg; AMT - <span id="p14deviceName"></span></h1> </div> <iframe id="p14iframe" style="width:100%;height:calc(100vh - 242px);border:0;overflow:hidden" src="/commander.htm"></iframe> </div> <div id="p15" style="display:none"> <div id="p15title"> <div id="p15BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1><span id="p15deviceName"></span></h1> </div> <table cellpadding="0" cellspacing="0" style="width:100%;padding:0px;padding:0px;margin-top:0px"> <tr> <td style="background:#C0C0C0"> <div style="float:right;padding-right:4px"> <div style="padding:4px;display:inline-block" id="p15coreName" title="Information about current core running on this agent"></div> <input type="button" id="p15uploadCore" value="Agent Action" onclick="p15uploadCore(event)" title="Change the agent Java Script code module"> </div> <div id="p15statetext" style="padding:4px"></div> </td> </tr> <tr> <td> <div style="background-color:gray"><div id="consoleprogressbar" style="height:2px;width:0%;background-color:red"></div></div> </td> </tr> <tr> <td id="p15agentConsole" style="background:black;margin:0;padding:0;color:lightgray;width:100%;height:calc(100vh - 296px);max-height:500px;position:relative"> <pre id="p15agentConsoleText" style="position:absolute;margin:0;padding:0;top:0;bottom:0;left:0;right:0;overflow-y:scroll;overflow-x:auto"></pre> </td> </tr> <tr> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <table style="width:100%"> <tr> <td style="width:99%"> <input id="p15consoleText" style="width:100%" onkeyup="p15consoleSend(event)" onfocus="onConsoleFocus(1)" onblur="onConsoleFocus(0)"> </td> <td>&nbsp;</td> <td style="width:1%"><input id="id_p15consoleClear" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Clear" onclick="p15consoleClear()"></td> </tr> </table> </td> </tr> </table> </div> <div id="p16" style="display:none"> <div id="p16title"> <div id="p16BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Events - <span id="p16deviceName"></span></h1> </div> <div style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px"> <div class="style7" style="width:16px;height:100%;float:left">&nbsp;</div> <div class="h1" style="height:100%;float:left">&nbsp;</div> <div class="style14" style="height:100%;float:left">&nbsp;&nbsp;<input type="button" value="Refresh" onclick="refreshDeviceEvents()">&nbsp;</div> <div class="auto-style1" style="height:100%;float:right"> Show <select id="p16limitdropdown" onchange="refreshDeviceEvents()"> <option value="60">Last 60 <option value="120">Last 120 <option value="250">Last 250 <option value="500">Last 500 <option value="1000">Last 1000 </select> <div style="height:100%;width:20px;float:right;background-color:#ffffff"></div> <div class="h2" style="height:100%;float:right">&nbsp;</div> </div> </div> <div id="p16events" style="max-height:calc(100vh - 267px);overflow-y:auto"></div> </div> <div id="p20" style="display:none"> <picture id="MainMeshImage" style="border-width:0px;height:200px;width:200px;float:right"> <source type="image/webp" width="200" height="200" srcset="images/webp/mesh-200.webp"> <img alt="" width="200" height="200" src="images/mesh-200.jpg"> </source></picture> <div style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>General - <span id="p20meshName"></span></h1> <p id="p20info"> </div> <div id="p30" style="display:none"> <table style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="width:auto" valign="top"> <div id="p30title"> <div style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>General - <span id="p30userName"></span></h1> </div> <div id="p30html"></div> </td> <td style="width:20px"></td> <td style="width:200px"> <picture id="MainUserImage" style="border-width:0px;height:200px;width:200px;float:right"> <source type="image/webp" width="200" height="200" srcset="images/webp/user-200.webp"> <img alt="" width="200" height="200" src="images/user-200.jpg"> </source></picture> <div style="width:100%;text-align:center"><strong><span id="MainUserState"></span></strong></div> </td> </tr> </table><br> <div id="p30html2"></div> <div id="p30html3"></div> </div> <div id="p31" style="display:none"> <div style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Events - <span id="p31userName"></span></h1> <div style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px"> <div class="style7" style="width:16px;height:100%;float:left">&nbsp;</div> <div class="h1" style="height:100%;float:left">&nbsp;</div> <div class="style14" style="height:100%;float:left">&nbsp;&nbsp;<input type="button" value="Refresh" onclick="refreshUsersEvents()">&nbsp;</div> <div class="auto-style1" style="height:100%;float:right"> Show <select id="p31limitdropdown" onchange="refreshUsersEvents()"> <option value="60">Last 60 <option value="120">Last 120 <option value="250">Last 250 <option value="500">Last 500 <option value="1000">Last 1000 </select> <div style="height:100%;width:20px;float:right;background-color:#ffffff"></div> <div class="h2" style="height:100%;float:right;">&nbsp;</div> </div> </div> <div id="p31events" style="max-height:calc(100vh - 267px);overflow-y:scroll"></div> </div> <br id="column_l_bottomgap"> </div> <div id="footer" class="noselect"> <table cellpadding="0" cellspacing="10" style="width:100%"> <tr> <td style="text-align:left;color:white"> {{{footer}}} </td> <td style="text-align:right"> <a id="verifyEmailId2" style="color:yellow;margin-left:3px;cursor:pointer;display:none" onclick="account_showVerifyEmail()">Verify Email</a> <a style="margin-left:3px" href="terms">Terms &amp; Privacy</a> </td> </tr> </table> </div> <div id="dialog" style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:5px;position:fixed;top:160px;width:400px;left:calc((100% / 2) - 200px);display:none"> <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0"> <div id="id_dialogclose" style="float:right;padding:3px;margin-right:3px;cursor:pointer" onclick="setDialogMode()">&#x2716;</div> <div id="id_dialogtitle" style="padding:5px"></div> <div style="width:100%;margin:6px"></div> </div> <div style="margin-right:16px;margin-left:8px"> <div id="dialog1" style="margin:auto;text-align:center;margin:3px"> <div id="id_dialogMessage" style="padding:10px"></div> </div> <div id="dialog2" style="margin:auto;margin:3px"> <div id="id_dialogOptions"></div> </div> <div id="dialog3" style="margin:auto;margin:3px"> <div style="height:26px"> <select id="d3uploadMode" style="float:right;width:260px" onchange="d3modechange()"> <option value="1">Local file upload <option value="2">Server file selection </select> <div>File Selection</div> </div> <div id="d3localmode" style="height:26px;display:none"> <form id="d3localmodeform" method="post" enctype="multipart/form-data" action="uploadfile.ashx" target="fileUploadFrame"> <input type="text" id="d3attrib" name="attrib" style="display:none"> <input type="file" id="d3localFile" name="files" style="float:right;width:260px" onchange="d3setActions()"> <input type="submit" id="d3submit" style="display:none"> </form> <div>Upload File</div> </div> <div id="d3servermode"> <div style="width:100%;background-color:#d3d9d6;text-align:left;padding:3px" valign="bottom"> <input type="button" id="p3FolderUp" disabled="disabled" onclick="d3folderup()" value="Up">&nbsp; </div> <div id="d3serverfiles" style="width:100%;height:150px;background-color:white;padding:2px;border:1px solid gray;overflow-y:scroll"></div> </div> </div> <div id="dialog7" style="margin:auto;margin:3px"> <div id="d7meshkvm"> <h4 style="width:100%;border-bottom:1px solid gray">Agent Remote Desktop</h4> <div style="margin:3px 0 3px 0"> <select id="d7bitmapquality" style="float:right;width:200px;height:20px" dir="rtl"></select> <div style="height:20px">Quality</div> </div> <div style="margin:3px 0 3px 0"> <select id="d7bitmapscaling" style="float:right;width:200px;height:20px" dir="rtl"> <option selected="selected" value="1024">100% <option value="896">87.5% <option value="768">75% <option value="640">62.5% <option value="512">50% <option value="384">37.5% <option value="256">25% <option value="128">12.5% </select> <div style="height:20px">Scaling</div> </div> <div style="margin:3px 0 3px 0"> <select id="d7framelimiter" style="float:right;width:200px;height:20px" dir="rtl"> <option selected="selected" value="50">Fast <option value="100">Medium <option value="400">Slow <option value="1000">Very slow </select> <div style="height:20px">Frame rate</div> </div> </div> <div id="d7amtkvm"> <h4 style="width:100%;border-bottom:1px solid gray">Intel&reg; AMT Hardware KVM</h4> <div style='height:26px'> <select id="d7desktopmode" style="float:right;width:200px"> <option value="1">RLE8, Fastest <option value="2">RLE16, Recommended <option value="3">RAW8, Slow <option value="4">RAW16, Very Slow </select> <div>Image Encoding</div> </div> <div style="height:60px"> <div style="float:right;border:1px solid #666;width:200px;height:60px;overflow-y:scroll;background-color:white"> <label><input type="checkbox" id='d7showfocus'>Show Focus Tool<br></label> <label><input type="checkbox" id='d7showcursor'>Show Local Mouse Cursor<br></label> <label><input type="checkbox" id='d7localKeyMap'>Local Keyboard Map<br></label> </div> <div>Other Settings</div> </div> </div> </div> </div> <div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:4px"> <input id="idx_dlgCancelButton" type="button" value="Cancel" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)"> <input id="idx_dlgOkButton" type="button" value="OK" style="float:right;width:80px" onclick="dialogclose(1)"> <div style="height:25px"><input id="idx_dlgDeleteButton" type="button" value="Delete" style="width:80px;display:none" onclick="dialogclose(2)"></div> </div> </div> <iframe name="fileUploadFrame" style="display:none"></iframe> <form style="display:none" method="post" action="uploadfile.ashx" enctype="multipart/form-data" target="fileUploadFrame"><input id="p5fileDragName" name="name"><input id="p5fileDragSize" name="size"><input id="p5fileDragType" name="type"><input id="p5fileDragData" name="data"><input id="p5fileDragLink" name="link"><input type="submit" id="p5loginSubmit2" style="display:none"></form> <form style="display:none" method="post" action="uploadnodefile.ashx" enctype="multipart/form-data" target="fileUploadFrame"><input id="p13fileDragName" name="name"><input id="p13fileDragSize" name="size"><input id="p13fileDragType" name="type"><input id="p13fileDragData" name="data"><input id="p13fileDragLink" name="link"><input type="submit" id="p13loginSubmit2" style="display:none"></form> <audio id="chimes"><source src="sounds/chimes.mp3" type="audio/mp3"></source></audio> </div> </div> <script>if(!String.prototype.startsWith){String.prototype.startsWith=function(a){return this.lastIndexOf(a,0)===0}}if(!String.prototype.endsWith){String.prototype.endsWith=function(a){return this.indexOf(a,this.length-a.length)!==-1}}function Q(a){return document.getElementById(a)}function QS(a){try{return Q(a).style}catch(a){}}function QE(a,b){try{Q(a).disabled=!b}catch(a){}}function QV(a,b){try{QS(a).display=(b?"":"none")}catch(a){}}function QA(a,b){Q(a).innerHTML+=b}function QH(a,b){Q(a).innerHTML=b}function inputBoxFocus(b){Q(b).focus();var a=Q(b).value;Q(b).value="";Q(b).value=a}function ReadShort(b,a){return(b.charCodeAt(a)<<8)+b.charCodeAt(a+1)}function ReadShortX(b,a){return(b.charCodeAt(a+1)<<8)+b.charCodeAt(a)}function ReadInt(b,a){return(b.charCodeAt(a)*16777216)+(b.charCodeAt(a+1)<<16)+(b.charCodeAt(a+2)<<8)+b.charCodeAt(a+3)}function ReadSInt(b,a){return(b.charCodeAt(a)<<24)+(b.charCodeAt(a+1)<<16)+(b.charCodeAt(a+2)<<8)+b.charCodeAt(a+3)}function ReadIntX(b,a){return(b.charCodeAt(a+3)*16777216)+(b.charCodeAt(a+2)<<16)+(b.charCodeAt(a+1)<<8)+b.charCodeAt(a)}function ShortToStr(a){return String.fromCharCode((a>>8)&255,a&255)}function ShortToStrX(a){return String.fromCharCode(a&255,(a>>8)&255)}function IntToStr(a){return String.fromCharCode((a>>24)&255,(a>>16)&255,(a>>8)&255,a&255)}function IntToStrX(a){return String.fromCharCode(a&255,(a>>8)&255,(a>>16)&255,(a>>24)&255)}function MakeToArray(a){if(!a||a==null||typeof a=="object"){return a}return[a]}function SplitArray(a){return a.split(",")}function Clone(a){return JSON.parse(JSON.stringify(a))}function EscapeHtml(a){if(typeof a=="string"){return a.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}if(typeof a=="boolean"){return a}if(typeof a=="number"){return a}}function EscapeHtmlBreaks(a){if(typeof a=="string"){return a.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/\r/g,"<br />").replace(/\n/g,"").replace(/\t/g,"&nbsp;&nbsp;")}if(typeof a=="boolean"){return a}if(typeof a=="number"){return a}}function ArrayElementMove(a,b,c){a.splice(c,0,a.splice(b,1)[0])}function ObjectToStringEx(e,a){var d="";if(e!=0&&(!e||e==null)){return"(Null)"}if(e instanceof Array){for(var b in e){d+="<br />"+gap(a)+"Item #"+b+": "+ObjectToStringEx(e[b],a+1)}}else{if(e instanceof Object){for(var b in e){d+="<br />"+gap(a)+b+" = "+ObjectToStringEx(e[b],a+1)}}else{d+=EscapeHtml(e)}}return d}function ObjectToStringEx2(e,a){var d="";if(e!=0&&(!e||e==null)){return"(Null)"}if(e instanceof Array){for(var b in e){d+="\r\n"+gap2(a)+"Item #"+b+": "+ObjectToStringEx2(e[b],a+1)}}else{if(e instanceof Object){for(var b in e){d+="\r\n"+gap2(a)+b+" = "+ObjectToStringEx2(e[b],a+1)}}else{d+=EscapeHtml(e)}}return d}function gap(a){var d="";for(var b=0;b<(a*4);b++){d+="&nbsp;"}return d}function gap2(a){var d="";for(var b=0;b<(a*4);b++){d+=" "}return d}function ObjectToString(a){return ObjectToStringEx(a,0)}function ObjectToString2(a){return ObjectToStringEx2(a,0)}function hex2rstr(a){if(typeof a!="string"||a.length==0){return""}var c="",b=(""+a).match(/../g),e;while(e=b.shift()){c+=String.fromCharCode("0x"+e)}return c}function char2hex(a){return(a+256).toString(16).substr(-2).toUpperCase()}function rstr2hex(b){var c="",a;for(a=0;a<b.length;a++){c+=char2hex(b.charCodeAt(a))}return c}function encode_utf8(a){return unescape(encodeURIComponent(a))}function decode_utf8(a){return decodeURIComponent(escape(a))}function data2blob(c){var b=new Array(c.length);for(var d=0;d<c.length;d++){b[d]=c.charCodeAt(d)}var a=new Blob([new Uint8Array(b)]);return a}function random(a){return Math.floor(Math.random()*a)}function trademarks(a){return a.replace(/\(R\)/g,"&reg;").replace(/\(TM\)/g,"&trade;")}var MeshServerCreateControl=function(b,a){var c={};c.State=0;c.connectstate=0;c.pingTimer=null;c.authCookie=a;c.xxStateChange=function(e,d){if(c.State==e){return}var g=c.State;c.State=e;if(c.onStateChanged){c.onStateChanged(c,c.State,g,d)}};c.Start=function(){if(c.connectstate!=0){return}c.connectstate=0;var d=window.location.protocol.replace("http","ws")+"//"+window.location.host+b+"control.ashx";if(c.authCookie&&(c.authCookie!="")){d+="?auth="+c.authCookie}c.socket=new WebSocket(d);c.socket.onopen=function(g){c.connectstate=1};c.socket.onmessage=c.xxOnMessage;c.socket.onclose=function(g){c.Stop(g.code)};c.xxStateChange(1,0);if(c.pingTimer!=null){clearInterval(c.pingTimer)}c.pingTimer=setInterval(function(){c.send({action:"ping"})},29000)};c.Stop=function(d){c.connectstate=0;if(c.socket){c.socket.close();delete c.socket}if(c.pingTimer!=null){clearInterval(c.pingTimer);c.pingTimer=null}c.xxStateChange(0,d)};c.xxOnMessage=function(d){if(c.State==1){c.xxStateChange(2)}var g;try{g=JSON.parse(d.data)}catch(d){return}if((typeof g!="object")||(g.action=="pong")){return}if(g.action=="close"){if(g.msg){console.log(g.msg)}c.Stop(g.cause);return}if(c.onMessage){c.onMessage(c,g)}};c.send=function(d){if(c.socket!=null&&c.connectstate==1){c.socket.send(JSON.stringify(d))}};return c};function AmtStackCreateService(t){var s=new Object();s.wsman=t;s.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/"];s.PendingEnums=[];s.PendingBatchOperations=0;s.ActiveEnumsCount=0;s.MaxActiveEnumsCount=1;s.onProcessChanged=null;var n=0;var m=0;s.GetPendingActions=function(){return(s.PendingEnums.length*2)+(s.ActiveEnumsCount)+s.wsman.comm.PendingAjax.length+s.wsman.comm.ActiveAjaxCount+s.PendingBatchOperations};function r(){var u=s.GetPendingActions();if(n<u){n=u}if(s.onProcessChanged!=null&&m!=u){m=u;s.onProcessChanged(u,n)}if(u==0){n=0}}s.Subscribe=function(w,v,C,u,B,z,A,x,D,y){s.wsman.ExecSubscribe(s.CompleteName(w),v,C,function(G,F,E,H){r();u(s,w,E,H,B)},0,z,A,x,D,y);r()};s.UnSubscribe=function(v,u,y,w,x){s.wsman.ExecUnSubscribe(s.CompleteName(v),function(B,A,z,C){r();u(s,v,z,C,y)},0,w,x);r()};s.Get=function(v,u,x,w){s.wsman.ExecGet(s.CompleteName(v),function(A,z,y,B){r();u(s,v,y,B,x)},0,w);r()};s.Put=function(v,x,u,z,w,y){s.wsman.ExecPut(s.CompleteName(v),x,function(C,B,A,D){r();u(s,v,A,D,z)},0,w,y);r()};s.Create=function(v,x,u,y,w){s.wsman.ExecCreate(s.CompleteName(v),x,function(B,A,z,C){r();u(s,v,z,C,y)},0,w);r()};s.Delete=function(v,x,u,y,w){s.wsman.ExecDelete(s.CompleteName(v),x,function(B,A,z,C){r();u(s,v,z,C,y)},0,w);r()};s.Exec=function(x,w,u,v,A,y,z){s.wsman.ExecMethod(s.CompleteName(x),w,u,function(D,C,B,E){r();v(s,x,s.CompleteExecResponse(B),E,A)},0,y,z);r()};s.ExecWithXml=function(x,w,u,v,A,y,z){s.wsman.ExecMethodXml(s.CompleteName(x),w,execArgumentsToXml(u),function(D,C,B,E){r();v(s,x,s.CompleteExecResponse(B),E,A)},0,y,z);r()};s.Enum=function(v,u,x,w){if(s.ActiveEnumsCount<s.MaxActiveEnumsCount){s.ActiveEnumsCount++;s.wsman.ExecEnum(s.CompleteName(v),function(B,z,y,C,A){r();d(v,y,u,z,C,A)},x,w)}else{s.PendingEnums.push([v,u,x,w])}r()};function d(w,y,u,z,A,B,x){if(A!=200){u(s,w,null,A,B);c(1);return}if(y==null||y.Header.Method!="EnumerateResponse"||!y.Body.EnumerationContext){u(s,w,null,603,B);c(1);return}var v=y.Body.EnumerationContext;s.wsman.ExecPull(z,v,function(E,D,C,F){b(w,C,u,D,[],F,B,x)})}function b(z,B,u,C,x,D,E,A){if(D!=200){u(s,z,null,D,E);c(1);return}if(B==null||B.Header.Method!="PullResponse"){u(s,z,null,604,E);c(1);return}for(var w in B.Body.Items){if(B.Body.Items[w] instanceof Array){for(var y in B.Body.Items[w]){x.push(B.Body.Items[w][y])}}else{x.push(B.Body.Items[w])}}if(B.Body.EnumerationContext){var v=B.Body.EnumerationContext;s.wsman.ExecPull(C,v,function(H,G,F,I){b(z,F,u,G,x,I,E,1)})}else{c(1);u(s,z,x,D,E);r()}}function c(u){s.ActiveEnumsCount-=u;if(s.ActiveEnumsCount>=s.MaxActiveEnumsCount||s.PendingEnums.length==0){return}var v=s.PendingEnums.shift();s.Enum(v[0],v[1],v[2]);c(0)}s.BatchEnum=function(u,x,v,z,w,y){s.PendingBatchOperations+=(x.length*2);a(u,Clone(x),v,z,{},w,y);r()};function a(u,z,v,C,B,w,A){s.PendingBatchOperations-=2;var y=z.shift(),x=s.Enum;if(y[0]=="*"){x=s.Get;y=y.substring(1)}x(y,function(F,D,E,G,H){H[2][D]={response:(E==null?null:E.Body),responses:E,status:G};if(H[1].length==0||G==401||(w!=true&&G!=200&&G!=400)){s.PendingBatchOperations-=(z.length*2);r();v(s,u,H[2],G,C)}else{r();a(u,z,v,C,H[2],A)}},[u,z,B],A);r()}s.BatchGet=function(u,w,v,y,x){h({name:u,names:w,callback:v,current:0,responses:{},tag:y,pri:x});r()};function h(u){if(u.names.length<=u.current){u.callback(s,u.name,u.responses,200,u.tag)}else{s.wsman.ExecGet(s.CompleteName(u.names[u.current]),function(x,w,v,y){g(u,v,y)},u.pri);u.current++}r()}function g(u,v,w){if(v==null||w!=200){u.callback(s,u.name,null,w,u.tag)}else{u.responses[v.Header.Method]=v;h(u)}}s.CompleteName=function(u){if(u.indexOf("AMT_")==0){return s.pfx[0]+u}if(u.indexOf("CIM_")==0){return s.pfx[1]+u}if(u.indexOf("IPS_")==0){return s.pfx[2]+u}};s.CompleteExecResponse=function(u){if(u&&u!=null&&u.Body&&u.Body.ReturnValue){u.Body.ReturnValueStr=s.AmtStatusToStr(u.Body.ReturnValue)}return u};s.RequestPowerStateChange=function(v,u){s.CIM_PowerManagementService_RequestPowerStateChange(v,'<Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing"><ResourceURI xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystem</ResourceURI><SelectorSet xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"><Selector Name="CreationClassName">CIM_ComputerSystem</Selector><Selector Name="Name">ManagedSystem</Selector></SelectorSet></ReferenceParameters>',null,null,u)};s.SetBootConfigRole=function(v,u){s.CIM_BootService_SetBootConfigRole('<Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing"><ResourceURI xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_BootConfigSetting</ResourceURI><SelectorSet xmlns="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"><Selector Name="InstanceID">Intel(r) AMT: Boot Configuration 0</Selector></SelectorSet></ReferenceParameters>',v,u)};s.CancelAllQueries=function(u){s.wsman.CancelAllQueries(u)};s.AMT_AgentPresenceWatchdog_RegisterAgent=function(u){s.Exec("AMT_AgentPresenceWatchdog","RegisterAgent",{},u)};s.AMT_AgentPresenceWatchdog_AssertPresence=function(v,u){s.Exec("AMT_AgentPresenceWatchdog","AssertPresence",{SequenceNumber:v},u)};s.AMT_AgentPresenceWatchdog_AssertShutdown=function(v,u){s.Exec("AMT_AgentPresenceWatchdog","AssertShutdown",{SequenceNumber:v},u)};s.AMT_AgentPresenceWatchdog_AddAction=function(z,y,x,v,u,w,C,A,B){s.Exec("AMT_AgentPresenceWatchdog","AddAction",{OldState:z,NewState:y,EventOnTransition:x,ActionSd:v,ActionEac:u},w,C,A,B)};s.AMT_AgentPresenceWatchdog_DeleteAllActions=function(u,x,v,w){s.Exec("AMT_AgentPresenceWatchdog","DeleteAllActions",{},u,x,v,w)};s.AMT_AgentPresenceWatchdogAction_GetActionEac=function(u){s.Exec("AMT_AgentPresenceWatchdogAction","GetActionEac",{},u)};s.AMT_AgentPresenceWatchdogVA_RegisterAgent=function(u){s.Exec("AMT_AgentPresenceWatchdogVA","RegisterAgent",{},u)};s.AMT_AgentPresenceWatchdogVA_AssertPresence=function(v,u){s.Exec("AMT_AgentPresenceWatchdogVA","AssertPresence",{SequenceNumber:v},u)};s.AMT_AgentPresenceWatchdogVA_AssertShutdown=function(v,u){s.Exec("AMT_AgentPresenceWatchdogVA","AssertShutdown",{SequenceNumber:v},u)};s.AMT_AgentPresenceWatchdogVA_AddAction=function(z,y,x,v,u,w){s.Exec("AMT_AgentPresenceWatchdogVA","AddAction",{OldState:z,NewState:y,EventOnTransition:x,ActionSd:v,ActionEac:u},w)};s.AMT_AgentPresenceWatchdogVA_DeleteAllActions=function(u,v){s.Exec("AMT_AgentPresenceWatchdogVA","DeleteAllActions",{_method_dummy:u},v)};s.AMT_AuditLog_ClearLog=function(u){s.Exec("AMT_AuditLog","ClearLog",{},u)};s.AMT_AuditLog_RequestStateChange=function(v,w,u){s.Exec("AMT_AuditLog","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AMT_AuditLog_ReadRecords=function(v,u,w){s.Exec("AMT_AuditLog","ReadRecords",{StartIndex:v},u,w)};s.AMT_AuditLog_SetAuditLock=function(x,v,w,u){s.Exec("AMT_AuditLog","SetAuditLock",{LockTimeoutInSeconds:x,Flag:v,Handle:w},u)};s.AMT_AuditLog_ExportAuditLogSignature=function(v,u){s.Exec("AMT_AuditLog","ExportAuditLogSignature",{SigningMechanism:v},u)};s.AMT_AuditLog_SetSigningKeyMaterial=function(y,x,w,v,u){s.Exec("AMT_AuditLog","SetSigningKeyMaterial",{SigningMechanismType:y,SigningKey:x,LengthOfCertificates:w,Certificates:v},u)};s.AMT_AuditPolicyRule_SetAuditPolicy=function(w,u,x,y,v){s.Exec("AMT_AuditPolicyRule","SetAuditPolicy",{Enable:w,AuditedAppID:u,EventID:x,PolicyType:y},v)};s.AMT_AuditPolicyRule_SetAuditPolicyBulk=function(w,u,x,y,v){s.Exec("AMT_AuditPolicyRule","SetAuditPolicyBulk",{Enable:w,AuditedAppID:u,EventID:x,PolicyType:y},v)};s.AMT_AuthorizationService_AddUserAclEntryEx=function(x,w,y,u,z,v){s.Exec("AMT_AuthorizationService","AddUserAclEntryEx",{DigestUsername:x,DigestPassword:w,KerberosUserSid:y,AccessPermission:u,Realms:z},v)};s.AMT_AuthorizationService_EnumerateUserAclEntries=function(v,u){s.Exec("AMT_AuthorizationService","EnumerateUserAclEntries",{StartIndex:v},u)};s.AMT_AuthorizationService_GetUserAclEntryEx=function(v,u,w){s.Exec("AMT_AuthorizationService","GetUserAclEntryEx",{Handle:v},u,w)};s.AMT_AuthorizationService_UpdateUserAclEntryEx=function(y,x,w,z,u,A,v){s.Exec("AMT_AuthorizationService","UpdateUserAclEntryEx",{Handle:y,DigestUsername:x,DigestPassword:w,KerberosUserSid:z,AccessPermission:u,Realms:A},v)};s.AMT_AuthorizationService_RemoveUserAclEntry=function(v,u){s.Exec("AMT_AuthorizationService","RemoveUserAclEntry",{Handle:v},u)};s.AMT_AuthorizationService_SetAdminAclEntryEx=function(w,v,u){s.Exec("AMT_AuthorizationService","SetAdminAclEntryEx",{Username:w,DigestPassword:v},u)};s.AMT_AuthorizationService_GetAdminAclEntry=function(u){s.Exec("AMT_AuthorizationService","GetAdminAclEntry",{},u)};s.AMT_AuthorizationService_GetAdminAclEntryStatus=function(u){s.Exec("AMT_AuthorizationService","GetAdminAclEntryStatus",{},u)};s.AMT_AuthorizationService_GetAdminNetAclEntryStatus=function(u){s.Exec("AMT_AuthorizationService","GetAdminNetAclEntryStatus",{},u)};s.AMT_AuthorizationService_SetAclEnabledState=function(w,v,u,x){s.Exec("AMT_AuthorizationService","SetAclEnabledState",{Handle:w,Enabled:v},u,x)};s.AMT_AuthorizationService_GetAclEnabledState=function(v,u,w){s.Exec("AMT_AuthorizationService","GetAclEnabledState",{Handle:v},u,w)};s.AMT_EndpointAccessControlService_RequestStateChange=function(v,w,u){s.Exec("AMT_EndpointAccessControlService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AMT_EndpointAccessControlService_GetPosture=function(v,u){s.Exec("AMT_EndpointAccessControlService","GetPosture",{PostureType:v},u)};s.AMT_EndpointAccessControlService_GetPostureHash=function(v,u){s.Exec("AMT_EndpointAccessControlService","GetPostureHash",{PostureType:v},u)};s.AMT_EndpointAccessControlService_UpdatePostureState=function(v,u){s.Exec("AMT_EndpointAccessControlService","UpdatePostureState",{UpdateType:v},u)};s.AMT_EndpointAccessControlService_GetEacOptions=function(u){s.Exec("AMT_EndpointAccessControlService","GetEacOptions",{},u)};s.AMT_EndpointAccessControlService_SetEacOptions=function(v,w,u){s.Exec("AMT_EndpointAccessControlService","SetEacOptions",{EacVendors:v,PostureHashAlgorithm:w},u)};s.AMT_EnvironmentDetectionSettingData_SetSystemDefensePolicy=function(v,u){s.Exec("AMT_EnvironmentDetectionSettingData","SetSystemDefensePolicy",{Policy:v},u)};s.AMT_EnvironmentDetectionSettingData_EnableVpnRouting=function(v,u){s.Exec("AMT_EnvironmentDetectionSettingData","EnableVpnRouting",{Enable:v},u)};s.AMT_EthernetPortSettings_SetLinkPreference=function(v,w,u){s.Exec("AMT_EthernetPortSettings","SetLinkPreference",{LinkPreference:v,Timeout:w},u)};s.AMT_HeuristicPacketFilterStatistics_ResetSelectedStats=function(v,u){s.Exec("AMT_HeuristicPacketFilterStatistics","ResetSelectedStats",{SelectedStatistics:v},u)};s.AMT_KerberosSettingData_GetCredentialCacheState=function(u){s.Exec("AMT_KerberosSettingData","GetCredentialCacheState",{},u)};s.AMT_KerberosSettingData_SetCredentialCacheState=function(v,u){s.Exec("AMT_KerberosSettingData","SetCredentialCacheState",{Enable:v},u)};s.AMT_MessageLog_CancelIteration=function(v,u){s.Exec("AMT_MessageLog","CancelIteration",{IterationIdentifier:v},u)};s.AMT_MessageLog_RequestStateChange=function(v,w,u){s.Exec("AMT_MessageLog","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AMT_MessageLog_ClearLog=function(u){s.Exec("AMT_MessageLog","ClearLog",{},u)};s.AMT_MessageLog_GetRecords=function(v,w,u,x){s.Exec("AMT_MessageLog","GetRecords",{IterationIdentifier:v,MaxReadRecords:w},u,x)};s.AMT_MessageLog_GetRecord=function(v,w,u){s.Exec("AMT_MessageLog","GetRecord",{IterationIdentifier:v,PositionToNext:w},u)};s.AMT_MessageLog_PositionAtRecord=function(v,w,x,u){s.Exec("AMT_MessageLog","PositionAtRecord",{IterationIdentifier:v,MoveAbsolute:w,RecordNumber:x},u)};s.AMT_MessageLog_PositionToFirstRecord=function(u,v){s.Exec("AMT_MessageLog","PositionToFirstRecord",{},u,v)};s.AMT_MessageLog_FreezeLog=function(v,u){s.Exec("AMT_MessageLog","FreezeLog",{Freeze:v},u)};s.AMT_PublicKeyManagementService_AddCRL=function(w,v,u){s.Exec("AMT_PublicKeyManagementService","AddCRL",{Url:w,SerialNumbers:v},u)};s.AMT_PublicKeyManagementService_ResetCRLList=function(u,v){s.Exec("AMT_PublicKeyManagementService","ResetCRLList",{_method_dummy:u},v)};s.AMT_PublicKeyManagementService_AddCertificate=function(v,u){s.Exec("AMT_PublicKeyManagementService","AddCertificate",{CertificateBlob:v},u)};s.AMT_PublicKeyManagementService_AddTrustedRootCertificate=function(v,u){s.Exec("AMT_PublicKeyManagementService","AddTrustedRootCertificate",{CertificateBlob:v},u)};s.AMT_PublicKeyManagementService_AddKey=function(v,u){s.Exec("AMT_PublicKeyManagementService","AddKey",{KeyBlob:v},u)};s.AMT_PublicKeyManagementService_GeneratePKCS10Request=function(w,v,x,u){s.Exec("AMT_PublicKeyManagementService","GeneratePKCS10Request",{KeyPair:w,DNName:v,Usage:x},u)};s.AMT_PublicKeyManagementService_GeneratePKCS10RequestEx=function(v,x,w,u){s.Exec("AMT_PublicKeyManagementService","GeneratePKCS10RequestEx",{KeyPair:v,SigningAlgorithm:x,NullSignedCertificateRequest:w},u)};s.AMT_PublicKeyManagementService_GenerateKeyPair=function(v,w,u){s.Exec("AMT_PublicKeyManagementService","GenerateKeyPair",{KeyAlgorithm:v,KeyLength:w},u)};s.AMT_RedirectionService_RequestStateChange=function(v,u){s.Exec("AMT_RedirectionService","RequestStateChange",{RequestedState:v},u)};s.AMT_RedirectionService_TerminateSession=function(v,u){s.Exec("AMT_RedirectionService","TerminateSession",{SessionType:v},u)};s.AMT_RemoteAccessService_AddMpServer=function(u,z,B,v,x,C,A,y,w){s.Exec("AMT_RemoteAccessService","AddMpServer",{AccessInfo:u,InfoFormat:z,Port:B,AuthMethod:v,Certificate:x,Username:C,Password:A,CN:y},w)};s.AMT_RemoteAccessService_AddRemoteAccessPolicyRule=function(x,y,v,w,u){s.Exec("AMT_RemoteAccessService","AddRemoteAccessPolicyRule",{Trigger:x,TunnelLifeTime:y,ExtendedData:v,MpServer:w},u)};s.AMT_RemoteAccessService_CloseRemoteAccessConnection=function(u,v){s.Exec("AMT_RemoteAccessService","CloseRemoteAccessConnection",{_method_dummy:u},v)};s.AMT_SetupAndConfigurationService_CommitChanges=function(u,v){s.Exec("AMT_SetupAndConfigurationService","CommitChanges",{_method_dummy:u},v)};s.AMT_SetupAndConfigurationService_Unprovision=function(v,u){s.Exec("AMT_SetupAndConfigurationService","Unprovision",{ProvisioningMode:v},u)};s.AMT_SetupAndConfigurationService_PartialUnprovision=function(u,v){s.Exec("AMT_SetupAndConfigurationService","PartialUnprovision",{_method_dummy:u},v)};s.AMT_SetupAndConfigurationService_ResetFlashWearOutProtection=function(u,v){s.Exec("AMT_SetupAndConfigurationService","ResetFlashWearOutProtection",{_method_dummy:u},v)};s.AMT_SetupAndConfigurationService_ExtendProvisioningPeriod=function(v,u){s.Exec("AMT_SetupAndConfigurationService","ExtendProvisioningPeriod",{Duration:v},u)};s.AMT_SetupAndConfigurationService_SetMEBxPassword=function(v,u){s.Exec("AMT_SetupAndConfigurationService","SetMEBxPassword",{Password:v},u)};s.AMT_SetupAndConfigurationService_SetTLSPSK=function(v,w,u){s.Exec("AMT_SetupAndConfigurationService","SetTLSPSK",{PID:v,PPS:w},u)};s.AMT_SetupAndConfigurationService_GetProvisioningAuditRecord=function(u){s.Exec("AMT_SetupAndConfigurationService","GetProvisioningAuditRecord",{},u)};s.AMT_SetupAndConfigurationService_GetUuid=function(u){s.Exec("AMT_SetupAndConfigurationService","GetUuid",{},u)};s.AMT_SetupAndConfigurationService_GetUnprovisionBlockingComponents=function(u){s.Exec("AMT_SetupAndConfigurationService","GetUnprovisionBlockingComponents",{},u)};s.AMT_SetupAndConfigurationService_GetProvisioningAuditRecordV2=function(u){s.Exec("AMT_SetupAndConfigurationService","GetProvisioningAuditRecordV2",{},u)};s.AMT_SystemDefensePolicy_GetTimeout=function(u){s.Exec("AMT_SystemDefensePolicy","GetTimeout",{},u)};s.AMT_SystemDefensePolicy_SetTimeout=function(v,u){s.Exec("AMT_SystemDefensePolicy","SetTimeout",{Timeout:v},u)};s.AMT_SystemDefensePolicy_UpdateStatistics=function(v,x,u,z,w,y){s.Exec("AMT_SystemDefensePolicy","UpdateStatistics",{NetworkInterface:v,ResetOnRead:x},u,z,w,y)};s.AMT_SystemPowerScheme_SetPowerScheme=function(u,v,w){s.Exec("AMT_SystemPowerScheme","SetPowerScheme",{},u,w,0,{InstanceID:v})};s.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch=function(u,v){s.Exec("AMT_TimeSynchronizationService","GetLowAccuracyTimeSynch",{},u,v)};s.AMT_TimeSynchronizationService_SetHighAccuracyTimeSynch=function(v,x,y,u,w){s.Exec("AMT_TimeSynchronizationService","SetHighAccuracyTimeSynch",{Ta0:v,Tm1:x,Tm2:y},u,w)};s.AMT_UserInitiatedConnectionService_RequestStateChange=function(v,w,u){s.Exec("AMT_UserInitiatedConnectionService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AMT_WebUIService_RequestStateChange=function(v,w,u){s.Exec("AMT_WebUIService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AMT_WiFiPortConfigurationService_AddWiFiSettings=function(y,z,x,w,u,v){s.ExecWithXml("AMT_WiFiPortConfigurationService","AddWiFiSettings",{WiFiEndpoint:y,WiFiEndpointSettingsInput:z,IEEE8021xSettingsInput:x,ClientCredential:w,CACredential:u},v)};s.AMT_WiFiPortConfigurationService_UpdateWiFiSettings=function(y,z,x,w,u,v){s.ExecWithXml("AMT_WiFiPortConfigurationService","UpdateWiFiSettings",{WiFiEndpointSettings:y,WiFiEndpointSettingsInput:z,IEEE8021xSettingsInput:x,ClientCredential:w,CACredential:u},v)};s.AMT_WiFiPortConfigurationService_DeleteAllITProfiles=function(u,v){s.Exec("AMT_WiFiPortConfigurationService","DeleteAllITProfiles",{_method_dummy:u},v)};s.AMT_WiFiPortConfigurationService_DeleteAllUserProfiles=function(u,v){s.Exec("AMT_WiFiPortConfigurationService","DeleteAllUserProfiles",{_method_dummy:u},v)};s.CIM_Account_RequestStateChange=function(v,w,u){s.Exec("CIM_Account","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_AccountManagementService_CreateAccount=function(w,u,v){s.Exec("CIM_AccountManagementService","CreateAccount",{System:w,AccountTemplate:u},v)};s.CIM_BootConfigSetting_ChangeBootOrder=function(v,u){s.Exec("CIM_BootConfigSetting","ChangeBootOrder",{Source:v},u)};s.CIM_BootService_SetBootConfigRole=function(u,w,v){s.Exec("CIM_BootService","SetBootConfigRole",{BootConfigSetting:u,Role:w},v,0,1)};s.CIM_Card_ConnectorPower=function(v,w,u){s.Exec("CIM_Card","ConnectorPower",{Connector:v,PoweredOn:w},u)};s.CIM_Card_IsCompatible=function(v,u){s.Exec("CIM_Card","IsCompatible",{ElementToCheck:v},u)};s.CIM_Chassis_IsCompatible=function(v,u){s.Exec("CIM_Chassis","IsCompatible",{ElementToCheck:v},u)};s.CIM_Fan_SetSpeed=function(v,u){s.Exec("CIM_Fan","SetSpeed",{DesiredSpeed:v},u)};s.CIM_KVMRedirectionSAP_RequestStateChange=function(v,w,u){s.Exec("CIM_KVMRedirectionSAP","RequestStateChange",{RequestedState:v},u)};s.CIM_MediaAccessDevice_LockMedia=function(v,u){s.Exec("CIM_MediaAccessDevice","LockMedia",{Lock:v},u)};s.CIM_MediaAccessDevice_SetPowerState=function(v,w,u){s.Exec("CIM_MediaAccessDevice","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_MediaAccessDevice_Reset=function(u){s.Exec("CIM_MediaAccessDevice","Reset",{},u)};s.CIM_MediaAccessDevice_EnableDevice=function(v,u){s.Exec("CIM_MediaAccessDevice","EnableDevice",{Enabled:v},u)};s.CIM_MediaAccessDevice_OnlineDevice=function(v,u){s.Exec("CIM_MediaAccessDevice","OnlineDevice",{Online:v},u)};s.CIM_MediaAccessDevice_QuiesceDevice=function(v,u){s.Exec("CIM_MediaAccessDevice","QuiesceDevice",{Quiesce:v},u)};s.CIM_MediaAccessDevice_SaveProperties=function(u){s.Exec("CIM_MediaAccessDevice","SaveProperties",{},u)};s.CIM_MediaAccessDevice_RestoreProperties=function(u){s.Exec("CIM_MediaAccessDevice","RestoreProperties",{},u)};s.CIM_MediaAccessDevice_RequestStateChange=function(v,w,u){s.Exec("CIM_MediaAccessDevice","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_PhysicalFrame_IsCompatible=function(v,u){s.Exec("CIM_PhysicalFrame","IsCompatible",{ElementToCheck:v},u)};s.CIM_PhysicalPackage_IsCompatible=function(v,u){s.Exec("CIM_PhysicalPackage","IsCompatible",{ElementToCheck:v},u)};s.CIM_PowerManagementService_RequestPowerStateChange=function(w,v,x,y,u){s.Exec("CIM_PowerManagementService","RequestPowerStateChange",{PowerState:w,ManagedElement:v,Time:x,TimeoutPeriod:y},u,0,1)};s.CIM_PowerSupply_SetPowerState=function(v,w,u){s.Exec("CIM_PowerSupply","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_PowerSupply_Reset=function(u){s.Exec("CIM_PowerSupply","Reset",{},u)};s.CIM_PowerSupply_EnableDevice=function(v,u){s.Exec("CIM_PowerSupply","EnableDevice",{Enabled:v},u)};s.CIM_PowerSupply_OnlineDevice=function(v,u){s.Exec("CIM_PowerSupply","OnlineDevice",{Online:v},u)};s.CIM_PowerSupply_QuiesceDevice=function(v,u){s.Exec("CIM_PowerSupply","QuiesceDevice",{Quiesce:v},u)};s.CIM_PowerSupply_SaveProperties=function(u){s.Exec("CIM_PowerSupply","SaveProperties",{},u)};s.CIM_PowerSupply_RestoreProperties=function(u){s.Exec("CIM_PowerSupply","RestoreProperties",{},u)};s.CIM_PowerSupply_RequestStateChange=function(v,w,u){s.Exec("CIM_PowerSupply","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_Processor_SetPowerState=function(v,w,u){s.Exec("CIM_Processor","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_Processor_Reset=function(u){s.Exec("CIM_Processor","Reset",{},u)};s.CIM_Processor_EnableDevice=function(v,u){s.Exec("CIM_Processor","EnableDevice",{Enabled:v},u)};s.CIM_Processor_OnlineDevice=function(v,u){s.Exec("CIM_Processor","OnlineDevice",{Online:v},u)};s.CIM_Processor_QuiesceDevice=function(v,u){s.Exec("CIM_Processor","QuiesceDevice",{Quiesce:v},u)};s.CIM_Processor_SaveProperties=function(u){s.Exec("CIM_Processor","SaveProperties",{},u)};s.CIM_Processor_RestoreProperties=function(u){s.Exec("CIM_Processor","RestoreProperties",{},u)};s.CIM_Processor_RequestStateChange=function(v,w,u){s.Exec("CIM_Processor","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_RecordLog_ClearLog=function(u){s.Exec("CIM_RecordLog","ClearLog",{},u)};s.CIM_RecordLog_RequestStateChange=function(v,w,u){s.Exec("CIM_RecordLog","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_RedirectionService_RequestStateChange=function(v,w,u){s.Exec("CIM_RedirectionService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_Sensor_SetPowerState=function(v,w,u){s.Exec("CIM_Sensor","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_Sensor_Reset=function(u){s.Exec("CIM_Sensor","Reset",{},u)};s.CIM_Sensor_EnableDevice=function(v,u){s.Exec("CIM_Sensor","EnableDevice",{Enabled:v},u)};s.CIM_Sensor_OnlineDevice=function(v,u){s.Exec("CIM_Sensor","OnlineDevice",{Online:v},u)};s.CIM_Sensor_QuiesceDevice=function(v,u){s.Exec("CIM_Sensor","QuiesceDevice",{Quiesce:v},u)};s.CIM_Sensor_SaveProperties=function(u){s.Exec("CIM_Sensor","SaveProperties",{},u)};s.CIM_Sensor_RestoreProperties=function(u){s.Exec("CIM_Sensor","RestoreProperties",{},u)};s.CIM_Sensor_RequestStateChange=function(v,w,u){s.Exec("CIM_Sensor","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_StatisticalData_ResetSelectedStats=function(v,u){s.Exec("CIM_StatisticalData","ResetSelectedStats",{SelectedStatistics:v},u)};s.CIM_Watchdog_KeepAlive=function(u){s.Exec("CIM_Watchdog","KeepAlive",{},u)};s.CIM_Watchdog_SetPowerState=function(v,w,u){s.Exec("CIM_Watchdog","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_Watchdog_Reset=function(u){s.Exec("CIM_Watchdog","Reset",{},u)};s.CIM_Watchdog_EnableDevice=function(v,u){s.Exec("CIM_Watchdog","EnableDevice",{Enabled:v},u)};s.CIM_Watchdog_OnlineDevice=function(v,u){s.Exec("CIM_Watchdog","OnlineDevice",{Online:v},u)};s.CIM_Watchdog_QuiesceDevice=function(v,u){s.Exec("CIM_Watchdog","QuiesceDevice",{Quiesce:v},u)};s.CIM_Watchdog_SaveProperties=function(u){s.Exec("CIM_Watchdog","SaveProperties",{},u)};s.CIM_Watchdog_RestoreProperties=function(u){s.Exec("CIM_Watchdog","RestoreProperties",{},u)};s.CIM_Watchdog_RequestStateChange=function(v,w,u){s.Exec("CIM_Watchdog","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.CIM_WiFiPort_SetPowerState=function(v,w,u){s.Exec("CIM_WiFiPort","SetPowerState",{PowerState:v,Time:w},u)};s.CIM_WiFiPort_Reset=function(u){s.Exec("CIM_WiFiPort","Reset",{},u)};s.CIM_WiFiPort_EnableDevice=function(v,u){s.Exec("CIM_WiFiPort","EnableDevice",{Enabled:v},u)};s.CIM_WiFiPort_OnlineDevice=function(v,u){s.Exec("CIM_WiFiPort","OnlineDevice",{Online:v},u)};s.CIM_WiFiPort_QuiesceDevice=function(v,u){s.Exec("CIM_WiFiPort","QuiesceDevice",{Quiesce:v},u)};s.CIM_WiFiPort_SaveProperties=function(u){s.Exec("CIM_WiFiPort","SaveProperties",{},u)};s.CIM_WiFiPort_RestoreProperties=function(u){s.Exec("CIM_WiFiPort","RestoreProperties",{},u)};s.CIM_WiFiPort_RequestStateChange=function(v,w,u){s.Exec("CIM_WiFiPort","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.IPS_HostBasedSetupService_Setup=function(y,z,x,v,A,w,u){s.Exec("IPS_HostBasedSetupService","Setup",{NetAdminPassEncryptionType:y,NetworkAdminPassword:z,McNonce:x,Certificate:v,SigningAlgorithm:A,DigitalSignature:w},u)};s.IPS_HostBasedSetupService_AddNextCertInChain=function(x,v,w,u){s.Exec("IPS_HostBasedSetupService","AddNextCertInChain",{NextCertificate:x,IsLeafCertificate:v,IsRootCertificate:w},u)};s.IPS_HostBasedSetupService_AdminSetup=function(x,y,w,z,v,u){s.Exec("IPS_HostBasedSetupService","AdminSetup",{NetAdminPassEncryptionType:x,NetworkAdminPassword:y,McNonce:w,SigningAlgorithm:z,DigitalSignature:v},u)};s.IPS_HostBasedSetupService_UpgradeClientToAdmin=function(w,x,v,u){s.Exec("IPS_HostBasedSetupService","UpgradeClientToAdmin",{McNonce:w,SigningAlgorithm:x,DigitalSignature:v},u)};s.IPS_HostBasedSetupService_DisableClientControlMode=function(u,v){s.Exec("IPS_HostBasedSetupService","DisableClientControlMode",{_method_dummy:u},v)};s.IPS_KVMRedirectionSettingData_TerminateSession=function(u){s.Exec("IPS_KVMRedirectionSettingData","TerminateSession",{},u)};s.IPS_OptInService_StartOptIn=function(u){s.Exec("IPS_OptInService","StartOptIn",{},u)};s.IPS_OptInService_CancelOptIn=function(u){s.Exec("IPS_OptInService","CancelOptIn",{},u)};s.IPS_OptInService_SendOptInCode=function(v,u){s.Exec("IPS_OptInService","SendOptInCode",{OptInCode:v},u)};s.IPS_OptInService_StartService=function(u){s.Exec("IPS_OptInService","StartService",{},u)};s.IPS_OptInService_StopService=function(u){s.Exec("IPS_OptInService","StopService",{},u)};s.IPS_OptInService_RequestStateChange=function(v,w,u){s.Exec("IPS_OptInService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.IPS_ProvisioningRecordLog_RequestStateChange=function(v,w,u){s.Exec("IPS_ProvisioningRecordLog","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.IPS_ProvisioningRecordLog_ClearLog=function(u,v){s.Exec("IPS_ProvisioningRecordLog","ClearLog",{_method_dummy:u},v)};s.IPS_SecIOService_RequestStateChange=function(v,w,u){s.Exec("IPS_SecIOService","RequestStateChange",{RequestedState:v,TimeoutPeriod:w},u)};s.AmtStatusToStr=function(u){if(s.AmtStatusCodes[u]){return s.AmtStatusCodes[u]}else{return"UNKNOWN_ERROR"}};s.AmtStatusCodes={0:"SUCCESS",1:"INTERNAL_ERROR",2:"NOT_READY",3:"INVALID_PT_MODE",4:"INVALID_MESSAGE_LENGTH",5:"TABLE_FINGERPRINT_NOT_AVAILABLE",6:"INTEGRITY_CHECK_FAILED",7:"UNSUPPORTED_ISVS_VERSION",8:"APPLICATION_NOT_REGISTERED",9:"INVALID_REGISTRATION_DATA",10:"APPLICATION_DOES_NOT_EXIST",11:"NOT_ENOUGH_STORAGE",12:"INVALID_NAME",13:"BLOCK_DOES_NOT_EXIST",14:"INVALID_BYTE_OFFSET",15:"INVALID_BYTE_COUNT",16:"NOT_PERMITTED",17:"NOT_OWNER",18:"BLOCK_LOCKED_BY_OTHER",19:"BLOCK_NOT_LOCKED",20:"INVALID_GROUP_PERMISSIONS",21:"GROUP_DOES_NOT_EXIST",22:"INVALID_MEMBER_COUNT",23:"MAX_LIMIT_REACHED",24:"INVALID_AUTH_TYPE",25:"AUTHENTICATION_FAILED",26:"INVALID_DHCP_MODE",27:"INVALID_IP_ADDRESS",28:"INVALID_DOMAIN_NAME",29:"UNSUPPORTED_VERSION",30:"REQUEST_UNEXPECTED",31:"INVALID_TABLE_TYPE",32:"INVALID_PROVISIONING_STATE",33:"UNSUPPORTED_OBJECT",34:"INVALID_TIME",35:"INVALID_INDEX",36:"INVALID_PARAMETER",37:"INVALID_NETMASK",38:"FLASH_WRITE_LIMIT_EXCEEDED",39:"INVALID_IMAGE_LENGTH",40:"INVALID_IMAGE_SIGNATURE",41:"PROPOSE_ANOTHER_VERSION",42:"INVALID_PID_FORMAT",43:"INVALID_PPS_FORMAT",44:"BIST_COMMAND_BLOCKED",45:"CONNECTION_FAILED",46:"CONNECTION_TOO_MANY",47:"RNG_GENERATION_IN_PROGRESS",48:"RNG_NOT_READY",49:"CERTIFICATE_NOT_READY",1024:"DISABLED_BY_POLICY",2048:"NETWORK_IF_ERROR_BASE",2049:"UNSUPPORTED_OEM_NUMBER",2050:"UNSUPPORTED_BOOT_OPTION",2051:"INVALID_COMMAND",2052:"INVALID_SPECIAL_COMMAND",2053:"INVALID_HANDLE",2054:"INVALID_PASSWORD",2055:"INVALID_REALM",2056:"STORAGE_ACL_ENTRY_IN_USE",2057:"DATA_MISSING",2058:"DUPLICATE",2059:"EVENTLOG_FROZEN",2060:"PKI_MISSING_KEYS",2061:"PKI_GENERATING_KEYS",2062:"INVALID_KEY",2063:"INVALID_CERT",2064:"CERT_KEY_NOT_MATCH",2065:"MAX_KERB_DOMAIN_REACHED",2066:"UNSUPPORTED",2067:"INVALID_PRIORITY",2068:"NOT_FOUND",2069:"INVALID_CREDENTIALS",2070:"INVALID_PASSPHRASE",2072:"NO_ASSOCIATION",2075:"AUDIT_FAIL",2076:"BLOCKING_COMPONENT",2081:"USER_CONSENT_REQUIRED",4096:"APP_INTERNAL_ERROR",4097:"NOT_INITIALIZED",4098:"LIB_VERSION_UNSUPPORTED",4099:"INVALID_PARAM",4100:"RESOURCES",4101:"HARDWARE_ACCESS_ERROR",4102:"REQUESTOR_NOT_REGISTERED",4103:"NETWORK_ERROR",4104:"PARAM_BUFFER_TOO_SHORT",4105:"COM_NOT_INITIALIZED_IN_THREAD",4106:"URL_REQUIRED"};s.GetMessageLog=function(u,v){s.AMT_MessageLog_PositionToFirstRecord(k,[u,v,[]])};function k(w,u,v,x,y){if(x!=200||v.Body.ReturnValue!="0"){y[0](s,null,y[2]);return}s.AMT_MessageLog_GetRecords(v.Body.IterationIdentifier,390,l,y)}function l(D,A,C,E,G){if(E!=200||C.Body.ReturnValue!="0"){G[0](s,null,G[2]);return}var y,z,I,v,u=G[2],F=new Date(),H,B=C.Body.RecordArray;if(typeof B==="string"){C.Body.RecordArray=[C.Body.RecordArray]}for(y in B){v=null;try{v=window.atob(B[y])}catch(w){}if(v!=null){H=ReadIntX(v,0);if((H>0)&&(H<4294967295)){I={DeviceAddress:v.charCodeAt(4),EventSensorType:v.charCodeAt(5),EventType:v.charCodeAt(6),EventOffset:v.charCodeAt(7),EventSourceType:v.charCodeAt(8),EventSeverity:v.charCodeAt(9),SensorNumber:v.charCodeAt(10),Entity:v.charCodeAt(11),EntityInstance:v.charCodeAt(12),EventData:[],Time:new Date((H+(F.getTimezoneOffset()*60))*1000)};for(z=13;z<21;z++){I.EventData.push(v.charCodeAt(z))}I.EntityStr=o[I.Entity];I.Desc=j(I.EventSensorType,I.EventOffset,I.EventData,I.Entity);if(!I.EntityStr){I.EntityStr="Unknown"}u.push(I)}}}if(C.Body.NoMoreRecords!=true){s.AMT_MessageLog_GetRecords(C.Body.IterationIdentifier,390,l,[G[0],u,G[2]])}else{G[0](s,u,G[2])}}var e="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 p="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 q="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 o="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("|");s.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("|");s.WatchdogCurrentStates={1:"Not Started",2:"Stopped",4:"Running",8:"Expired",16:"Suspended"};function j(x,w,v,u){if(x==15){if(v[0]==235){return"Invalid Data"}if(w==0){return p[v[1]]}return q[v[1]]}if(x==18&&v[0]==170){return"Agent watchdog "+char2hex(v[4])+char2hex(v[3])+char2hex(v[2])+char2hex(v[1])+"-"+char2hex(v[6])+char2hex(v[5])+"-... changed to "+s.WatchdogCurrentStates[v[7]]}if(x==6){return"Authentication failed "+(v[1]+(v[2]<<8))+" times. The system may be under attack."}if(x==30){return"No bootable media"}if(x==32){return"Operating system lockup or power interrupt"}if(x==35){return"System boot failure"}if(x==37){return"System firmware started (at least one CPU is properly executing)."}return"Unknown Sensor Type #"+x}return s}var md5_k=[];for(var i=0;i<64;){md5_k[i]=0|(Math.abs(Math.sin(++i))*4294967296)}function hex_md5(p){var g,k,l,o,r=[],q=unescape(encodeURI(p)),e=q.length,m=[g=1732584193,k=-271733879,~g,~k],n=0;for(;n<=e;){r[n>>2]|=(q.charCodeAt(n)||128)<<8*(n++%4)}r[p=(e+8>>6)*16+14]=e*8;n=0;for(;n<p;n+=16){e=m;o=0;for(;o<64;){e=[l=e[3],((g=e[1]|0)+((l=((e[0]+[g&(k=e[2])|~g&l,l&g|~l&k,g^k^l,k^(g|~l)][e=o>>4])+(md5_k[o]+(r[[o,5*o+1,3*o+5,7*o][e]%16+n]|0))))<<(e=[7,12,17,22,5,9,14,20,4,11,16,23,6,10,15,21][4*e+o++%4])|l>>>32-e)),g,k]}for(o=4;o;){m[--o]=m[o]+e[o]}}p="";for(;o<32;){p+=((m[o>>3]>>((1^o++&7)*4))&15).toString(16)}return p}function rstr_md5(a){return hex2rstr(hex_md5(a))}function execArgumentsToXml(c){if(c===undefined||c===null){return null}var d="";for(var b in c){var a=c[b];if(!a){continue}if(a.__parameterType==="reference"){d+=referenceToXml(b,a)}else{d+=instanceToXml(b,a)}}return d}function instanceToXml(d,c){if(c===undefined||c===null){return null}var b=!!c.__namespace;var j=b?"<q:":"<";var a=b?"</q:":"</";var e=b?(' xmlns:q="'+c.__namespace+'"'):"";var h="<r:"+d+e+">";for(var g in c){if(!c.hasOwnProperty(g)||g.indexOf("__")===0){continue}if(typeof c[g]==="function"||Array.isArray(c[g])){continue}if(typeof c[g]==="object"){console.error("only convert one level down...")}else{h+=j+g+">"+c[g].toString()+a+g+">"}}h+="</r:"+d+">";return h}function referenceToXml(b,a){if(a===undefined||a===null){return null}var c="<r:"+b+"><a:Address>/wsman</a:Address><a:ReferenceParameters><w:ResourceURI>"+a.__resourceUri+"</w:ResourceURI><w:SelectorSet>";for(var d in a){if(!a.hasOwnProperty(d)||d.indexOf("__")===0){continue}if(typeof a[d]==="function"||typeof a[d]==="object"||Array.isArray(a[d])){continue}c+='<w:Selector Name="'+d+'">'+a[d].toString()+"</w:Selector>"}c+="</w:SelectorSet></a:ReferenceParameters></r:"+b+">";return c}function GetSidString(c){var b="S-"+c.charCodeAt(0)+"-"+c.charCodeAt(7);for(var a=2;a<(c.length/4);a++){b+="-"+ReadIntX(c,a*4)}return b}function GetSidByteArray(d){if(!d||d==null){return null}var c=d.split("-");if(c.length<4||(c[0]!="s"&&c[0]!="S")){return null}for(var a=1;a<c.length;a++){var e=parseInt(c[a]);if(e!=c[a]){return null}c[a]=e}var b=String.fromCharCode(c[1])+String.fromCharCode(c.length-3)+ShortToStr(Math.floor(c[2]/Math.pow(2,32)))+IntToStr((c[2])&65535);for(var a=3;a<c.length;a++){b+=IntToStrX(c[a])}return b}var WsmanStackCreateService=function(h,l,n,k,m,g){var j={};j.NextMessageId=1;j.Address="/wsman";j.comm=CreateWsmanComm(h,l,n,k,m,g);j.PerformAjax=function(q,o,s,r,p){if(p==undefined){p=""}j.comm.PerformAjax('<?xml version="1.0" encoding="utf-8"?><Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns="http://www.w3.org/2003/05/soap-envelope" '+p+"><Header><a:Action>"+q,function(t,u,v){if(u!=200){o(j,null,{Header:{HttpError:u}},u,v);return}var w=j.ParseWsman(t);if(!w||w==null){o(j,null,{Header:{HttpError:u}},601,v)}else{o(j,w.Header.ResourceURI,w,200,v)}},s,r)};j.CancelAllQueries=function(o){j.comm.CancelAllQueries(o)};j.GetNameFromUrl=function(o){var p=o.lastIndexOf("/");return(p==-1)?o:o.substring(p+1)};j.ExecSubscribe=function(w,q,z,o,y,v,x,t,A,u){var r="",s="";if(A!=undefined&&u!=undefined){r="<t:IssuedTokens><t:RequestSecurityTokenResponse><t:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</t:TokenType><t:RequestedSecurityToken><se:UsernameToken><se:Username>"+A+'</se:Username><se:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText">'+u+"</se:Password></se:UsernameToken></t:RequestedSecurityToken></t:RequestSecurityTokenResponse></t:IssuedTokens>";s='<Auth Profile="http://schemas.xmlsoap.org/ws/2004/08/eventing/DeliveryModes/secprofile/http/digest"/>'}if(t!=undefined&&t!=null){t="<a:ReferenceParameters>"+t+"</a:ReferenceParameters>"}else{t=""}var p="http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+w+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>"+d(x)+r+'</Header><Body><e:Subscribe><e:Delivery Mode="http://schemas.dmtf.org/wbem/wsman/1/wsman/'+q+'"><e:NotifyTo><a:Address>'+z+"</a:Address></e:NotifyTo>"+s+"</e:Delivery><e:Expires>PT0.000000S</e:Expires></e:Subscribe>";j.PerformAjax(p+"</Body></Envelope>",o,y,v,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:se="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:m="http://x.com"')};j.ExecUnSubscribe=function(r,o,t,q,s){var p="http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+r+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>"+d(s)+"</Header><Body><e:Unsubscribe/>";j.PerformAjax(p+"</Body></Envelope>",o,t,q,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"')};j.ExecPut=function(s,r,o,u,q,t){var p="http://schemas.xmlsoap.org/ws/2004/09/transfer/Put</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+s+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout>"+d(t)+"</Header><Body>"+c(s,r);j.PerformAjax(p+"</Body></Envelope>",o,u,q)};j.ExecCreate=function(u,t,o,w,s,v){var r=j.GetNameFromUrl(u);var p="http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+u+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+d(v)+"</Header><Body><g:"+r+' xmlns:g="'+u+'">';for(var q in t){p+="<g:"+q+">"+t[q]+"</g:"+q+">"}j.PerformAjax(p+"</g:"+r+"></Body></Envelope>",o,w,s)};j.ExecCreateXml=function(s,o,p,u,r){var q=j.GetNameFromUrl(s),t="";j.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+s+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout></Header><Body><r:"+q+' xmlns:r="'+s+'">'+o+"</r:"+q+"></Body></Envelope>",p,u,r)};j.ExecDelete=function(s,r,o,t,q){var p="http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+s+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+d(r)+"</Header><Body /></Envelope>";j.PerformAjax(p,o,t,q)};j.ExecGet=function(q,o,r,p){j.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+q+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body /></Envelope>",o,r,p)};j.ExecMethod=function(u,s,o,q,w,t,v){var p="";for(var r in o){if(o[r]!=null){if(Array.isArray(o[r])){for(var y in o[r]){p+="<r:"+r+">"+o[r][y]+"</r:"+r+">"}}else{p+="<r:"+r+">"+o[r]+"</r:"+r+">"}}}j.ExecMethodXml(u,s,p,q,w,t,v)};j.ExecMethodXml=function(s,q,o,p,u,r,t){j.PerformAjax(s+"/"+q+"</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+s+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+d(t)+"</Header><Body><r:"+q+'_INPUT xmlns:r="'+s+'">'+o+"</r:"+q+"_INPUT></Body></Envelope>",p,u,r)};j.ExecEnum=function(q,o,r,p){j.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+q+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+'</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Enumerate xmlns="http://schemas.xmlsoap.org/ws/2004/09/enumeration" /></Body></Envelope>',o,r,p)};j.ExecPull=function(r,p,o,s,q){j.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>"+j.Address+"</a:To><w:ResourceURI>"+r+"</w:ResourceURI><a:MessageID>"+(j.NextMessageId++)+'</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns="http://schemas.xmlsoap.org/ws/2004/09/enumeration"><EnumerationContext>'+p+"</EnumerationContext><MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters></Pull></Body></Envelope>",o,s,q)};j.ParseWsman=function(x){try{if(!x.childNodes){x=e(x)}var v={Header:{}},s=x.getElementsByTagName("Header")[0],w;if(!s){s=x.getElementsByTagName("a:Header")[0]}if(!s){return null}for(var u=0;u<s.childNodes.length;u++){var p=s.childNodes[u];v.Header[p.localName]=p.textContent}var o=x.getElementsByTagName("Body")[0];if(!o){o=x.getElementsByTagName("a:Body")[0]}if(!o){return null}if(o.childNodes.length>0){w=o.childNodes[0].localName;if(w.indexOf("_OUTPUT")==w.length-7){w=w.substring(0,w.length-7)}v.Header.Method=w;v.Body=b(o.childNodes[0])}return v}catch(q){console.log("Unable to parse XML: "+x);return null}};function b(u){var q,v={};for(var s=0;s<u.childNodes.length;s++){var o=u.childNodes[s];if(o.childElementCount==0){q=o.textContent}else{q=b(o)}if(q=="true"){q=true}if(q=="false"){q=false}var p=q;if(o.attributes.length>0){p={Value:q};for(var t=0;t<o.attributes.length;t++){p["@"+o.attributes[t].name]=o.attributes[t].value}}if(v[o.localName] instanceof Array){v[o.localName].push(p)}else{if(v[o.localName]==undefined){v[o.localName]=p}else{v[o.localName]=[v[o.localName],p]}}}return v}function c(t,r){if(!t||r===undefined||r===null){return""}var p=j.GetNameFromUrl(t);var s="<r:"+p+' xmlns:r="'+t+'">';for(var q in r){if(!r.hasOwnProperty(q)||q.indexOf("__")===0||q.indexOf("@")===0){continue}if(r[q]===undefined||r[q]===null||typeof r[q]==="function"){continue}if(typeof r[q]==="object"&&r[q]["ReferenceParameters"]){s+="<r:"+q+"><a:Address>"+r[q].Address+"</a:Address><a:ReferenceParameters><w:ResourceURI>"+r[q]["ReferenceParameters"]["ResourceURI"]+"</w:ResourceURI><w:SelectorSet>";var u=r[q]["ReferenceParameters"]["SelectorSet"]["Selector"];if(Array.isArray(u)){for(var o=0;o<u.length;o++){s+="<w:Selector"+a(u[o])+">"+u[o]["Value"]+"</w:Selector>"}}else{s+="<w:Selector"+a(u)+">"+u.Value+"</w:Selector>"}s+="</w:SelectorSet></a:ReferenceParameters></r:"+q+">"}else{if(Array.isArray(r[q])){for(var o=0;o<r[q].length;o++){s+="<r:"+q+">"+r[q][o].toString()+"</r:"+q+">"}}else{s+="<r:"+q+">"+r[q].toString()+"</r:"+q+">"}}}s+="</r:"+p+">";return s}function a(o){if(!o){return""}var q=" ";for(var p in o){if(!o.hasOwnProperty(p)||p.indexOf("@")!==0){continue}q+=p.substring(1)+'="'+o[p]+'" '}return q}function d(s){if(!s){return""}if(typeof s=="string"){return s}if(s.InstanceID){return'<w:SelectorSet><w:Selector Name="InstanceID">'+s.InstanceID+"</w:Selector></w:SelectorSet>"}var q="<w:SelectorSet>";for(var p in s){if(!s.hasOwnProperty(p)){continue}q+='<w:Selector Name="'+p+'">';if(s[p]["ReferenceParameters"]){q+="<a:EndpointReference>";q+="<a:Address>"+s[p]["Address"]+"</a:Address><a:ReferenceParameters><w:ResourceURI>"+s[p]["ReferenceParameters"]["ResourceURI"]+"</w:ResourceURI><w:SelectorSet>";var r=s[p]["ReferenceParameters"]["SelectorSet"]["Selector"];if(Array.isArray(r)){for(var o=0;o<r.length;o++){q+="<w:Selector"+a(r[o])+">"+r[o]["Value"]+"</w:Selector>"}}else{q+="<w:Selector"+a(r)+">"+r.Value+"</w:Selector>"}q+="</w:SelectorSet></a:ReferenceParameters></a:EndpointReference>"}else{q+=s[p]}q+="</w:Selector>"}q+="</w:SelectorSet>";return q}function e(o){if(window.DOMParser){return new DOMParser().parseFromString(o,"text/xml")}else{var p=new ActiveXObject("Microsoft.XMLDOM");p.async=false;p.loadXML(o);return p}}return j};var CreateAmtRemoteDesktop=function(m,p){var o={};o.canvasid=m;o.CanvasId=Q(m);o.scrolldiv=p;o.canvas=Q(m).getContext("2d");o.protocol=2;o.state=0;o.acc="";o.ScreenWidth=960;o.ScreenHeight=700;o.width=0;o.height=0;o.rwidth=0;o.rheight=0;o.bpp=2;o.useZRLE=true;o.showmouse=true;o.buttonmask=0;o.localKeyMap=true;o.spare=null;o.sparew=0;o.spareh=0;o.sparew2=0;o.spareh2=0;o.sparecache={};o.ZRLEfirst=1;o.onScreenSizeChange=null;o.frameRateDelay=0;o.kvmDataSupported=false;o.onKvmData=null;o.onKvmDataPending=[];o.onKvmDataAck=-1;o.holding=false;o.lastKeepAlive=Date.now();o.Debug=function(q){console.log(q)};o.xxStateChange=function(q){if(q==0){o.canvas.fillStyle="#000000";o.canvas.fillRect(0,0,o.width,o.height);o.canvas.canvas.width=o.rwidth=o.width=640;o.canvas.canvas.height=o.rheight=o.height=400;QS(o.canvasid).cursor="default"}else{QS(o.canvasid).cursor=o.showmouse?"default":"none"}};o.ProcessData=function(t){if(!t){return}o.acc+=t;while(o.acc.length>0){var q=0;if(o.state==0&&o.acc.length>=12){q=12;o.state=1;o.send("RFB 003.008\n")}else{if(o.state==1&&o.acc.length>=1){q=o.acc.charCodeAt(0)+1;o.send(String.fromCharCode(1));o.state=2}else{if(o.state==2&&o.acc.length>=4){q=4;if(ReadInt(o.acc,0)!=0){return o.Stop()}o.send(String.fromCharCode(1));o.state=3}else{if(o.state==3&&o.acc.length>=24){var D=ReadInt(o.acc,20);if(o.acc.length<24+D){return}q=24+D;o.canvas.canvas.width=o.rwidth=o.width=o.ScreenWidth=ReadShort(o.acc,0);o.canvas.canvas.height=o.rheight=o.height=o.ScreenHeight=ReadShort(o.acc,2);var G="";if(o.useZRLE){G+=IntToStr(16)}G+=IntToStr(0);G+=IntToStr(1092);o.send(String.fromCharCode(2,0)+ShortToStr((G.length/4)+1)+G+IntToStr(-223));if(o.bpp==1){o.send(String.fromCharCode(0,0,0,0,8,8,0,1)+ShortToStr(7)+ShortToStr(7)+ShortToStr(3)+String.fromCharCode(5,2,0,0,0,0))}o.state=4;o.parent.xxStateChange(3);h();if(o.onScreenSizeChange!=null){o.onScreenSizeChange(o,o.ScreenWidth,o.ScreenHeight)}}else{if(o.state==4){switch(o.acc.charCodeAt(0)){case 0:if(o.acc.length<4){return}o.state=100+ReadShort(o.acc,2);q=4;break;case 2:q=1;break;case 3:if(o.acc.length<8){return}var C=ReadInt(o.acc,4)+8;if(o.acc.length<C){return}q=n(o.acc);break}}else{if(o.state>100&&o.acc.length>=12){var I=ReadShort(o.acc,0),K=ReadShort(o.acc,2),H=ReadShort(o.acc,4),A=ReadShort(o.acc,6),F=H*A,z=ReadInt(o.acc,8);if(z<17){if(H<1||H>64||A<1||A>64){console.log("Invalid tile size ("+H+","+A+"), disconnecting.");return o.Stop()}if(o.sparew!=H||o.spareh!=A){o.sparew=o.sparew2=H;o.spareh=o.spareh2=A;var J=o.sparew2+"x"+o.spareh2;o.spare=o.sparecache[J];if(!o.spare){o.sparecache[J]=o.spare=o.canvas.createImageData(o.sparew2,o.spareh2)}}}if(z==4294967073){o.canvas.canvas.width=o.rwidth=o.width=H;o.canvas.canvas.height=o.rheight=o.height=A;o.send(String.fromCharCode(3,0,0,0,0,0)+ShortToStr(o.width)+ShortToStr(o.height));q=12;if(o.onScreenSizeChange!=null){o.onScreenSizeChange(o,o.ScreenWidth,o.ScreenHeight)}}else{if(z==0){var E=12,r=12+(F*o.bpp);if(o.acc.length<r){return}q=r;for(var B=0;B<F;B++){j(o.acc.charCodeAt(E++)+((o.bpp==2)?(o.acc.charCodeAt(E++)<<8):0),B)}g(o.spare,I,K)}else{if(z==16){if(o.acc.length<16){return}var u=ReadInt(o.acc,12);if(o.acc.length<(16+u)){return}var E=16,v=5,w=0;if(u>5&&o.acc.charCodeAt(E)==0&&ReadShortX(o.acc,E+1)==(u-v)){a(o.acc,E+5,I,K,H,A,F,u)}q=16+u}else{o.Debug("Unknown Encoding: "+z);return o.Stop()}}}if(--o.state==100){o.state=4;if(o.frameRateDelay==0){h()}else{setTimeout(h,o.frameRateDelay)}}}}}}}}if(q==0){return}o.acc=o.acc.substring(q)}};function a(t,C,K,L,J,w,G,u){var H=t.charCodeAt(C++),A,I,F,B={},D=0,E=0,z;if(H==0){for(z=0;z<G;z++){j(t.charCodeAt(C++)+((o.bpp==2)?(t.charCodeAt(C++)<<8):0),z)}g(o.spare,K,L)}else{if(H==1){I=t.charCodeAt(C++)+((o.bpp==2)?(t.charCodeAt(C++)<<8):0);o.canvas.fillStyle="rgb("+((o.bpp==1)?((I&224)+","+((I&28)<<3)+","+b((I&3)<<6)):(((I>>8)&248)+","+((I>>3)&252)+","+((I&31)<<3)))+")";o.canvas.fillRect(K,L,J,w)}else{if(H>1&&H<17){var r=4,q=15;for(z=0;z<H;z++){B[z]=t.charCodeAt(C++)+((o.bpp==2)?(t.charCodeAt(C++)<<8):0)}if(H==2){r=1;q=1}else{if(H<=4){r=2;q=3}}while(D<G&&C<t.length){I=t.charCodeAt(C++);for(z=(8-r);z>=0;z-=r){j(B[(I>>z)&q],D++)}}g(o.spare,K,L)}else{if(H==128){while(D<G&&C<t.length){I=t.charCodeAt(C++)+((o.bpp==2)?(t.charCodeAt(C++)<<8):0);E=1;do{E+=(F=t.charCodeAt(C++))}while(F==255);while(--E>=0){j(I,D++)}}g(o.spare,K,L)}else{if(H>129){for(z=0;z<(H-128);z++){B[z]=t.charCodeAt(C++)+((o.bpp==2)?(t.charCodeAt(C++)<<8):0)}while(D<G&&C<t.length){E=1;A=t.charCodeAt(C++);I=B[A%128];if(A>127){do{E+=(F=t.charCodeAt(C++))}while(F==255)}while(--E>=0){j(I,D++)}}g(o.spare,K,L)}}}}}}o.hold=function(q){if(o.holding==q){return}o.holding=q;o.canvas.fillStyle="#000000";o.canvas.fillRect(0,0,o.width,o.height);if(o.holding==false){if((o.canvas.canvas.width!=o.width)||(o.canvas.canvas.height!=o.height)){o.canvas.canvas.width=o.width;o.canvas.canvas.height=o.height;if(o.onScreenSizeChange!=null){o.onScreenSizeChange(o,o.ScreenWidth,o.ScreenHeight)}}o.Send(String.fromCharCode(3,0,0,0,0,0)+ShortToStr(o.width)+ShortToStr(o.height))}else{o.UnGrabMouseInput();o.UnGrabKeyInput()}};function g(q,r,s){if(o.holding==true){return}o.canvas.putImageData(q,r,s)}function j(s,q){var r=q*4;if(o.bpp==1){o.spare.data[r++]=s&224;o.spare.data[r++]=(s&28)<<3;o.spare.data[r++]=b((s&3)<<6)}else{o.spare.data[r++]=(s>>8)&248;o.spare.data[r++]=(s>>3)&252;o.spare.data[r++]=(s&31)<<3}o.spare.data[r]=255}function b(q){return(q>127)?(q+32):q}function h(){if(o.holding==true){return}o.send(String.fromCharCode(3,1,0,0,0,0)+ShortToStr(o.rwidth)+ShortToStr(o.rheight))}o.Start=function(){o.state=0;o.acc="";o.ZRLEfirst=1;o.onKvmDataPending=[];o.onKvmDataAck=-1;o.kvmDataSupported=false;for(var q in o.sparecache){delete o.sparecache[q]}};o.Stop=function(){o.UnGrabMouseInput();o.UnGrabKeyInput();o.parent.Stop()};o.send=function(q){o.parent.send(q)};var l={Pause:19,CapsLock:20,Space:32,Quote:39,Minus:45,NumpadMultiply:42,NumpadAdd:43,PrintScreen:44,Comma:44,NumpadSubtract:45,NumpadDecimal:46,Period:46,Slash:47,NumpadDivide:47,Semicolon:59,Equal:61,OSLeft:91,BracketLeft:91,OSRight:91,Backslash:92,BracketRight:93,ContextMenu:93,Backquote:96,NumLock:144,ScrollLock:145,Backspace:65288,Tab:65289,Enter:65293,NumpadEnter:65293,Escape:65307,Delete:65535,Home:65360,PageUp:65365,PageDown:65366,ArrowLeft:65361,ArrowUp:65362,ArrowRight:65363,ArrowDown:65364,End:65367,Insert:65379,F1:65470,F2:65471,F3:65472,F4:65473,F5:65474,F6:65475,F7:65476,F8:65477,F9:65478,F10:65479,F11:65480,F12:65481,ShiftLeft:65505,ShiftRight:65506,ControlLeft:65507,ControlRight:65508,AltLeft:65513,AltRight:65514,MetaLeft:65511,MetaRight:65512};function k(q){if(q.code.startsWith("Key")&&q.code.length==4){return q.code.charCodeAt(3)+((q.shiftKey==false)?32:0)}if(q.code.startsWith("Digit")&&q.code.length==6){return q.code.charCodeAt(5)}if(q.code.startsWith("Numpad")&&q.code.length==7){return q.code.charCodeAt(6)}return l[q.code]}function c(q,r){if(!r){r=window.event}if(r.code&&(o.localKeyMap==false)){var s=k(r);if(s!=null){o.sendkey(s,q)}}else{var s=r.keyCode,t=s;if(r.shiftKey==false&&s>=65&&s<=90){t=s+32}if(s>=112&&s<=124){t=s+65358}if(s==8){t=65288}if(s==9){t=65289}if(s==13){t=65293}if(s==16){t=65505}if(s==17){t=65507}if(s==18){t=65513}if(s==27){t=65307}if(s==33){t=65365}if(s==34){t=65366}if(s==35){t=65367}if(s==36){t=65360}if(s==37){t=65361}if(s==38){t=65362}if(s==39){t=65363}if(s==40){t=65364}if(s==45){t=65379}if(s==46){t=65535}if(s>=96&&s<=105){t=s-48}if(s==106){t=42}if(s==107){t=43}if(s==109){t=45}if(s==110){t=46}if(s==111){t=47}if(s==186){t=59}if(s==187){t=61}if(s==188){t=44}if(s==189){t=45}if(s==190){t=46}if(s==191){t=47}if(s==192){t=96}if(s==219){t=91}if(s==220){t=92}if(s==221){t=93}if(s==222){t=39}o.sendkey(t,q)}return o.haltEvent(r)}o.sendkey=function(s,q){if(typeof s=="object"){for(var r in s){o.sendkey(s[r][0],s[r][1])}}else{o.send(String.fromCharCode(4,q,0,0)+IntToStr(s))}};function n(q){if(q.length<8){return 0}var s=ReadInt(o.acc,4)+8;if(q.length<s){return 0}if(o.onKvmData!=null){var r=q.substring(8,s);if((r.length>=16)&&(r.substring(0,15)=="\0KvmDataChannel")){if(o.kvmDataSupported==false){o.kvmDataSupported=true;console.log("KVM Data Channel Supported.")}if(((o.onKvmDataAck==-1)&&(r.length==16))||(r.charCodeAt(15)!=0)){o.onKvmDataAck=true}if(r.length>=16){o.onKvmData(r.substring(16))}if((o.onKvmDataAck==true)&&(o.onKvmDataPending.length>0)){o.sendKvmData(o.onKvmDataPending.shift())}}}return s}o.sendKvmData=function(q){if(o.onKvmDataAck!==true){o.onKvmDataPending.push(q)}else{q="\0KvmDataChannel\0"+q;o.send(String.fromCharCode(6,0,0,0)+IntToStr(q.length)+q);o.onKvmDataAck=false}};o.sendKeepAlive=function(){if(o.lastKeepAlive<Date.now()-5000){o.lastKeepAlive=Date.now();o.send(String.fromCharCode(6,0,0,0)+IntToStr(16)+"\0KvmDataChannel\0")}};o.SendCtrlAltDelMsg=function(){o.sendcad()};o.sendcad=function(){o.sendkey([[65507,1],[65513,1],[65535,1],[65535,0],[65513,0],[65507,0]])};var e=false;var d=false;o.GrabMouseInput=function(){if(e==true){return}var q=o.canvas.canvas;q.onmouseup=o.mouseup;q.onmousedown=o.mousedown;q.onmousemove=o.mousemove;e=true};o.UnGrabMouseInput=function(){if(e==false){return}var q=o.canvas.canvas;q.onmousemove=null;q.onmouseup=null;q.onmousedown=null;e=false};o.GrabKeyInput=function(){if(d==true){return}document.onkeyup=o.handleKeyUp;document.onkeydown=o.handleKeyDown;document.onkeypress=o.handleKeys;d=true};o.UnGrabKeyInput=function(){if(d==false){return}document.onkeyup=null;document.onkeydown=null;document.onkeypress=null;d=false};o.handleKeys=function(q){return o.haltEvent(q)};o.handleKeyUp=function(q){return c(0,q)};o.handleKeyDown=function(q){return c(1,q)};o.haltEvent=function(q){if(q.preventDefault){q.preventDefault()}if(q.stopPropagation){q.stopPropagation()}return false};o.mousedblclick=function(q){};o.mousedown=function(q){o.buttonmask|=(1<<q.button);return o.mousemove(q)};o.mouseup=function(q){o.buttonmask&=(65535-(1<<q.button));return o.mousemove(q)};o.mousemove=function(q){if(o.state!=4){return true}var r=o.getPositionOfControl(Q(o.canvasid));o.mx=(q.pageX-r[0])*(o.canvas.canvas.height/Q(o.canvasid).offsetHeight);o.my=((q.pageY-r[1]+(p?p.scrollTop:0))*(o.canvas.canvas.width/Q(o.canvasid).offsetWidth));o.send(String.fromCharCode(5,o.buttonmask)+ShortToStr(o.mx)+ShortToStr(o.my));return o.haltEvent(q)};o.getPositionOfControl=function(q){var r=Array(2);r[0]=r[1]=0;while(q){r[0]+=q.offsetLeft;r[1]+=q.offsetTop;q=q.offsetParent}return r};return o};var CreateAmtRemoteTerminal=function(B){var C={};C.DivId=B;C.DivElement=document.getElementById(B);C.protocol=1;C.fxEmulation=0;C.lineFeed="\r\n";C.debugmode=0;C.width=80;C.height=25;var r=21;var s=13;var m=["000000","BB0000","00BB00","BBBB00","0000BB","BB00BB","00BBBB","BBBBBB","555555","FF5555","55FF55","FFFF55","5555FF","FF55FF","55FFFF","FFFFFF"];var p=0;var o=7;var n=0;var t=true;var w=0;var x=0;var v=0;var d=[];var e=0;var l=[];var y=[];var A=1;var z=2;C.Start=function(){};C.Init=function(E,D){C.width=E?E:80;C.height=D?D:25;for(var G=0;G<C.height;G++){y[G]=[];l[G]=[];for(var F=0;F<C.width;F++){y[G][F]=" ";l[G][F]=(7<<6)}}C.TermInit();C.TermDraw()};C.xxStateChange=function(D){};C.ProcessData=function(D){if(C.debugmode==2){console.log("TRecv("+D.length+"): "+rstr2hex(D))}if(C.capture!=null){C.capture+=D}k(D);C.TermDraw()};function k(E){for(var D=0;D<E.length;D++){j(String.fromCharCode(E.charCodeAt(D)),E.charCodeAt(D))}}function j(D,E){switch(v){case 0:switch(E){case 27:v=1;break;default:h(D);break}break;case 1:switch(D){case"[":e=0;d=[];v=2;break;case"(":v=4;break;case")":v=5;break;default:v=0;break}break;case 2:if(D>="0"&&D<="9"){if(!d[e]){d[e]=(D-"0")}else{d[e]=((d[e]*10)+(D-"0"))}break}else{if(D==";"){e++;break}else{if(!d[0]){d[0]=0}g(D,d,e+1);v=0}}break;case 4:v=0;break;case 5:v=0;break}}function g(G,D,E){var H;switch(G){case"c":C.TermResetScreen();break;case"A":if(E==1){x-=D[0];if(x<0){x=0}}break;case"B":if(E==1){x+=D[0];if(x>C.height){x=C.height}}break;case"C":if(E==1){w+=D[0];if(w>C.width){w=C.width}}break;case"D":if(E==1){w-=D[0];if(w<0){w=0}}break;case"d":if(E==1){x=D[0]-1;if(x>C.height){x=C.height}if(x<0){x=0}}break;case"G":if(E==1){w=D[0]-1;if(w<0){w=0}if(w>79){w=79}}break;case"J":if(E==1&&D[0]==2){C.TermClear((n<<12)+(o<<6));w=0;x=0}else{if(E==0||E==1&&D[0]==0){b();for(H=x+1;H<C.height;H++){c(H)}}else{if(E==1&&D[0]==1){b();for(H=0;H<x-1;H++){c(H)}}}}break;case"H":if(E==2){if(D[0]<1){D[0]=1}if(D[1]<1){D[1]=1}if(D[0]>C.height){D[0]=C.height}if(D[1]>C.width){D[1]=C.width}x=D[0]-1;w=D[1]-1}else{x=0;w=0}break;case"m":for(H=0;H<E;H++){if(!D[H]||D[H]==0){n=0;o=7;p=0}else{if(D[H]==1){if(o<8){o+=8}}else{if(D[H]==2||D[H]==22){if(o>=8){o-=8}}else{if(D[H]==7){p=2}else{if(D[H]==27){p=0}else{if(D[H]>=30&&D[H]<=37){var F=(o>=8);o=(D[H]-30);if(F&&o<=8){o+=8}}else{if(D[H]>=40&&D[H]<=47){n=(D[H]-40)}else{if(D[H]>=90&&D[H]<=99){o=(D[H]-82)}else{if(D[H]>=100&&D[H]<=109){n=(D[H]-92)}}}}}}}}}}break;case"K":if(E==0||(E==1&&(!D[0]||D[0]==0))){b()}else{if(E==1){if(D[0]==1){a()}else{if(D[0]==2){c(x)}}}}break;case"h":t=true;break;case"l":t=false;break;default:break}}C.ProcessVt100String=function(E){for(var D=0;D<E.length;D++){h(String.fromCharCode(E.charCodeAt(D)))}};function h(D){if(D=="\0"||D.charCodeAt()==7){return}var E=D.charCodeAt();switch(E){case 16:D=" ";break;case 24:D="?";break;case 25:D="?";break}if(w>C.width){w=C.width}if(x>(C.height-1)){x=(C.height-1)}switch(D){case"\b":if(w>0){w=w-1;q(" ")}break;case"\t":var F=8-(w%8);for(var G=0;G<F;G++){h(" ")}break;case"\n":x++;if(x>(C.height-1)){u(1);x=(C.height-1)}if(C.lineFeed="\n"){w=0}break;case"\r":w=0;break;default:if(w>=C.width){w=0;if(t){x++}if(x>=(C.height-1)){u(1);x=(C.height-1)}}q(D);w++;break}}function q(D){y[x][w]=D;l[x][w]=(o<<6)+(n<<12)+p}C.TermClear=function(D){for(var F=0;F<C.height;F++){for(var E=0;E<C.width;E++){y[F][E]=" ";l[F][E]=D}}};C.TermResetScreen=function(){p=0;o=7;n=0;t=true;w=0;x=0;C.TermClear(7<<6)};function b(){var D=(n<<12);for(var E=w;E<C.width;E++){y[x][E]=" ";l[x][E]=D}}function a(){var D=(n<<12);for(var E=0;E<w;E++){y[x][E]=" ";l[x][E]=D}}function c(D){var E=(n<<12);for(var F=0;F<C.width;F++){y[D][F]=" ";l[D][F]=E}}C.TermSendKeys=function(D){if(C.debugmode==2){if(C.debugmode==2){console.log("TSend("+D.length+"): "+rstr2hex(D))}}C.parent.send(D)};C.TermSendKey=function(D){if(C.debugmode==2){if(C.debugmode==2){console.log("TSend(1): "+rstr2hex(String.fromCharCode(D)))}}C.parent.send(String.fromCharCode(D))};function u(D){var E,F;for(F=0;F<C.height-D;F++){y[F]=y[F+D];l[F]=l[F+D]}for(F=C.height-D;F<C.height;F++){y[F]=[];l[F]=[];for(E=0;E<C.width;E++){y[F][E]=" ";l[F][E]=(7<<6)}}}C.TermHandleKeys=function(D){if(!D.ctrlKey){if(D.which==127){C.TermSendKey(8)}else{if(D.which==13){C.TermSendKeys(C.lineFeed)}else{if(D.which!=0){C.TermSendKey(D.which)}}}return false}if(D.preventDefault){D.preventDefault()}if(D.stopPropagation){D.stopPropagation()}};C.TermHandleKeyUp=function(D){if((D.which!=8)&&(D.which!=32)&&(D.which!=9)){return true}if(D.preventDefault){D.preventDefault()}if(D.stopPropagation){D.stopPropagation()}return false};C.TermHandleKeyDown=function(D){if((D.which>=65)&&(D.which<=90)&&(D.ctrlKey==true)){C.TermSendKey(D.which-64);if(D.preventDefault){D.preventDefault()}if(D.stopPropagation){D.stopPropagation()}return}if(D.which==27){C.TermSendKeys(String.fromCharCode(27));return true}if(D.which==37){C.TermSendKeys(String.fromCharCode(27,91,68));return true}if(D.which==38){C.TermSendKeys(String.fromCharCode(27,91,65));return true}if(D.which==39){C.TermSendKeys(String.fromCharCode(27,91,67));return true}if(D.which==40){C.TermSendKeys(String.fromCharCode(27,91,66));return true}if(D.which==9){C.TermSendKeys("\t");if(D.preventDefault){D.preventDefault()}if(D.stopPropagation){D.stopPropagation()}return true}if(D.which!=8&&D.which!=32&&D.which!=9){return true}C.TermSendKey(D.which);if(D.preventDefault){D.preventDefault()}if(D.stopPropagation){D.stopPropagation()}return false};C.TermDraw=function(){var E,D="",F="",G,H=1,J,K;for(var L=0;L<C.height;++L){for(var I=0;I<C.width;++I){G=l[L][I];if(w==I&&x==L){G|=z}if(G!=H){D+=F;F="";J=6;K=12;if(G&z){J=12;K=6}D+='<span style="color:#'+m[(G>>J)&63]+";background-color:#"+m[(G>>K)&63];if(G&A){D+=";text-decoration:underline"}D+=';">';F="</span>"+F;H=G}E=y[L][I];switch(E){case"&":D+="&amp;";break;case"<":D+="&lt;";break;case">":D+="&gt;";break;case" ":D+="&nbsp;";break;default:D+=E;break}}if(L!=(C.height-1)){D+="<br>"}}C.DivElement.innerHTML="<font size='4'><b>"+D+F+"</b></font>"};C.TermInit=function(){C.TermResetScreen()};C.Init();return C};var ZLIB=(ZLIB||{});if(typeof ZLIB.common_initialized==="undefined"){ZLIB.Z_NO_FLUSH=0;ZLIB.Z_PARTIAL_FLUSH=1;ZLIB.Z_SYNC_FLUSH=2;ZLIB.Z_FULL_FLUSH=3;ZLIB.Z_FINISH=4;ZLIB.Z_BLOCK=5;ZLIB.Z_TREES=6;ZLIB.Z_OK=0;ZLIB.Z_STREAM_END=1;ZLIB.Z_NEED_DICT=2;ZLIB.Z_ERRNO=(-1);ZLIB.Z_STREAM_ERROR=(-2);ZLIB.Z_DATA_ERROR=(-3);ZLIB.Z_MEM_ERROR=(-4);ZLIB.Z_BUF_ERROR=(-5);ZLIB.Z_VERSION_ERROR=(-6);ZLIB.Z_DEFLATED=8;ZLIB.z_stream=function(){this.next_in=0;this.avail_in=0;this.total_in=0;this.next_out=0;this.avail_out=0;this.total_out=0;this.msg=null;this.state=null;this.data_type=0;this.adler=0;this.input_data="";this.output_data="";this.error=0;this.checksum_function=null};ZLIB.gz_header=function(){this.text=0;this.time=0;this.xflags=0;this.os=255;this.extra=null;this.extra_len=0;this.extra_max=0;this.name=null;this.name_max=0;this.comment=null;this.comm_max=0;this.hcrc=0;this.done=0};ZLIB.common_initialized=true}if(typeof ZLIB==="undefined"){alert("ZLIB is not defined. SRC zlib.js before zlib-inflate.js")}(function(){var o=15;var G=0;var D=1;var am=2;var af=3;var A=4;var B=5;var ac=6;var j=7;var F=8;var q=9;var p=10;var an=11;var ao=12;var aj=13;var l=14;var k=15;var al=16;var W=17;var g=18;var S=19;var R=20;var T=21;var r=22;var s=23;var aa=24;var Y=25;var d=26;var V=27;var v=28;var a=29;var ab=30;var ak=31;var z=852;var y=592;var x=(z+y);var h=0;var X=1;var u=2;var N=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0];var O=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,203,69];var L=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0];var M=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];ZLIB.inflate_copyright=" inflate 1.2.6 Copyright 1995-2012 Mark Adler ";function K(aR,aV){var aM=15;var aU=aR.next;var at=(aV==u?aR.distbits:aR.lenbits);var aX=aR.work;var aH=aR.lens;var aI=(aV==u?aR.nlen:0);var aS=aR.codes;var au;if(aV==X){au=aR.nlen}else{if(aV==u){au=aR.ndist}else{au=19}}var aG;var aT;var aN,aL;var aQ;var aw;var ax;var aF;var aW;var aD;var aE;var aB;var aJ;var aK;var aC;var aO;var aq;var ar;var az;var aA;var ay;var av=new Array(aM+1);var aP=new Array(aM+1);for(aG=0;aG<=aM;aG++){av[aG]=0}for(aT=0;aT<au;aT++){av[aH[aI+aT]]++}aQ=at;for(aL=aM;aL>=1;aL--){if(av[aL]!=0){break}}if(aQ>aL){aQ=aL}if(aL==0){aC={op:64,bits:1,val:0};aS[aU++]=aC;aS[aU++]=aC;if(aV==u){aR.distbits=1}else{aR.lenbits=1}aR.next=aU;return 0}for(aN=1;aN<aL;aN++){if(av[aN]!=0){break}}if(aQ<aN){aQ=aN}aF=1;for(aG=1;aG<=aM;aG++){aF<<=1;aF-=av[aG];if(aF<0){return -1}}if(aF>0&&(aV==h||aL!=1)){aR.next=aU;return -1}aP[1]=0;for(aG=1;aG<aM;aG++){aP[aG+1]=aP[aG]+av[aG]}for(aT=0;aT<au;aT++){if(aH[aI+aT]!=0){aX[aP[aH[aI+aT]]++]=aT}}switch(aV){case h:aq=az=aX;ar=0;aA=0;ay=19;break;case X:aq=N;ar=-257;az=O;aA=-257;ay=256;break;default:aq=L;az=M;ar=0;aA=0;ay=-1}aD=0;aT=0;aG=aN;aO=aU;aw=aQ;ax=0;aJ=-1;aW=1<<aQ;aK=aW-1;if((aV==X&&aW>=z)||(aV==u&&aW>=y)){aR.next=aU;return 1}for(;;){aC={op:0,bits:aG-ax,val:0};if(aX[aT]<ay){aC.val=aX[aT]}else{if(aX[aT]>ay){aC.op=az[aA+aX[aT]];aC.val=aq[ar+aX[aT]]}else{aC.op=32+64}}aE=1<<(aG-ax);aB=1<<aw;aN=aB;do{aB-=aE;aS[aO+(aD>>>ax)+aB]=aC}while(aB!=0);aE=1<<(aG-1);while(aD&aE){aE>>>=1}if(aE!=0){aD&=aE-1;aD+=aE}else{aD=0}aT++;if(--(av[aG])==0){if(aG==aL){break}aG=aH[aI+aX[aT]]}if(aG>aQ&&(aD&aK)!=aJ){if(ax==0){ax=aQ}aO+=aN;aw=aG-ax;aF=(1<<aw);while(aw+ax<aL){aF-=av[aw+ax];if(aF<=0){break}aw++;aF<<=1}aW+=1<<aw;if((aV==X&&aW>=z)||(aV==u&&aW>=y)){aR.next=aU;return 1}aJ=aD&aK;aS[aU+aJ]={op:aw,bits:aQ,val:aO-aU}}}if(aD!=0){aS[aO+aD]={op:64,bits:aG-ax,val:0}}aR.next=aU+aW;if(aV==u){aR.distbits=aQ}else{aR.lenbits=aQ}return 0}function H(aN,aL){var aM;var aC;var aI;var aD;var aK;var aq;var ax;var aR;var aO;var aQ;var aP;var aB;var ar;var at;var aE;var au;var aH;var aw;var aA;var aJ;var aF;var av;var az=-1;var ay=-1;aM=aN.state;aC=aN.input_data;aI=aN.next_in;aD=aI+aN.avail_in-5;aK=aN.next_out;aq=aK-(aL-aN.avail_out);ax=aK+(aN.avail_out-257);aR=aM.wsize;aO=aM.whave;aQ=aM.wnext;aP=aM.window;aB=aM.hold;ar=aM.bits;at=aM.codes;aE=aM.lencode;au=aM.distcode;aH=(1<<aM.lenbits)-1;aw=(1<<aM.distbits)-1;loop:do{if(ar<15){aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8;aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8}aA=at[aE+(aB&aH)];dolen:while(true){aJ=aA.bits;aB>>>=aJ;ar-=aJ;aJ=aA.op;if(aJ==0){aN.output_data+=String.fromCharCode(aA.val);aK++}else{if(aJ&16){aF=aA.val;aJ&=15;if(aJ){if(ar<aJ){aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8}aF+=aB&((1<<aJ)-1);aB>>>=aJ;ar-=aJ}if(ar<15){aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8;aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8}aA=at[au+(aB&aw)];dodist:while(true){aJ=aA.bits;aB>>>=aJ;ar-=aJ;aJ=aA.op;if(aJ&16){av=aA.val;aJ&=15;if(ar<aJ){aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8;if(ar<aJ){aB+=(aC.charCodeAt(aI++)&255)<<ar;ar+=8}}av+=aB&((1<<aJ)-1);aB>>>=aJ;ar-=aJ;aJ=aK-aq;if(av>aJ){aJ=av-aJ;if(aJ>aO){if(aM.sane){aN.msg="invalid distance too far back";aM.mode=a;break loop}}az=0;ay=-1;if(aQ==0){az+=aR-aJ;if(aJ<aF){aF-=aJ;aN.output_data+=aP.substring(az,az+aJ);aK+=aJ;aJ=0;az=-1;ay=aK-av}}else{az+=aQ-aJ;if(aJ<aF){aF-=aJ;aN.output_data+=aP.substring(az,az+aJ);aK+=aJ;az=-1;ay=aK-av}}}else{az=-1;ay=aK-av}if(az>=0){aN.output_data+=aP.substring(az,az+aF);aK+=aF;az+=aF}else{var aG=aF;if(aG>aK-ay){aG=aK-ay}aN.output_data+=aN.output_data.substring(ay,ay+aG);aK+=aG;aF-=aG;ay+=aG;aK+=aF;while(aF>2){aN.output_data+=aN.output_data.charAt(ay++);aN.output_data+=aN.output_data.charAt(ay++);aN.output_data+=aN.output_data.charAt(ay++);aF-=3}if(aF){aN.output_data+=aN.output_data.charAt(ay++);if(aF>1){aN.output_data+=aN.output_data.charAt(ay++)}}}}else{if((aJ&64)==0){aA=at[au+(aA.val+(aB&((1<<aJ)-1)))];continue dodist}else{aN.msg="invalid distance code";aM.mode=a;break loop}}break dodist}}else{if((aJ&64)==0){aA=at[aE+(aA.val+(aB&((1<<aJ)-1)))];continue dolen}else{if(aJ&32){aM.mode=an;break loop}else{aN.msg="invalid literal/length code";aM.mode=a;break loop}}}}break dolen}}while(aI<aD&&aK<ax);aF=ar>>>3;aI-=aF;ar-=aF<<3;aB&=(1<<ar)-1;aN.next_in=aI;aN.next_out=aK;aN.avail_in=(aI<aD?5+(aD-aI):5-(aI-aD));aN.avail_out=(aK<ax?257+(ax-aK):257-(aK-ax));aM.hold=aB;aM.bits=ar}function ae(at){var ar;var aq=new Array(at);for(ar=0;ar<at;ar++){aq[ar]=0}return aq}function E(at,ar,aq){return(at&&(ar in at))?at[ar]:aq}function e(){return 0}function J(){var ar;this.mode=0;this.last=0;this.wrap=0;this.havedict=0;this.flags=0;this.dmax=0;this.check=0;this.total=0;this.head=null;this.wbits=0;this.wsize=0;this.whave=0;this.wnext=0;this.window=null;this.hold=0;this.bits=0;this.length=0;this.offset=0;this.extra=0;this.lencode=0;this.distcode=0;this.lenbits=0;this.distbits=0;this.ncode=0;this.nlen=0;this.ndist=0;this.have=0;this.next=0;this.lens=ae(320);this.work=ae(288);this.codes=new Array(x);var aq={op:0,bits:0,val:0};for(ar=0;ar<x;ar++){this.codes[ar]=aq}this.sane=0;this.back=0;this.was=0}ZLIB.inflateResetKeep=function(ar){var aq;if(!ar||!ar.state){return ZLIB.Z_STREAM_ERROR}aq=ar.state;ar.total_in=ar.total_out=aq.total=0;ar.msg=null;if(aq.wrap){ar.adler=aq.wrap&1}aq.mode=G;aq.last=0;aq.havedict=0;aq.dmax=32768;aq.head=null;aq.hold=0;aq.bits=0;aq.lencode=0;aq.distcode=0;aq.next=0;aq.sane=1;aq.back=-1;return ZLIB.Z_OK};ZLIB.inflateReset=function(ar,at){var au;var aq;if(!ar||!ar.state){return ZLIB.Z_STREAM_ERROR}aq=ar.state;if(typeof at==="undefined"){at=o}if(at<0){au=0;at=-at}else{au=(at>>>4)+1;if(at<48){at&=15}}if(au==1&&(typeof ZLIB.adler32==="function")){ar.checksum_function=ZLIB.adler32}else{if(au==2&&(typeof ZLIB.crc32==="function")){ar.checksum_function=ZLIB.crc32}else{ar.checksum_function=e}}if(at&&(at<8||at>15)){return ZLIB.Z_STREAM_ERROR}if(aq.window&&aq.wbits!=at){aq.window=null}aq.wrap=au;aq.wbits=at;aq.wsize=0;aq.whave=0;aq.wnext=0;return ZLIB.inflateResetKeep(ar)};ZLIB.inflateInit=function(ar){var aq=new ZLIB.z_stream();aq.state=new J();ZLIB.inflateReset(aq,ar);return aq};ZLIB.inflatePrime=function(at,aq,au){var ar;if(!at||!at.state){return ZLIB.Z_STREAM_ERROR}ar=at.state;if(aq<0){ar.hold=0;ar.bits=0;return ZLIB.Z_OK}if(aq>16||ar.bits+aq>32){return ZLIB.Z_STREAM_ERROR}au&=(1<<aq)-1;ar.hold+=au<<ar.bits;ar.bits+=aq;return ZLIB.Z_OK};var U=null;var t=null;function C(ar){var aq;if(!U){U=[{op:96,bits:7,val:0},{op:0,bits:8,val:80},{op:0,bits:8,val:16},{op:20,bits:8,val:115},{op:18,bits:7,val:31},{op:0,bits:8,val:112},{op:0,bits:8,val:48},{op:0,bits:9,val:192},{op:16,bits:7,val:10},{op:0,bits:8,val:96},{op:0,bits:8,val:32},{op:0,bits:9,val:160},{op:0,bits:8,val:0},{op:0,bits:8,val:128},{op:0,bits:8,val:64},{op:0,bits:9,val:224},{op:16,bits:7,val:6},{op:0,bits:8,val:88},{op:0,bits:8,val:24},{op:0,bits:9,val:144},{op:19,bits:7,val:59},{op:0,bits:8,val:120},{op:0,bits:8,val:56},{op:0,bits:9,val:208},{op:17,bits:7,val:17},{op:0,bits:8,val:104},{op:0,bits:8,val:40},{op:0,bits:9,val:176},{op:0,bits:8,val:8},{op:0,bits:8,val:136},{op:0,bits:8,val:72},{op:0,bits:9,val:240},{op:16,bits:7,val:4},{op:0,bits:8,val:84},{op:0,bits:8,val:20},{op:21,bits:8,val:227},{op:19,bits:7,val:43},{op:0,bits:8,val:116},{op:0,bits:8,val:52},{op:0,bits:9,val:200},{op:17,bits:7,val:13},{op:0,bits:8,val:100},{op:0,bits:8,val:36},{op:0,bits:9,val:168},{op:0,bits:8,val:4},{op:0,bits:8,val:132},{op:0,bits:8,val:68},{op:0,bits:9,val:232},{op:16,bits:7,val:8},{op:0,bits:8,val:92},{op:0,bits:8,val:28},{op:0,bits:9,val:152},{op:20,bits:7,val:83},{op:0,bits:8,val:124},{op:0,bits:8,val:60},{op:0,bits:9,val:216},{op:18,bits:7,val:23},{op:0,bits:8,val:108},{op:0,bits:8,val:44},{op:0,bits:9,val:184},{op:0,bits:8,val:12},{op:0,bits:8,val:140},{op:0,bits:8,val:76},{op:0,bits:9,val:248},{op:16,bits:7,val:3},{op:0,bits:8,val:82},{op:0,bits:8,val:18},{op:21,bits:8,val:163},{op:19,bits:7,val:35},{op:0,bits:8,val:114},{op:0,bits:8,val:50},{op:0,bits:9,val:196},{op:17,bits:7,val:11},{op:0,bits:8,val:98},{op:0,bits:8,val:34},{op:0,bits:9,val:164},{op:0,bits:8,val:2},{op:0,bits:8,val:130},{op:0,bits:8,val:66},{op:0,bits:9,val:228},{op:16,bits:7,val:7},{op:0,bits:8,val:90},{op:0,bits:8,val:26},{op:0,bits:9,val:148},{op:20,bits:7,val:67},{op:0,bits:8,val:122},{op:0,bits:8,val:58},{op:0,bits:9,val:212},{op:18,bits:7,val:19},{op:0,bits:8,val:106},{op:0,bits:8,val:42},{op:0,bits:9,val:180},{op:0,bits:8,val:10},{op:0,bits:8,val:138},{op:0,bits:8,val:74},{op:0,bits:9,val:244},{op:16,bits:7,val:5},{op:0,bits:8,val:86},{op:0,bits:8,val:22},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:118},{op:0,bits:8,val:54},{op:0,bits:9,val:204},{op:17,bits:7,val:15},{op:0,bits:8,val:102},{op:0,bits:8,val:38},{op:0,bits:9,val:172},{op:0,bits:8,val:6},{op:0,bits:8,val:134},{op:0,bits:8,val:70},{op:0,bits:9,val:236},{op:16,bits:7,val:9},{op:0,bits:8,val:94},{op:0,bits:8,val:30},{op:0,bits:9,val:156},{op:20,bits:7,val:99},{op:0,bits:8,val:126},{op:0,bits:8,val:62},{op:0,bits:9,val:220},{op:18,bits:7,val:27},{op:0,bits:8,val:110},{op:0,bits:8,val:46},{op:0,bits:9,val:188},{op:0,bits:8,val:14},{op:0,bits:8,val:142},{op:0,bits:8,val:78},{op:0,bits:9,val:252},{op:96,bits:7,val:0},{op:0,bits:8,val:81},{op:0,bits:8,val:17},{op:21,bits:8,val:131},{op:18,bits:7,val:31},{op:0,bits:8,val:113},{op:0,bits:8,val:49},{op:0,bits:9,val:194},{op:16,bits:7,val:10},{op:0,bits:8,val:97},{op:0,bits:8,val:33},{op:0,bits:9,val:162},{op:0,bits:8,val:1},{op:0,bits:8,val:129},{op:0,bits:8,val:65},{op:0,bits:9,val:226},{op:16,bits:7,val:6},{op:0,bits:8,val:89},{op:0,bits:8,val:25},{op:0,bits:9,val:146},{op:19,bits:7,val:59},{op:0,bits:8,val:121},{op:0,bits:8,val:57},{op:0,bits:9,val:210},{op:17,bits:7,val:17},{op:0,bits:8,val:105},{op:0,bits:8,val:41},{op:0,bits:9,val:178},{op:0,bits:8,val:9},{op:0,bits:8,val:137},{op:0,bits:8,val:73},{op:0,bits:9,val:242},{op:16,bits:7,val:4},{op:0,bits:8,val:85},{op:0,bits:8,val:21},{op:16,bits:8,val:258},{op:19,bits:7,val:43},{op:0,bits:8,val:117},{op:0,bits:8,val:53},{op:0,bits:9,val:202},{op:17,bits:7,val:13},{op:0,bits:8,val:101},{op:0,bits:8,val:37},{op:0,bits:9,val:170},{op:0,bits:8,val:5},{op:0,bits:8,val:133},{op:0,bits:8,val:69},{op:0,bits:9,val:234},{op:16,bits:7,val:8},{op:0,bits:8,val:93},{op:0,bits:8,val:29},{op:0,bits:9,val:154},{op:20,bits:7,val:83},{op:0,bits:8,val:125},{op:0,bits:8,val:61},{op:0,bits:9,val:218},{op:18,bits:7,val:23},{op:0,bits:8,val:109},{op:0,bits:8,val:45},{op:0,bits:9,val:186},{op:0,bits:8,val:13},{op:0,bits:8,val:141},{op:0,bits:8,val:77},{op:0,bits:9,val:250},{op:16,bits:7,val:3},{op:0,bits:8,val:83},{op:0,bits:8,val:19},{op:21,bits:8,val:195},{op:19,bits:7,val:35},{op:0,bits:8,val:115},{op:0,bits:8,val:51},{op:0,bits:9,val:198},{op:17,bits:7,val:11},{op:0,bits:8,val:99},{op:0,bits:8,val:35},{op:0,bits:9,val:166},{op:0,bits:8,val:3},{op:0,bits:8,val:131},{op:0,bits:8,val:67},{op:0,bits:9,val:230},{op:16,bits:7,val:7},{op:0,bits:8,val:91},{op:0,bits:8,val:27},{op:0,bits:9,val:150},{op:20,bits:7,val:67},{op:0,bits:8,val:123},{op:0,bits:8,val:59},{op:0,bits:9,val:214},{op:18,bits:7,val:19},{op:0,bits:8,val:107},{op:0,bits:8,val:43},{op:0,bits:9,val:182},{op:0,bits:8,val:11},{op:0,bits:8,val:139},{op:0,bits:8,val:75},{op:0,bits:9,val:246},{op:16,bits:7,val:5},{op:0,bits:8,val:87},{op:0,bits:8,val:23},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:119},{op:0,bits:8,val:55},{op:0,bits:9,val:206},{op:17,bits:7,val:15},{op:0,bits:8,val:103},{op:0,bits:8,val:39},{op:0,bits:9,val:174},{op:0,bits:8,val:7},{op:0,bits:8,val:135},{op:0,bits:8,val:71},{op:0,bits:9,val:238},{op:16,bits:7,val:9},{op:0,bits:8,val:95},{op:0,bits:8,val:31},{op:0,bits:9,val:158},{op:20,bits:7,val:99},{op:0,bits:8,val:127},{op:0,bits:8,val:63},{op:0,bits:9,val:222},{op:18,bits:7,val:27},{op:0,bits:8,val:111},{op:0,bits:8,val:47},{op:0,bits:9,val:190},{op:0,bits:8,val:15},{op:0,bits:8,val:143},{op:0,bits:8,val:79},{op:0,bits:9,val:254},{op:96,bits:7,val:0},{op:0,bits:8,val:80},{op:0,bits:8,val:16},{op:20,bits:8,val:115},{op:18,bits:7,val:31},{op:0,bits:8,val:112},{op:0,bits:8,val:48},{op:0,bits:9,val:193},{op:16,bits:7,val:10},{op:0,bits:8,val:96},{op:0,bits:8,val:32},{op:0,bits:9,val:161},{op:0,bits:8,val:0},{op:0,bits:8,val:128},{op:0,bits:8,val:64},{op:0,bits:9,val:225},{op:16,bits:7,val:6},{op:0,bits:8,val:88},{op:0,bits:8,val:24},{op:0,bits:9,val:145},{op:19,bits:7,val:59},{op:0,bits:8,val:120},{op:0,bits:8,val:56},{op:0,bits:9,val:209},{op:17,bits:7,val:17},{op:0,bits:8,val:104},{op:0,bits:8,val:40},{op:0,bits:9,val:177},{op:0,bits:8,val:8},{op:0,bits:8,val:136},{op:0,bits:8,val:72},{op:0,bits:9,val:241},{op:16,bits:7,val:4},{op:0,bits:8,val:84},{op:0,bits:8,val:20},{op:21,bits:8,val:227},{op:19,bits:7,val:43},{op:0,bits:8,val:116},{op:0,bits:8,val:52},{op:0,bits:9,val:201},{op:17,bits:7,val:13},{op:0,bits:8,val:100},{op:0,bits:8,val:36},{op:0,bits:9,val:169},{op:0,bits:8,val:4},{op:0,bits:8,val:132},{op:0,bits:8,val:68},{op:0,bits:9,val:233},{op:16,bits:7,val:8},{op:0,bits:8,val:92},{op:0,bits:8,val:28},{op:0,bits:9,val:153},{op:20,bits:7,val:83},{op:0,bits:8,val:124},{op:0,bits:8,val:60},{op:0,bits:9,val:217},{op:18,bits:7,val:23},{op:0,bits:8,val:108},{op:0,bits:8,val:44},{op:0,bits:9,val:185},{op:0,bits:8,val:12},{op:0,bits:8,val:140},{op:0,bits:8,val:76},{op:0,bits:9,val:249},{op:16,bits:7,val:3},{op:0,bits:8,val:82},{op:0,bits:8,val:18},{op:21,bits:8,val:163},{op:19,bits:7,val:35},{op:0,bits:8,val:114},{op:0,bits:8,val:50},{op:0,bits:9,val:197},{op:17,bits:7,val:11},{op:0,bits:8,val:98},{op:0,bits:8,val:34},{op:0,bits:9,val:165},{op:0,bits:8,val:2},{op:0,bits:8,val:130},{op:0,bits:8,val:66},{op:0,bits:9,val:229},{op:16,bits:7,val:7},{op:0,bits:8,val:90},{op:0,bits:8,val:26},{op:0,bits:9,val:149},{op:20,bits:7,val:67},{op:0,bits:8,val:122},{op:0,bits:8,val:58},{op:0,bits:9,val:213},{op:18,bits:7,val:19},{op:0,bits:8,val:106},{op:0,bits:8,val:42},{op:0,bits:9,val:181},{op:0,bits:8,val:10},{op:0,bits:8,val:138},{op:0,bits:8,val:74},{op:0,bits:9,val:245},{op:16,bits:7,val:5},{op:0,bits:8,val:86},{op:0,bits:8,val:22},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:118},{op:0,bits:8,val:54},{op:0,bits:9,val:205},{op:17,bits:7,val:15},{op:0,bits:8,val:102},{op:0,bits:8,val:38},{op:0,bits:9,val:173},{op:0,bits:8,val:6},{op:0,bits:8,val:134},{op:0,bits:8,val:70},{op:0,bits:9,val:237},{op:16,bits:7,val:9},{op:0,bits:8,val:94},{op:0,bits:8,val:30},{op:0,bits:9,val:157},{op:20,bits:7,val:99},{op:0,bits:8,val:126},{op:0,bits:8,val:62},{op:0,bits:9,val:221},{op:18,bits:7,val:27},{op:0,bits:8,val:110},{op:0,bits:8,val:46},{op:0,bits:9,val:189},{op:0,bits:8,val:14},{op:0,bits:8,val:142},{op:0,bits:8,val:78},{op:0,bits:9,val:253},{op:96,bits:7,val:0},{op:0,bits:8,val:81},{op:0,bits:8,val:17},{op:21,bits:8,val:131},{op:18,bits:7,val:31},{op:0,bits:8,val:113},{op:0,bits:8,val:49},{op:0,bits:9,val:195},{op:16,bits:7,val:10},{op:0,bits:8,val:97},{op:0,bits:8,val:33},{op:0,bits:9,val:163},{op:0,bits:8,val:1},{op:0,bits:8,val:129},{op:0,bits:8,val:65},{op:0,bits:9,val:227},{op:16,bits:7,val:6},{op:0,bits:8,val:89},{op:0,bits:8,val:25},{op:0,bits:9,val:147},{op:19,bits:7,val:59},{op:0,bits:8,val:121},{op:0,bits:8,val:57},{op:0,bits:9,val:211},{op:17,bits:7,val:17},{op:0,bits:8,val:105},{op:0,bits:8,val:41},{op:0,bits:9,val:179},{op:0,bits:8,val:9},{op:0,bits:8,val:137},{op:0,bits:8,val:73},{op:0,bits:9,val:243},{op:16,bits:7,val:4},{op:0,bits:8,val:85},{op:0,bits:8,val:21},{op:16,bits:8,val:258},{op:19,bits:7,val:43},{op:0,bits:8,val:117},{op:0,bits:8,val:53},{op:0,bits:9,val:203},{op:17,bits:7,val:13},{op:0,bits:8,val:101},{op:0,bits:8,val:37},{op:0,bits:9,val:171},{op:0,bits:8,val:5},{op:0,bits:8,val:133},{op:0,bits:8,val:69},{op:0,bits:9,val:235},{op:16,bits:7,val:8},{op:0,bits:8,val:93},{op:0,bits:8,val:29},{op:0,bits:9,val:155},{op:20,bits:7,val:83},{op:0,bits:8,val:125},{op:0,bits:8,val:61},{op:0,bits:9,val:219},{op:18,bits:7,val:23},{op:0,bits:8,val:109},{op:0,bits:8,val:45},{op:0,bits:9,val:187},{op:0,bits:8,val:13},{op:0,bits:8,val:141},{op:0,bits:8,val:77},{op:0,bits:9,val:251},{op:16,bits:7,val:3},{op:0,bits:8,val:83},{op:0,bits:8,val:19},{op:21,bits:8,val:195},{op:19,bits:7,val:35},{op:0,bits:8,val:115},{op:0,bits:8,val:51},{op:0,bits:9,val:199},{op:17,bits:7,val:11},{op:0,bits:8,val:99},{op:0,bits:8,val:35},{op:0,bits:9,val:167},{op:0,bits:8,val:3},{op:0,bits:8,val:131},{op:0,bits:8,val:67},{op:0,bits:9,val:231},{op:16,bits:7,val:7},{op:0,bits:8,val:91},{op:0,bits:8,val:27},{op:0,bits:9,val:151},{op:20,bits:7,val:67},{op:0,bits:8,val:123},{op:0,bits:8,val:59},{op:0,bits:9,val:215},{op:18,bits:7,val:19},{op:0,bits:8,val:107},{op:0,bits:8,val:43},{op:0,bits:9,val:183},{op:0,bits:8,val:11},{op:0,bits:8,val:139},{op:0,bits:8,val:75},{op:0,bits:9,val:247},{op:16,bits:7,val:5},{op:0,bits:8,val:87},{op:0,bits:8,val:23},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:119},{op:0,bits:8,val:55},{op:0,bits:9,val:207},{op:17,bits:7,val:15},{op:0,bits:8,val:103},{op:0,bits:8,val:39},{op:0,bits:9,val:175},{op:0,bits:8,val:7},{op:0,bits:8,val:135},{op:0,bits:8,val:71},{op:0,bits:9,val:239},{op:16,bits:7,val:9},{op:0,bits:8,val:95},{op:0,bits:8,val:31},{op:0,bits:9,val:159},{op:20,bits:7,val:99},{op:0,bits:8,val:127},{op:0,bits:8,val:63},{op:0,bits:9,val:223},{op:18,bits:7,val:27},{op:0,bits:8,val:111},{op:0,bits:8,val:47},{op:0,bits:9,val:191},{op:0,bits:8,val:15},{op:0,bits:8,val:143},{op:0,bits:8,val:79},{op:0,bits:9,val:255}]}if(!t){t=[{op:16,bits:5,val:1},{op:23,bits:5,val:257},{op:19,bits:5,val:17},{op:27,bits:5,val:4097},{op:17,bits:5,val:5},{op:25,bits:5,val:1025},{op:21,bits:5,val:65},{op:29,bits:5,val:16385},{op:16,bits:5,val:3},{op:24,bits:5,val:513},{op:20,bits:5,val:33},{op:28,bits:5,val:8193},{op:18,bits:5,val:9},{op:26,bits:5,val:2049},{op:22,bits:5,val:129},{op:64,bits:5,val:0},{op:16,bits:5,val:2},{op:23,bits:5,val:385},{op:19,bits:5,val:25},{op:27,bits:5,val:6145},{op:17,bits:5,val:7},{op:25,bits:5,val:1537},{op:21,bits:5,val:97},{op:29,bits:5,val:24577},{op:16,bits:5,val:4},{op:24,bits:5,val:769},{op:20,bits:5,val:49},{op:28,bits:5,val:12289},{op:18,bits:5,val:13},{op:26,bits:5,val:3073},{op:22,bits:5,val:193},{op:64,bits:5,val:0}]}ar.lencode=0;ar.distcode=512;for(aq=0;aq<512;aq++){ar.codes[aq]=U[aq]}for(aq=0;aq<32;aq++){ar.codes[aq+512]=t[aq]}ar.lenbits=9;ar.distbits=5}function ap(at){var ar=at.state;var aq=at.output_data.length;if(ar.window===null){ar.window=""}if(ar.wsize==0){ar.wsize=1<<ar.wbits}if(aq>=ar.wsize){ar.window=at.output_data.substring(aq-ar.wsize)}else{if(ar.whave+aq<ar.wsize){ar.window+=at.output_data}else{ar.window=ar.window.substring(ar.whave-(ar.wsize-aq))+at.output_data}}ar.whave=ar.window.length;if(ar.whave<ar.wsize){ar.wnext=ar.whave}else{ar.wnext=0}return 0}function m(ar,at){var aq=[at&255,(at>>>8)&255];ar.state.check=ar.checksum_function(ar.state.check,aq,0,2)}function n(ar,at){var aq=[at&255,(at>>>8)&255,(at>>>16)&255,(at>>>24)&255];ar.state.check=ar.checksum_function(ar.state.check,aq,0,4)}function Z(ar,aq){aq.strm=ar;aq.left=ar.avail_out;aq.next=ar.next_in;aq.have=ar.avail_in;aq.hold=ar.state.hold;aq.bits=ar.state.bits;return aq}function ah(aq){var ar=aq.strm;ar.next_in=aq.next;ar.avail_out=aq.left;ar.avail_in=aq.have;ar.state.hold=aq.hold;ar.state.bits=aq.bits}function P(aq){aq.hold=0;aq.bits=0}function ag(aq){if(aq.have==0){return false}aq.have--;aq.hold+=(aq.strm.input_data.charCodeAt(aq.next++)&255)<<aq.bits;aq.bits+=8;return true}function ad(ar,aq){while(ar.bits<aq){if(!ag(ar)){return false}}return true}function b(ar,aq){return ar.hold&((1<<aq)-1)}function w(ar,aq){ar.hold>>>=aq;ar.bits-=aq}function c(aq){aq.hold>>>=aq.bits&7;aq.bits-=aq.bits&7}function ai(aq){return((aq>>>24)&255)+((aq>>>8)&65280)+((aq&65280)<<8)+((aq&255)<<24)}var I=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];ZLIB.inflate=function(aD,at){var aC;var aB;var aq,az;var ar;var av=-1;var au=-1;var aw;var ax;var ay;var aA;if(!aD||!aD.state||(!aD.input_data&&aD.avail_in!=0)){return ZLIB.Z_STREAM_ERROR}aC=aD.state;if(aC.mode==an){aC.mode=ao}aB={};Z(aD,aB);aq=aB.have;az=aB.left;aA=ZLIB.Z_OK;inf_leave:for(;;){switch(aC.mode){case G:if(aC.wrap==0){aC.mode=ao;break}if(!ad(aB,16)){break inf_leave}if((aC.wrap&2)&&aB.hold==35615){aC.check=aD.checksum_function(0,null,0,0);m(aD,aB.hold);P(aB);aC.mode=D;break}aC.flags=0;if(aC.head!==null){aC.head.done=-1}if(!(aC.wrap&1)||((b(aB,8)<<8)+(aB.hold>>>8))%31){aD.msg="incorrect header check";aC.mode=a;break}if(b(aB,4)!=ZLIB.Z_DEFLATED){aD.msg="unknown compression method";aC.mode=a;break}w(aB,4);ay=b(aB,4)+8;if(aC.wbits==0){aC.wbits=ay}else{if(ay>aC.wbits){aD.msg="invalid window size";aC.mode=a;break}}aC.dmax=1<<ay;aD.adler=aC.check=aD.checksum_function(0,null,0,0);aC.mode=aB.hold&512?q:an;P(aB);break;case D:if(!ad(aB,16)){break inf_leave}aC.flags=aB.hold;if((aC.flags&255)!=ZLIB.Z_DEFLATED){aD.msg="unknown compression method";aC.mode=a;break}if(aC.flags&57344){aD.msg="unknown header flags set";aC.mode=a;break}if(aC.head!==null){aC.head.text=(aB.hold>>>8)&1}if(aC.flags&512){m(aD,aB.hold)}P(aB);aC.mode=am;case am:if(!ad(aB,32)){break inf_leave}if(aC.head!==null){aC.head.time=aB.hold}if(aC.flags&512){n(aD,aB.hold)}P(aB);aC.mode=af;case af:if(!ad(aB,16)){break inf_leave}if(aC.head!==null){aC.head.xflags=aB.hold&255;aC.head.os=aB.hold>>>8}if(aC.flags&512){m(aD,aB.hold)}P(aB);aC.mode=A;case A:if(aC.flags&1024){if(!ad(aB,16)){break inf_leave}aC.length=aB.hold;if(aC.head!==null){aC.head.extra_len=aB.hold}if(aC.flags&512){m(aD,aB.hold)}P(aB);aC.head.extra=""}else{if(aC.head!==null){aC.head.extra=null}}aC.mode=B;case B:if(aC.flags&1024){ar=aC.length;if(ar>aB.have){ar=aB.have}if(ar){if(aC.head!==null&&aC.head.extra!==null){ay=aC.head.extra_len-aC.length;aC.head.extra+=aD.input_data.substring(aB.next,aB.next+(ay+ar>aC.head.extra_max?aC.head.extra_max-ay:ar))}if(aC.flags&512){aC.check=aD.checksum_function(aC.check,aD.input_data,aB.next,ar)}aB.have-=ar;aB.next+=ar;aC.length-=ar}if(aC.length){break inf_leave}}aC.length=0;aC.mode=ac;case ac:if(aC.flags&2048){if(aB.have==0){break inf_leave}if(aC.head!==null&&aC.head.name===null){aC.head.name=""}ar=0;do{ay=aD.input_data.charAt(aB.next+ar);ar++;if(ay==="\0"){break}if(aC.head!==null&&aC.length<aC.head.name_max){aC.head.name+=ay;aC.length++}}while(ar<aB.have);if(aC.flags&512){aC.check=aD.checksum_function(aC.check,aD.input_data,aB.next,ar)}aB.have-=ar;aB.next+=ar;if(ay!=="\0"){break inf_leave}}else{if(aC.head!==null){aC.head.name=null}}aC.length=0;aC.mode=j;case j:if(aC.flags&4096){if(aB.have==0){break inf_leave}ar=0;if(aC.head!==null&&aC.head.comment===null){aC.head.comment=""}do{ay=aD.input_data.charAt(aB.next+ar);ar++;if(ay==="\0"){break}if(aC.head!==null&&aC.length<aC.head.comm_max){aC.head.comment+=ay;aC.length++}}while(ar<aB.have);if(aC.flags&512){aC.check=aD.checksum_function(aC.check,aD.input_data,aB.next,ar)}aB.have-=ar;aB.next+=ar;if(ay!=="\0"){break inf_leave}}else{if(aC.head!==null){aC.head.comment=null}}aC.mode=F;case F:if(aC.flags&512){if(!ad(aB,16)){break inf_leave}if(aB.hold!=(aC.check&65535)){aD.msg="header crc mismatch";aC.mode=a;break}P(aB)}if(aC.head!==null){aC.head.hcrc=(aC.flags>>>9)&1;aC.head.done=1}aD.adler=aC.check=aD.checksum_function(0,null,0,0);aC.mode=an;break;case q:if(!ad(aB,32)){break inf_leave}aD.adler=aC.check=ai(aB.hold);P(aB);aC.mode=p;case p:if(aC.havedict==0){ah(aB);return ZLIB.Z_NEED_DICT}aD.adler=aC.check=aD.checksum_function(0,null,0,0);aC.mode=an;case an:if(at==ZLIB.Z_BLOCK||at==ZLIB.Z_TREES){break inf_leave}case ao:if(aC.last){c(aB);aC.mode=d;break}if(!ad(aB,3)){break inf_leave}aC.last=b(aB,1);w(aB,1);switch(b(aB,2)){case 0:aC.mode=aj;break;case 1:C(aC);aC.mode=S;if(at==ZLIB.Z_TREES){w(aB,2);break inf_leave}break;case 2:aC.mode=al;break;case 3:aD.msg="invalid block type";aC.mode=a}w(aB,2);break;case aj:c(aB);if(!ad(aB,32)){break inf_leave}if((aB.hold&65535)!=(((aB.hold>>>16)&65535)^65535)){aD.msg="invalid stored block lengths";aC.mode=a;break}aC.length=aB.hold&65535;P(aB);aC.mode=l;if(at==ZLIB.Z_TREES){break inf_leave}case l:aC.mode=k;case k:ar=aC.length;if(ar){if(ar>aB.have){ar=aB.have}if(ar>aB.left){ar=aB.left}if(ar==0){break inf_leave}aD.output_data+=aD.input_data.substring(aB.next,aB.next+ar);aD.next_out+=ar;aB.have-=ar;aB.next+=ar;aB.left-=ar;aC.length-=ar;break}aC.mode=an;break;case al:if(!ad(aB,14)){break inf_leave}aC.nlen=b(aB,5)+257;w(aB,5);aC.ndist=b(aB,5)+1;w(aB,5);aC.ncode=b(aB,4)+4;w(aB,4);if(aC.nlen>286||aC.ndist>30){aD.msg="too many length or distance symbols";aC.mode=a;break}aC.have=0;aC.mode=W;case W:while(aC.have<aC.ncode){if(!ad(aB,3)){break inf_leave}var aE=b(aB,3);aC.lens[I[aC.have++]]=aE;w(aB,3)}while(aC.have<19){aC.lens[I[aC.have++]]=0}aC.next=0;aC.lencode=0;aC.lenbits=7;aA=K(aC,h);if(aA){aD.msg="invalid code lengths set";aC.mode=a;break}aC.have=0;aC.mode=g;case g:while(aC.have<aC.nlen+aC.ndist){for(;;){aw=aC.codes[aC.lencode+b(aB,aC.lenbits)];if(aw.bits<=aB.bits){break}if(!ag(aB)){break inf_leave}}if(aw.val<16){w(aB,aw.bits);aC.lens[aC.have++]=aw.val}else{if(aw.val==16){if(!ad(aB,aw.bits+2)){break inf_leave}w(aB,aw.bits);if(aC.have==0){aD.msg="invalid bit length repeat";aC.mode=a;break}ay=aC.lens[aC.have-1];ar=3+b(aB,2);w(aB,2)}else{if(aw.val==17){if(!ad(aB,aw.bits+3)){break inf_leave}w(aB,aw.bits);ay=0;ar=3+b(aB,3);w(aB,3)}else{if(!ad(aB,aw.bits+7)){break inf_leave}w(aB,aw.bits);ay=0;ar=11+b(aB,7);w(aB,7)}}if(aC.have+ar>aC.nlen+aC.ndist){aD.msg="invalid bit length repeat";aC.mode=a;break}while(ar--){aC.lens[aC.have++]=ay}}}if(aC.mode==a){break}if(aC.lens[256]==0){aD.msg="invalid code -- missing end-of-block";aC.mode=a;break}aC.next=0;aC.lencode=aC.next;aC.lenbits=9;aA=K(aC,X);if(aA){aD.msg="invalid literal/lengths set";aC.mode=a;break}aC.distcode=aC.next;aC.distbits=6;aA=K(aC,u);if(aA){aD.msg="invalid distances set";aC.mode=a;break}aC.mode=S;if(at==ZLIB.Z_TREES){break inf_leave}case S:aC.mode=R;case R:if(aB.have>=6&&aB.left>=258){ah(aB);H(aD,az);Z(aD,aB);if(aC.mode==an){aC.back=-1}break}aC.back=0;for(;;){aw=aC.codes[aC.lencode+b(aB,aC.lenbits)];if(aw.bits<=aB.bits){break}if(!ag(aB)){break inf_leave}}if(aw.op&&(aw.op&240)==0){ax=aw;for(;;){aw=aC.codes[aC.lencode+ax.val+(b(aB,ax.bits+ax.op)>>>ax.bits)];if(ax.bits+aw.bits<=aB.bits){break}if(!ag(aB)){break inf_leave}}w(aB,ax.bits);aC.back+=ax.bits}w(aB,aw.bits);aC.back+=aw.bits;aC.length=aw.val;if(aw.op==0){aC.mode=Y;break}if(aw.op&32){aC.back=-1;aC.mode=an;break}if(aw.op&64){aD.msg="invalid literal/length code";aC.mode=a;break}aC.extra=aw.op&15;aC.mode=T;case T:if(aC.extra){if(!ad(aB,aC.extra)){break inf_leave}aC.length+=b(aB,aC.extra);w(aB,aC.extra);aC.back+=aC.extra}aC.was=aC.length;aC.mode=r;case r:for(;;){aw=aC.codes[aC.distcode+b(aB,aC.distbits)];if(aw.bits<=aB.bits){break}if(!ag(aB)){break inf_leave}}if((aw.op&240)==0){ax=aw;for(;;){aw=aC.codes[aC.distcode+ax.val+(b(aB,ax.bits+ax.op)>>>ax.bits)];if((ax.bits+aw.bits)<=aB.bits){break}if(!ag(aB)){break inf_leave}}w(aB,ax.bits);aC.back+=ax.bits}w(aB,aw.bits);aC.back+=aw.bits;if(aw.op&64){aD.msg="invalid distance code";aC.mode=a;break}aC.offset=aw.val;aC.extra=aw.op&15;aC.mode=s;case s:if(aC.extra){if(!ad(aB,aC.extra)){break inf_leave}aC.offset+=b(aB,aC.extra);w(aB,aC.extra);aC.back+=aC.extra}aC.mode=aa;case aa:if(aB.left==0){break inf_leave}ar=az-aB.left;if(aC.offset>ar){ar=aC.offset-ar;if(ar>aC.whave){if(aC.sane){aD.msg="invalid distance too far back";aC.mode=a;break}}if(ar>aC.wnext){ar-=aC.wnext;av=aC.wsize-ar;au=-1}else{av=aC.wnext-ar;au=-1}if(ar>aC.length){ar=aC.length}}else{av=-1;au=aD.next_out-aC.offset;ar=aC.length}if(ar>aB.left){ar=aB.left}aB.left-=ar;aC.length-=ar;if(av>=0){aD.output_data+=aC.window.substring(av,av+ar);aD.next_out+=ar;ar=0}else{aD.next_out+=ar;do{aD.output_data+=aD.output_data.charAt(au++)}while(--ar)}if(aC.length==0){aC.mode=R}break;case Y:if(aB.left==0){break inf_leave}aD.output_data+=String.fromCharCode(aC.length);aD.next_out++;aB.left--;aC.mode=R;break;case d:if(aC.wrap){if(!ad(aB,32)){break inf_leave}az-=aB.left;aD.total_out+=az;aC.total+=az;if(az){aD.adler=aC.check=aD.checksum_function(aC.check,aD.output_data,aD.output_data.length-az,az)}az=aB.left;if((aC.flags?aB.hold:ai(aB.hold))!=aC.check){aD.msg="incorrect data check";aC.mode=a;break}P(aB)}aC.mode=V;case V:if(aC.wrap&&aC.flags){if(!ad(aB,32)){break inf_leave}if(aB.hold!=(aC.total&4294967295)){aD.msg="incorrect length check";aC.mode=a;break}P(aB)}aC.mode=v;case v:aA=ZLIB.Z_STREAM_END;break inf_leave;case a:aA=ZLIB.Z_DATA_ERROR;break inf_leave;case ab:return ZLIB.Z_MEM_ERROR;case ak:default:return ZLIB.Z_STREAM_ERROR}}inf_leave:ah(aB);if(aC.wsize||(az!=aD.avail_out&&aC.mode<a&&(aC.mode<d||at!=ZLIB.Z_FINISH))){if(ap(aD)){aC.mode=ab;return ZLIB.Z_MEM_ERROR}}aq-=aD.avail_in;az-=aD.avail_out;aD.total_in+=aq;aD.total_out+=az;aC.total+=az;if(aC.wrap&&az){aD.adler=aC.check=aD.checksum_function(aC.check,aD.output_data,0,aD.output_data.length)}aD.data_type=aC.bits+(aC.last?64:0)+(aC.mode==an?128:0)+(aC.mode==S||aC.mode==l?256:0);if(((aq==0&&az==0)||at==ZLIB.Z_FINISH)&&aA==ZLIB.Z_OK){aA=ZLIB.Z_BUF_ERROR}return aA};ZLIB.inflateEnd=function(ar){var aq;if(!ar||!ar.state){return ZLIB.Z_STREAM_ERROR}aq=ar.state;aq.window=null;ar.state=null;return ZLIB.Z_OK};ZLIB.z_stream.prototype.inflate=function(au,av){var at;var aq;var ar=16384;this.input_data=au;this.next_in=E(av,"next_in",0);this.avail_in=E(av,"avail_in",au.length-this.next_in);at=E(av,"flush",ZLIB.Z_SYNC_FLUSH);aq=E(av,"avail_out",-1);var aw="";do{this.avail_out=(aq>=0?aq:ar);this.output_data="";this.next_out=0;this.error=ZLIB.inflate(this,at);if(aq>=0){return this.output_data}aw+=this.output_data;if(this.avail_out>0){break}}while(this.error==ZLIB.Z_OK);return aw};ZLIB.z_stream.prototype.inflateReset=function(aq){return ZLIB.inflateReset(this,aq)}}());if(typeof ZLIB==="undefined"){alert("ZLIB is not defined. SRC zlib.js before zlib-adler32.js")}(function(){var c=65521;var d=5552;function b(e,g,k,h){var l;var j;l=(e>>>16)&65535;e&=65535;if(h==1){e+=g.charCodeAt(k)&255;if(e>=c){e-=c}l+=e;if(l>=c){l-=c}return e|(l<<16)}if(g===null){return 1}if(h<16){while(h--){e+=g.charCodeAt(k++)&255;l+=e}if(e>=c){e-=c}l%=c;return e|(l<<16)}while(h>=d){h-=d;j=d>>4;do{e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e}while(--j);e%=c;l%=c}if(h){while(h>=16){h-=16;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e;e+=g.charCodeAt(k++)&255;l+=e}while(h--){e+=g.charCodeAt(k++)&255;l+=e}e%=c;l%=c}return e|(l<<16)}function a(e,g,k,h){var l;var j;l=(e>>>16)&65535;e&=65535;if(h==1){e+=g[k];if(e>=c){e-=c}l+=e;if(l>=c){l-=c}return e|(l<<16)}if(g===null){return 1}if(h<16){while(h--){e+=g[k++];l+=e}if(e>=c){e-=c}l%=c;return e|(l<<16)}while(h>=d){h-=d;j=d>>4;do{e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e}while(--j);e%=c;l%=c}if(h){while(h>=16){h-=16;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e;e+=g[k++];l+=e}while(h--){e+=g[k++];l+=e}e%=c;l%=c}return e|(l<<16)}ZLIB.adler32=function(e,g,j,h){if(typeof g==="string"){return b(e,g,j,h)}else{return a(e,g,j,h)}};ZLIB.adler32_combine=function(e,g,h){var k;var l;var j;if(h<0){return 4294967295}h%=c;j=h;k=e&65535;l=j*k;l%=c;k+=(g&65535)+c-1;l+=((e>>16)&65535)+((g>>16)&65535)+c-j;if(k>=c){k-=c}if(k>=c){k-=c}if(l>=(c<<1)){l-=(c<<1)}if(l>=c){l-=c}return k|(l<<16)}}());if(typeof ZLIB==="undefined"){alert("ZLIB is not defined. SRC zlib.js before zlib-crc32.js")}(function(){var a=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918000,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];function c(j,h,l,k){if(h==null){return 0}j=j^4294967295;while(k>=8){j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);j=a[(j^h.charCodeAt(l++))&255]^(j>>>8);k-=8}if(k){do{j=a[(j^h.charCodeAt(l++))&255]^(j>>>8)}while(--k)}return j^4294967295}function b(j,h,l,k){if(h==null){return 0}j=j^4294967295;while(k>=8){j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);j=a[(j^h[l++])&255]^(j>>>8);k-=8}if(k){do{j=a[(j^h[l++])&255]^(j>>>8)}while(--k)}return j^4294967295}ZLIB.crc32=function(j,h,l,k){if(typeof h==="string"){return c(j,h,l,k)}else{return b(j,h,l,k)}};var d=32;function g(h,l){var k;var j=0;k=0;while(l){if(l&1){k^=h[j]}l>>=1;j++}return k}function e(k,h){var j;for(j=0;j<d;j++){k[j]=g(h,h[j])}}ZLIB.crc32_combine=function(h,j,l){var m;var p;var k;var o;if(l<=0){return h}k=new Array(d);o=new Array(d);o[0]=3988292384;p=1;for(m=1;m<d;m++){o[m]=p;p<<=1}e(k,o);e(o,k);do{e(k,o);if(l&1){h=g(k,h)}l>>=1;if(l==0){break}e(o,k);if(l&1){h=g(o,h)}l>>=1}while(l!=0);h^=j;return h}}());var CreateAmtRedirect=function(e,a){var g={};g.m=e;e.parent=g;g.authCookie=a;g.State=0;g.socket=null;g.host=null;g.port=0;g.user=null;g.pass=null;g.authuri="/RedirectionService";g.tlsv1only=0;g.inDataCount=0;g.connectstate=0;g.protocol=e.protocol;g.debugmode=0;g.amtaccumulator="";g.amtsequence=1;g.amtkeepalivetimer=null;g.onStateChanged=null;g.Start=function(h,k,n,j,l){g.host=h;g.port=k;g.user=n;g.pass=j;g.connectstate=0;g.inDataCount=0;var m=window.location.protocol.replace("http","ws")+"//"+window.location.host+window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/"))+"/webrelay.ashx?p=2&host="+h+"&port="+k+"&tls="+l+((n=="*")?"&serverauth=1":"")+((typeof j==="undefined")?("&serverauth=1&user="+n):"");if((a!=null)&&(a!="")){m+="&auth="+a}g.socket=new WebSocket(m);g.socket.onopen=g.xxOnSocketConnected;g.socket.onmessage=g.xxOnMessage;g.socket.onclose=g.xxOnSocketClosed;g.xxStateChange(1)};g.xxOnSocketConnected=function(){if(g.debugmode==1){console.log("onSocketConnected")}g.xxStateChange(2);if(g.protocol==1){g.xxSend(g.RedirectStartSol)}if(g.protocol==2){g.xxSend(g.RedirectStartKvm)}if(g.protocol==3){g.xxSend(g.RedirectStartIder)}};var b=new FileReader();var d=false,c=[];if(b.readAsBinaryString){b.onload=function(h){g.xxOnSocketData(h.target.result);if(c.length==0){d=false}else{b.readAsBinaryString(new Blob([c.shift()]))}}}else{if(b.readAsArrayBuffer){b.onloadend=function(h){g.xxOnSocketData(h.target.result);if(c.length==0){d=false}else{b.readAsArrayBuffer(c.shift())}}}}g.xxOnMessage=function(k){g.inDataCount++;if(typeof k.data=="object"){if(d==true){c.push(k.data);return}if(b.readAsBinaryString){d=true;b.readAsBinaryString(new Blob([k.data]))}else{if(f.readAsArrayBuffer){d=true;b.readAsArrayBuffer(k.data)}else{var h="",j=new Uint8Array(k.data),m=j.byteLength;for(var l=0;l<m;l++){h+=String.fromCharCode(j[l])}g.xxOnSocketData(h)}}}else{g.xxOnSocketData(k.data)}};g.xxOnSocketData=function(t){if(!t||g.connectstate==-1){return}if(typeof t==="object"){var m="";var o=new Uint8Array(t);var y=o.byteLength;for(var x=0;x<y;x++){m+=String.fromCharCode(o[x])}t=m}else{if(typeof t!=="string"){return}}if((g.protocol==2||g.protocol==3)&&g.connectstate==1){return g.m.ProcessData(t)}g.amtaccumulator+=t;while(g.amtaccumulator.length>=1){var p=0;switch(g.amtaccumulator.charCodeAt(0)){case 17:if(g.amtaccumulator.length<4){return}var L=g.amtaccumulator.charCodeAt(1);switch(L){case 0:if(g.amtaccumulator.length<13){return}var C=g.amtaccumulator.charCodeAt(12);if(g.amtaccumulator.length<13+C){return}g.xxSend(String.fromCharCode(19,0,0,0,0,0,0,0,0));p=(13+C);break;default:g.Stop(1);break}break;case 20:if(g.amtaccumulator.length<9){return}var k=ReadIntX(g.amtaccumulator,5);if(g.amtaccumulator.length<9+k){return}var K=g.amtaccumulator.charCodeAt(1);var l=g.amtaccumulator.charCodeAt(4);var h=[];for(x=0;x<k;x++){h.push(g.amtaccumulator.charCodeAt(9+x))}var j=g.amtaccumulator.substring(9,9+k);p=9+k;if(l==0){if(h.indexOf(4)>=0){g.xxSend(String.fromCharCode(19,0,0,0,4)+IntToStrX(g.user.length+g.authuri.length+8)+String.fromCharCode(g.user.length)+g.user+String.fromCharCode(0,0)+String.fromCharCode(g.authuri.length)+g.authuri+String.fromCharCode(0,0,0,0))}else{if(h.indexOf(3)>=0){g.xxSend(String.fromCharCode(19,0,0,0,3)+IntToStrX(g.user.length+g.authuri.length+7)+String.fromCharCode(g.user.length)+g.user+String.fromCharCode(0,0)+String.fromCharCode(g.authuri.length)+g.authuri+String.fromCharCode(0,0,0))}else{if(h.indexOf(1)>=0){g.xxSend(String.fromCharCode(19,0,0,0,1)+IntToStrX(g.user.length+g.pass.length+2)+String.fromCharCode(g.user.length)+g.user+String.fromCharCode(g.pass.length)+g.pass)}else{g.Stop(2)}}}}else{if((l==3||l==4)&&K==1){var s=0;var G=j.charCodeAt(s);var F=j.substring(s+1,s+1+G);s+=(G+1);var B=j.charCodeAt(s);var A=j.substring(s+1,s+1+B);s+=(B+1);var E=0;var D=null;var q=g.xxRandomNonce(32);var J="00000002";var v="";if(l==4){E=j.charCodeAt(s);D=j.substring(s+1,s+1+E);s+=(E+1);v=J+":"+q+":"+D+":"}var u=hex_md5(hex_md5(g.user+":"+F+":"+g.pass)+":"+A+":"+v+hex_md5("POST:"+g.authuri));var M=g.user.length+F.length+A.length+g.authuri.length+q.length+J.length+u.length+7;if(l==4){M+=(D.length+1)}var n=String.fromCharCode(19,0,0,0,l)+IntToStrX(M)+String.fromCharCode(g.user.length)+g.user+String.fromCharCode(F.length)+F+String.fromCharCode(A.length)+A+String.fromCharCode(g.authuri.length)+g.authuri+String.fromCharCode(q.length)+q+String.fromCharCode(J.length)+J+String.fromCharCode(u.length)+u;if(l==4){n+=(String.fromCharCode(D.length)+D)}g.xxSend(n)}else{if(K==0){if(g.protocol==1){var z=10000;var O=100;var N=0;var I=10000;var H=100;var w=0;g.xxSend(String.fromCharCode(32,0,0,0)+IntToStrX(g.amtsequence++)+ShortToStrX(z)+ShortToStrX(O)+ShortToStrX(N)+ShortToStrX(I)+ShortToStrX(H)+ShortToStrX(w)+IntToStrX(0))}if(g.protocol==2){g.xxSend(String.fromCharCode(64,0,0,0,0,0,0,0))}if(g.protocol==3){g.connectstate=1;g.xxStateChange(3)}}else{g.Stop(3)}}}break;case 33:if(g.amtaccumulator.length<23){break}p=23;g.xxSend(String.fromCharCode(39,0,0,0)+IntToStrX(g.amtsequence++)+String.fromCharCode(0,0,27,0,0,0));if(g.protocol==1){g.amtkeepalivetimer=setInterval(g.xxSendAmtKeepAlive,2000)}g.connectstate=1;g.xxStateChange(3);break;case 41:if(g.amtaccumulator.length<10){break}p=10;break;case 42:if(g.amtaccumulator.length<10){break}var r=(10+((g.amtaccumulator.charCodeAt(9)&255)<<8)+(g.amtaccumulator.charCodeAt(8)&255));if(g.amtaccumulator.length<r){break}g.m.ProcessData(g.amtaccumulator.substring(10,r));p=r;break;case 43:if(g.amtaccumulator.length<8){break}p=8;break;case 65:if(g.amtaccumulator.length<8){break}g.connectstate=1;g.m.Start();if(g.amtaccumulator.length>8){g.m.ProcessData(g.amtaccumulator.substring(8))}p=g.amtaccumulator.length;break;default:console.log("Unknown Intel AMT command: "+g.amtaccumulator.charCodeAt(0)+" acclen="+g.amtaccumulator.length);g.Stop(4);return}if(p==0){return}g.amtaccumulator=g.amtaccumulator.substring(p)}};g.xxSend=function(k){if(g.socket!=null&&g.socket.readyState==WebSocket.OPEN){if(g.debugmode==1){console.log("Send",k)}var h=new Uint8Array(k.length);for(var j=0;j<k.length;++j){h[j]=k.charCodeAt(j)}g.socket.send(h.buffer)}};g.send=function(h){if(g.socket==null||g.connectstate!=1){return}if(g.protocol==1){g.xxSend(String.fromCharCode(40,0,0,0)+IntToStrX(g.amtsequence++)+ShortToStrX(h.length)+h)}else{g.xxSend(h)}};g.xxSendAmtKeepAlive=function(){if(g.socket==null){return}g.xxSend(String.fromCharCode(43,0,0,0)+IntToStrX(g.amtsequence++))};g.xxRandomNonceX="abcdef0123456789";g.xxRandomNonce=function(j){var k="";for(var h=0;h<j;h++){k+=g.xxRandomNonceX.charAt(Math.floor(Math.random()*g.xxRandomNonceX.length))}return k};g.xxOnSocketClosed=function(){if(g.debugmode==1){console.log("onSocketClosed")}if((g.inDataCount==0)&&(g.tlsv1only==0)){g.tlsv1only=1;g.socket=new WebSocket(window.location.protocol.replace("http","ws")+"//"+window.location.host+window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/"))+"/webrelay.ashx?p=2&host="+g.host+"&port="+g.port+"&tls="+g.tls+"&tls1only=1"+((g.user=="*")?"&serverauth=1":"")+((typeof pass==="undefined")?("&serverauth=1&user="+g.user):""));g.socket.onopen=g.xxOnSocketConnected;g.socket.onmessage=g.xxOnMessage;g.socket.onclose=g.xxOnSocketClosed}else{g.Stop(5)}};g.xxStateChange=function(h){if(g.State==h){return}g.State=h;g.m.xxStateChange(g.State);if(g.onStateChanged!=null){g.onStateChanged(g,g.State)}};g.Stop=function(h){if(g.debugmode==1){console.log("onSocketStop",h)}g.xxStateChange(0);g.connectstate=-1;g.amtaccumulator="";if(g.socket!=null){g.socket.close();g.socket=null}if(g.amtkeepalivetimer!=null){clearInterval(g.amtkeepalivetimer);g.amtkeepalivetimer=null}};g.RedirectStartSol=String.fromCharCode(16,0,0,0,83,79,76,32);g.RedirectStartKvm=String.fromCharCode(16,1,0,0,75,86,77,82);g.RedirectStartIder=String.fromCharCode(16,0,0,0,73,68,69,82);return g};var CreateWsmanComm=function(l,o,q,n,p){var m={};m.PendingAjax=[];m.ActiveAjaxCount=0;m.MaxActiveAjaxCount=1;m.FailAllError=0;m.challengeParams=null;m.noncecounter=1;m.authcounter=0;m.socket=null;m.socketState=0;m.host=l;m.port=o;m.user=q;m.pass=n;m.tls=p;m.tlsv1only=1;m.cnonce=Math.random().toString(36).substring(7);m.PerformAjax=function(t,s,v,u,w,r){if(m.ActiveAjaxCount<m.MaxActiveAjaxCount&&m.PendingAjax.length==0){m.PerformAjaxEx(t,s,v,w,r)}else{if(u==1){m.PendingAjax.unshift([t,s,v,w,r])}else{m.PendingAjax.push([t,s,v,w,r])}}};m.PerformNextAjax=function(){if(m.ActiveAjaxCount>=m.MaxActiveAjaxCount||m.PendingAjax.length==0){return}var r=m.PendingAjax.shift();m.PerformAjaxEx(r[0],r[1],r[2],r[3],r[4]);m.PerformNextAjax()};m.PerformAjaxEx=function(t,s,u,v,r){if(m.FailAllError!=0){m.gotNextMessagesError({status:m.FailAllError},"error",null,[t,s,u,v,r]);return}if(!t){t=""}m.ActiveAjaxCount++;return m.PerformAjaxExNodeJS(t,s,u,v,r)};m.pendingAjaxCall=[];m.PerformAjaxExNodeJS=function(t,s,u,v,r){m.PerformAjaxExNodeJS2(t,s,u,v,r,3)};m.PerformAjaxExNodeJS2=function(t,s,v,w,r,u){if(u<=0||m.FailAllError!=0){m.ActiveAjaxCount--;if(m.FailAllError!=999){m.gotNextMessages(null,"error",{status:((m.FailAllError==0)?408:m.FailAllError)},[t,s,v,w,r])}m.PerformNextAjax();return}m.pendingAjaxCall.push([t,s,v,w,r,u]);if(m.socketState==0){m.xxConnectHttpSocket()}else{if(m.socketState==2){m.sendRequest(t,w,r)}}};m.sendRequest=function(t,v,r){v=v?v:"/wsman";r=r?r:"POST";var s=r+" "+v+" HTTP/1.1\r\n";if(m.challengeParams!=null){var u=hex_md5(hex_md5(m.user+":"+m.challengeParams.realm+":"+m.pass)+":"+m.challengeParams.nonce+":"+m.noncecounter+":"+m.cnonce+":"+m.challengeParams.qop+":"+hex_md5(r+":"+v));s+="Authorization: "+m.renderDigest({username:m.user,realm:m.challengeParams.realm,nonce:m.challengeParams.nonce,uri:v,qop:m.challengeParams.qop,response:u,nc:m.noncecounter++,cnonce:m.cnonce})+"\r\n"}s+="Host: "+m.host+":"+m.port+"\r\nTransfer-Encoding: chunked\r\n\r\n"+t.length.toString(16).toUpperCase()+"\r\n"+t+"\r\n0\r\n\r\n";g(s)};m.parseDigest=function(r){var s=r.substring(7).split(",");for(i in s){s[i]=s[i].trim()}return s.reduce(function(t,v){var u=v.split("=");t[u[0]]=u[1].replace(/"/g,"");return t},{})};m.renderDigest=function(r){var s=[];for(i in r){s.push(i)}return"Digest "+s.reduce(function(u,t){return u+","+t+'="'+r[t]+'"'},"").substring(1)};m.xxConnectHttpSocket=function(){m.socketParseState=0;m.socketAccumulator="";m.socketHeader=null;m.socketData="";m.socketState=1;console.log(m.tlsv1only);m.socket=new WebSocket(window.location.protocol.replace("http","ws")+"//"+window.location.host+window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/"))+"/webrelay.ashx?p=1&host="+m.host+"&port="+m.port+"&tls="+m.tls+"&tlsv1only="+m.tlsv1only+((q=="*")?"&serverauth=1":"")+((typeof n==="undefined")?("&serverauth=1&user="+q):""));m.socket.onopen=c;m.socket.onmessage=a;m.socket.onclose=b};function c(){m.socketState=2;for(i in m.pendingAjaxCall){m.sendRequest(m.pendingAjaxCall[i][0],m.pendingAjaxCall[i][3],m.pendingAjaxCall[i][4])}}var h=new FileReader();var k=false,j=[];if(h.readAsBinaryString){h.onload=function(r){d(r.target.result);if(j.length==0){k=false}else{h.readAsBinaryString(new Blob([j.shift()]))}}}else{if(h.readAsArrayBuffer){h.onloadend=function(r){d(r.target.result);if(j.length==0){k=false}else{h.readAsArrayBuffer(j.shift())}}}}function a(t){if(typeof t.data=="object"){if(k==true){j.push(t.data);return}if(h.readAsBinaryString){k=true;h.readAsBinaryString(new Blob([t.data]))}else{if(h.readAsArrayBuffer){k=true;h.readAsArrayBuffer(t.data)}else{var r="",s=new Uint8Array(t.data),v=s.byteLength;for(var u=0;u<v;u++){r+=String.fromCharCode(s[u])}d(r)}}}else{d(t.data)}}function d(v){if(typeof v==="object"){var r="",s=new Uint8Array(v),y=s.byteLength;for(var x=0;x<y;x++){r+=String.fromCharCode(s[x])}v=r}else{if(typeof v!=="string"){return}}m.socketAccumulator+=v;while(true){if(m.socketParseState==0){var w=m.socketAccumulator.indexOf("\r\n\r\n");if(w<0){return}m.socketHeader=m.socketAccumulator.substring(0,w).split("\r\n");m.socketAccumulator=m.socketAccumulator.substring(w+4);m.socketParseState=1;m.socketData="";m.socketXHeader={Directive:m.socketHeader[0].split(" ")};for(x in m.socketHeader){if(x!=0){var z=m.socketHeader[x].indexOf(":");m.socketXHeader[m.socketHeader[x].substring(0,z).toLowerCase()]=m.socketHeader[x].substring(z+2)}}}if(m.socketParseState==1){var u=-1;if((m.socketXHeader.connection!=undefined)&&(m.socketXHeader.connection.toLowerCase()=="close")&&((m.socketXHeader["transfer-encoding"]==undefined)||(m.socketXHeader["transfer-encoding"].toLowerCase()!="chunked"))){u=0}else{if(m.socketXHeader["content-length"]!=undefined){u=parseInt(m.socketXHeader["content-length"]);if(m.socketAccumulator.length<u){return}var v=m.socketAccumulator.substring(0,u);m.socketAccumulator=m.socketAccumulator.substring(u);m.socketData=v;u=0}else{var t=m.socketAccumulator.indexOf("\r\n");if(t<0){return}u=parseInt(m.socketAccumulator.substring(0,t),16);if(isNaN(u)){if(m.websocket){m.websocket.close()}return}if(m.socketAccumulator.length<t+2+u+2){return}var v=m.socketAccumulator.substring(t+2,t+2+u);m.socketAccumulator=m.socketAccumulator.substring(t+2+u+2);m.socketData+=v}}if(u==0){e(m.socketXHeader,m.socketData);m.socketParseState=0;m.socketHeader=null}}}}function e(u,t){var w=parseInt(u.Directive[1]);if(isNaN(w)){w=602}if(w==401&&++(m.authcounter)<3){m.challengeParams=m.parseDigest(u["www-authenticate"])}else{var v=m.pendingAjaxCall.shift();m.authcounter=0;m.ActiveAjaxCount--;m.gotNextMessages(t,"success",{status:w},v);m.PerformNextAjax()}}function b(s){m.socketState=0;if(m.socket!=null){m.socket.close();m.socket=null}if(m.pendingAjaxCall.length>0){var t=m.pendingAjaxCall.shift();var u=t[5];m.PerformAjaxExNodeJS2(t[0],t[1],t[2],t[3],t[4],--u)}}function g(u){if(m.socketState==2&&m.socket!=null&&m.socket.readyState==WebSocket.OPEN){var r=new Uint8Array(u.length);for(var t=0;t<u.length;++t){r[t]=u.charCodeAt(t)}try{m.socket.send(r.buffer)}catch(s){}}}m.gotNextMessages=function(s,u,t,r){if(m.FailAllError==999){return}if(m.FailAllError!=0){r[1](null,m.FailAllError,r[2]);return}if(t.status!=200){r[1](null,t.status,r[2]);return}r[1](s,200,r[2])};m.gotNextMessagesError=function(t,u,s,r){if(m.FailAllError==999){return}if(m.FailAllError!=0){r[1](null,m.FailAllError,r[2]);return}r[1](m,null,{Header:{HttpError:t.status}},t.status,r[2])};m.CancelAllQueries=function(r){while(m.PendingAjax.length>0){var t=m.PendingAjax.shift();t[1](null,r,t[2])}if(m.websocket!=null){m.websocket.close();m.websocket=null;m.socketState=0}};return m};var CreateAgentRedirect=function(e,g,k,a){var h={};h.m=g;g.parent=h;h.meshserver=e;h.authCookie=a;h.State=0;h.nodeid=null;h.socket=null;h.connectstate=-1;h.tunnelid=Math.random().toString(36).substring(2);h.protocol=g.protocol;h.onStateChanged=null;h.ctrlMsgAllowed=true;h.attemptWebRTC=false;h.webRtcActive=false;h.webSwitchOk=false;h.webchannel=null;h.webrtc=null;h.debugmode=0;h.Start=function(l){var n,m=window.location.protocol.replace("http","ws")+"//"+window.location.host+window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/"))+"/meshrelay.ashx?id="+h.tunnelid;if((a!=null)&&(a!="")){m+="&auth="+a}h.nodeid=l;h.connectstate=0;h.socket=new WebSocket(m);h.socket.onopen=h.xxOnSocketConnected;h.socket.onmessage=h.xxOnMessage;h.socket.onerror=function(o){};h.socket.onclose=h.xxOnSocketClosed;h.xxStateChange(1);h.meshserver.send({action:"msg",type:"tunnel",nodeid:h.nodeid,value:"*/meshrelay.ashx?id="+h.tunnelid})};h.xxOnSocketConnected=function(){if(h.debugmode==1){console.log("onSocketConnected")}h.xxStateChange(2)};h.xxOnControlCommand=function(n){var l;try{l=JSON.parse(n)}catch(m){return}if(l.ctrlChannel!="102938"){h.xxOnSocketData(n);return}if(h.webrtc!=null){if(l.type=="answer"){h.webrtc.setRemoteDescription(new RTCSessionDescription(l),function(){},h.xxCloseWebRTC)}else{if(l.type=="webrtc0"){h.webSwitchOk=true;j()}else{if(l.type=="webrtc1"){h.sendCtrlMsg('{"ctrlChannel":"102938","type":"webrtc2"}')}else{if(l.type=="webrtc2"){}}}}}};h.sendCtrlMsg=function(m){if(h.ctrlMsgAllowed==true){if((typeof args!="undefined")&&args.redirtrace){console.log("RedirSend",typeof m,m)}try{h.socket.send(m)}catch(l){}}};function j(){if((h.webSwitchOk==true)&&(h.webRtcActive==true)){h.sendCtrlMsg('{"ctrlChannel":"102938","type":"webrtc0"}');h.sendCtrlMsg('{"ctrlChannel":"102938","type":"webrtc1"}');if(h.onStateChanged!=null){h.onStateChanged(h,h.State)}}}h.xxOnMessage=function(o){if(h.State<3){if(o.data=="c"){try{h.socket.send(h.protocol)}catch(p){}h.xxStateChange(3);if(h.attemptWebRTC==true){var n=null;if(typeof RTCPeerConnection!=="undefined"){h.webrtc=new RTCPeerConnection(n)}else{if(typeof webkitRTCPeerConnection!=="undefined"){h.webrtc=new webkitRTCPeerConnection(n)}}if(h.webrtc!=null){h.webchannel=h.webrtc.createDataChannel("DataChannel",{});h.webchannel.onmessage=h.xxOnMessage;h.webchannel.onopen=function(){h.webRtcActive=true;j()};h.webchannel.onclose=function(s){if(h.webRtcActive){h.Stop()}};h.webrtc.onicecandidate=function(s){if(s.candidate==null){try{h.socket.send(JSON.stringify(h.webrtcoffer))}catch(t){}}else{h.webrtcoffer.sdp+=("a="+s.candidate.candidate+"\r\n")}};h.webrtc.oniceconnectionstatechange=function(){if(h.webrtc!=null){if(h.webrtc.iceConnectionState=="disconnected"){if(h.webRtcActive==true){h.Stop()}else{h.xxCloseWebRTC()}}else{if(h.webrtc.iceConnectionState=="failed"){h.xxCloseWebRTC()}}}};h.webrtc.createOffer(function(s){h.webrtcoffer=s;h.webrtc.setLocalDescription(s,function(){},h.xxCloseWebRTC)},h.xxCloseWebRTC,{mandatory:{OfferToReceiveAudio:false,OfferToReceiveVideo:false}})}}return}}if(typeof o.data=="string"){h.xxOnControlCommand(o.data);return}if(typeof o.data=="object"){if(d==true){c.push(o.data);return}if(b.readAsBinaryString){d=true;b.readAsBinaryString(new Blob([o.data]))}else{if(b.readAsArrayBuffer){d=true;b.readAsArrayBuffer(o.data)}else{var l="",m=new Uint8Array(o.data),r=m.byteLength;for(var q=0;q<r;q++){l+=String.fromCharCode(m[q])}h.xxOnSocketData(l)}}}else{h.xxOnSocketData(o.data)}};var b=new FileReader();var d=false,c=[];if(b.readAsBinaryString){b.onload=function(l){h.xxOnSocketData(l.target.result);if(c.length==0){d=false}else{b.readAsBinaryString(new Blob([c.shift()]))}}}else{if(b.readAsArrayBuffer){b.onloadend=function(l){h.xxOnSocketData(l.target.result);if(c.length==0){d=false}else{b.readAsArrayBuffer(c.shift())}}}}h.xxOnSocketData=function(n){if(!n||h.connectstate==-1){return}if(typeof n==="object"){var l="",m=new Uint8Array(n),p=m.byteLength;for(var o=0;o<p;o++){l+=String.fromCharCode(m[o])}n=l}else{if(typeof n!=="string"){return}}if((typeof args!="undefined")&&args.redirtrace){console.log("RedirRecv",typeof n,n.length,n)}return h.m.ProcessData(n)};h.sendText=function(l){if(typeof l!="string"){l=JSON.stringify(l)}h.send(encode_utf8(l))};h.send=function(p){if((typeof args!="undefined")&&args.redirtrace){console.log("RedirSend",typeof p,p.length,p)}try{if(h.socket!=null&&h.socket.readyState==WebSocket.OPEN){if(typeof p=="string"){if(h.debugmode==1){var l=new Uint8Array(p.length),m=[];for(var o=0;o<p.length;++o){l[o]=p.charCodeAt(o);m.push(p.charCodeAt(o))}if(h.webRtcActive==true){h.webchannel.send(l.buffer)}else{h.socket.send(l.buffer)}}else{var l=new Uint8Array(p.length);for(var o=0;o<p.length;++o){l[o]=p.charCodeAt(o)}if(h.webRtcActive==true){h.webchannel.send(l.buffer)}else{h.socket.send(l.buffer)}}}else{if(h.webRtcActive==true){h.webchannel.send(p)}else{h.socket.send(p)}}}}catch(n){}};h.xxOnSocketClosed=function(){h.Stop(1)};h.xxStateChange=function(l){if(h.State==l){return}h.State=l;h.m.xxStateChange(h.State);if(h.onStateChanged!=null){h.onStateChanged(h,h.State)}};h.xxCloseWebRTC=function(){if(h.webchannel!=null){try{h.webchannel.close()}catch(l){}h.webchannel=null}if(h.webrtc!=null){try{h.webrtc.close()}catch(l){}h.webrtc=null}h.webRtcActive=false};h.Stop=function(m){if(h.debugmode==1){console.log("stop",m)}h.xxCloseWebRTC();h.connectstate=-1;if(h.socket!=null){try{if(h.socket.readyState==1){h.sendCtrlMsg('{"ctrlChannel":"102938","type":"close"}');h.socket.close()}}catch(l){}h.socket=null}h.xxStateChange(0)};return h};var CreateKvmDataChannel=function(h,e,d){var g={};g.m=e;e.parent=g;g.webchannel=h;g.State=0;g.protocol=e.protocol;g.onStateChanged=null;g.onControlMsg=null;g.debugmode=0;g.keepalive=d;g.rtcKeepAlive=null;g.Start=function(){if(g.debugmode==1){console.log("start")}g.xxStateChange(3);g.webchannel.onmessage=g.xxOnMessage;g.rtcKeepAlive=setInterval(g.xxSendRtcKeepAlive,30000)};var a=new FileReader();var c=false,b=[];if(a.readAsBinaryString){a.onload=function(j){g.xxOnSocketData(j.target.result);if(b.length==0){c=false}else{a.readAsBinaryString(new Blob([b.shift()]))}}}else{if(a.readAsArrayBuffer){a.onloadend=function(j){g.xxOnSocketData(j.target.result);if(b.length==0){c=false}else{a.readAsArrayBuffer(b.shift())}}}}g.xxOnMessage=function(l){if(typeof l.data=="string"){if(g.onControlMsg!=null){g.onControlMsg(l.data)}return}if(typeof l.data=="object"){if(c==true){b.push(l.data);return}if(a.readAsBinaryString){c=true;a.readAsBinaryString(new Blob([l.data]))}else{if(f.readAsArrayBuffer){c=true;a.readAsArrayBuffer(l.data)}else{var j="",k=new Uint8Array(l.data),n=k.byteLength;for(var m=0;m<n;m++){j+=String.fromCharCode(k[m])}g.xxOnSocketData(j)}}}else{g.xxOnSocketData(l.data)}};g.xxOnSocketData=function(l){if(!l){return}if(typeof l==="object"){var j="",k=new Uint8Array(l),n=k.byteLength;for(var m=0;m<n;m++){j+=String.fromCharCode(k[m])}l=j}else{if(typeof l!=="string"){return}}return g.m.ProcessData(l)};g.sendCtrlMsg=function(j){if(typeof j=="string"){g.webchannel.send(j);if(g.keepalive!=null){g.keepalive.sendKeepAlive()}}};g.send=function(l){if(typeof l=="string"){var j=new Uint8Array(l.length);for(var k=0;k<l.length;++k){j[k]=l.charCodeAt(k)}l=j}g.webchannel.send(l)};g.xxStateChange=function(j){if(g.State==j){return}g.State=j;g.m.xxStateChange(g.State);if(g.onStateChanged!=null){g.onStateChanged(g,g.State)}};g.Stop=function(){if(g.debugmode==1){console.log("stop")}if(g.rtcKeepAlive!=null){clearInterval(g.rtcKeepAlive);g.rtcKeepAlive=null}g.xxStateChange(0)};g.xxSendRtcKeepAlive=function(){g.sendCtrlMsg(JSON.stringify({action:"ping"}))};return g};var CreateAgentRemoteDesktop=function(a,e){var d={};d.CanvasId=a;if(typeof a==="string"){d.CanvasId=Q(a)}d.Canvas=d.CanvasId.getContext("2d");d.scrolldiv=e;d.State=0;d.PendingOperations=[];d.tilesReceived=0;d.TilesDrawn=0;d.KillDraw=0;d.ipad=false;d.tabletKeyboardVisible=false;d.LastX=0;d.LastY=0;d.touchenabled=0;d.submenuoffset=0;d.touchtimer=null;d.TouchArray={};d.connectmode=0;d.connectioncount=0;d.rotation=0;d.protocol=2;d.debugmode=0;d.firstUpKeys=[];d.stopInput=false;d.localKeyMap=true;d.sessionid=0;d.username;d.oldie=false;d.CompressionLevel=50;d.ScalingLevel=1024;d.FrameRateTimer=50;d.FirstDraw=false;d.ScreenWidth=960;d.ScreenHeight=700;d.width=960;d.height=960;d.onScreenSizeChange=null;d.onMessage=null;d.onConnectCountChanged=null;d.onDebugMessage=null;d.onTouchEnabledChanged=null;d.onDisplayinfo=null;d.accumulator=null;d.Start=function(){d.State=0;d.accumulator=null};d.Stop=function(){d.setRotation(0);d.UnGrabKeyInput();d.UnGrabMouseInput();d.touchenabled=0;if(d.onScreenSizeChange!=null){d.onScreenSizeChange(d,d.ScreenWidth,d.ScreenHeight,d.CanvasId)}d.Canvas.clearRect(0,0,d.CanvasId.width,d.CanvasId.height)};d.xxStateChange=function(g){if(d.State==g){return}d.State=g;d.CanvasId.style.cursor="default";switch(g){case 0:d.Stop();break;case 3:break}};d.send=function(g){if(d.debugmode>1){console.log("KSend("+g.length+"): "+rstr2hex(g))}d.parent.send(g)};d.ProcessPictureMsg=function(h,k,l){var j=new Image();j.xcount=d.tilesReceived++;var g=d.tilesReceived;j.src="data:image/jpeg;base64,"+btoa(h.substring(4,h.length));j.onload=function(){if(d.Canvas!=null&&d.KillDraw<g&&d.State!=0){d.PendingOperations.push([g,2,j,k,l]);while(d.DoPendingOperations()){}}};j.error=function(){console.log("DecodeTileError")}};d.DoPendingOperations=function(){if(d.PendingOperations.length==0){return false}for(var g=0;g<d.PendingOperations.length;g++){var h=d.PendingOperations[g];if(h[0]==(d.TilesDrawn+1)){if(h[1]==1){d.ProcessCopyRectMsg(h[2])}else{if(h[1]==2){d.Canvas.drawImage(h[2],d.rotX(h[3],h[4]),d.rotY(h[3],h[4]));delete h[2]}}d.PendingOperations.splice(g,1);delete h;d.TilesDrawn++;if(d.TilesDrawn==d.tilesReceived&&d.KillDraw<d.TilesDrawn){d.KillDraw=d.TilesDrawn=d.tilesReceived=0}return true}}if(d.oldie&&d.PendingOperations.length>0){d.TilesDrawn++}return false};d.ProcessCopyRectMsg=function(k){var l=((k.charCodeAt(0)&255)<<8)+(k.charCodeAt(1)&255);var m=((k.charCodeAt(2)&255)<<8)+(k.charCodeAt(3)&255);var g=((k.charCodeAt(4)&255)<<8)+(k.charCodeAt(5)&255);var h=((k.charCodeAt(6)&255)<<8)+(k.charCodeAt(7)&255);var n=((k.charCodeAt(8)&255)<<8)+(k.charCodeAt(9)&255);var j=((k.charCodeAt(10)&255)<<8)+(k.charCodeAt(11)&255);d.Canvas.drawImage(Canvas.canvas,l,m,n,j,g,h,n,j)};d.SendUnPause=function(){d.send(String.fromCharCode(0,8,0,5,0))};d.SendPause=function(){d.send(String.fromCharCode(0,8,0,5,1))};d.SendCompressionLevel=function(k,h,j,g){if(h){d.CompressionLevel=h}if(j){d.ScalingLevel=j}if(g){d.FrameRateTimer=g}d.send(String.fromCharCode(0,5,0,10,k,d.CompressionLevel)+d.shortToStr(d.ScalingLevel)+d.shortToStr(d.FrameRateTimer))};d.SendRefresh=function(){d.send(String.fromCharCode(0,6,0,4))};d.ProcessScreenMsg=function(h,g){if(d.debugmode>0){console.log("ScreenSize: "+h+" x "+g)}d.Canvas.setTransform(1,0,0,1,0,0);d.rotation=0;d.FirstDraw=true;d.ScreenWidth=d.width=h;d.ScreenHeight=d.height=g;d.KillDraw=d.tilesReceived;while(d.PendingOperations.length>0){d.PendingOperations.shift()}d.SendCompressionLevel(1);d.SendUnPause();if(d.onScreenSizeChange!=null){d.onScreenSizeChange(d,d.ScreenWidth,d.ScreenHeight,d.CanvasId)}};d.ProcessData=function(h){var g=0;while(g<h.length){g+=d.ProcessDataEx(h.substring(g))}};d.ProcessDataEx=function(r){if(d.accumulator!=null){r=d.accumulator+r;console.log("KVM using accumulated data, total size is now "+r.length+" bytes.");d.accumulator=null}if(d.debugmode>1){console.log("KRecv("+r.length+"): "+rstr2hex(r.substring(0,Math.min(r.length,40))))}if(r.length<4){return}var g=null,s=0,t=0,j=ReadShort(r,0),h=ReadShort(r,2),n=0;if((j==27)&&(h==8)){if(r.length<12){return}j=ReadShort(r,8);h=ReadInt(r,4);if((h+8)>r.length){console.log("KVM accumulator set to "+r.length+" bytes, need "+h+" bytes.");d.accumulator=r;return}r=r.substring(8);n=8}if((h!=r.length)&&(d.debugmode>0)){console.log(h,r.length,h==r.length)}if((j>=18)&&(j!=65)){console.error("Invalid KVM command "+j+" of size "+h);console.log("Invalid KVM data",r.length,rstr2hex(r.substring(0,40))+"...");return}if(h>r.length){console.log("KVM accumulator set to "+r.length+" bytes, need "+h+" bytes.");d.accumulator=r;return}if(j==3||j==4||j==7){g=r.substring(4,h);s=((g.charCodeAt(0)&255)<<8)+(g.charCodeAt(1)&255);t=((g.charCodeAt(2)&255)<<8)+(g.charCodeAt(3)&255);if(d.debugmode>0){console.log("CMD"+j+" at X="+s+" Y="+t)}}switch(j){case 3:if(d.FirstDraw){d.onResize()}d.ProcessPictureMsg(g,s,t);break;case 4:if(d.FirstDraw){d.onResize()}if(d.TilesDrawn==d.tilesReceived){d.ProcessCopyRectMsg(g)}else{d.PendingOperations.push([++tilesReceived,1,g])}break;case 7:d.ProcessScreenMsg(s,t);d.SendKeyMsgKC(d.KeyAction.UP,16);d.SendKeyMsgKC(d.KeyAction.UP,17);d.SendKeyMsgKC(d.KeyAction.UP,18);d.SendKeyMsgKC(d.KeyAction.UP,91);d.SendKeyMsgKC(d.KeyAction.UP,92);d.SendKeyMsgKC(d.KeyAction.UP,16);d.send(String.fromCharCode(0,14,0,4));break;case 11:var o=[],k=((r.charCodeAt(4)&255)<<8)+(r.charCodeAt(5)&255);if(k>0){var q=0,p=((r.charCodeAt(6+(k*2))&255)<<8)+(r.charCodeAt(7+(k*2))&255);for(var m=0;m<k;m++){var l=((r.charCodeAt(6+(m*2))&255)<<8)+(r.charCodeAt(7+(m*2))&255);if(l==65535){o.push("All Displays")}else{o.push("Display "+l)}if(l==p){q=m}}}if(d.onDisplayinfo!=null){d.onDisplayinfo(d,o,q)}break;case 12:break;case 14:d.touchenabled=1;d.TouchArray={};if(d.onTouchEnabledChanged!=null){d.onTouchEnabledChanged(d.touchenabled)}break;case 15:d.TouchArray={};break;case 16:d.connectioncount=ReadInt(r,4);if(d.onConnectCountChanged!=null){d.onConnectCountChanged(d.connectioncount,d)}break;case 17:if(d.onMessage!=null){d.onMessage(r.substring(4,h),d)}break;case 65:r=r.substring(4);if(r[0]!="."){console.log(r);alert("KVM: "+r)}else{console.log("KVM: "+r.substring(1))}break}return h+n};d.MouseButton={NONE:0,LEFT:2,RIGHT:8,MIDDLE:32};d.KeyAction={NONE:0,DOWN:1,UP:2,SCROLL:3,EXUP:4,EXDOWN:5,DBLCLICK:6};d.InputType={KEY:1,MOUSE:2,CTRLALTDEL:10,TOUCH:15};d.Alternate=0;var c={Pause:19,CapsLock:20,Space:32,Quote:222,Minus:189,NumpadMultiply:106,NumpadAdd:107,PrintScreen:44,Comma:188,NumpadSubtract:109,NumpadDecimal:110,Period:190,Slash:191,NumpadDivide:111,Semicolon:186,Equal:187,OSLeft:91,BracketLeft:219,OSRight:91,Backslash:220,BracketRight:221,ContextMenu:93,Backquote:192,NumLock:144,ScrollLock:145,Backspace:8,Tab:9,Enter:13,NumpadEnter:13,Escape:27,Delete:46,Home:36,PageUp:33,PageDown:34,ArrowLeft:37,ArrowUp:38,ArrowRight:39,ArrowDown:40,End:35,Insert:45,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,ShiftLeft:16,ShiftRight:16,ControlLeft:17,ControlRight:17,AltLeft:18,AltRight:18,MetaLeft:91,MetaRight:92,VolumeMute:181};function b(g){if(g.code.startsWith("Key")&&g.code.length==4){return g.code.charCodeAt(3)}if(g.code.startsWith("Digit")&&g.code.length==6){return g.code.charCodeAt(5)}if(g.code.startsWith("Numpad")&&g.code.length==7){return g.code.charCodeAt(6)+48}return c[g.code]}d.SendKeyMsg=function(g,h){if(g==null){return}if(!h){h=window.event}if(h.code&&(d.localKeyMap==false)){var j=b(h);if(j!=null){d.SendKeyMsgKC(g,j)}}else{var j=h.keyCode;if(j==59){j=186}d.SendKeyMsgKC(g,j)}};d.SendMessage=function(g){if(d.State==3){d.send(String.fromCharCode(0,17)+d.shortToStr(4+g.length)+g)}};d.SendKeyMsgKC=function(g,j){if(d.State!=3){return}if(typeof g=="object"){for(var h in g){d.SendKeyMsgKC(g[h][0],g[h][1])}}else{d.send(String.fromCharCode(0,d.InputType.KEY,0,6,(g-1),j))}};d.sendcad=function(){d.SendCtrlAltDelMsg()};d.SendCtrlAltDelMsg=function(){if(d.State==3){d.send(String.fromCharCode(0,d.InputType.CTRLALTDEL,0,4))}};d.SendEscKey=function(){if(d.State==3){d.send(String.fromCharCode(0,d.InputType.KEY,0,6,0,27,0,d.InputType.KEY,0,6,1,27))}};d.SendStartMsg=function(){d.SendKeyMsgKC(d.KeyAction.EXDOWN,91);d.SendKeyMsgKC(d.KeyAction.EXUP,91)};d.SendCharmsMsg=function(){d.SendKeyMsgKC(d.KeyAction.EXDOWN,91);d.SendKeyMsgKC(d.KeyAction.DOWN,67);d.SendKeyMsgKC(d.KeyAction.UP,67);d.SendKeyMsgKC(d.KeyAction.EXUP,91)};d.SendTouchMsg1=function(h,g,j,k){if(d.State==3){d.send(String.fromCharCode(0,d.InputType.TOUCH)+d.shortToStr(14)+String.fromCharCode(1,h)+d.intToStr(g)+d.shortToStr(j)+d.shortToStr(k))}};d.SendTouchMsg2=function(j,g){var m="";var h;var n="TOUCHSEND: ";for(var l in d.TouchArray){if(l==j){h=g}else{if(d.TouchArray[l].f==1){h=65536|2|4;d.TouchArray[l].f=3;n+="START"+l}else{if(d.TouchArray[l].f==2){h=262144;n+="STOP"+l}else{h=2|4|131072}}}m+=String.fromCharCode(l)+d.intToStr(h)+d.shortToStr(d.TouchArray[l].x)+d.shortToStr(d.TouchArray[l].y);if(d.TouchArray[l].f==2){delete d.TouchArray[l]}}if(d.State==3){d.send(String.fromCharCode(0,d.InputType.TOUCH)+d.shortToStr(5+m.length)+String.fromCharCode(2)+m)}if(Object.keys(d.TouchArray).length==0&&d.touchtimer!=null){clearInterval(d.touchtimer);d.touchtimer=null}};d.SendMouseMsg=function(g,k){if(d.State!=3){return}if(g!=null&&d.Canvas!=null){if(!k){var k=window.event}var n=(d.Canvas.canvas.height/d.CanvasId.clientHeight);var o=(d.Canvas.canvas.width/d.CanvasId.clientWidth);var m=d.GetPositionOfControl(d.Canvas.canvas);var p=((k.pageX-m[0])*o);var q=((k.pageY-m[1])*n);if(p>=0&&p<=d.Canvas.canvas.width&&q>=0&&q<=d.Canvas.canvas.height){var h=0;var j=0;if(g==d.KeyAction.UP||g==d.KeyAction.DOWN){if(k.which){((k.which==1)?(h=d.MouseButton.LEFT):((k.which==2)?(h=d.MouseButton.MIDDLE):(h=d.MouseButton.RIGHT)))}else{if(k.button){((k.button==0)?(h=d.MouseButton.LEFT):((k.button==1)?(h=d.MouseButton.MIDDLE):(h=d.MouseButton.RIGHT)))}}}else{if(g==d.KeyAction.SCROLL){if(k.detail){j=(-1*(k.detail*120))}else{if(k.wheelDelta){j=(k.wheelDelta*3)}}}}var l="";if(g==d.KeyAction.DBLCLICK){l=String.fromCharCode(0,d.InputType.MOUSE,0,10,0,136,((p/256)&255),(p&255),((q/256)&255),(q&255))}else{if(g==d.KeyAction.SCROLL){l=String.fromCharCode(0,d.InputType.MOUSE,0,12,0,0,((p/256)&255),(p&255),((q/256)&255),(q&255),((j/256)&255),(j&255))}else{l=String.fromCharCode(0,d.InputType.MOUSE,0,10,0,((g==d.KeyAction.DOWN)?h:((h*2)&255)),((p/256)&255),(p&255),((q/256)&255),(q&255))}}if(d.Action==d.KeyAction.NONE){if(d.Alternate==0||d.ipad){d.send(l);d.Alternate=1}else{d.Alternate=0}}else{d.send(l)}}}};d.GetDisplayNumbers=function(){d.send(String.fromCharCode(0,11,0,4))};d.SetDisplay=function(g){d.send(String.fromCharCode(0,12,0,6,g>>8,g&255))};d.intToStr=function(g){return String.fromCharCode((g>>24)&255,(g>>16)&255,(g>>8)&255,g&255)};d.shortToStr=function(g){return String.fromCharCode((g>>8)&255,g&255)};d.onResize=function(){if(d.ScreenWidth==0||d.ScreenHeight==0){return}if(d.Canvas.canvas.width==d.ScreenWidth&&d.Canvas.canvas.height==d.ScreenHeight){return}if(d.FirstDraw){d.Canvas.canvas.width=d.ScreenWidth;d.Canvas.canvas.height=d.ScreenHeight;d.Canvas.fillRect(0,0,d.ScreenWidth,d.ScreenHeight);if(d.onScreenSizeChange!=null){d.onScreenSizeChange(d,d.ScreenWidth,d.ScreenHeight,d.CanvasId)}}d.FirstDraw=false};d.xxMouseInputGrab=false;d.xxKeyInputGrab=false;d.xxMouseMove=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.NONE,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxMouseUp=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.UP,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxMouseDown=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.DOWN,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxMouseDblClick=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.DBLCLICK,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxDOMMouseScroll=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.SCROLL,g);return false}return true};d.xxMouseWheel=function(g){if(d.State==3){d.SendMouseMsg(d.KeyAction.SCROLL,g);return false}return true};d.xxKeyUp=function(g){if(d.State==3){d.SendKeyMsg(d.KeyAction.UP,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxKeyDown=function(g){if(d.State==3){d.SendKeyMsg(d.KeyAction.DOWN,g)}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.xxKeyPress=function(g){if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};d.handleKeys=function(g){if(d.stopInput==true||desktop.State!=3){return false}return d.xxKeyPress(g)};d.handleKeyUp=function(g){if(d.stopInput==true||desktop.State!=3){return false}if(d.firstUpKeys.length<5){d.firstUpKeys.push(g.keyCode);if((d.firstUpKeys.length==5)){var h=d.firstUpKeys.join(",");if((h=="16,17,91,91,16")||(h=="16,17,18,91,92")){d.stopInput=true}}}return d.xxKeyUp(g)};d.handleKeyDown=function(g){if(d.stopInput==true||desktop.State!=3){return false}return d.xxKeyDown(g)};d.mousedblclick=function(g){if(d.stopInput==true){return false}return d.xxMouseDblClick(g)};d.mousedown=function(g){if(d.stopInput==true){return false}return d.xxMouseDown(g)};d.mouseup=function(g){if(d.stopInput==true){return false}return d.xxMouseUp(g)};d.mousemove=function(g){if(d.stopInput==true){return false}return d.xxMouseMove(g)};d.mousewheel=function(g){if(d.stopInput==true){return false}return d.xxMouseWheel(g)};d.xxMsTouchEvent=function(g){if(g.originalEvent.pointerType==4){return}if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}if(g.type=="MSPointerDown"||g.type=="MSPointerMove"||g.type=="MSPointerUp"){var h=0;var j=g.originalEvent.pointerId%256;var k=g.offsetX*(Canvas.canvas.width/d.CanvasId.clientWidth);var l=g.offsetY*(Canvas.canvas.height/d.CanvasId.clientHeight);if(g.type=="MSPointerDown"){h=65536|2|4}else{if(g.type=="MSPointerMove"){h=131072|2|4}else{if(g.type=="MSPointerUp"){h=262144}}}if(!d.TouchArray[j]){d.TouchArray[j]={x:k,y:l}}d.SendTouchMsg2(j,h);if(g.type=="MSPointerUp"){delete d.TouchArray[j]}}else{alert(g.type)}return true};d.xxTouchStart=function(g){if(d.State!=3){return}if(g.preventDefault){g.preventDefault()}if(d.touchenabled==0||d.touchenabled==1){if(g.originalEvent.touches.length>1){return}var l=g.originalEvent.touches[0];g.which=1;d.LastX=g.pageX=l.pageX;d.LastY=g.pageY=l.pageY;d.SendMouseMsg(KeyAction.DOWN,g)}else{var k=d.GetPositionOfControl(Canvas.canvas);for(var h in g.originalEvent.changedTouches){if(!g.originalEvent.changedTouches[h].identifier){continue}var j=g.originalEvent.changedTouches[h].identifier%256;if(!d.TouchArray[j]){d.TouchArray[j]={x:(g.originalEvent.touches[h].pageX-k[0])*(Canvas.canvas.width/d.CanvasId.clientWidth),y:(g.originalEvent.touches[h].pageY-k[1])*(Canvas.canvas.height/d.CanvasId.clientHeight),f:1}}}if(Object.keys(d.TouchArray).length>0&&touchtimer==null){d.touchtimer=setInterval(function(){d.SendTouchMsg2(256,0)},50)}}};d.xxTouchMove=function(g){if(d.State!=3){return}if(g.preventDefault){g.preventDefault()}if(d.touchenabled==0||d.touchenabled==1){if(g.originalEvent.touches.length>1){return}var l=g.originalEvent.touches[0];g.which=1;d.LastX=g.pageX=l.pageX;d.LastY=g.pageY=l.pageY;d.SendMouseMsg(d.KeyAction.NONE,g)}else{var k=d.GetPositionOfControl(Canvas.canvas);for(var h in g.originalEvent.changedTouches){if(!g.originalEvent.changedTouches[h].identifier){continue}var j=g.originalEvent.changedTouches[h].identifier%256;if(d.TouchArray[j]){d.TouchArray[j].x=(g.originalEvent.touches[h].pageX-k[0])*(d.Canvas.canvas.width/d.CanvasId.clientWidth);d.TouchArray[j].y=(g.originalEvent.touches[h].pageY-k[1])*(d.Canvas.canvas.height/d.CanvasId.clientHeight)}}}};d.xxTouchEnd=function(g){if(d.State!=3){return}if(g.preventDefault){g.preventDefault()}if(d.touchenabled==0||d.touchenabled==1){if(g.originalEvent.touches.length>1){return}g.which=1;g.pageX=LastX;g.pageY=LastY;d.SendMouseMsg(KeyAction.UP,g)}else{for(var h in g.originalEvent.changedTouches){if(!g.originalEvent.changedTouches[h].identifier){continue}var j=g.originalEvent.changedTouches[h].identifier%256;if(d.TouchArray[j]){d.TouchArray[j].f=2}}}};d.GrabMouseInput=function(){if(d.xxMouseInputGrab==true){return}var g=d.CanvasId;g.onmousemove=d.xxMouseMove;g.onmouseup=d.xxMouseUp;g.onmousedown=d.xxMouseDown;g.touchstart=d.xxTouchStart;g.touchmove=d.xxTouchMove;g.touchend=d.xxTouchEnd;g.MSPointerDown=d.xxMsTouchEvent;g.MSPointerMove=d.xxMsTouchEvent;g.MSPointerUp=d.xxMsTouchEvent;if(navigator.userAgent.match(/mozilla/i)){g.DOMMouseScroll=d.xxDOMMouseScroll}else{g.onmousewheel=d.xxMouseWheel}d.xxMouseInputGrab=true};d.UnGrabMouseInput=function(){if(d.xxMouseInputGrab==false){return}var g=d.CanvasId;g.onmousemove=null;g.onmouseup=null;g.onmousedown=null;g.touchstart=null;g.touchmove=null;g.touchend=null;g.MSPointerDown=null;g.MSPointerMove=null;g.MSPointerUp=null;if(navigator.userAgent.match(/mozilla/i)){g.DOMMouseScroll=null}else{g.onmousewheel=null}d.xxMouseInputGrab=false};d.GrabKeyInput=function(){if(d.xxKeyInputGrab==true){return}document.onkeyup=d.xxKeyUp;document.onkeydown=d.xxKeyDown;document.onkeypress=d.xxKeyPress;d.xxKeyInputGrab=true};d.UnGrabKeyInput=function(){if(d.xxKeyInputGrab==false){return}document.onkeyup=null;document.onkeydown=null;document.onkeypress=null;d.xxKeyInputGrab=false};d.GetPositionOfControl=function(g){var h=Array(2);h[0]=h[1]=0;while(g){h[0]+=g.offsetLeft;h[1]+=g.offsetTop;g=g.offsetParent}return h};d.crotX=function(g,h){if(d.rotation==0){return g}if(d.rotation==1){return h}if(d.rotation==2){return d.Canvas.canvas.width-g}if(d.rotation==3){return d.Canvas.canvas.height-h}};d.crotY=function(g,h){if(d.rotation==0){return h}if(d.rotation==1){return d.Canvas.canvas.width-g}if(d.rotation==2){return d.Canvas.canvas.height-h}if(d.rotation==3){return g}};d.rotX=function(g,h){if(d.rotation==0||d.rotation==1){return g}if(d.rotation==2){return g-d.Canvas.canvas.width}if(d.rotation==3){return g-d.Canvas.canvas.height}};d.rotY=function(g,h){if(d.rotation==0||d.rotation==3){return h}if(d.rotation==1){return h-d.Canvas.canvas.width}if(d.rotation==2){return h-d.Canvas.canvas.height}};d.tcanvas=null;d.setRotation=function(l){while(l<0){l+=4}var g=l%4;if(g==d.rotation){return true}var j=d.Canvas.canvas.width;var h=d.Canvas.canvas.height;if(d.rotation==1||d.rotation==3){j=d.Canvas.canvas.height;h=d.Canvas.canvas.width}if(d.tcanvas==null){d.tcanvas=document.createElement("canvas")}var k=d.tcanvas.getContext("2d");k.setTransform(1,0,0,1,0,0);k.canvas.width=j;k.canvas.height=h;k.rotate((d.rotation*-90)*Math.PI/180);if(d.rotation==0){k.drawImage(d.Canvas.canvas,0,0)}if(d.rotation==1){k.drawImage(d.Canvas.canvas,-d.Canvas.canvas.width,0)}if(d.rotation==2){k.drawImage(d.Canvas.canvas,-d.Canvas.canvas.width,-d.Canvas.canvas.height)}if(d.rotation==3){k.drawImage(d.Canvas.canvas,0,-d.Canvas.canvas.height)}if(d.rotation==0||d.rotation==2){d.Canvas.canvas.height=j;d.Canvas.canvas.width=h}if(d.rotation==1||d.rotation==3){d.Canvas.canvas.height=h;d.Canvas.canvas.width=j}d.Canvas.setTransform(1,0,0,1,0,0);d.Canvas.rotate((g*90)*Math.PI/180);d.rotation=g;d.Canvas.drawImage(d.tcanvas,d.rotX(0,0),d.rotY(0,0));d.ScreenWidth=d.Canvas.canvas.width;d.ScreenHeight=d.Canvas.canvas.height;if(d.onScreenSizeChange!=null){d.onScreenSizeChange(d,d.ScreenWidth,d.ScreenHeight,d.CanvasId)}return true};d.MuchTheSame=function(g,h){return(Math.abs(g-h)<4)};d.Debug=function(g){console.log(g)};d.getIEVersion=function(){var g=-1;if(navigator.appName=="Microsoft Internet Explorer"){var j=navigator.userAgent;var h=new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");if(h.exec(j)!=null){g=parseFloat(RegExp.$1)}}return g};d.haltEvent=function(g){if(g.preventDefault){g.preventDefault()}if(g.stopPropagation){g.stopPropagation()}return false};return d};var QRCode;!function(){function t(c){this.mode=v.MODE_8BIT_BYTE,this.data=c,this.parsedData=[];for(var g=[],h=0,j=this.data.length;j>h;h++){var k=this.data.charCodeAt(h);k>65536?(g[0]=240|(1835008&k)>>>18,g[1]=128|(258048&k)>>>12,g[2]=128|(4032&k)>>>6,g[3]=128|63&k):k>2048?(g[0]=224|(61440&k)>>>12,g[1]=128|(4032&k)>>>6,g[2]=128|63&k):k>128?(g[0]=192|(1984&k)>>>6,g[1]=128|63&k):g[0]=k,this.parsedData=this.parsedData.concat(g)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function u(c,d){this.typeNumber=c,this.errorCorrectLevel=d,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function B(e,g){if(void 0==e.length){throw new Error(e.length+"/"+g)}for(var h=0;h<e.length&&0==e[h];){h++}this.num=new Array(e.length-h+g);for(var j=0;j<e.length-h;j++){this.num[j]=e[j+h]}}function C(c,d){this.totalCount=c,this.dataCount=d}function D(){this.buffer=[],this.length=0}function F(){return"undefined"!=typeof CanvasRenderingContext2D}function G(){var c=!1,d=navigator.userAgent;return/android/i.test(d)&&(c=!0,aMat=d.toString().match(/android ([0-9]\.[0-9])/i),aMat&&aMat[1]&&(c=parseFloat(aMat[1]))),c}function K(d,j){for(var k=1,l=L(d),m=0,n=E.length;n>=m;m++){var o=0;switch(j){case w.L:o=E[m][0];break;case w.M:o=E[m][1];break;case w.Q:o=E[m][2];break;case w.H:o=E[m][3]}if(o>=l){break}k++}if(k>E.length){throw new Error("Too long data")}return k}function L(c){var d=encodeURI(c).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return d.length+(d.length!=c?3:0)}t.prototype={getLength:function(){return this.parsedData.length},write:function(d){for(var e=0,g=this.parsedData.length;g>e;e++){d.put(this.parsedData[e],8)}}},u.prototype={addData:function(a){var d=new t(a);this.dataList.push(d),this.dataCache=null},isDark:function(c,d){if(0>c||this.moduleCount<=c||0>d||this.moduleCount<=d){throw new Error(c+","+d)}return this.modules[c][d]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(b,g){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var h=0;h<this.moduleCount;h++){this.modules[h]=new Array(this.moduleCount);for(var j=0;j<this.moduleCount;j++){this.modules[h][j]=null}}this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(b,g),this.typeNumber>=7&&this.setupTypeNumber(b),null==this.dataCache&&(this.dataCache=u.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,g)},setupPositionProbePattern:function(e,g){for(var h=-1;7>=h;h++){if(!(-1>=e+h||this.moduleCount<=e+h)){for(var j=-1;7>=j;j++){-1>=g+j||this.moduleCount<=g+j||(this.modules[e+h][g+j]=h>=0&&6>=h&&(0==j||6==j)||j>=0&&6>=j&&(0==h||6==h)||h>=2&&4>=h&&j>=2&&4>=j?!0:!1)}}}},getBestMaskPattern:function(){for(var e=0,g=0,h=0;8>h;h++){this.makeImpl(!0,h);var j=y.getLostPoint(this);(0==h||e>j)&&(e=j,g=h)}return g},createMovieClip:function(k,l,m){var n=k.createEmptyMovieClip(l,m),o=1;this.make();for(var p=0;p<this.modules.length;p++){for(var q=p*o,r=0;r<this.modules[p].length;r++){var s=r*o,M=this.modules[p][r];M&&(n.beginFill(0,100),n.moveTo(s,q),n.lineTo(s+o,q),n.lineTo(s+o,q+o),n.lineTo(s,q+o),n.endFill())}}return n},setupTimingPattern:function(){for(var c=8;c<this.moduleCount-8;c++){null==this.modules[c][6]&&(this.modules[c][6]=0==c%2)}for(var d=8;d<this.moduleCount-8;d++){null==this.modules[6][d]&&(this.modules[6][d]=0==d%2)}},setupPositionAdjustPattern:function(){for(var j=y.getPatternPosition(this.typeNumber),k=0;k<j.length;k++){for(var l=0;l<j.length;l++){var m=j[k],n=j[l];if(null==this.modules[m][n]){for(var o=-2;2>=o;o++){for(var p=-2;2>=p;p++){this.modules[m+o][n+p]=-2==o||2==o||-2==p||2==p||0==o&&0==p?!0:!1}}}}}},setupTypeNumber:function(e){for(var g=y.getBCHTypeNumber(this.typeNumber),h=0;18>h;h++){var j=!e&&1==(1&g>>h);this.modules[Math.floor(h/3)][h%3+this.moduleCount-8-3]=j}for(var h=0;18>h;h++){var j=!e&&1==(1&g>>h);this.modules[h%3+this.moduleCount-8-3][Math.floor(h/3)]=j}},setupTypeInfo:function(h,j){for(var k=this.errorCorrectLevel<<3|j,l=y.getBCHTypeInfo(k),m=0;15>m;m++){var n=!h&&1==(1&l>>m);6>m?this.modules[m][8]=n:8>m?this.modules[m+1][8]=n:this.modules[this.moduleCount-15+m][8]=n}for(var m=0;15>m;m++){var n=!h&&1==(1&l>>m);8>m?this.modules[8][this.moduleCount-m-1]=n:9>m?this.modules[8][15-m-1+1]=n:this.modules[8][15-m-1]=n}this.modules[this.moduleCount-8][8]=!h},mapData:function(l,m){for(var n=-1,o=this.moduleCount-1,p=7,q=0,r=this.moduleCount-1;r>0;r-=2){for(6==r&&r--;;){for(var s=0;2>s;s++){if(null==this.modules[o][r-s]){var M=!1;q<l.length&&(M=1==(1&l[q]>>>p));var N=y.getMask(m,o,r-s);N&&(M=!M),this.modules[o][r-s]=M,p--,-1==p&&(q++,p=7)}}if(o+=n,0>o||this.moduleCount<=o){o-=n,n=-n;break}}}}},u.PAD0=236,u.PAD1=17,u.createData=function(b,j,k){for(var m=C.getRSBlocks(b,j),n=new D,o=0;o<k.length;o++){var p=k[o];n.put(p.mode,4),n.put(p.getLength(),y.getLengthInBits(p.mode,b)),p.write(n)}for(var q=0,o=0;o<m.length;o++){q+=m[o].dataCount}if(n.getLengthInBits()>8*q){throw new Error("code length overflow. ("+n.getLengthInBits()+">"+8*q+")")}for(n.getLengthInBits()+4<=8*q&&n.put(0,4);0!=n.getLengthInBits()%8;){n.putBit(!1)}for(;;){if(n.getLengthInBits()>=8*q){break}if(n.put(u.PAD0,8),n.getLengthInBits()>=8*q){break}n.put(u.PAD1,8)}return u.createBytes(n,m)},u.createBytes=function(M,N){for(var O=0,P=0,R=0,S=new Array(N.length),T=new Array(N.length),U=0;U<N.length;U++){var V=N[U].dataCount,W=N[U].totalCount-V;P=Math.max(P,V),R=Math.max(R,W),S[U]=new Array(V);for(var X=0;X<S[U].length;X++){S[U][X]=255&M.buffer[X+O]}O+=V;var Y=y.getErrorCorrectPolynomial(W),Z=new B(S[U],Y.getLength()-1),aa=Z.mod(Y);T[U]=new Array(Y.getLength()-1);for(var X=0;X<T[U].length;X++){var ab=X+aa.getLength()-T[U].length;T[U][X]=ab>=0?aa.get(ab):0}}for(var ac=0,X=0;X<N.length;X++){ac+=N[X].totalCount}for(var ad=new Array(ac),ae=0,X=0;P>X;X++){for(var U=0;U<N.length;U++){X<S[U].length&&(ad[ae++]=S[U][X])}}for(var X=0;R>X;X++){for(var U=0;U<N.length;U++){X<T[U].length&&(ad[ae++]=T[U][X])}}return ad};for(var v={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},w={L:1,M:0,Q:3,H:2},x={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},y={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(c){for(var d=c<<10;y.getBCHDigit(d)-y.getBCHDigit(y.G15)>=0;){d^=y.G15<<y.getBCHDigit(d)-y.getBCHDigit(y.G15)}return(c<<10|d)^y.G15_MASK},getBCHTypeNumber:function(c){for(var d=c<<12;y.getBCHDigit(d)-y.getBCHDigit(y.G18)>=0;){d^=y.G18<<y.getBCHDigit(d)-y.getBCHDigit(y.G18)}return c<<12|d},getBCHDigit:function(c){for(var d=0;0!=c;){d++,c>>>=1}return d},getPatternPosition:function(b){return y.PATTERN_POSITION_TABLE[b-1]},getMask:function(d,e,g){switch(d){case x.PATTERN000:return 0==(e+g)%2;case x.PATTERN001:return 0==e%2;case x.PATTERN010:return 0==g%3;case x.PATTERN011:return 0==(e+g)%3;case x.PATTERN100:return 0==(Math.floor(e/2)+Math.floor(g/3))%2;case x.PATTERN101:return 0==e*g%2+e*g%3;case x.PATTERN110:return 0==(e*g%2+e*g%3)%2;case x.PATTERN111:return 0==(e*g%3+(e+g)%2)%2;default:throw new Error("bad maskPattern:"+d)}},getErrorCorrectPolynomial:function(d){for(var e=new B([1],0),g=0;d>g;g++){e=e.multiply(new B([1,z.gexp(g)],0))}return e},getLengthInBits:function(c,d){if(d>=1&&10>d){switch(c){case v.MODE_NUMBER:return 10;case v.MODE_ALPHA_NUM:return 9;case v.MODE_8BIT_BYTE:return 8;case v.MODE_KANJI:return 8;default:throw new Error("mode:"+c)}}else{if(27>d){switch(c){case v.MODE_NUMBER:return 12;case v.MODE_ALPHA_NUM:return 11;case v.MODE_8BIT_BYTE:return 16;case v.MODE_KANJI:return 10;default:throw new Error("mode:"+c)}}else{if(!(41>d)){throw new Error("type:"+d)}switch(c){case v.MODE_NUMBER:return 14;case v.MODE_ALPHA_NUM:return 13;case v.MODE_8BIT_BYTE:return 16;case v.MODE_KANJI:return 12;default:throw new Error("mode:"+c)}}}},getLostPoint:function(m){for(var n=m.getModuleCount(),o=0,p=0;n>p;p++){for(var q=0;n>q;q++){for(var r=0,s=m.isDark(p,q),M=-1;1>=M;M++){if(!(0>p+M||p+M>=n)){for(var N=-1;1>=N;N++){0>q+N||q+N>=n||(0!=M||0!=N)&&s==m.isDark(p+M,q+N)&&r++}}}r>5&&(o+=3+r-5)}}for(var p=0;n-1>p;p++){for(var q=0;n-1>q;q++){var O=0;m.isDark(p,q)&&O++,m.isDark(p+1,q)&&O++,m.isDark(p,q+1)&&O++,m.isDark(p+1,q+1)&&O++,(0==O||4==O)&&(o+=3)}}for(var p=0;n>p;p++){for(var q=0;n-6>q;q++){m.isDark(p,q)&&!m.isDark(p,q+1)&&m.isDark(p,q+2)&&m.isDark(p,q+3)&&m.isDark(p,q+4)&&!m.isDark(p,q+5)&&m.isDark(p,q+6)&&(o+=40)}}for(var q=0;n>q;q++){for(var p=0;n-6>p;p++){m.isDark(p,q)&&!m.isDark(p+1,q)&&m.isDark(p+2,q)&&m.isDark(p+3,q)&&m.isDark(p+4,q)&&!m.isDark(p+5,q)&&m.isDark(p+6,q)&&(o+=40)}}for(var P=0,q=0;n>q;q++){for(var p=0;n>p;p++){m.isDark(p,q)&&P++}}var R=Math.abs(100*P/n/n-50)/5;return o+=10*R}},z={glog:function(b){if(1>b){throw new Error("glog("+b+")")}return z.LOG_TABLE[b]},gexp:function(b){for(;0>b;){b+=255}for(;b>=256;){b-=255}return z.EXP_TABLE[b]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},A=0;8>A;A++){z.EXP_TABLE[A]=1<<A}for(var A=8;256>A;A++){z.EXP_TABLE[A]=z.EXP_TABLE[A-4]^z.EXP_TABLE[A-5]^z.EXP_TABLE[A-6]^z.EXP_TABLE[A-8]}for(var A=0;255>A;A++){z.LOG_TABLE[z.EXP_TABLE[A]]=A}B.prototype={get:function(b){return this.num[b]},getLength:function(){return this.num.length},multiply:function(e){for(var g=new Array(this.getLength()+e.getLength()-1),h=0;h<this.getLength();h++){for(var j=0;j<e.getLength();j++){g[h+j]^=z.gexp(z.glog(this.get(h))+z.glog(e.get(j)))}}return new B(g,0)},mod:function(e){if(this.getLength()-e.getLength()<0){return this}for(var g=z.glog(this.get(0))-z.glog(e.get(0)),h=new Array(this.getLength()),j=0;j<this.getLength();j++){h[j]=this.get(j)}for(var j=0;j<e.getLength();j++){h[j]^=z.gexp(z.glog(e.get(j))+g)}return new B(h,0).mod(e)}},C.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],C.getRSBlocks=function(j,l){var m=C.getRsBlockTable(j,l);if(void 0==m){throw new Error("bad rs block @ typeNumber:"+j+"/errorCorrectLevel:"+l)}for(var n=m.length/3,o=[],p=0;n>p;p++){for(var q=m[3*p+0],r=m[3*p+1],s=m[3*p+2],M=0;q>M;M++){o.push(new C(r,s))}}return o},C.getRsBlockTable=function(c,d){switch(d){case w.L:return C.RS_BLOCK_TABLE[4*(c-1)+0];case w.M:return C.RS_BLOCK_TABLE[4*(c-1)+1];case w.Q:return C.RS_BLOCK_TABLE[4*(c-1)+2];case w.H:return C.RS_BLOCK_TABLE[4*(c-1)+3];default:return void 0}},D.prototype={get:function(c){var d=Math.floor(c/8);return 1==(1&this.buffer[d]>>>7-c%8)},put:function(d,e){for(var g=0;e>g;g++){this.putBit(1==(1&d>>>e-g-1))}},getLengthInBits:function(){return this.length},putBit:function(c){var d=Math.floor(this.length/8);this.buffer.length<=d&&this.buffer.push(0),c&&(this.buffer[d]|=128>>>this.length%8),this.length++}};var E=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],H=function(){var b=function(c,d){this._el=c,this._htOption=d};return b.prototype.draw=function(e){function o(g,h){var j=document.createElementNS("http://www.w3.org/2000/svg",g);for(var k in h){h.hasOwnProperty(k)&&j.setAttribute(k,h[k])}return j}var l=this._htOption,m=this._el,n=e.getModuleCount();Math.floor(l.width/n),Math.floor(l.height/n),this.clear();var p=o("svg",{viewBox:"0 0 "+String(n)+" "+String(n),width:"100%",height:"100%",fill:l.colorLight});p.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),m.appendChild(p),p.appendChild(o("rect",{fill:l.colorDark,width:"1",height:"1",id:"template"}));for(var q=0;n>q;q++){for(var r=0;n>r;r++){if(e.isDark(q,r)){var s=o("use",{x:String(q),y:String(r)});s.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),p.appendChild(s)}}}},b.prototype.clear=function(){for(;this._el.hasChildNodes();){this._el.removeChild(this._el.lastChild)}},b}(),I="svg"===document.documentElement.tagName.toLowerCase(),J=I?H:F()?function(){function g(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function k(m,n){var o=this;if(o._fFail=n,o._fSuccess=m,null===o._bSupportDataURI){var p=document.createElement("img"),q=function(){o._bSupportDataURI=!1,o._fFail&&_fFail.call(o)},r=function(){o._bSupportDataURI=!0,o._fSuccess&&o._fSuccess.call(o)};return p.onabort=q,p.onerror=q,p.onload=r,p.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}o._bSupportDataURI===!0&&o._fSuccess?o._fSuccess.call(o):o._bSupportDataURI===!1&&o._fFail&&o._fFail.call(o)}if(this._android&&this._android<=2.1){var h=1/window.devicePixelRatio,j=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(b,c,m,n,o,p,q,r){if("nodeName" in b&&/img/i.test(b.nodeName)){for(var s=arguments.length-1;s>=1;s--){arguments[s]=arguments[s]*h}}else{"undefined"==typeof r&&(arguments[1]*=h,arguments[2]*=h,arguments[3]*=h,arguments[4]*=h)}j.apply(this,arguments)}}var l=function(c,d){this._bIsPainted=!1,this._android=G(),this._htOption=d,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=d.width,this._elCanvas.height=d.height,c.appendChild(this._elCanvas),this._el=c,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return l.prototype.draw=function(o){var p=this._elImage,q=this._oContext,r=this._htOption,s=o.getModuleCount(),M=r.width/s,N=r.height/s,O=Math.round(M),P=Math.round(N);p.style.display="none",this.clear();for(var R=0;s>R;R++){for(var S=0;s>S;S++){var T=o.isDark(R,S),U=S*M,V=R*N;q.strokeStyle=T?r.colorDark:r.colorLight,q.lineWidth=1,q.fillStyle=T?r.colorDark:r.colorLight,q.fillRect(U,V,M,N),q.strokeRect(Math.floor(U)+0.5,Math.floor(V)+0.5,O,P),q.strokeRect(Math.ceil(U)-0.5,Math.ceil(V)-0.5,O,P)}}this._bIsPainted=!0},l.prototype.makeImage=function(){this._bIsPainted&&k.call(this,g)},l.prototype.isPainted=function(){return this._bIsPainted},l.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},l.prototype.round=function(b){return b?Math.floor(1000*b)/1000:b},l}():function(){var b=function(c,d){this._el=c,this._htOption=d};return b.prototype.draw=function(m){for(var n=this._htOption,o=this._el,p=m.getModuleCount(),q=Math.floor(n.width/p),r=Math.floor(n.height/p),s=['<table style="border:0;border-collapse:collapse;">'],M=0;p>M;M++){s.push("<tr>");for(var N=0;p>N;N++){s.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:'+q+"px;height:"+r+"px;background-color:"+(m.isDark(M,N)?n.colorDark:n.colorLight)+';"></td>')}s.push("</tr>")}s.push("</table>"),o.innerHTML=s.join("");var O=o.childNodes[0],P=(n.width-O.offsetWidth)/2,R=(n.height-O.offsetHeight)/2;P>0&&R>0&&(O.style.margin=R+"px "+P+"px")},b.prototype.clear=function(){this._el.innerHTML=""},b}();QRCode=function(d,e){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:w.H},"string"==typeof e&&(e={text:e}),e){for(var g in e){this._htOption[g]=e[g]}}"string"==typeof d&&(d=document.getElementById(d)),this._android=G(),this._el=d,this._oQRCode=null,this._oDrawing=new J(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(b){this._oQRCode=new u(K(b,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(b),this._oQRCode.make(),this._el.title=b,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=w}();"use strict";if(!window.u2f){var u2f=u2f||{};var js_api_version;u2f.EXTENSION_ID="kmendfapggjehodndflmmgagdbamhnfd";u2f.MessageTypes={U2F_REGISTER_REQUEST:"u2f_register_request",U2F_REGISTER_RESPONSE:"u2f_register_response",U2F_SIGN_REQUEST:"u2f_sign_request",U2F_SIGN_RESPONSE:"u2f_sign_response",U2F_GET_API_VERSION_REQUEST:"u2f_get_api_version_request",U2F_GET_API_VERSION_RESPONSE:"u2f_get_api_version_response"};u2f.ErrorCodes={OK:0,OTHER_ERROR:1,BAD_REQUEST:2,CONFIGURATION_UNSUPPORTED:3,DEVICE_INELIGIBLE:4,TIMEOUT:5};u2f.U2fRequest;u2f.U2fResponse;u2f.Error;u2f.Transport;u2f.Transports;u2f.SignRequest;u2f.SignResponse;u2f.RegisterRequest;u2f.RegisterResponse;u2f.RegisteredKey;u2f.GetJsApiVersionResponse;u2f.getMessagePort=function(a){if(typeof chrome!="undefined"&&chrome.runtime){var b={type:u2f.MessageTypes.U2F_SIGN_REQUEST,signRequests:[]};chrome.runtime.sendMessage(u2f.EXTENSION_ID,b,function(){if(!chrome.runtime.lastError){u2f.getChromeRuntimePort_(a)}else{u2f.getIframePort_(a)}})}else{if(u2f.isAndroidChrome_()){u2f.getAuthenticatorPort_(a)}else{if(u2f.isIosChrome_()){u2f.getIosPort_(a)}else{u2f.getIframePort_(a)}}}};u2f.isAndroidChrome_=function(){var a=navigator.userAgent;return a.indexOf("Chrome")!=-1&&a.indexOf("Android")!=-1};u2f.isIosChrome_=function(){var b=["iPhone","iPad","iPod"];for(var a in b){if(navigator.platform==b[a]){return true}}return false};u2f.getChromeRuntimePort_=function(a){var b=chrome.runtime.connect(u2f.EXTENSION_ID,{includeTlsChannelId:true});setTimeout(function(){a(new u2f.WrappedChromeRuntimePort_(b))},0)};u2f.getAuthenticatorPort_=function(a){setTimeout(function(){a(new u2f.WrappedAuthenticatorPort_())},0)};u2f.getIosPort_=function(a){setTimeout(function(){a(new u2f.WrappedIosPort_())},0)};u2f.WrappedChromeRuntimePort_=function(a){this.port_=a};u2f.formatSignRequest_=function(a,b,d,h,e){if(js_api_version===undefined||js_api_version<1.1){var g=[];for(var c=0;c<d.length;c++){g[c]={version:d[c].version,challenge:b,keyHandle:d[c].keyHandle,appId:a}}return{type:u2f.MessageTypes.U2F_SIGN_REQUEST,signRequests:g,timeoutSeconds:h,requestId:e}}return{type:u2f.MessageTypes.U2F_SIGN_REQUEST,appId:a,challenge:b,registeredKeys:d,timeoutSeconds:h,requestId:e}};u2f.formatRegisterRequest_=function(a,c,d,h,e){if(js_api_version===undefined||js_api_version<1.1){for(var b=0;b<d.length;b++){d[b].appId=a}var g=[];for(var b=0;b<c.length;b++){g[b]={version:c[b].version,challenge:d[0],keyHandle:c[b].keyHandle,appId:a}}return{type:u2f.MessageTypes.U2F_REGISTER_REQUEST,signRequests:g,registerRequests:d,timeoutSeconds:h,requestId:e}}return{type:u2f.MessageTypes.U2F_REGISTER_REQUEST,appId:a,registerRequests:d,registeredKeys:c,timeoutSeconds:h,requestId:e}};u2f.WrappedChromeRuntimePort_.prototype.postMessage=function(a){this.port_.postMessage(a)};u2f.WrappedChromeRuntimePort_.prototype.addEventListener=function(a,b){var c=a.toLowerCase();if(c=="message"||c=="onmessage"){this.port_.onMessage.addListener(function(d){b({data:d})})}else{console.error("WrappedChromeRuntimePort only supports onMessage")}};u2f.WrappedAuthenticatorPort_=function(){this.requestId_=-1;this.requestObject_=null};u2f.WrappedAuthenticatorPort_.prototype.postMessage=function(b){var a=u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_+";S.request="+encodeURIComponent(JSON.stringify(b))+";end";document.location=a};u2f.WrappedAuthenticatorPort_.prototype.getPortType=function(){return"WrappedAuthenticatorPort_"};u2f.WrappedAuthenticatorPort_.prototype.addEventListener=function(a,b){var c=a.toLowerCase();if(c=="message"){var d=this;window.addEventListener("message",d.onRequestUpdate_.bind(d,b),false)}else{console.error("WrappedAuthenticatorPort only supports message")}};u2f.WrappedAuthenticatorPort_.prototype.onRequestUpdate_=function(a,d){var e=JSON.parse(d.data);var c=e.intentURL;var b=e.errorCode;var g=null;if(e.hasOwnProperty("data")){g=(JSON.parse(e.data))}a({data:g})};u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_="intent:#Intent;action=com.google.android.apps.authenticator.AUTHENTICATE";u2f.WrappedIosPort_=function(){};u2f.WrappedIosPort_.prototype.postMessage=function(a){var b=JSON.stringify(a);var c="u2f://auth?"+encodeURI(b);location.replace(c)};u2f.WrappedIosPort_.prototype.getPortType=function(){return"WrappedIosPort_"};u2f.WrappedIosPort_.prototype.addEventListener=function(a,b){var c=a.toLowerCase();if(c!=="message"){console.error("WrappedIosPort only supports message")}};u2f.getIframePort_=function(a){var d="chrome-extension://"+u2f.EXTENSION_ID;var c=document.createElement("iframe");c.src=d+"/u2f-comms.html";c.setAttribute("style","display:none");document.body.appendChild(c);var b=new MessageChannel();var e=function(g){if(g.data=="ready"){b.port1.removeEventListener("message",e);a(b.port1)}else{console.error('First event on iframe port was not "ready"')}};b.port1.addEventListener("message",e);b.port1.start();c.addEventListener("load",function(){c.contentWindow.postMessage("init",d,[b.port2])})};u2f.EXTENSION_TIMEOUT_SEC=30;u2f.port_=null;u2f.waitingForPort_=[];u2f.reqCounter_=0;u2f.callbackMap_={};u2f.getPortSingleton_=function(a){if(u2f.port_){a(u2f.port_)}else{if(u2f.waitingForPort_.length==0){u2f.getMessagePort(function(b){u2f.port_=b;u2f.port_.addEventListener("message",(u2f.responseHandler_));while(u2f.waitingForPort_.length){u2f.waitingForPort_.shift()(u2f.port_)}})}u2f.waitingForPort_.push(a)}};u2f.responseHandler_=function(b){var d=b.data;var c=d.requestId;if(!c||!u2f.callbackMap_[c]){console.error("Unknown or missing requestId in response.");return}var a=u2f.callbackMap_[c];delete u2f.callbackMap_[c];a(d.responseData)};u2f.sign=function(a,c,e,b,d){if(js_api_version===undefined){u2f.getApiVersion(function(g){js_api_version=g.js_api_version===undefined?0:g.js_api_version;u2f.sendSignRequest(a,c,e,b,d)})}else{u2f.sendSignRequest(a,c,e,b,d)}};u2f.sendSignRequest=function(a,c,e,b,d){u2f.getPortSingleton_(function(g){var j=++u2f.reqCounter_;u2f.callbackMap_[j]=b;var k=(typeof d!=="undefined"?d:u2f.EXTENSION_TIMEOUT_SEC);var h=u2f.formatSignRequest_(a,c,e,k,j);g.postMessage(h)})};u2f.register=function(a,e,d,b,c){if(js_api_version===undefined){u2f.getApiVersion(function(g){js_api_version=g.js_api_version===undefined?0:g.js_api_version;u2f.sendRegisterRequest(a,e,d,b,c)})}else{u2f.sendRegisterRequest(a,e,d,b,c)}};u2f.sendRegisterRequest=function(a,e,d,b,c){u2f.getPortSingleton_(function(g){var j=++u2f.reqCounter_;u2f.callbackMap_[j]=b;var k=(typeof c!=="undefined"?c:u2f.EXTENSION_TIMEOUT_SEC);var h=u2f.formatRegisterRequest_(a,d,e,k,j);g.postMessage(h)})};u2f.getApiVersion=function(a,b){u2f.getPortSingleton_(function(d){if(d.getPortType){var c;switch(d.getPortType()){case"WrappedIosPort_":case"WrappedAuthenticatorPort_":c=1.1;break;default:c=0;break}a({js_api_version:c});return}var g=++u2f.reqCounter_;u2f.callbackMap_[g]=a;var e={type:u2f.MessageTypes.U2F_GET_API_VERSION_REQUEST,timeoutSeconds:(typeof b!=="undefined"?b:u2f.EXTENSION_TIMEOUT_SEC),requestId:g};d.postMessage(e)})}}"use strict";var args;var autoReconnect=true;var powerStatetable=["","Powered","Sleep","Sleep","Sleep","Hibernating","Power off","Present"];var StatusStrs=["Disconnected","Connecting...","Setup...","Connected","Intel&reg; AMT Connected"];var sort=0;var searchFocus=0;var mapSearchFocus=0;var userSearchFocus=0;var consoleFocus=0;var showRealNames=false;var meshserver=null;var meshes={};var meshcount=0;var nodes=null;var filetree={};var userinfo=null;var serverinfo=null;var events=[];var users=null;var wssessions=null;var nodeShortIdent=0;var desktop;var desktopsettings={encoding:2,showfocus:false,showmouse:true,showcad:true,quality:40,scaling:1024,framerate:50,localkeymap:false};var multidesktopsettings={quality:20,scaling:128,framerate:1000};var terminal;var files;var debugLevel=parseInt("{{{debuglevel}}}");var features=parseInt("{{{features}}}");var sessionTime=parseInt("{{{sessiontime}}}");var domain="{{{domain}}}";var domainUrl="{{{domainurl}}}";var authCookie="{{{authCookie}}}";var authCookieRenewTimer=null;var multiDesktop={};var multiDesktopFilter=null;var serverPublicNamePort="{{{serverDnsName}}}:{{{serverPublicPort}}}";var amtScanResults=null;var debugmode=0;var clickOnce=(((features&256)!=0)&&detectClickOnce());var attemptWebRTC=((features&128)!=0);var webPageFullScreen=getstore("webPageFullScreen",true);if(webPageFullScreen=="false"){webPageFullScreen=false}if(webPageFullScreen=="true"){webPageFullScreen=true}var passRequirements="{{{passRequirements}}}";if(passRequirements!=""){passRequirements=JSON.parse(decodeURIComponent(passRequirements))}function startup(){if((features&32)==0){var h=null;try{h=top.location.toString().toLowerCase()}catch(b){}if(top!=self&&(h==null||top.active==false)){top.location=self.location;return}}args=parseUriArgs();debugmode=args.debug;if(args.webrtc!=null){attemptWebRTC=(args.webrtc==1)}QV("p13AutoConnect",debugmode);QV("autoconnectbutton2",debugmode);QV("autoconnectbutton1",debugmode);toggleFullScreen();if(args.hide){var d=parseInt(args.hide);QV("masthead",!(d&1));QV("topbarmaster",!(d&2));QV("footer",!(d&4));QV("p10title",!(d&8));QV("p11title",!(d&8));QV("p12title",!(d&8));QV("p13title",!(d&8));QV("p14title",!(d&8));QV("p15title",!(d&8));QV("p16title",!(d&8));if(d&16){QV("page_leftbar",false);QS("page_content").left="0px"}}if("{{currentNode}}"!=""){QV("p10BackButton",false);QV("p11BackButton",false);QV("p12BackButton",false);QV("p13BackButton",false);QV("p14BackButton",false);QV("p15BackButton",false);QV("p16BackButton",false)}p1updateInfo();document.onclick=function(c){hideContextMenu()};document.onkeypress=ondockeypress;document.onkeydown=ondockeydown;document.onkeyup=ondockeyup;window.onresize=function(){masterUpdate(512)};masterUpdate(512);meshserver=MeshServerCreateControl(domainUrl,authCookie);meshserver.onStateChanged=onStateChanged;meshserver.onMessage=onMessage;meshserver.Start();Q("sortselect").selectedIndex=sort=getstore("sort",0);Q("sizeselect").selectedIndex=getstore("viewsize",1);Q("SearchInput").value=getstore("search","");showRealNames=(getstore("showRealNames",0)==1);Q("RealNameCheckBox").checked=showRealNames;Q("viewselect").value=getstore("deviceView",1);Q("DeskControl").checked=(getstore("DeskControl",1)==1);masterUpdate(3);for(var g=1;g<5;g++){Q("devViewButton"+g).classList.remove("viewSelectorSel")}Q("devViewButton"+Q("viewselect").value).classList.add("viewSelectorSel");Q("p5filetable").addEventListener("drop",p5fileDragDrop,false);Q("p5filetable").addEventListener("dragover",p5fileDragOver,false);Q("p5filetable").addEventListener("dragleave",p5fileDragLeave,false);Q("p13filetable").addEventListener("drop",p13fileDragDrop,false);Q("p13filetable").addEventListener("dragover",p13fileDragOver,false);Q("p13filetable").addEventListener("dragleave",p13fileDragLeave,false);setInterval(updateDeviceTimeline,120000);var k=localStorage.getItem("desktopsettings");if(k!=null){desktopsettings=JSON.parse(k)}k=localStorage.getItem("multidesktopsettings");if(k!=null){multidesktopsettings=JSON.parse(k)}applyDesktopSettings();var l="";for(var a=1;a<27;a++){l+="<option value='"+a+"'>Ctrl-"+String.fromCharCode(64+a)+" ("+a+")</option>"}QH("specialkeylist",l);setupServerStats()}function toggleFullScreen(b){if(b===1){webPageFullScreen=!webPageFullScreen;putstore("webPageFullScreen",webPageFullScreen)}var a=0;if(args.hide){a=parseInt(args.hide)}if(webPageFullScreen==false){QS("container").width="960px";QS("container")["border-right"]="1px solid #b7b7b7";QS("container")["border-left"]="1px solid #b7b7b7";QS("container")["min-width"]="960px";QS("container")["overflow"]="";QS("column_l").width="930px";QS("column_l").height="";QS("column_l")["margin-left"]="";QS("column_l")["overflow-y"]="";QS("column_l")["max-height"]=(xxcurrentView>=10)?"calc(100vh - 159px)":"calc(100vh - 135px)";QS("container").position="";QS("page_content").position="";QV("MainMenuSpan",true);QV("UserDummyMenuSpan",false);QV("page_leftbar",false)}else{QS("container").position="absolute";QS("container").width="100%";QS("container").top="0px";QS("container").bottom="0px";QS("container")["border-right"]="0";QS("container")["border-left"]="0";QS("container")["min-width"]="700px";QS("container")["overflow"]="hidden";QS("page_content").position="absolute";QS("page_content").top="66px";QS("page_content").left=(a&16)?"0px":"90px";QS("page_content").right="0px";QS("page_content").bottom="0px";QS("column_l").height="calc(100vh - 135px)";QS("column_l").width="calc(100% - 30px)";QS("column_l")["overflow-y"]="auto";QS("column_l")["max-height"]="calc(100vh - 135px)";QV("MainMenuSpan",false);QV("UserDummyMenuSpan",(xxcurrentView<10)&&webPageFullScreen);QV("page_leftbar",!(a&16))}masterUpdate(512);QV("body",true)}function getNodeFromId(b){if(nodes!=null){for(var a in nodes){if(nodes[a]._id==b){return nodes[a]}}}return null}function reload(){window.location.href=window.location.href}function onStateChanged(c,d,b,a){if(d==0){setDialogMode(0);go(0);powerTimeline=null;powerTimelineReq=null;powerTimelineNode=null;powerTimelineUpdate=null;deleteAllNotifications();hideContextMenu();QV("verifyEmailId2",false);QV("logoutControl",false);if(a=="noauth"){QH("p0span","Unable to perform authentication");return}if(b==2){if(autoReconnect){setTimeout(serverPoll,5000)}}else{QH("p0span","Unable to connect web socket")}if(authCookieRenewTimer!=null){clearInterval(authCookieRenewTimer);authCookieRenewTimer=null}}else{if(d==2){meshserver.send({action:"meshes"});meshserver.send({action:"nodes",id:"{{currentNode}}"});if("{{currentNode}}"==""){meshserver.send({action:"files"})}go(1);authCookieRenewTimer=setInterval(function(){meshserver.send({action:"authcookie"})},1800000)}}}function serverPoll(){var b=null;try{b=new XDomainRequest()}catch(a){}if(!b){b=new XMLHttpRequest()}b.open("HEAD",window.location.href);b.timeout=15000;b.onload=function(){reload()};b.onerror=b.ontimeout=function(){setTimeout(serverPoll,10000)};b.send()}function detectClickOnce(){for(var a in window.navigator.mimeTypes){if(window.navigator.mimeTypes[a].type=="application/x-ms-application"){return true}}var b=window.navigator.userAgent.toUpperCase();return(b.indexOf(".NET CLR 3.5")>=0)||(b.indexOf("(WINDOWS NT ")>=0)}function updateSiteAdmin(){var a="{{{noServerBackup}}}";var b=userinfo.siteadmin;if(a==1){b&=4294967290}QV("p2AccountSecurity",((features&4)==0)&&(serverinfo.domainauth==false)&&((features&4096)!=0));QV("p2AccountActions",((features&4)==0)&&(serverinfo.domainauth==false));QV("p2AccountImage",((features&4)==0)&&(serverinfo.domainauth==false));QV("p2ServerActions",b&21);QV("LeftMenuMyServer",b&21);QV("MainMenuMyServer",b&21);QV("p2ServerActionsBackup",b&1);QV("p2ServerActionsRestore",b&4);QV("p2ServerActionsVersion",b&16);QV("MainMenuMyFiles",b&8);QV("LeftMenuMyFiles",b&8);if(((b&8)==0)&&(xxcurrentView==5)){setDialogMode(0);go(1)}if(currentNode!=null){gotoDevice(currentNode._id,xxcurrentView,true)}if((userinfo.siteadmin&2)!=0){if(users==null){meshserver.send({action:"users"})}if(wssessions==null){meshserver.send({action:"wssessioncount"})}}else{users=null;wssessions=null;updateUsers();if(xxcurrentView==4||((xxcurrentView>=30)&&(xxcurrentView<40))){setDialogMode(0);go(1);currentUser=null}}meshserver.send({action:"events",limit:parseInt(p3limitdropdown.value)});QV("p2deleteall",userinfo.siteadmin==4294967295);QV("ServerConsole",userinfo.siteadmin===4294967295);if((xxcurrentView==115)&&(userinfo.siteadmin!=4294967295)){go(6)}if((xxcurrentView==6)&&((userinfo.siteadmin&21)==0)){go(1)}if((b&21)!=0){meshserver.send({action:"serverstats",interval:10000})}}var updateNaggleTimer=null;var updateNaggleFlags=0;function masterUpdate(a){updateNaggleFlags|=a;if(updateNaggleTimer==null){updateNaggleTimer=setTimeout(function(){if(updateNaggleFlags&512){center()}if(updateNaggleFlags&1){onSearchInputChanged()}if(updateNaggleFlags&2){onSortSelectChange(true)}if(updateNaggleFlags&128){updateMeshes()}if(updateNaggleFlags&4){updateDevices()}if(updateNaggleFlags&8){drawNotifications()}if(updateNaggleFlags&16){updateMapMarkers()}if(updateNaggleFlags&32){eventsUpdate()}if(updateNaggleFlags&64){refreshMap(false,true)}if(updateNaggleFlags&256){drawDeviceTimeline()}if(updateNaggleFlags&1024){deviceEventsUpdate()}if(updateNaggleFlags&2048){userEventsUpdate()}updateNaggleTimer=null;updateNaggleFlags=0},150)}}function updateSelf(){QV("verifyEmailId",(userinfo.emailVerified!==true)&&(userinfo.email!=null)&&(serverinfo.emailcheck==true));QV("verifyEmailId2",(userinfo.emailVerified!==true)&&(userinfo.email!=null)&&(serverinfo.emailcheck==true));QV("manageOtp",(userinfo.otpsecret==1)||(userinfo.otphkeys>0));QV("authAppSetupCheck",userinfo.otpsecret==1);QV("authKeySetupCheck",userinfo.otphkeys>0);QV("authCodesSetupCheck",userinfo.otpkeys>0);if(typeof userinfo.passchange=="number"){if(userinfo.passchange==-1){QH("p2nextPasswordUpdateTime"," - Reset on next login.")}else{if((passRequirements!=null)&&(typeof passRequirements.reset=="number")){var a=(userinfo.passchange)+(passRequirements.reset*86400)-Math.floor(Date.now()/1000);if(a<0){QH("p2nextPasswordUpdateTime"," - Reset on next login.")}else{if(a<3600){QH("p2nextPasswordUpdateTime"," - Reset in "+Math.floor(a/60)+" minute"+addLetterS(Math.floor(a/60))+".")}else{if(a<86400){QH("p2nextPasswordUpdateTime"," - Reset in "+Math.floor(a/3600)+" hour"+addLetterS(Math.floor(a/3600))+".")}else{QH("p2nextPasswordUpdateTime"," - Reset in "+Math.floor(a/86400)+" day"+addLetterS(Math.floor(a/86400))+".")}}}}}}}function addLetterS(a){return(a>1)?"s":""}function onMessage(D,l){switch(l.action){case"serverstats":updateServerStats(l);break;case"authcookie":authCookie=l.cookie;break;case"serverinfo":serverinfo=l.serverinfo;break;case"userinfo":userinfo=l.userinfo;updateSiteAdmin();updateSelf();break;case"users":users={};for(var k in l.users){users[l.users[k]._id]=l.users[k]}updateUsers();break;case"wssessioncount":wssessions=l.wssessions;updateUsers();break;case"meshes":meshes={};for(var k in l.meshes){meshes[l.meshes[k]._id]=l.meshes[k]}masterUpdate(4+128);break;case"files":filetree=setupBackPointers(l.filetree);updateFiles();d3updatefiles();break;case"nodes":nodes=[];for(var k in l.nodes){if(!meshes[k]){console.log("Invalid mesh (1): "+k);continue}for(var o in l.nodes[k]){if(l.nodes[k][o]._id==null){console.log("Invalid node ("+o+"): "+JSON.stringify(l.nodes));continue}l.nodes[k][o].namel=l.nodes[k][o].name.toLowerCase();if(l.nodes[k][o].rname){l.nodes[k][o].rnamel=l.nodes[k][o].rname.toLowerCase()}else{l.nodes[k][o].rnamel=l.nodes[k][o].namel}l.nodes[k][o].meshnamel=meshes[k].name.toLowerCase();l.nodes[k][o].meshid=k;l.nodes[k][o].state=(l.nodes[k][o].state)?(l.nodes[k][o].state):0;l.nodes[k][o].desc=l.nodes[k][o].desc;if(!l.nodes[k][o].icon){l.nodes[k][o].icon=1}l.nodes[k][o].ident=++nodeShortIdent;nodes.push(l.nodes[k][o])}}masterUpdate(1|2|4|64);if(xxcurrentView==0){if("{{viewmode}}"!=""){go(parseInt("{{viewmode}}"))}else{setDialogMode(0);go(1)}}if("{{currentNode}}"!=""){gotoDevice("{{currentNode}}",parseInt("{{viewmode}}"))}break;case"powertimeline":if(l.nodeid!=powerTimelineReq){break}powerTimelineNode=l.nodeid;powerTimeline=l.timeline;powerTimelineUpdate=Date.now()+300000;if(currentNode._id==l.nodeid){masterUpdate(256)}break;case"lastconnect":var v=getNodeFromId(l.nodeid);if(v!=null){v.lastconnect=l.time;v.lastaddr=l.addr;if((currentNode._id==v._id)&&(Q("MainComputerState").innerHTML=="")){QH("MainComputerState","<span style=font-size:12px>Last seen:<br />"+new Date(v.lastconnect).toLocaleDateString()+", "+new Date(v.lastconnect).toLocaleTimeString()+"</span>")}}break;case"msg":if(l.nodeid!=null){var e=-1;if(nodes!=null){for(var d in nodes){if(nodes[d]._id==l.nodeid){e=d;break}}}if(e!=-1){if(l.type=="console"){p15consoleReceive(nodes[e],l.value)}else{if(l.type=="notify"){var o={text:l.value};if(l.nodeid!=null){o.nodeid=l.nodeid}if(l.tag!=null){o.tag=l.tag}if(l.username!=null){o.username=l.username}addNotification(o)}else{if(l.type=="ps"){showDeskToolsProcesses(l)}else{if((l.type=="getclip")&&(xxdialogTag=="clipboard")&&(currentNode!=null)&&(currentNode._id==l.nodeid)){Q("d2clipText").value=l.data}else{if((l.type=="setclip")&&(xxdialogTag=="clipboard")&&(currentNode!=null)&&(currentNode._id==l.nodeid)){QH("dlgClipStatus",l.success?"<span style=color:green>Success</span>":"<span style=color:red>Failed</span>");setTimeout(function(){try{QH("dlgClipStatus","")}catch(j){}},2000)}}}}}}}else{if(l.type=="notify"){var o={text:l.value};if(l.tag!=null){o.tag=l.tag}if(l.username!=null){o.username=l.username}addNotification(o)}}break;case"getnetworkinfo":if((currentNode._id==l.nodeid)&&(xxdialogMode==2)&&(xxdialogTag=="if"+l.nodeid)){if(l.netif==null){QH("d2netinfo","No network interface information available for this device.")}else{var I="<div style=width:100%;max-height:260px;overflow-x:hidden;overflow-y:auto;line-height:160%>";if(currentNode.lastconnect){I+=addHtmlValue2("Last agent connection",new Date(currentNode.lastconnect).toLocaleString())}if(currentNode.lastaddr){if(isPrivateIP(currentNode.lastaddr)){I+=addHtmlValue2("Last agent address",currentNode.lastaddr.split(":")[0])}else{I+=addHtmlValue2("Last agent address",'<a href="https://iplocation.com/?ip='+currentNode.lastaddr.split(":")[0]+'" rel="noreferrer noopener" target="MeshIPLoopup">'+currentNode.lastaddr.split(":")[0]+"</a>")}}I+=addHtmlValue2("Last interfaces update",new Date(l.updateTime).toLocaleString());for(var d in l.netif){var q=l.netif[d];I+="<hr />";if(q.name){I+=addHtmlValue2("Name","<b>"+EscapeHtml(q.name)+"</b>")}if(q.desc){I+=addHtmlValue2("Description",EscapeHtml(q.desc).replace("(R)","&reg;").replace("(r)","&reg;"))}if(q.dnssuffix){I+=addHtmlValue2("DNS suffix",EscapeHtml(q.dnssuffix))}if(q.mac){I+=addHtmlValue2("MAC address",'<a href="https://dnslytics.com/mac-address-lookup/'+q.mac.substring(0,6)+'" rel="noreferrer noopener" target="MeshMACLoopup">'+EscapeHtml(q.mac.toLowerCase())+"</a>")}if(q.v4addr){I+=addHtmlValue2("IPv4 address",EscapeHtml(q.v4addr))}if(q.v4mask){I+=addHtmlValue2("IPv4 mask",EscapeHtml(q.v4mask))}if(q.v4gateway){I+=addHtmlValue2("IPv4 gateway",EscapeHtml(q.v4gateway))}if(q.gatewaymac){I+=addHtmlValue2("Gateway MAC",'<a href="https://dnslytics.com/mac-address-lookup/'+q.gatewaymac.substring(0,6)+'" rel="noreferrer noopener" target="MeshMACLoopup">'+EscapeHtml(q.gatewaymac.toLowerCase())+"</a>")}}I+="</div>";QH("d2netinfo",I)}}break;case"serverversion":if((xxdialogMode==2)&&(xxdialogTag=="MeshCentralServerUpdate")){var I="<div style=width:100%;max-height:260px;overflow-x:hidden;overflow-y:auto;line-height:160%>";if(!l.current){l.current="Unknown"}if(!l.latest){l.latest="Unknown"}I+=addHtmlValue2("Current Version","<b>"+EscapeHtml(l.current)+"</b>");I+=addHtmlValue2("Latest Version","<b>"+EscapeHtml(l.latest)+"</b>");I+="</div>";if((l.latest.indexOf(".")==-1)||(l.current==l.latest)||((features&2048)==0)){setDialogMode(2,"MeshCentral Version",1,null,I)}else{setDialogMode(2,"MeshCentral Version",3,server_showVersionDlgEx,I+"<br /><label><input id=d2updateCheck type=checkbox onclick=server_showVersionDlgUpdate() /> Check and click OK to start server self-update.</label>");server_showVersionDlgUpdate()}}break;case"servererrors":if((xxdialogMode==2)&&(xxdialogTag=="MeshCentralServerErrors")){if(l.data==null){setDialogMode(2,"MeshCentral Server Errors",1,null,"Server has no error log.")}else{var I="<div style=width:100%;max-height:260px;overflow-x:hidden;overflow:auto;line-height:160%;font-size:10px><pre>"+l.data+"<pre></div>";setDialogMode(2,"MeshCentral Server Errors",3,server_showErrorsDlgEx,I+"<br /><label><input id=d2updateCheck type=checkbox onclick=server_showVersionDlgUpdate() /> Check and click OK to clear error log.</label>");server_showVersionDlgUpdate()}}break;case"serverconsole":p15consoleReceive("serverconsole",l.value);break;case"events":if((l.nodeid!=null)&&(l.nodeid==currentNode._id)){currentDeviceEvents=l.events;masterUpdate(1024)}else{if((l.user!=null)&&(l.user==currentUser.name)){currentUserEvents=l.events;masterUpdate(2048)}else{events=l.events;masterUpdate(32)}}break;case"getcookie":if(l.tag=="clickonce"){var a="{{{serverRedirPort}}}"==""?"{{{serverPublicPort}}}":"{{{serverRedirPort}}}";var A="http://"+window.location.hostname+":"+a+"/clickonce/minirouter/MeshMiniRouter.application?WS=wss%3A%2F%2F"+window.location.hostname+"%2Fmeshrelay.ashx%3Fauth="+l.cookie+"&CH={{{webcerthash}}}&AP="+l.protocol+((debugmode==1)?"":"&HOL=1");var u=window.open(A,"_blank");u.opener=null}break;case"getNotes":var o=Q("d2devNotes");if(o&&(l.id==decodeURIComponent(o.attributes.noteid.value))){if(l.notes){QH("d2devNotes",decodeURIComponent(l.notes))}else{QH("d2devNotes","")}var B=o.attributes.ro.value=="true";if(B==false){o.removeAttribute("readonly");QE("idx_dlgOkButton",true);QV("idx_dlgOkButton",true);focusTextBox("d2devNotes")}}break;case"otpauth-request":if((xxdialogMode==2)&&(xxdialogTag=="otpauth-request")){var C=l.secret;if(C.length==52){C=C.split(/(.............)/).filter(Boolean).join(" ")}else{if(C.length==32){C=C.split(/(....)/).filter(Boolean).join(" ");C=C.substring(0,20)+"<br/>"+C.substring(20)}}QH("d2optinfo",'<table style=width:380px><tr><td style=vertical-align:top>Install <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" rel="noreferrer noopener" target=_blank>Google Authenticator</a> or a compatible application and scan the barcode, use <a href="'+l.url+'" rel="noreferrer noopener" target=_blank> this link</a> or enter the secret. Then, enter the current 6 digit token below to activate 2-Step login.<br /><br />Secret<br /><tt id=d2optsecret secret="'+l.secret+'" style=font-size:12px>'+C+'</tt><br /><br /></td><td style=width:1px;vertical-align:top><a href="'+l.url+'" rel="noreferrer noopener" target=_blank><div id="qrcode"></div></a></td><tr><td colspan=2 style="text-align:center;border-top:1px solid black"><br />Enter the token here for 2-step login: <input type=text onkeypress="return (event.keyCode == 8) || (event.charCode >= 48 && event.charCode <= 57)" onkeyup=account_addOtpCheck(event) onkeydown=account_addOtpCheck() maxlength=6 id=d2otpauthinput type=text></td></table>');new QRCode(Q("qrcode"),{text:l.url,width:128,height:128,colorDark:"#000000",colorLight:"#EEE",correctLevel:QRCode.CorrectLevel.H});QV("idx_dlgOkButton",true);QE("idx_dlgOkButton",false);Q("d2otpauthinput").focus()}break;case"otpauth-setup":if(xxdialogMode){return}setDialogMode(2,"Authenticator App",1,null,l.success?"<b style=color:green>Authenticator app activation successful</b>. You will now need a valid token to login again.":"<b style=color:red>2-step login activation failed</b>. Clear the secret from the application and try again. You only have a few minutes to enter the proper code.");break;case"otpauth-clear":if(xxdialogMode){return}setDialogMode(2,"Authenticator App",1,null,l.success?"<b>Authenticator application removed</b>. You can reactivate this feature at any time.":"<b style=color:red>2-step login activation removal failed</b>. Try again.");break;case"otpauth-getpasswords":if(xxdialogMode){return}var I="One time tokens can be used as secondary authentication. Generate a set, print them and keep them in a safe place.";I+="<div style='border-radius:6px;border: 2px dashed #888;width:100%;margin-top:8px'><div style='padding:8px;font-family:Arial, Helvetica, sans-serif;font-size:20px;font-weight:bold'><table style=width:100%;text-align:center>";if(l.passwords){var g=0;for(var d in l.passwords){if(++g%2){I+="<tr>"}var y=""+l.passwords[d].p;while(y.length<8){y="0"+y}if(l.passwords[d].u===true){I+="<td>"+y.substring(0,4)+"&nbsp;"+y.substring(4)}else{I+="<td><strike style=color:#BBB>"+y.substring(0,4)+"&nbsp;"+y.substring(4);+"</strike>"}}}else{I+="<tr><td>No Active Tokens"}I+="</table></div></div><br />";I+="<div><input type=button value='Close' onclick=setDialogMode(0) style=float:right></input>";I+="<input type=button value='Generate New Tokens' onclick='account_manageOtp(1);'></input>";if(l.passwords!=null){I+="<input type=button value='Clear Tokens' onclick='account_manageOtp(2);'></input>"}I+="</div><br />";setDialogMode(2,"Manage Backup Codes",8,null,I,"otpauth-manage");break;case"otp-hkey-get":if(xxdialogMode&&(xxdialogTag!="otpauth-hardware-manage")){return}var F="<div style='border-radius:6px;border:2px solid #CCC;background-color:#BBB;width:100%;box-sizing:border-box;margin-bottom:6px'><div style='margin:3px;font-family:Arial, Helvetica, sans-serif;font-size:16px;font-weight:bold'><table style=width:100%;text-align:left>";var b="</table></div></div>";var I="<a href='https://www.yubico.com/' rel='noreferrer noopener' target='_blank'>Hardware keys</a> are used as secondary login authentication.";I+="<div style='max-height:150px;overflow-y:auto;overflow-x:hidden;margin-top:6px;margin-bottom:6px'>";if(l.keys&&l.keys.length>0){for(var d in l.keys){var h=l.keys[d],H=(h.type==1)?"U2F":"OTP";I+=F+'<tr style=margin:5px><td style=width:30px><img width=24 height=18 src="images/hardware-key-'+H+'-24.png" style=margin-top:4px><td style=width:250px>'+h.name+"<td><input type=button value='Remove' onclick=account_removehkey("+h.i+")></input>"+b}}else{I+=F+"<tr style=text-align:center><td>No Keys Configured"+b}I+="</div>";I+="<div><input type=button value='Close' onclick=setDialogMode(0) style=float:right></input>";I+="<input id=d2addkey1 type=button value='Add U2F Key' onclick='account_addhkey(1);'></input>";if((features&16384)!=0){I+="<input id=d2addkey2 type=button value='Add OTP Key' onclick='account_addhkey(2);'></input>"}I+="</div><br />";setDialogMode(2,"Manage Security Keys",8,null,I,"otpauth-hardware-manage");if(u2fSupported()==false){QE("d2addkey1",false)}break;case"otp-hkey-yubikey-add":if(l.result){meshserver.send({action:"otp-hkey-get"})}else{setDialogMode(2,"Add Security Key",1,null,"<br />Error, Unable to add key.<br /><br />")}break;case"otp-hkey-setup-request":if(xxdialogMode&&(xxdialogTag!="otpauth-hardware-manage")){return}var I="Press the key button now.<br /><br /><div style=width:100%;text-align:center><img width=120 height=117 src='images/hardware-keypress-120.png' /></div><input id=dp1keyname style=display:none value="+l.name+" />";setDialogMode(2,"Add Security Key",2,null,I);window.u2f.register(l.request.appId,l.request.registerRequests,l.request.registeredKeys,function(m){if(m.registrationData){meshserver.send({action:"otp-hkey-setup-response",response:m,name:Q("dp1keyname").value});setDialogMode(2,"Add Security Key",0,null,"<br />Checking...<br /><br /><br />","otpauth-hardware-manage")}else{var j=["","Unknown error","Bad request","Unsupported configuration","This key was already registered","Timeout"];setDialogMode(2,"Add Security Key",1,null,"<br />"+j[m.errorCode]+".<br /><br />")}},l.request.timeoutSeconds);break;case"otp-hkey-setup-response":if(xxdialogMode&&(xxdialogTag!="otpauth-hardware-manage")){return}if(l.result==true){meshserver.send({action:"otp-hkey-get"})}else{setDialogMode(2,"Add Security Key",1,null,"<br />ERROR: Unable to add key.<br /><br />","otpauth-hardware-manage")}break;case"event":if(!l.event.nolog){events.unshift(l.event);var c=parseInt(p3limitdropdown.value);while(events.length>c){events.pop()}masterUpdate(32)}switch(l.event.action){case"accountcreate":case"accountchange":if(userinfo.name==l.event.account.name){var t=l.event.account.siteadmin?l.event.account.siteadmin:0;var w=userinfo.siteadmin?userinfo.siteadmin:0;if((l.event.account.quota!=userinfo.quota)||(((userinfo.siteadmin&8)==0)&&((l.event.account.siteadmin&8)!=0))){meshserver.send({action:"files"})}userinfo=l.event.account;if(w!=t){updateSiteAdmin()}updateSelf()}if(users==null){break}users[l.event.account._id]=l.event.account;updateUsers();break;case"accountremove":if(users==null){break}delete users["user/"+domain+"/"+l.event.username.toLowerCase()];updateUsers();break;case"createmesh":if(l.event.links["user/"+domain+"/"+userinfo.name.toLowerCase()]!=null){meshes[l.event.meshid]={_id:l.event.meshid,name:l.event.name,mtype:l.event.mtype,desc:l.event.desc,links:l.event.links};masterUpdate(4+128);meshserver.send({action:"files"})}break;case"meshchange":if(meshes[l.event.meshid]==null){meshes[l.event.meshid]={_id:l.event.meshid,name:l.event.name,mtype:l.event.mtype,desc:l.event.desc,links:l.event.links};meshserver.send({action:"nodes"})}else{if(l.event.name){meshes[l.event.meshid].name=l.event.name}if(l.event.desc){meshes[l.event.meshid].desc=l.event.desc}if(l.event.flags!=null){meshes[l.event.meshid].flags=l.event.flags}if(l.event.links){meshes[l.event.meshid].links=l.event.links}if(l.event.amt){meshes[l.event.meshid].amt=l.event.amt}if(meshes[l.event.meshid].links["user/"+domain+"/"+userinfo.name.toLowerCase()]==null){if((xxcurrentView==20)&&(currentMesh==meshes[l.event.meshid])){go(2)}delete meshes[l.event.meshid];var s=[];for(var d in nodes){if(nodes[d].meshid!=l.event.meshid){s.push(nodes[d])}}nodes=s;if(xxcurrentView>=10&&xxcurrentView<20&&currentNode&&currentNode.meshid==l.event.meshid){setDialogMode(0);go(1)}}}masterUpdate(4+128);if(xxcurrentView==20&&currentMesh._id==l.event.meshid){p20updateMesh()}break;case"deletemesh":if(meshes[l.event.meshid]){delete meshes[l.event.meshid];masterUpdate(128);meshserver.send({action:"files"})}var s=[];if(nodes!=null){for(var d in nodes){if(nodes[d].meshid!=l.event.meshid){s.push(nodes[d])}}}nodes=s;masterUpdate(4);if(xxcurrentView>=20&&xxcurrentView<30&&currentMesh._id==l.event.meshid){setDialogMode(0);go(2)}if(xxcurrentView>=10&&xxcurrentView<20&&currentNode&&currentNode.meshid==l.event.meshid){setDialogMode(0);go(1)}break;case"addnode":var v=l.event.node;if(!meshes[v.meshid]){break}v.namel=v.name.toLowerCase();if(v.rname){v.rnamel=v.rname.toLowerCase()}else{v.rnamel=v.namel}v.meshnamel=meshes[v.meshid].name.toLowerCase();v.state=0;if(!v.icon){v.icon=1}v.ident=++nodeShortIdent;if(nodes==null){}nodes.push(v);masterUpdate(1|2|4|16);break;case"removenode":var e=-1;for(var d in nodes){if(nodes[d]._id==l.event.nodeid){e=d;break}}if(e!=-1){var v=nodes[e];if(currentNode==v){if(xxcurrentView>=10&&xxcurrentView<20){setDialogMode(0);go(1)}currentNode=null}nodes.splice(e,1);masterUpdate(4|16)}break;case"changenode":var e=-1;for(var d in nodes){if(nodes[d]._id==l.event.nodeid){e=d;break}}if(e!=-1){var v=nodes[e];v.name=l.event.node.name;v.rname=l.event.node.rname;v.users=l.event.node.users;v.host=l.event.node.host;v.desc=l.event.node.desc;v.osdesc=l.event.node.osdesc;v.publicip=l.event.node.publicip;v.iploc=l.event.node.iploc;v.wifiloc=l.event.node.wifiloc;v.gpsloc=l.event.node.gpsloc;v.tags=l.event.node.tags;v.userloc=l.event.node.userloc;if(l.event.node.agent!=null){if(v.agent==null){v.agent={}}if(l.event.node.agent.ver!=null){v.agent.ver=l.event.node.agent.ver}if(l.event.node.agent.id!=null){v.agent.id=l.event.node.agent.id}if(l.event.node.agent.caps!=null){v.agent.caps=l.event.node.agent.caps}if(l.event.node.agent.core!=null){v.agent.core=l.event.node.agent.core}else{if(v.agent.core){delete v.agent.core}}v.agent.tag=l.event.node.agent.tag}if(l.event.node.intelamt!=null){if(v.intelamt==null){v.intelamt={}}if(l.event.node.intelamt.host!=null){v.intelamt.user=l.event.node.intelamt.host}if(l.event.node.intelamt.user!=null){v.intelamt.user=l.event.node.intelamt.user}if(l.event.node.intelamt.tls!=null){v.intelamt.tls=l.event.node.intelamt.tls}if(l.event.node.intelamt.ver!=null){v.intelamt.ver=l.event.node.intelamt.ver}if(l.event.node.intelamt.state!=null){v.intelamt.state=l.event.node.intelamt.state}}v.namel=v.name.toLowerCase();if(v.rname){v.rnamel=v.rname.toLowerCase()}else{v.rnamel=v.namel}if(l.event.node.icon){v.icon=l.event.node.icon}masterUpdate(2|4|8|16);refreshDevice(v._id);if((currentNode==v)&&(xxdialogMode!=null)&&(xxdialogTag=="@xxmap")){p10showNodeLocationDialog()}}break;case"nodemeshchange":var e=-1;for(var d in nodes){if(nodes[d]._id==l.event.nodeid){e=d;break}}if(e!=-1){var v=nodes[e];if(meshes[l.event.newMeshId]==null){if(currentNode==v){if(xxcurrentView>=10&&xxcurrentView<20){setDialogMode(0);go(1)}currentNode=null}nodes.splice(e,1);masterUpdate(4|16)}else{v.meshid=l.event.newMeshId;v.meshnamel=meshes[l.event.newMeshId].name.toLowerCase();masterUpdate(1|2|4)}refreshDevice(l.event.nodeid)}else{var v=l.event.node;if(!meshes[v.meshid]){break}v.namel=v.name.toLowerCase();if(v.rname){v.rnamel=v.rname.toLowerCase()}else{v.rnamel=v.namel}v.meshnamel=meshes[v.meshid].name.toLowerCase();v.state=0;if(!v.icon){v.icon=1}v.ident=++nodeShortIdent;if(nodes==null){}nodes.push(v);masterUpdate(1|2|4|16)}break;case"nodeconnect":var e=-1;for(var d in nodes){if(nodes[d]._id==l.event.nodeid){e=d;break}}if(e!=-1){var v=nodes[e];v.conn=l.event.conn;v.pwr=l.event.pwr;masterUpdate(4|16);refreshDevice(v._id)}break;case"wssessioncount":if(wssessions!=null){if(l.event.count==0&&wssessions["user/"+domain+"/"+l.event.username.toLowerCase()]){delete wssessions["user/"+domain+"/"+l.event.username.toLowerCase()]}else{wssessions["user/"+domain+"/"+l.event.username.toLowerCase()]=l.event.count}updateUsers()}break;case"clearevents":events=[];masterUpdate(32);break;case"login":if(users!=null&&users["user/"+domain+"/"+l.event.username.toLowerCase()]){users["user/"+domain+"/"+l.event.username.toLowerCase()].login=Math.floor(new Date(l.event.time).getTime()/1000)}break;case"scanamtdevice":if((xxdialogMode==null)||(!Q("dp1range"))||(Q("dp1range").value!=l.event.range)){return}var I="";if(l.event.results==null){I="<div style=width:100%;text-align:center;margin-top:12px>Unable to scan this address range.</div><div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>Sample IP range values<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>"}else{amtScanResults=l.event.results;for(var d in l.event.results){var z=l.event.results[d],E=z.hostname;if(E.length>20){E=E.substring(0,20)+"..."}var G='<b title="'+EscapeHtml(z.hostname)+'">'+EscapeHtml(E)+"</b> - v"+z.ver;if(z.state==2){if(z.tls==1){G+=" with TLS."}else{G+=" without TLS."}}else{G+=" not activated."}I+='<div style=width:100%;margin-bottom:2px;background-color:lightgray><div style=padding:4px><div style=display:inline-block;margin-right:5px><input class=DevScanCheckbox name=dp1checkbox tag="'+EscapeHtml(d)+'" type=checkbox onclick=addAmtScanToMeshCheckbox() /></div><div class=j1 style=display:inline-block></div><div style=display:inline-block;margin-left:5px;overflow-x:auto;white-space:nowrap>'+G+"</div></div></div>"}if(I==""){I="<div style=width:100%;text-align:center;margin-top:12px>Scan returned no results.</div><div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>Sample IP range values<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>"}}QH("dp1results",I);QE("dp1range",true);QE("dp1rangebutton",true);break;case"notify":var o={text:l.event.value};if(l.event.tag!=null){o.tag=l.event.tag}addNotification(o);break;case"stopped":break;default:break}break;case"stopped":autoReconnect=false;QH("p0span",l.msg);break;default:console.log("Unknown message.action",l.action);break}}function onRealNameCheckBox(){showRealNames=Q("RealNameCheckBox").checked;putstore("showRealNames",showRealNames?1:0);masterUpdate(6);return}function onDeviceViewChange(a){if(a!=null){Q("viewselect").value=a}for(var b=1;b<5;b++){Q("devViewButton"+b).classList.remove("viewSelectorSel")}Q("devViewButton"+Q("viewselect").value).classList.add("viewSelectorSel");putstore("deviceView",Q("viewselect").value);putstore("viewsize",Q("sizeselect").value);masterUpdate(4)}function ondockeypress(a){if(!xxdialogMode&&xxcurrentView==11&&desktop&&Q("DeskControl").checked){if(currentNode!=null){var d=meshes[currentNode.meshid];var g=d.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;var b=((g==4294967295)||(((g&8)!=0)&&((g&256)==0)));if(b==false){return false}var c=((g!=4294967295)||(((g&8)!=0)&&((g&256)==0)&&((g&4096)!=0)));if(c==true){if((a.altKey==true)||(a.ctrlKey==true)||(a.keyCode<32)||(a.keyCode>90)){return false}}}return desktop.m.handleKeys(a)}if(!xxdialogMode&&xxcurrentView==12&&terminal&&terminal.State==3){return terminal.m.TermHandleKeys(a)}if(!xxdialogMode&&((xxcurrentView==15)||(xxcurrentView==115))){return agentConsoleHandleKeys(a)}if(!xxdialogMode&&xxcurrentView==4){if(a.ctrlKey==true||a.altKey==true||a.metaKey==true){return}var h=0;if(a.key){if(a.key.length===1&&userSearchFocus==0){Q("UserSearchInput").value=((Q("UserSearchInput").value+a.key));h=1}if(a.keyCode==8&&userSearchFocus==0){var j=Q("UserSearchInput").value;Q("UserSearchInput").value=j.substring(0,j.length-1);h=1}if(a.keyCode==27){Q("UserSearchInput").value="";h=1}}else{if(a.charCode!=0&&userSearchFocus==0){Q("UserSearchInput").value=((Q("UserSearchInput").value+String.fromCharCode(a.charCode)));h=1}}if(h>0){if(h==1){onUserSearchInputChanged()}return haltEvent(a)}}if(xxdialogMode||xxcurrentView!=1){return}if(a.ctrlKey==true&&a.charCode==96){showRealNames=!showRealNames;Q("RealNameCheckBox").value=showRealNames;putstore("showRealNames",showRealNames?1:0);masterUpdate(6);return}if(a.ctrlKey==true||a.altKey==true||a.metaKey==true){return}if(Q("viewselect").value<3){var h=0;if(a.key){if(a.key.length===1&&searchFocus==0){Q("SearchInput").value=((Q("SearchInput").value+a.key));h=1}if(a.keyCode==8&&searchFocus==0){var j=Q("SearchInput").value;Q("SearchInput").value=j.substring(0,j.length-1);h=1}if(a.keyCode==27){Q("SearchInput").value="";h=1}}else{if(a.charCode!=0&&searchFocus==0){Q("SearchInput").value=((Q("SearchInput").value+String.fromCharCode(a.charCode)));h=1}}if(h>0){if(h==1){masterUpdate(5)}return haltEvent(a)}}if(Q("viewselect").value==3){if(a.key){if(a.key.length===1&&mapSearchFocus==0){Q("mapSearchLocation").value=((Q("mapSearchLocation").value+a.key));h=1}if(a.keyCode==27){Q("mapSearchLocation").value="";mapCloseSearchWindow();h=1}if(a.keyCode==13){getSearchLocation()}}else{if(a.charCode!=0&&mapSearchFocus==0){Q("mapSearchLocation").value=((Q("mapSearchLocation").value+String.fromCharCode(a.charCode)));h=1}}}}function ondockeydown(a){if(!xxdialogMode&&xxcurrentView==11&&desktop&&Q("DeskControl").checked){if(currentNode!=null){var d=meshes[currentNode.meshid];var g=d.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;var b=((g==4294967295)||(((g&8)!=0)&&((g&256)==0)));if(b==false){return false}var c=((g!=4294967295)||(((g&8)!=0)&&((g&256)==0)&&((g&4096)!=0)));if(c==true){if((a.altKey==true)||(a.ctrlKey==true)||(a.keyCode<32)||(a.keyCode>90)){return false}}}return desktop.m.handleKeyDown(a)}if(!xxdialogMode&&xxcurrentView==12&&terminal&&terminal.State==3){return terminal.m.TermHandleKeyDown(a)}if(!xxdialogMode&&xxcurrentView==13&&a.keyCode==116&&p13filetree!=null){haltEvent(a);return false}if(!xxdialogMode&&((xxcurrentView==15)||(xxcurrentView==115))){return agentConsoleHandleKeys(a)}if(!xxdialogMode&&xxcurrentView==4){if(a.keyCode===8&&userSearchFocus==0){var j=Q("UserSearchInput").value;Q("UserSearchInput").value=(j.substring(0,j.length-1));h=1}if(a.keyCode===27){Q("UserSearchInput").value="";h=1}if(h>0){if(h==1){masterUpdate(5)}return haltEvent(a)}}if(xxdialogMode||xxcurrentView!=1||a.ctrlKey==true||a.altKey==true||a.metaKey==true){return}var h=0;if(Q("viewselect").value<3){if(a.keyCode===8&&searchFocus==0){var j=Q("SearchInput").value;Q("SearchInput").value=(j.substring(0,j.length-1));h=1}if(a.keyCode===27){Q("SearchInput").value="";h=1}if(h>0){if(h==1){masterUpdate(5)}return haltEvent(a)}}if(Q("viewselect").value==3){if(a.keyCode===8&&mapSearchFocus==0){var j=Q("mapSearchLocation").value;Q("mapSearchLocation").value=(j.substring(0,j.length-1));h=1}if(a.keyCode===27){Q("mapSearchLocation").value="";mapCloseSearchWindow();h=1}}}function ondockeyup(a){if(!xxdialogMode&&xxcurrentView==11&&desktop&&Q("DeskControl").checked){if(currentNode!=null){var d=meshes[currentNode.meshid];var g=d.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;var b=((g==4294967295)||(((g&8)!=0)&&((g&256)==0)));if(b==false){return false}var c=((g!=4294967295)||(((g&8)!=0)&&((g&256)==0)&&((g&4096)!=0)));if(c==true){if((a.altKey==true)||(a.ctrlKey==true)||(a.keyCode<32)||(a.keyCode>90)){return false}}}return desktop.m.handleKeyUp(a)}if(!xxdialogMode&&xxcurrentView==12&&terminal&&terminal.State==3){return terminal.m.TermHandleKeyUp(a)}if(!xxdialogMode&&xxcurrentView==13&&a.keyCode==116&&p13filetree!=null){p13folderup(9999);haltEvent(a);return false}if(!xxdialogMode&&xxcurrentView==4){if((a.keyCode===8&&searchFocus==0)||a.keyCode===27){return haltEvent(a)}}if(xxdialogMode&&a.keyCode==27){dialogclose(0)}if(xxdialogMode||xxcurrentView!=0||a.ctrlKey==true||a.altKey==true||a.metaKey==true){return}if(Q("viewselect").value<3){if((a.keyCode===8&&searchFocus==0)||a.keyCode===27){return haltEvent(a)}}if(Q("viewselect").value==3){if((a.keyCode===8&&mapSearchFocus==0)||a.keyCode===27){return haltEvent(a)}}}function devMouseHover(b,c){var d=Q("viewselect").value;if(d==1){var a=b.children[1].children[1];a.children[0].classList.remove("g1s");a.children[1].classList.remove("e2s");a.children[2].classList.remove("g2s");if(c==1){a.children[0].classList.add("g1s");a.children[1].classList.add("e2s");a.children[2].classList.add("g2s")}}else{if(d==2){var a=b;a.children[2].classList.remove("g1s");a.children[4].classList.remove("e2s");a.children[3].classList.remove("g2s");if(c==1){a.children[2].classList.add("g1s");a.children[4].classList.add("e2s");a.children[3].classList.add("g2s")}}}}var deviceHeaderId=0;var deviceHeaderTotal=0;var deviceHeadersTitles={};var deviceHeaderCount;var deviceHeaders={};var oldviewmode=0;function updateDevices(){if(nodes==null){return}var G="",a=0,g=null,e=0,l={},O=Q("viewselect").value,s={},p={};QV("xdevices",O<4);QV("xdevicesmap",O==4);QV("devListToolbar",O<3);QV("kvmListToolbar",O==3);QV("devMapToolbar",O==4);QV("devListToolbarSize",O==3);QV("NoMeshesPanel",meshcount==0);QV("devListToolbarViewIcons",(meshcount!=0)&&(nodes.length>0));QV("devListToolbarSort",(meshcount!=0)&&(nodes.length>0)&&(O<4));if((meshcount==0)||(nodes.length==0)){O=1;sort=0}if(O==4){setTimeout(function(){if(xxmap.map!=null){xxmap.map.updateSize()}},200)}else{deviceHeaderId=0;deviceHeaderCount={};deviceHeaderTotal=0;deviceHeaders={};deviceHeadersTitles={};var x=[];if(sort==0){nodes.sort(meshSort)}else{if(sort==1){nodes.sort(powerSort)}else{if(sort==2){if(showRealNames==true){nodes.sort(deviceHostSort)}else{nodes.sort(deviceSort)}}}}var d=[],m=document.getElementsByClassName("DeviceCheckbox"),b=0;for(var t=0;t<m.length;t++){if(m[t].checked){d.push(m[t].value)}}if((oldviewmode<3)&&(O==3)){multiDesktopFilter=d}else{if((oldviewmode==3)&&(O<3)){d=multiDesktopFilter}}var M=Q("column_l").clientWidth-60;var k=Math.floor(M/301);k=301+Math.floor((M-(k*301))/k);if(O==2){G+="<table style=width:100%;margin-top:4px cellpadding=0 cellspacing=0><th style=color:gray><th style=color:gray;width:120px>User<th style=color:gray;width:120px>Address<th style=color:gray;width:100px>Connectivity"}for(var t in nodes){var E=nodes[t];if(E.v==false){continue}var z=meshes[E.meshid],B=z.links["user/"+domain+"/"+userinfo.name.toLowerCase()];if(B==null){continue}var C=B.rights;if((O==3)&&(z.mtype==1)){continue}if(sort==0){if(E.meshid!=g){deviceHeaderSet();var o="";if(O==2){G+="<tr><td colspan=5>"}if(meshes[E.meshid].mtype==1){o="<span class=devHeaderx>, Intel&reg; AMT only</span>"}if((O==1)&&(g!=null)){if(a==2){G+="<td><div style=width:301px></div></td>"}if(G!=""){G+="</tr></table>"}}if(O==2){G+="<div>"}G+="<div class=DevSt style=width:100%;padding-top:4px><span style=float:right>";G+=getMeshActions(z,C);G+='</span><span id=MxMESH style=cursor:pointer onclick=gotoMesh("'+E.meshid+'")>'+EscapeHtml(meshes[E.meshid].name)+"</span>"+o+"<span id=DevxHeader"+deviceHeaderId+" class=devHeaderx></span></div>";if(O==2){G+="</div>"}g=E.meshid;l[g]=1;a=0}}else{if(sort==1){var F=E.pwr?E.pwr:0;if(F!==g){deviceHeaderSet();if((O==1)&&(g!==null)){if(a==2){G+="<td><div style=width:301px></div></td>"}if(G!=""){G+="</tr></table>"}}G+="<div class=DevSt style=width:100%;padding-top:4px><span>"+PowerStateStr2(E.pwr)+"</span><span id=DevxHeader"+deviceHeaderId+' class="devHeaderx"></span></div>';g=F;a=0}}else{if(sort==2){if(g==null){g="1"}}}}e++;var L=EscapeHtml(E.name);if(L.length==0){L="<i>None</i>"}if((E.rname!=null)&&(E.rname.length>0)){L+=" / "+EscapeHtml(E.rname)}var D=EscapeHtml(E.name);if(showRealNames==true&&E.rname!=null){D=EscapeHtml(E.rname)}if(D.length==0){D="<i>None</i>"}var u=E.icon;if((!E.conn)||(E.conn==0)){u+=" gray"}if(O==1){G+="<div id=devs onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=display:inline-block;width:"+k+'px;height:50px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:12px><input class="'+E.meshid+' DeviceCheckbox" onclick=p1updateInfo() value=devid_'+E._id+" type=checkbox></div><div style=height:100%;cursor:pointer onclick=gotoDevice('"+E._id+"',null,null,event)><div class=\"i"+u+'" style=width:50px;float:left></div><div style=height:100%><div class=g1></div><div class=e2><div class=e1 style=width:'+(k-100)+'px title="'+L+'">'+D+"</div><div>"+NodeStateStr(E)+"</div></div><div class=g2></div></div></div></div>"}else{if(O==2){var J=[];if(E.conn){if((E.conn&1)!=0){J.push('<span title="Mesh agent is connected and ready for use.">Agent</span>')}if((E.conn&2)!=0){J.push('<span title="Intel&reg; AMT CIRA is connected and ready for use.">CIRA</span>')}else{if((E.conn&4)!=0){J.push('<span title="Intel&reg; AMT is routable.">AMT</span>')}}if((E.conn&8)!=0){J.push('<span title="Mesh agent is reachable using another agent as relay.">Relay</span>')}}G+="<tr><td><div id=devs class=bar18 onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=height:18px;width:100%;font-size:medium>";G+='<div style=width:22px;float:left;background-color:white><input class="'+E.meshid+' DeviceCheckbox" onclick=p1updateInfo() value=devid_'+E._id+" type=checkbox></div>";G+="<div style=float:left;height:18px;width:18px;background-color:white onclick=gotoDevice('"+E._id+"',null,null,event)><div class=j"+u+" style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>";G+="<div class=g1 style=height:18px;float:left></div><div class=g2 style=height:18px;float:right></div>";G+='<div style=cursor:pointer;font-size:14px title="'+L+"\" onclick=gotoDevice('"+E._id+"',null,null,event)><span style=width:300px>"+D+"</span></div></div></td>";G+="<td style=text-align:center>"+getUserShortStr(E);G+="<td style=text-align:center>"+(E.ip!=null?E.ip:"");G+="<td style=text-align:center>"+J.join("&nbsp;+&nbsp;");G+="</tr>"}else{if((O==3)&&(E.conn&1)&&(((C&8)||(C&256))!=0)&&((E.agent.caps&1)!=0)){if((multiDesktopFilter.length==0)||(multiDesktopFilter.indexOf("devid_"+E._id)>=0)){G+="<div id=devs style=display:inline-block;margin:1px;background-color:lightgray;border-radius:5px;position:relative><div style=padding:3px;cursor:pointer onclick=gotoDevice('"+E._id+"',11,null,event)>";G+='<div class="j'+u+'" style=width:16px;float:left></div>&nbsp;'+D+"</div>";G+="<span onclick=gotoDevice('"+E._id+"',null,null,event)></span><div id=xkvmid_"+E._id.split("/")[2]+"><div id=skvmid_"+E._id.split("/")[2]+' style="position:absolute;color:white;left:5px;top:27px;text-shadow:0px 0px 5px #000;z-index:1000;cursor:default" onclick=toggleKvmDevice(\''+E._id+"')>Disconnected</div></div>";G+="</div>";x.push(E._id)}}}}if((sort==3)&&(G!="")){if(E.tags){for(var w in E.tags){var K=E.tags[w];if(s[K]==null){s[K]=G;p[K]=1}else{s[K]+=G;p[K]+=1}if(O==3){break}}}G=""}deviceHeaderTotal++;if(typeof deviceHeaderCount[E.state]=="undefined"){deviceHeaderCount[E.state]=1}else{deviceHeaderCount[E.state]++}}if(sort==3){var q=[];for(var t in s){q.push(t)}q.sort(function(c,j){return c.toLowerCase().localeCompare(j.toLowerCase())});for(var w in q){var t=q[w];G+="<div class=DevSt style=width:100%;padding-top:4px><span>"+t+'</span><span class="devHeaderx">, '+p[t]+" device"+((p[t]>1)?"s":"")+"</span></div>"+s[t]}}if((G=="")&&(meshcount>0)&&(Q("SearchInput").value!="")){if(sort==3){G='<div style="margin:30px">No devices are included in any groups, click on a device\'s "Groups" to add to a group.</div>'}else{G='<div style="margin:30px">No devices matching this search.</div>'}}if((O==1)&&(a==2)){G+="<td><div style=width:301px></div></td>"}if((sort==0)&&(Q("SearchInput").value=="")&&(O<3)){for(var t in meshes){var y=meshes[t],A=y.links["user/"+domain+"/"+userinfo.name.toLowerCase()];if(A!=null){var C=A.rights;if(l[y._id]==null){if((g!="")&&(G!="")){G+="</tr></table>"}G+="<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt><span style=float:right>";G+=getMeshActions(y,C);G+='</span><span id=MxMESH style=cursor:pointer onclick=gotoMesh("'+y._id+'")>'+EscapeHtml(y.name)+"</span></td></tr><tr>";if(y.mtype==1){G+="<td><div style=padding:10px><i>No Intel&reg; AMT devices in this mesh";if((C&4)!=0){G+=', <a style=cursor:pointer onclick=addDeviceToMesh("'+y._id+'")>add one</a>'}}if(y.mtype==2){G+="<td><div style=padding:10px><i>No devices in this mesh";if((C&4)!=0){G+=', <a style=cursor:pointer onclick=addAgentToMesh("'+y._id+'")>add one</a>'}}G+=".</i></div></td>";g=y._id;e++}}}}G+="</tr></table><div style=height:1px></div>";G+="<div style=border-top-style:solid;border-top-width:1px;border-top-color:#DDDDDD;cursor:pointer;font-size:10px>";if((O<3)&&(sort==0)&&(meshcount>0)){G+='<a onclick=account_createMesh() title="Create a new group of devices." style=cursor:pointer>Add Device Group</a>&nbsp'}G+='<a onclick=p10showMeshCmdDialog(0) style=cursor:pointer title="Download MeshCmd, a command line tool that performs many functions.">MeshCmd</a></div>';G+="</div><br/>";QH("xdevices",G);deviceHeaderSet();var m=document.getElementsByClassName("DeviceCheckbox"),b=0;for(var t=0;t<m.length;t++){m[t].checked=(d.indexOf(m[t].value)>=0)}for(var t in deviceHeaders){QH(t,deviceHeaders[t])}for(var t in deviceHeadersTitles){Q(t).title=deviceHeadersTitles[t]}p1updateInfo();if(O==3){var P=[{x:180,y:101},{x:302,y:169},{x:454,y:255}][Q("sizeselect").selectedIndex];var H=P.x+2,N=M-5,R=Math.floor(N/H);R=H+Math.floor((N-(R*H))/R);P.y=P.y*(R/P.x);P.x=R;for(var t in multiDesktop){multiDesktop[t].xxdelete=true}for(var t in x){var v=x[t],I=v.split("/")[2],h=multiDesktop[v];if(h!=null){h.m.CanvasId.setAttribute("style","background-color:black;width:"+P.x+"px;height:"+P.y+"px");Q("xkvmid_"+I).appendChild(h.m.CanvasId);delete h.xxdelete;QH("skvmid_"+I,["Disconnected","Connecting...","Setup...","",""][((h.m.State==null)?h.m.state:h.m.State)])}else{var E=getNodeFromId(v);if((desktopNode==E)&&(desktop!=null)){var a=desktop.m.CanvasId;a.setAttribute("id","kvmid_"+I);a.setAttribute("style","background-color:black;width:"+P.x+"px;height:"+P.y+"px");a.setAttribute("onclick","toggleKvmDevice('"+v+"')");a.removeAttribute("onmousedown");a.removeAttribute("onmouseup");a.removeAttribute("onmousemove");Q("xkvmid_"+I).appendChild(a);QH("skvmid_"+I,["Disconnected","Connecting...","Setup...","",""][((desktop.m.State==null)?desktop.m.state:desktop.m.State)]);if(desktop.m.SendCompressionLevel){desktop.m.SendCompressionLevel(1,multidesktopsettings.quality,multidesktopsettings.scaling,multidesktopsettings.framerate)}desktop.shortid=I;desktop.onStateChanged=onMultiDesktopStateChange;multiDesktop[v]=desktop;desktop=desktopNode=currentNode=null;QH("DeskParent",'<canvas id="Desk" width="640" height="480" style="width:100%;-ms-touch-action:none;margin-left:0px" oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></canvas>')}else{var a=document.createElement("canvas");a.setAttribute("id","kvmid_"+I);a.setAttribute("width",640);a.setAttribute("height",480);a.setAttribute("oncontextmenu","return false");a.setAttribute("style","background-color:black;width:"+P.x+"px;height:"+P.y+"px");a.setAttribute("onclick","toggleKvmDevice('"+v+"')");try{Q("xkvmid_"+I).appendChild(a)}catch(n){}if(Q("autoConnectDesktopCheckbox").checked==true){setTimeout(function(){connectMultiDesktop(E,1)},100)}}}}for(var t in multiDesktop){if(multiDesktop[t].xxdelete==true){multiDesktop[t].Stop();delete multiDesktop[t]}else{if(debugmode&&multiDesktop[t].m&&multiDesktop[t].m.onScreenSizeChange){mdeskAdjust(multiDesktop[t].m,multiDesktop[t].m.ScreenWidth,multiDesktop[t].m.ScreenHeight,multiDesktop[t].m.CanvasId)}}}deskAdjust()}else{disconnectAllKvmFunction();Q("autoConnectDesktopCheckbox").checked=false}}oldviewmode=O}function toggleKvmDevice(d){var c=getNodeFromId(d),a=meshes[c.meshid],b=a.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;if((b&8)||(b&256)){if(c.conn&1){connectMultiDesktop(c,1)}}}function getUserShortStr(b){if(b==null||b.users==null||b.users.length==0){return""}if(b.users.length>1){return'<span title="'+EscapeHtml(b.users.join(", "))+'">'+b.users.length+"&nbsp;users</span>"}var d=b.users[0],c=d,a=d.indexOf("\\");if(a>0){c=d.substring(a+1)}c=EscapeHtml(c);if(c.length>15){c=c.substring(0,14)+"&#8230;"}return'<span title="'+EscapeHtml(d)+'">'+c+"</span>"}function autoConnectDesktops(){if(Q("autoConnectDesktopCheckbox").checked==true){connectAllKvmFunction()}}function connectAllKvmFunction(){for(var a in nodes){if(multiDesktop[nodes[a]._id]==null){toggleKvmDevice(nodes[a]._id)}}}function disconnectAllKvmFunction(){for(var a in multiDesktop){multiDesktop[a].Stop()}multiDesktop={}}function onMultiDesktopStateChange(a,c){try{QH("skvmid_"+a.shortid,["Disconnected","Connecting...","Setup...","",""][c])}catch(b){}}function showMultiDesktopSettings(){QV("d7amtkvm",false);QV("d7meshkvm",true);d7bitmapquality.value=multidesktopsettings.quality;d7bitmapscaling.value=multidesktopsettings.scaling;if(multidesktopsettings.framerate){d7framelimiter.value=multidesktopsettings.framerate}else{d7framelimiter.value=1000}setDialogMode(7,"Remote Desktop Settings",3,showMultiDesktopSettingsChanged)}function showMultiDesktopSettingsChanged(){multidesktopsettings.quality=d7bitmapquality.value;multidesktopsettings.scaling=d7bitmapscaling.value;multidesktopsettings.framerate=d7framelimiter.value;localStorage.setItem("multidesktopsettings",JSON.stringify(multidesktopsettings));for(var a in multiDesktop){multiDesktop[a].m.SendCompressionLevel(1,multidesktopsettings.quality,multidesktopsettings.scaling,multidesktopsettings.framerate)}}function connectMultiDesktop(c,a){var d=c._id,e=d.split("/")[2];var b=multiDesktop[d];if(b==null){if(Q("kvmid_"+e)==null){return}if(a==2){if((c.intelamt.user==null)||(c.intelamt.user=="")){return}b=CreateAmtRedirect(CreateAmtRemoteDesktop("kvmid_"+e),authCookie);b.shortid=e;b.onStateChanged=onMultiDesktopStateChange;b.m.bpp=1;b.m.useZRLE=true;b.m.showmouse=true;b.m.onKvmData=function(g){console.log("KVM Data received in multi-desktop mode, this is not supported.")};if(debugmode>0){b.m.onScreenSizeChange=mdeskAdjust}b.Start(d,16994,"*","*",0);b.contype=2;multiDesktop[d]=b}else{if(a==1){b=CreateAgentRedirect(meshserver,CreateAgentRemoteDesktop("kvmid_"+e),serverPublicNamePort,authCookie);b.shortid=e;b.attemptWebRTC=attemptWebRTC;b.onStateChanged=onMultiDesktopStateChange;b.m.CompressionLevel=multidesktopsettings.quality;b.m.ScalingLevel=multidesktopsettings.scaling;b.m.FrameRateTimer=multidesktopsettings.framerate;if(debugmode>0){b.m.onScreenSizeChange=mdeskAdjust}b.Start(d);b.contype=1;multiDesktop[d]=b}}}else{b.Stop();delete multiDesktop[d]}}function getMeshActions(a,b){if((b&4)==0){return""}var c="";if((features&1024)==0){c+=' <a style=cursor:pointer;font-size:10px title="Add a new Intel&reg; AMT computer that is located on the internet." onclick=addCiraDeviceToMesh("'+a._id+'")>Add CIRA</a>'}if(a.mtype==1){if((features&1)==0){c+=' <a style=cursor:pointer;font-size:10px title="Add a new Intel&reg; AMT computer that is located on the local network." onclick=addDeviceToMesh("'+a._id+'")>Add Local</a>';c+=' <a style=cursor:pointer;font-size:10px title="Add a new Intel&reg; AMT computer by scanning the local network." onclick=addAmtScanToMesh("'+a._id+'")>Scan Network</a>'}}if(a.mtype==2){c+=' <a style=cursor:pointer;font-size:10px title="Add a new computer to this mesh by installing the mesh agent." onclick=addAgentToMesh("'+a._id+'")>Add Agent</a>';if(features&64){c+=' <a style=cursor:pointer;font-size:10px title="Invite someone to install the mesh agent on this mesh." onclick=inviteAgentToMesh("'+a._id+'")>Invite</a>'}}return c}function addDeviceToMesh(b){if(xxdialogMode){return}var a=meshes[b];var c='Add a new Intel&reg; AMT device to device group "'+EscapeHtml(a.name)+'".<br /><br />';c+=addHtmlValue("Device Name","<input id=dp1devicename style=width:230px maxlength=32 autocomplete=off onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />");c+=addHtmlValue("Hostname",'<input id=dp1hostname style=width:230px maxlength=32 autocomplete=off placeholder="Same as device name" onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');c+=addHtmlValue("Username",'<input id=dp1username style=width:230px maxlength=32 autocomplete=off placeholder="admin" onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');c+=addHtmlValue("Password","<input id=dp1password type=password style=width:230px autocomplete=off maxlength=32 onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />");c+=addHtmlValue("Security","<select id=dp1tls style=width:236px><option value=0>No TLS security</option><option value=1>TLS security required</option></select>");setDialogMode(2,"Add Intel&reg; AMT device",3,addDeviceToMeshEx,c,b);validateDeviceToMesh();Q("dp1devicename").focus()}function addAmtScanToMesh(a){if(xxdialogMode){return}var b="Enter a range of IP addresses to scan for Intel AMT devices.<br /><br />";b+=addHtmlValue("IP Range",'<input id=dp1range style=width:184px value="192.168.1.0/24" onkeyup=addAmtScanToMeshKeyUp(event) /><input id=dp1rangebutton type=button value=Scan onclick=addAmtScanToMeshButton()></input>');b+='<div id=dp1results style="width:100%;height:200px;background-color:white;border:1px gray solid;overflow-y:scroll"></div>';setDialogMode(2,"Scan for Intel&reg; AMT devices",3,addAmtScanToMeshEx,b,a);QE("idx_dlgOkButton",false);QH("dp1results","<div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>Sample IP range values<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>");focusTextBox("dp1range")}function addAmtScanToMeshKeyUp(a){if(a.keyCode==13){haltEvent(a);addAmtScanToMeshButton()}}function addAmtScanToMeshEx(b,h){var d=document.getElementsByClassName("DevScanCheckbox"),c=0;for(var e=0;e<d.length;e++){if(d[e].checked){var g=d[e].getAttribute("tag");var a=amtScanResults[g];meshserver.send({action:"addamtdevice",meshid:h,devicename:g,hostname:a.hostname,amtusername:"",amtpassword:"",amttls:a.tls})}}}function addAmtScanToMeshButton(){QE("dp1range",false);QE("dp1rangebutton",false);QH("dp1results","<div style=width:100%;text-align:center;margin-top:12px>Scanning...</div>");meshserver.send({action:"scanamtdevice",range:Q("dp1range").value})}function addAmtScanToMeshCheckbox(){var b=document.getElementsByClassName("DevScanCheckbox"),a=0;for(var c=0;c<b.length;c++){if(b[c].checked){a++}}QE("idx_dlgOkButton",a>0)}function addCiraDeviceToMesh(b){if(xxdialogMode){return}var a=meshes[b];var c=b.split("/")[2].replace(/\@/g,"X").replace(/\$/g,"X");var e="<select id=dlgAddCiraSel onclick=dlgAddCiraSelClick() style=width:230px><option value=0>MeshCommander Script</option><option value=1>Manual Username/Password</option>";if((features&16)==0){e+="<option value=2>Manual Certificate</option></select>"}var d="";d+=addHtmlValue("Setup Method",e);d+="<hr>";d+='<div id=dlgAddCira0>To add a new Intel&reg; AMT device to device group "'+EscapeHtml(a.name)+"\" with CIRA, download the following script files and use <a href='http://meshcommander.com' rel='noreferrer noopener' target='_blank'>MeshCommander</a> to run the script to configure computers.<br /><br />";d+=addHtmlValue("Setup CIRA",'<a style=cursor:pointer onclick=fileDownload("mescript.ashx?type=1&meshid='+c.substring(0,16)+'","cira_setup.mescript")>cira_setup.mescript</a>');d+=addHtmlValue("Cleanup CIRA",'<a style=cursor:pointer onclick=fileDownload("mescript.ashx?type=2","cira_clean.mescript")>cira_clean.mescript</a>');d+="</div>";d+='<div id=dlgAddCira1 style=display:none>To add a new Intel&reg; AMT device to device group "'+EscapeHtml(a.name)+'" with CIRA, load the following certificate as trusted root within Intel AMT';if(serverinfo.mpspass){d+=" and authenticate to the server using this username and password.<br /><br />"}else{d+=" and authenticate to the server using this username and any password.<br /><br />"}d+=addHtmlValue("Root Certificate",'<a style=cursor:pointer onclick=fileDownload("MeshServerRootCert.cer","MeshServerRootCert.cer")>Root Certificate File</a>');d+=addHtmlValue("Username",'<input style=width:230px readonly value="'+c.substring(0,16)+'" />');if(serverinfo.mpspass){d+=addHtmlValue("Password",'<input style=width:230px readonly value="'+EscapeHtml(serverinfo.mpspass)+'" />')}if(serverinfo!=null){d+=addHtmlValue("MPS Server",'<input style=width:230px readonly value="'+EscapeHtml(serverinfo.mpsname)+":"+serverinfo.mpsport+'" />')}d+="</div>";if((features&16)==0){d+='<div id=dlgAddCira2 style=display:none>To add a new Intel&reg; AMT device to device group "'+EscapeHtml(a.name)+'" with CIRA, load the following certificate as trusted root within Intel AMT, authenticate using a client certificate with the following common name and connect to the following server.<br /><br />';d+=addHtmlValue("Root Certificate",'<a style=cursor:pointer onclick=fileDownload("MeshServerRootCert.cer","MeshServerRootCert.cer")>Root Certificate File</a>');d+=addHtmlValue("Organization",'<input style=width:230px readonly value="'+c+'" />');if(serverinfo!=null){d+=addHtmlValue("MPS Server",'<input style=width:230px readonly value="'+EscapeHtml(serverinfo.mpsname)+":"+serverinfo.mpsport+'" />')}d+="</div>"}setDialogMode(2,"Add Intel&reg; AMT CIRA device",2,null,d,"fileDownload")}function dlgAddCiraSelClick(){var a=Q("dlgAddCiraSel").value;QV("dlgAddCira0",a==0);QV("dlgAddCira1",a==1);QV("dlgAddCira2",a==2)}function checkEmail(c){var d=c.split("@");var b=((d.length==2)&&(d[0].length>0)&&(d[1].split(".").length>1)&&(d[1].length>2));if(b==true){var e=d[1].split(".");for(var a in e){if(e[a].length==0){b=false}}}return b}function inviteAgentToMesh(b){if(xxdialogMode){return}var a=meshes[b];var c="Invite someone to install the mesh agent. An email with be sent with the link to the mesh agent installation for "+EscapeHtml(a.name)+".<br /><br />";c+=addHtmlValue("Name (optional)",'<input id=agentInviteName value="" style=width:230px maxlength=64 />');c+=addHtmlValue("Email",'<input id=agentInviteEmail style=width:230px placeholder="example@email.com" onkeyup=validateAgentInvite()></input>');c+=addHtmlValue("Operating System","<select id=agentInviteNameOs style=width:236px><option value=0>Any supported</option><option value=1>Windows only</option><option value=3>Apple OSX only</option><option value=2>Linux only</option></select>");c+=addHtmlValue("Installation Type","<select id=agentInviteType style=width:236px><option value=0>Background and interactive</option><option value=2>Background only</option><option value=1>Interactive only</option></select>");c+=addHtmlValue("Message<br />(optional)",'<textarea id=agentInviteMessage value="" style=width:230px;height:100px;resize:none maxlength=1024 /></textarea>');setDialogMode(2,"Invite",3,performAgentInvite,c,b);validateAgentInvite()}function validateAgentInvite(){QE("idx_dlgOkButton",checkEmail(Q("agentInviteEmail").value))}function performAgentInvite(a,b){meshserver.send({action:"inviteAgent",meshid:b,email:Q("agentInviteEmail").value,name:Q("agentInviteName").value,os:Q("agentInviteNameOs").value,flags:Q("agentInviteType").value,msg:Q("agentInviteMessage").value})}function addAgentToMesh(d){if(xxdialogMode){return}var b=meshes[d],j="",a=0;j+=addHtmlValue("Operating System","<select id=aginsSelect onchange=addAgentToMeshClick() style=width:236px><option value=0>Windows</option><option value=1>Linux</option><option value=2>Apple OSX</option><option value=3>Windows (UnInstall)</option><option value=4>Linux (UnInstall)</option></select>");j+="<div id=aginsTypeDiv>";j+=addHtmlValue("Installation Type","<select id=aginsType onchange=addAgentToMeshClick() style=width:236px><option value=0>Background & interactive</option><option value=2>Background only</option><option value=1>Interactive only</option></select>");j+="</div><hr>";var c=b.name;c=c.split("\\").join("").split("/").join("").split(":").join("").split("*").join("").split("?").join("").split('"').join("").split("<").join("").split(">").join("").split("|").join("").split(" ").join("").split("'").join("");j+='<div id=agins_windows>To add a new computer to device group "'+EscapeHtml(b.name)+'", download the mesh agent and install it the computer to manage. This agent has server and mesh information embedded within it.<br /><br />';j+=addHtmlValue("Mesh Agent",'<a id=aginsw32lnk style=cursor:pointer onclick=fileDownload("meshagents?id=3&meshid='+d.split("/")[2]+'&installflags=","MeshAgent-'+c+'.exe",1) title="32bit version of the MeshAgent">Windows (.exe)</a>');j+=addHtmlValue("Mesh Agent",'<a id=aginsw64lnk style=cursor:pointer onclick=fileDownload("meshagents?id=4&meshid='+d.split("/")[2]+'&installflags=","MeshAgent-'+c+'.exe",1) title="64bit version of the MeshAgent">Windows x64 (.exe)</a>');if(debugmode>0){j+=addHtmlValue("Settings File",'<a id=aginswmshlnk href="meshsettings?id='+d.split("/")[2]+'&installflags=0" rel="noreferrer noopener" target="_blank">'+EscapeHtml(b.name)+" settings (.msh)</a>")}j+="</div>";j+="<div id=agins_linux style=display:none>To add a computer to "+EscapeHtml(b.name)+" run the following command. Root credentials will be needed.<br />";j+="<textarea id=agins_linux_area rows=2 cols=20 readonly=readonly style=width:100%;resize:none;height:120px;overflow:scroll;font-size:12px readonly></textarea>";j+="</div>";j+='<div id=agins_osx style=display:none>To add a new computer to device group "'+EscapeHtml(b.name)+'", download the mesh agent and install it the computer to manage. This agent installer has server and mesh information embedded within it.<br /><br />';j+=addHtmlValue("Mesh Agent",'<a href="meshosxagent?id=16&meshid='+d.split("/")[2]+'" rel="noreferrer noopener" target="_blank" title="64bit version of OSX Mesh Agent">OSX Agent (64bit)</a>');j+="</div>";j+='<div id=agins_windows_un style=display:none>To remove a mesh agent, download the file below, run it and click "uninstall".<br /><br />';j+=addHtmlValue("Mesh Agent",'<a style=cursor:pointer onclick=fileDownload("meshagents?id=3","MeshAgent.exe") title="32bit version of the MeshAgent">Windows (.exe)</a>');j+=addHtmlValue("Mesh Agent",'<a style=cursor:pointer onclick=fileDownload("meshagents?id=4","MeshAgent.exe") title="64bit version of the MeshAgent">Windows x64 (.exe)</a>');j+="</div>";j+="<div id=agins_linux_un style=display:none>To remove a mesh agent, run the following command. Root credentials will be needed.<br />";j+="<textarea id=agins_linux_area_un rows=2 cols=20 readonly=readonly style=width:100%;resize:none;height:120px;overflow:scroll;font-size:12px readonly></textarea>";j+="</div>";setDialogMode(2,"Add Mesh Agent",2,null,j,"fileDownload");var h=serverinfo.name;if((h.indexOf(".")==-1)||((features&2)!=0)){h=window.location.hostname}var e=((features&8192)!=0)?"--no-proxy ":"";if(serverinfo.https==true){var g=(serverinfo.port==443)?"":(":"+serverinfo.port);Q("agins_linux_area").value="wget https://"+h+g+"/meshagents?script=1 "+e+"--no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://"+h+g+" '"+d.split("/")[2]+"'\r\n";Q("agins_linux_area_un").value="wget https://"+h+g+"/meshagents?script=1 "+e+"--no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n"}else{var g=(serverinfo.port==80)?"":(":"+serverinfo.port);Q("agins_linux_area").value="wget http://"+h+g+"/meshagents?script=1 "+e+"-O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://"+h+g+" '"+d.split("/")[2]+"'\r\n";Q("agins_linux_area_un").value="wget http://"+h+g+"/meshagents?script=1 "+e+"-O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n"}Q("aginsSelect").focus();addAgentToMeshClick()}function fileDownload(g,d,a){var h=null,c="";if(a==1){c=Q("aginsType").value}else{if(a==2){c=Q("aginsSelect").value;if(parseInt(c)>=5){d=d.toLowerCase()}else{d+=".exe"}}}try{h=new XDomainRequest()}catch(b){}if(!h){h=new XMLHttpRequest()}h.open("GET",window.location.href+g+c);h.timeout=15000;h.responseType="blob";h.onprogress=function(e){};h.onload=function(j){saveAs(new Blob([j.target.response],{type:"application/octet-stream"}),d);if(xxdialogTag=="fileDownload"){setDialogMode(0)}};h.onerror=function(){if(xxdialogTag=="fileDownload"){setDialogMode(0)}alert("Agent downloads timeout.")};h.ontimeout=function(){if(xxdialogTag=="fileDownload"){setDialogMode(0)}alert("Unable to download agent.")};h.send()}function addAgentToMeshClick(){var a=Q("aginsSelect").value;QV("agins_windows",a==0);QV("agins_linux",a==1);QV("agins_osx",a==2);QV("agins_windows_un",a==3);QV("agins_linux_un",a==4);QV("aginsTypeDiv",a==0);if(debugmode>0){Q("aginswmshlnk").href=(Q("aginswmshlnk").href.split("installflags=")[0])+"installflags="+Q("aginsType").value}}function validateDeviceToMesh(){QE("idx_dlgOkButton",(Q("dp1devicename").value.length>0)&&(passwordcheck(Q("dp1password").value)))}function addDeviceToMeshEx(b,d){var a=Q("dp1username").value;if(a==""){a="admin"}var c=Q("dp1hostname").value;if(c==""){c=Q("dp1devicename").value}meshserver.send({action:"addamtdevice",meshid:d,devicename:Q("dp1devicename").value,hostname:c,amtusername:a,amtpassword:Q("dp1password").value,amttls:Q("dp1tls").value})}function deviceHeaderSet(){if(deviceHeaderId==0){deviceHeaderId=1;return}deviceHeaders["DevxHeader"+deviceHeaderId]=", "+deviceHeaderTotal+((deviceHeaderTotal==1)?" node":" nodes");deviceHeaderId++;deviceHeaderCount={};deviceHeaderTotal=0}var powerStateStrings=["",'<span title="Device is powered on.">Powered</span>','<span title="Device is in sleep state (S1).">Sleeping</span>','<span title="Device is in sleep state (S2).">Sleeping</span>','<span title="Device is in deep sleep state (S3).">Deep Sleep</span>','<span title="Device is in hibernating state (S4).">Hibernating</span>','<span title="Device is in powered off state (S5).">Soft-Off</span>','<span title="Device is detected but power state could not be obtained.">Present</span>'];var powerStateStrings2=["","Device is powered","Device is in sleep state (S1)","Device is in sleep state (S2)","Device is in deep sleep state (S3)","Device is hibernating (S4)","Device is in soft-off state (S5)","Device is present, but power state cannot be determined"];var powerColorTable=["#00000000","black","blue","blue","lightblue","blueviolet","darkgreen","lightseagreen","lightseagreen"];function NodeStateStr(a){var b=[];if(a.state>0&&a.state<powerStatetable.length){state.push(powerStatetable[a.state])}if(a.conn){if((a.conn&1)!=0){b.push('<span title="Mesh agent is connected and ready for use.">Agent</span>')}if((a.conn&2)!=0){b.push('<span title="Intel&reg; AMT CIRA is connected and ready for use.">CIRA</span>')}else{if((a.conn&4)!=0){b.push('<span title="Intel&reg; AMT is routable.">Intel&reg; AMT</span>')}}if((a.conn&8)!=0){b.push('<span title="Mesh agent is reachable using another agent as relay.">Relay</span>')}}if((a.pwr!=null)&&(a.pwr!=0)){b.push(powerStateStrings[a.pwr])}return b.join(", ")}function PowerStateStr(a){if(a<powerStatetable.length){return powerStatetable[a]}return""}function PowerStateStr2(a){if((a!=0)&&(a<powerStatetable.length)){return powerStatetable[a]}return"Unknown"}function selectallButtonFunction(){var b=document.getElementsByClassName("DeviceCheckbox"),a=0;for(var c=0;c<b.length;c++){if(b[c].checked===true){a++}}for(var c=0;c<b.length;c++){b[c].checked=(a==0)}p1updateInfo()}function p1updateInfo(){var b=document.getElementsByClassName("DeviceCheckbox"),a=0;for(var c=0;c<b.length;c++){if(b[c].checked===true){a++}}if(a>0){QE("GroupActionButton",true);Q("SelectAllButton").value="Select None";QV("cxmgroupsplit",true);QV("cxmdesktop",true)}else{QE("GroupActionButton",false);Q("SelectAllButton").value="Select All";QV("cxmgroupsplit",false);QV("cxmdesktop",false)}}function groupActionFunction(){var a="Select an operation to perform on all selected devices. Actions will be performed only with proper rights.<br /><br />";a+=addHtmlValue("Operation","<select id=d2groupop style=float:right;width:250px><option value=100>Wake-up devices</option><option value=4>Sleep devices</option><option value=3>Reset devices</option><option value=2>Power off devices</option><option value=102>Move to device group</option><option value=101>Delete devices</option></select>");setDialogMode(2,"Group Action",3,groupActionFunctionEx,a)}function getCheckedDevices(){var e=[],b=document.getElementsByClassName("DeviceCheckbox"),a=0;for(var c=0;c<b.length;c++){if(b[c].checked){if(b[c].value){var d=b[c].value.substring(6);if(e.indexOf(d)==-1){e.push(d)}}}}return e}function groupActionFunctionEx(){var a=Q("d2groupop").value;if(a==100){meshserver.send({action:"wakedevices",nodeids:getCheckedDevices()})}else{if(a==101){var b="Confirm delete selected devices(s)?<br /><br />";b+="<label><input id=d2check type=checkbox onchange=d2groupActionFunctionDelEx() />Confirm</label>";setDialogMode(2,"Delete Nodes",3,groupActionFunctionDelEx,b);QE("idx_dlgOkButton",false)}else{if(a==102){p10showChangeGroupDialog(getCheckedDevices())}else{meshserver.send({action:"poweraction",nodeids:getCheckedDevices(),actiontype:a})}}}}function d2groupActionFunctionDelEx(){QE("idx_dlgOkButton",Q("d2check").checked)}function groupActionFunctionDelEx(){meshserver.send({action:"removedevices",nodeids:getCheckedDevices()})}function onSortSelectChange(a){sort=document.getElementById("sortselect").selectedIndex;if(!a){putstore("sort",sort)}}function meshSort(c,d){if(c.meshnamel>d.meshnamel){return 1}if(c.meshnamel<d.meshnamel){return -1}if(c.meshid==d.meshid){if(showRealNames==true){if(c.rnamel>d.rnamel){return 1}if(c.rnamel<d.rnamel){return -1}return 0}else{if(c.namel>d.namel){return 1}if(c.namel<d.namel){return -1}return 0}}return 0}function powerSort(c,e){var d=c.pwr?c.pwr:0;var g=e.pwr?e.pwr:0;if(d>g){return -1}if(d<g){return 1}if(d==g){if(showRealNames==true){if(c.rnamel>e.rnamel){return 1}if(c.rnamel<e.rnamel){return -1}return 0}else{if(c.namel>e.namel){return 1}if(c.namel<e.namel){return -1}return 0}}return 0}function deviceSort(c,d){if(c.namel>d.namel){return 1}if(c.namel<d.namel){return -1}return 0}function deviceHostSort(c,d){if(c.rnamel>d.rnamel){return 1}if(c.rnamel<d.rnamel){return -1}return 0}function onSearchFocus(a){searchFocus=a}function onMapSearchFocus(a){mapSearchFocus=a}function onUserSearchFocus(a){userSearchFocus=a}function onConsoleFocus(a){consoleFocus=a}function onSearchInputChanged(){var m=Q("SearchInput").value.toLowerCase().trim();putstore("search",m);var l=null,g=null,c=null;if(m.startsWith("user:")){l=m.substring(5)}else{if(m.startsWith("u:")){l=m.substring(2)}else{if(m.startsWith("ip:")){g=m.substring(3)}else{if(m.startsWith("group:")){c=m.substring(6)}else{if(m.startsWith("g:")){c=m.substring(2)}}}}}if(m==""){for(var a in nodes){nodes[a].v=true}}else{if(g!=null){for(var a in nodes){nodes[a].v=((nodes[a].ip!=null)&&(nodes[a].ip.indexOf(g)>=0))}}else{if(c!=null){for(var a in nodes){nodes[a].v=(meshes[nodes[a].meshid].name.toLowerCase().indexOf(c)>=0)}}else{if(l!=null){for(var a in nodes){nodes[a].v=false;if(nodes[a].users&&nodes[a].users.length>0){for(var e in nodes[a].users){if(nodes[a].users[e].toLowerCase().indexOf(l)>=0){nodes[a].v=true}}}}}else{try{var h=m.split(/\s+/).join("|"),j=new RegExp(h);for(var a in nodes){nodes[a].v=(j.test(nodes[a].name.toLowerCase()))||(nodes[a].rnamel!=null&&j.test(nodes[a].rnamel.toLowerCase()));if((nodes[a].v==false)&&nodes[a].tags){for(var k in nodes[a].tags){if(j.test(nodes[a].tags[k].toLowerCase())){nodes[a].v=true;break}else{nodes[a].v=false}}}}}catch(b){for(var a in nodes){nodes[a].v=true}}}}}}}var contextelement=null;function handleContextMenu(d){hideContextMenu();var m=(window.pageXOffset!==null)?window.pageXOffset:(document.documentElement||document.body.parentNode||document.body).scrollLeft;var n=(window.pageYOffset!==null)?window.pageYOffset:(document.documentElement||document.body.parentNode||document.body).scrollTop;var c=document.elementFromPoint(d.pageX-m,d.pageY-n);if(c&&c!=null&&c.id=="MxMESH"){contextelement=c;var b=document.getElementById("meshContextMenu");b.style.left=d.pageX+"px";b.style.top=d.pageY+"px";b.style.display="block"}else{while(c&&c!=null&&c.id!="devs"){c=c.parentElement}if(!c||c==null){return true}contextelement=c;var b=document.getElementById("contextMenu");b.style.left=d.pageX+"px";b.style.top=d.pageY+"px";b.style.display="block"}var l=contextelement.children[1].attributes.onclick.value;var k=getNodeFromId(l.substring(12,l.length-18));var g=meshes[k.meshid];var h=g.links["user/"+domain+"/"+userinfo.name.toLowerCase()];var j=h.rights;var a=((j&16)!=0);var o=((j==4294967295)||((j&512)==0));var e=((j==4294967295)||((j&1024)==0));QV("cxdesktop",((g.mtype==1)||(k.agent==null)||(k.agent.caps==null)||((k.agent.caps&1)!=0)||(k.intelamt&&(k.intelamt.state==2)))&&((j&8)||(j&256)));QV("cxterminal",((g.mtype==1)||(k.agent==null)||(k.agent.caps==null)||((k.agent.caps&2)!=0)||(k.intelamt&&(k.intelamt.state==2)))&&(j&8)&&o);QV("cxfiles",((g.mtype==2)&&((k.agent==null)||(k.agent.caps==null)||((k.agent.caps&4)!=0)))&&(j&8)&&e);QV("cxevents",(k.intelamt!=null)&&((k.intelamt.state==2)||(k.conn&2))&&(j&8));QV("cxconsole",(a&&(g.mtype==2)&&((k.agent==null)||(k.agent.caps==null)||((k.agent.caps&8)!=0)))&&(j&8));return haltEvent(d)}function cmaction(a,b){var c=contextelement.children[1].attributes.onclick.value;c=c.substring(12,c.length-18);if(a==7){Q("viewselect").value=3;Q("viewselect").onchange();Q("autoConnectDesktopCheckbox").checked=true;Q("autoConnectDesktopCheckbox").onclick()}if((a>0)&&(a<7)){var d=[0,10,12,11,13,16,15][a];if(b&&(b.shiftKey==true)){window.open(window.location.origin+"?node="+c.split("/")[2]+"&viewmode="+d+"&hide=16","meshcentral:"+c)}else{gotoDevice(c,d)}}}function cmmeshaction(a){var d=contextelement.attributes.onclick.value.substring(32,(32+69));var b=document.getElementsByClassName("DeviceCheckbox");if(a==1){for(var c=0;c<b.length;c++){if((b[c].attributes)&&(b[c].attributes["class"]["value"].substring(0,69)==d)){b[c].checked=true}}}if(a==2){for(var c=0;c<b.length;c++){if((b[c].attributes)&&(b[c].attributes["class"]["value"].substring(0,69)==d)){b[c].checked=false}}}p1updateInfo()}function hideContextMenu(){QV("contextMenu",false);QV("meshContextMenu",false);contextelement=null}var xxmap={map:null,contextmenu:null,activeInteractions:[],showindex:0,markersSource:null,markersLayer:null,mapLayer:null,mapView:null,};function updateMapMarkers(j){if((xxmap!=null)&&(xxmap.map==null)){try{loadmap()}catch(b){console.error("loadmap() exception",b)}}if(xxmap==null){return}var a=null;for(var d in nodes){try{var g=map_parseNodeLoc(nodes[d]),c=xxmap.markersSource.getFeatureById(nodes[d]._id);if((g!=null)&&((nodes[d].meshid==j)||(j==null))){var e=g[0],h=g[1],k=g[2];if(a==null){a=[e,h,e,h,0]}else{if(e<a[0]){a[0]=e}if(h<a[1]){a[1]=h}if(e>a[2]){a[2]=e}if(h>a[3]){a[3]=h}}if(c==null){addFeature(nodes[d]);a[4]=1}else{updateFeature(nodes[d],c);c.setStyle(markerStyle(nodes[d],g[2]))}}else{if(c){xxmap.markersSource.removeFeature(c)}}}catch(b){console.error("updateMapMarkers() exception",b,JSON.stringify(nodes[d]))}}return a}var map_cm_popup=new ol.Overlay({element:Q("xmap-info-window"),positioning:"bottom-center",stopEvent:false});var map_cm_editMarker={text:"Modify node location",callback:function(a){modifyMarkerloc(a.data)}};var map_cm_clearMarker={text:"Remove node location",callback:function(a){meshserver.send({action:"changedevice",nodeid:a.data.a,userloc:[]})}};var map_cm_saveMarker={text:"Save node location",callback:function(a){saveMarkerloc(a.data)}};var map_cm_nodemenu_items=[{text:"General information",callback:function(a){if(a.data!=null){gotoDevice(a.data,10)}}},{text:"Desktop",callback:function(a){if(a.data!=null){gotoDevice(a.data,11)}}},{text:"Terminal",callback:function(a){if(a.data!=null){gotoDevice(a.data,12)}}},{text:"Intel&reg; AMT",callback:function(a){if(a.data!=null){gotoDevice(a.data,14)}}},"-",{text:"Zoom-in to extent",callback:function(b){var a=b.data.getGeometry().getCoordinates();zoomToLocation(a,19)}},{text:"Zoom-out to extent",callback:function(b){var a=b.data.getGeometry().getCoordinates();zoomToLocation(a,2)}}];var contextmenu_items=[{text:"Refresh",callback:function(){refreshMap(true,true)}},{text:"Zoom to fit extent",callback:function(){zoomToFitExtent()}},{text:"Center map here",callback:function(a){xxmap.mapView.animate({center:a.coordinate})}},{text:"Place node here",callback:function(a){placeNode(a.coordinate)}}];function stringToIntHash(c){var a=0,b;for(b=0;b<c.length;b++){a=((a<<5)-a)+c.charCodeAt(b);a|=0}return a}function map_parseNodeLoc(b){var a=null,c=0;if(b.iploc){a=b.iploc;c=1}if(b.wifiloc){a=b.wifiloc;c=2}if(b.gpsloc){a=b.gpsloc;c=3}if(b.userloc){a=b.userloc;c=4}if((a==null)||(typeof a!="string")){return null}a=a.split(",");if(c==1){return[parseFloat(a[0])+(stringToIntHash(b._id.substring(0,20))/100000000000),parseFloat(a[1])+(stringToIntHash(b._id.substring(20))/100000000000),c]}else{return[parseFloat(a[0]),parseFloat(a[1]),c]}}function loadmap(){if(xxmap==null){return}if((features&32768)==0){QV("viewselectmapoption",false);QV("devViewButton4",false);xxmap=null;return}try{xxmap.markersSource=new ol.source.Vector();xxmap.markersLayer=new ol.layer.Vector({source:xxmap.markersSource});xxmap.mapLayer=new ol.layer.Tile({source:new ol.source.OSM()});xxmap.mapView=new ol.View({center:ol.proj.transform([0,0],"EPSG:4326","EPSG:3857"),zoom:2,minZoom:2,maxZoom:20,extent:ol.proj.transformExtent([-100000,-69.55,100000,69.55],"EPSG:4326","EPSG:3857")});xxmap.map=new ol.Map({target:"xdevicesmap",layers:[xxmap.mapLayer,xxmap.markersLayer],view:xxmap.mapView});xxmap.map.addOverlay(map_cm_popup);xxmap.map.on("click",function(c){var d=xxmap.map.forEachFeatureAtPixel(c.pixel,function(h,j){return h});if(d){var g=d.getId();if(g!=null){gotoDevice(g,10)}else{var e=getCorrespondingFeature(d);gotoDevice(e.getId(),10)}}});xxmap.map.on("pointermove",function(d){var g=xxmap.map.forEachFeatureAtPixel(d.pixel,function(j,k){return j});if(g){xxmap.map.getTargetElement().style.cursor="pointer";var c=g.getGeometry().getCoordinates();map_cm_popup.setPosition(c);var e=g.getId();if(e){QH("xmap-info-window",g.get("name"))}else{var h=getCorrespondingFeature(g);QH("xmap-info-window",h.get("name"))}}else{xxmap.map.getTargetElement().style.cursor="";QH("xmap-info-window","")}});var a=new ContextMenu({width:160,defaultItems:false,items:contextmenu_items});a.on("open",function(c){var e=xxmap.map.forEachFeatureAtPixel(c.pixel,function(h,j){return h});xxmap.contextmenu.clear();if(e){var d=e.getId();if(d){addContextMenuItems(e)}else{var g=getCorrespondingFeature(e);if(g){addContextMenuItems(g)}else{xxmap.contextmenu.extend(contextmenu_items)}}}else{xxmap.contextmenu.extend(contextmenu_items)}});if(xxmap.contextmenu==null){xxmap.contextmenu=a}xxmap.map.addControl(xxmap.contextmenu)}catch(b){console.log(b);QV("viewselectmapoption",false);QV("devViewButton4",false);xxmap=null}}function addFeature(g,c,e){var a=getModifiedFeature(g._id);if(a){xxmap.markersSource.addFeature(a)}else{if(!c&&!e){var d=map_parseNodeLoc(g);c=d[0];e=d[1]}if(e>180){e=180-e;meshserver.send({action:"changedevice",nodeid:g._id,userloc:[c,e]})}if((c<90)&&(c>-90)&&(e<180)&&(e>-180)){var b=new ol.Feature({geometry:new ol.geom.Point(ol.proj.transform([e,c],"EPSG:4326","EPSG:3857")),name:g.name,status:g.conn,lat:c,lon:e});b.setId(g._id);b.setStyle(markerStyle(g));xxmap.markersSource.addFeature(b)}}}function removeFeature(b){var a=xxmap.markersSource.getFeatureById(b._id);if(a){xxmap.markersSource.removeFeature(a)}}function updateFeature(g,a){if(g.conn!=a.get("status")){a.set("status",g.conn);a.setStyle(markerStyle(g))}var c=map_parseNodeLoc(g);if(c!=null){var b=c[0],d=c[1];if((b!=a.get("lat"))||(d!=a.get("lon"))){a.set("lat",b);a.set("lon",d);var e=ol.proj.transform([parseFloat(d),parseFloat(b)],"EPSG:4326","EPSG:3857");a.getGeometry().setCoordinates(e)}}if(g.name!=a.get("name")){a.set("name",g.name)}}function modifyMarkerloc(c){var b=c.getId();if(b){c.setStyle(markerStyle(getNodeFromId(c.a),4));if(!getActiveInteractions(c)){var a=new ol.interaction.Modify({features:new ol.Collection([c]),pixelTolerance:10});xxmap.activeInteractions.push({featureid:b,feature:c,interaction:a});xxmap.map.addInteraction(a)}}}function saveMarkerloc(d){var c=d.getId();if(c){var a=getActiveInteractions(d);if(a){xxmap.map.removeInteraction(a);removeInteraction(c);var b=d.getGeometry().getCoordinates();var e=ol.proj.transform(b,"EPSG:3857","EPSG:4326");if(e[0]>180){e[0]=180-e[0]}var g=[e[1],e[0]];meshserver.send({action:"changedevice",nodeid:c,userloc:g})}}}function markerStyle(b,d){if(d==null){d=0;if(b.iploc){d=1}if(b.wifiloc){d=2}if(b.gpsloc){d=3}if(b.userloc){d=4}}var e=["","-ip","-wifi","-gps","-user"];var a=connStateColor(b);var c=new ol.style.Style({image:new ol.style.Icon({color:a,anchor:[0.5,1],src:"images/mapmarker"+e[d]+".png"})});return[c]}function connStateColor(a){if(a.conn==1||a.conn==3||a.conn==5){return"#00ffdd"}return"#C70039"}function addContextMenuItems(a){if(getActiveInteractions(a)){map_cm_saveMarker.data=a;xxmap.contextmenu.push(map_cm_saveMarker)}else{map_cm_editMarker.data=a;xxmap.contextmenu.push(map_cm_editMarker);var b=getNodeFromId(a.a);if(b.userloc){map_cm_clearMarker.data=a;xxmap.contextmenu.push(map_cm_clearMarker)}}map_cm_nodemenu_items.forEach(function(c){if(c.text=="Zoom-in to extent"||c.text=="Zoom-out to extent"){c.data=a}else{if(c!="-"){c.data=a.getId()}}});xxmap.contextmenu.extend(map_cm_nodemenu_items)}function getActiveInteractions(b){var a=b.getId();for(var c=0;c<xxmap.activeInteractions.length;c++){if(xxmap.activeInteractions[c].featureid==a){return xxmap.activeInteractions[c].interaction}}return false}function getModifiedFeature(a){if(a){for(var b=0;b<xxmap.activeInteractions.length;b++){if(xxmap.activeInteractions[b].featureid==a){return xxmap.activeInteractions[b].feature}}}return null}function removeInteraction(a){var c=-1;for(var b=0;b<xxmap.activeInteractions.length;b++){if(xxmap.activeInteractions[b].featureid===a){c=b;break}}if(c>=0){xxmap.activeInteractions.splice(c,1)}}function getCorrespondingFeature(e){var d=e.getGeometry().getCoordinates();for(var b=0;b<xxmap.activeInteractions.length;b++){var c=xxmap.activeInteractions[b].feature;var a=c.getGeometry().getCoordinates();if(a[0].toFixed(5)==d[0].toFixed(5)&&a[1].toFixed(5)==d[1].toFixed(5)){return c}}return null}function refreshMap(k,h){if(k){xxmap.map.setTarget(null);xxmap.map=null;xxmap.markersSource=null;xxmap.mapView=null;xxmap.mapLayer=null;xxmap.activeInteractions=[]}var a=updateMapMarkers();if((a!=null)&&(h||(a[4]==1))){var b=(a[0]+a[2])/2;var c=(a[1]+a[3])/2;var d=Math.max(Math.abs(a[0]-a[2]),Math.abs(a[1]-a[3]));var l=xxmap.map.getView();l.setCenter(ol.proj.transform([c,b],"EPSG:4326","EPSG:3857"));var e=360,g=-2;while(e>d){g++;e=e/2}l.setZoom(g)}}function placeNode(a){if(xxdialogMode){return}var c='<div style=margin-bottom:6px><label for=selectnode-search>Search</label>&nbsp&nbsp<input type=text placeholder="Device name" id="selectnode-search" onchange=onPlaceNodeInputChange() onkeyup=onPlaceNodeInputChange() autocomplete=off style=width:120px></div><div id=placenode style="height:254px;overflow-y:auto;width:100%;margin:12px 1px 4px 1px;"><div id=noNodesMapPlace style=text-align:center;width:100%;display:none>No devices found.</div>';for(var b in nodes){c+="<div class=noselect id="+nodes[b]._id+"-rowid onclick=selectNodeToPlace(event,'"+nodes[b]._id+"') style=background-color:lightgray;margin-bottom:4px;border-radius:2px><input name=PlaceMapDeviceCheckbox id="+nodes[b]._id+"-checkid type=checkbox style=width:16px;display:inline />";c+="<div class=j"+nodes[b].icon+" style=width:16px;height:16px;margin-top:2px;margin-right:4px;display:inline-block></div><div style=width:16px;display:inline>"+nodes[b].name+"</div></div>"}setDialogMode(2,"Select a node to place",3,placeNodeEx,c+"</div>",a);onPlaceNodeInputChange()}function placeNodeEx(b,c){var d=document.getElementsByName("PlaceMapDeviceCheckbox");for(var g in d){if(d[g].checked){var h=getNodeFromId(d[g].id.substring(0,d[g].id.length-8));if(h){var e=xxmap.markersSource.getFeatureById(g);var j=ol.proj.transform(c,"EPSG:3857","EPSG:4326");var k=[j[1],j[0]];if(e){e.getGeometry().setCoordinates(c);var a=getActiveInteractions(e);if(a){saveMarkerloc(e)}else{meshserver.send({action:"changedevice",nodeid:h._id,userloc:k})}}else{meshserver.send({action:"changedevice",nodeid:h._id,userloc:k})}}}}}function onPlaceNodeInputChange(){updatePlaceNodeTable(Q("selectnode-search").value.trim().toLowerCase())}function updatePlaceNodeTable(d){var b=document.getElementsByName("PlaceMapDeviceCheckbox"),a=0;for(var c in nodes){var e=((nodes[c].namel.indexOf(d)>=0||d=="")||(nodes[c].rnamel!=null&&nodes[c].rnamel.indexOf(d)>=0));if(e){a++}QV(nodes[c]._id+"-rowid",e)}QV("noNodesMapPlace",a==0)}function selectNodeToPlace(b,g){if(b.target.name!="PlaceMapDeviceCheckbox"){var h=Q(g+"-checkid");h.checked=!h.checked}var c=document.getElementsByName("PlaceMapDeviceCheckbox"),a=0;for(var d in c){if(c[d].checked){a++}}QE("idx_dlgOkButton",a>0)}function addMeshOptions(a,b){}function meshOptionRmvMod(a,b){}function meshExists(){for(var a in meshes){if(meshes[a]){return true}}return false}function setMeshView(a){var c=Q("select-mesh");var b=c.selectedIndex;if(c[b].value==a){c[0].selected=true;onSelectMeshChange()}}function clearMeshOptions(){}function getSearchLocation(){try{var b=Q("mapSearchLocation").value.trim();if(b.length>0){var c=new XMLHttpRequest();c.onreadystatechange=function(){if(c.readyState==4&&c.status==200){formatSearchData(c.responseText)}};c.open("GET","https://nominatim.openstreetmap.org/search?q="+b+"&format=json",true);c.send()}}catch(a){}}function formatSearchData(c){try{QH("xmapSearchResults","");var d=JSON.parse(c),b=0,k='<div style="overflow-y:auto;width:100%;max-height:240px">';for(var j=0;j<d.length;j++){if(d[j].display_name&&d[j].boundingbox[0]&&d[j].boundingbox[1]&&d[j].boundingbox[2]&&d[j].boundingbox[3]){b++;var a=(j%2==0)?"F5F5F5":"EBEBEB";k+="<div style=cursor:pointer;padding:5px;background-color:#"+a+" onclick=mapGotoSelectedLocation(this)><div>"+d[j].display_name+"</div><div style=display:none>"+d[j].boundingbox[0]+"!#!"+d[j].boundingbox[1]+"!#!"+d[j].boundingbox[2]+"!#!"+d[j].boundingbox[3]+"</div></div>"}}k+="</div>";if(b==1){var h=[parseFloat(d[0].boundingbox[2]),parseFloat(d[0].boundingbox[0]),parseFloat(d[0].boundingbox[3]),parseFloat(d[0].boundingbox[1])];zoomToExtent(h)}else{if(b==0){k="<div style=width:200px>No location found.<div>"}QV("xmapSearchResultsDlg",true)}QH("xmapSearchResults",k)}catch(g){}}function mapGotoSelectedLocation(c){var d=c.children;var a=d[1].innerHTML.split("!#!");var b=[parseFloat(a[2]),parseFloat(a[0]),parseFloat(a[3]),parseFloat(a[1])];zoomToExtent(b);mapCloseSearchWindow()}function mapCloseSearchWindow(){QH("xmapSearchResults","");QV("xmapSearchResultsDlg",false)}function zoomToLocation(a,c){var b=xxmap.map.getView();b.setCenter(a);b.setZoom(c)}function zoomToFitExtent(){var b=xxmap.markersSource.getFeatures();if(b.length>0){var a=xxmap.markersSource.getExtent();xxmap.map.getView().fit(a,xxmap.map.getSize())}}function zoomToExtent(b){var a=ol.proj.transformExtent(b,ol.proj.get("EPSG:4326"),ol.proj.get("EPSG:3857"));xxmap.map.getView().fit(a,xxmap.map.getSize())}function refreshDevice(a){if(!currentNode||currentNode._id!=a){return}gotoDevice(a,xxcurrentView,true)}function getNodeRights(c){var b=getNodeFromId(c),a=meshes[b.meshid];return a.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights}var currentNode;var powerTimelineNode=null;var powerTimelineReq=null;var powerTimelineUpdate=null;var powerTimeline=null;function getCurrentNode(){return currentNode}function gotoDevice(r,t,w,j){if((userinfo.emailVerified!==true)&&(serverinfo.emailcheck==true)&&(userinfo.siteadmin!=4294967295)){setDialogMode(2,"New Device Group",1,null,'Unable to create a new device group until a email address is verified. This is required for password recovery. Go to the "My Account" tab to change and verify an email address.');return}if(j&&(j.shiftKey==true)){window.open(window.location.origin+"?node="+r.split("/")[2]+"&viewmode=10&hide=16","meshcentral:"+r);return}var q=getNodeFromId(r);var n=meshes[q.meshid];var o=n.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;if(!currentNode||currentNode._id!=q._id||w==true){currentNode=q;var p=EscapeHtml(q.name);if(p.length==0){p="<i>None</i>"}if((o&4)!=0){p='<span title="Click here to edit the server-side device name" onclick=showEditNodeValueDialog(0) style=cursor:pointer>'+p+' <img class=hoverButton width=10 height=10 src="images/link5.png" /></span>'}QH("p10deviceName",p);QH("p11deviceName",p);QH("p12deviceName",p);QH("p13deviceName",p);QH("p14deviceName",p);QH("p15deviceName","Console - "+p);QH("p16deviceName",p);var B="<table style=width:100%>";B+=addDeviceAttribute('<span title="The name of the device group this computer belong to.">Group</span>','<a title="The name of the device group this computer belong to" onclick=gotoMesh("'+q.meshid+'") style=cursor:pointer>'+EscapeHtml(meshes[q.meshid].name)+"</a>");if((q.rname!=null)&&(q.name!=q.rname)){B+=addDeviceAttribute('<span title="The name of this computer as set in the operating system">Name</span>','<span title="The name of this computer as set in the operating system">'+EscapeHtml(q.rname)+"</span>")}if((features&1)==0){if((o&4)!=0){if(q.host){B+=addDeviceAttribute("Hostname","<span onclick=showEditNodeValueDialog(1) style=cursor:pointer>"+EscapeHtml(q.host)+"</span>")}else{B+=addDeviceAttribute("Hostname","<span onclick=showEditNodeValueDialog(1) style=cursor:pointer><i>None</i></span>")}}else{B+=addDeviceAttribute("Hostname",EscapeHtml(q.host))}}var h=q.desc?EscapeHtml(q.desc):"<i>None</i>";if((o&4)!=0){B+=addDeviceAttribute("Description","<span onclick=showEditNodeValueDialog(2) style=cursor:pointer>"+h+' <img class=hoverButton width=10 height=10 src="images/link5.png" /></span>')}else{B+=addDeviceAttribute("Description",h)}var a=["Unknown","Windows 32bit console","Windows 64bit console","Windows 32bit service","Windows 64bit service","Linux 32bit","Linux 64bit","MIPS","XENx86","Android ARM","Linux ARM","OSX 32bit","Android x86","PogoPlug ARM","Android APK","Linux Poky x86-32bit","OSX 64bit","ChromeOS","Linux Poky x86-64bit","Linux NoKVM x86-32bit","Linux NoKVM x86-64bit","Windows MinCore console","Windows MinCore service","NodeJS","ARM-Linaro","ARMv6l / ARMv7l"];if((q.agent!=null)&&(q.agent.id!=null)&&(q.agent.ver!=null)){var y="";if(q.agent.id<=a.length){y=a[q.agent.id]}else{y=a[0]}if(q.agent.ver!=0){y+=" v"+q.agent.ver}B+=addDeviceAttribute("Mesh Agent",y)}if(q.intelamt!=null){var y="";var v={0:"Not Activated (Pre)",1:"Not Activated (In)",2:"Activated"};if(q.intelamt.ver!=null&&q.intelamt.state==null){y+="<i>Unknown State</i>, v"+q.intelamt.ver}else{if((q.intelamt.ver==null)&&(q.intelamt.state==2)){y+="<i>Activated</i>"}else{if((q.intelamt.ver==null)||(q.intelamt.state==null)){y+="<i>Unknown Version & State</i>"}else{y+=v[q.intelamt.state];if((q.intelamt.state==2)&&q.intelamt.flags){if(q.intelamt.flags&2){y+=' <span title="Intel AMT is activated in Client Control Mode">CCM</span>'}else{if(q.intelamt.flags&4){y+=' <span title="Intel AMT is activated in Admin Control Mode">ACM</span>'}}}y+=(", v"+q.intelamt.ver)}}}if(q.intelamt.tls==1){y+=', <span title="Intel AMT is setup with TLS network security">TLS</span>'}if(q.intelamt.state==2){if(q.intelamt.user==null||q.intelamt.user==""){if((o&4)!=0){y+=', <i style=color:#FF0000;cursor:pointer title="Edit Intel&reg; AMT credentials" onclick=editDeviceAmtSettings("'+q._id+'")>No Credentials</i>'}else{y+=", <i style=color:#FF0000>No Credentials</i>"}}y+=" ";if((o&4)!=0){y+='<img src=images/link4.png height=10 width=10 title="Edit Intel&reg; AMT credentials" style=cursor:pointer onclick=editDeviceAmtSettings("'+q._id+'")>'}}B+=addDeviceAttribute("Intel&reg; AMT",y)}if((q.agent!=null)&&(q.agent.tag!=null)&&(q.agent.tag!="mailto:")){var z=EscapeHtml(q.agent.tag);if(z.startsWith("mailto:")){z='<a href="'+z+'">'+z.substring(7)+"</a>"}B+=addDeviceAttribute("Agent Tag",z)}if(q.osdesc){B+=addDeviceAttribute("Operating System",q.osdesc)}if(q.users&&q.conn&&(q.users.length>0)&&(q.conn&1)){B+=addDeviceAttribute("Active User"+((q.users.length>1)?"s":""),q.users.join(", "))}var d=q.conn;if(d&&d>1){var g=[];if((q.conn&1)!=0){g.push('<span title="Mesh agent is connected and ready for use.">Mesh Agent</span>')}if((q.conn&2)!=0){g.push('<span title="Intel&reg; AMT CIRA is connected and ready for use.">Intel&reg; AMT CIRA</span>')}else{if((q.conn&4)!=0){g.push('<span title="Intel&reg; AMT is routable and ready for use.">Intel&reg; AMT</span>')}}if((q.conn&8)!=0){g.push('<span title="Mesh agent is reachable using another agent as relay.">Mesh Relay</span>')}B+=addDeviceAttribute("Connectivity",g.join(", "))}var l="<i>None</i>";if(q.tags!=null){l="";for(var m in q.tags){l+='<span style="background-color:lightgray;padding:3px;margin-right:4px;border-radius:5px">'+q.tags[m]+"</span>"}}B+=addDeviceAttribute("Tags","<span onclick=showEditNodeValueDialog(3) style=cursor:pointer>"+l+' <img class=hoverButton width=10 height=10 src="images/link5.png" /></span>');B+="</table><br />";if((o&76)!=0){B+='<input type=button value=Actions title="Perform power actions on the device" onclick=deviceActionFunction() />'}B+='<input type=button value=Notes title="View notes about this device" onclick=showNotes('+((o&128)==0)+',"'+encodeURIComponent(q._id)+'") />';QH("p10html",B);masterUpdate(256);B="<div style=float:right;font-size:x-small>";if((o&4)!=0){B+='&nbsp;<a style=cursor:pointer onclick=p10showChangeGroupDialog(["'+q._id+'"]) title="Move this device to a different device group">Change Group</a>';B+='&nbsp;<a style=cursor:pointer onclick=p10showDeleteNodeDialog("'+q._id+'") title="Remove this device">Delete Device</a>'}B+="</div><div style=font-size:x-small>";if(n.mtype==2){B+='<a style=cursor:pointer onclick=p10showNodeNetInfoDialog("'+q._id+'") title="Show device network interface information">Interfaces</a>&nbsp;'}if(xxmap!=null){B+='<a style=cursor:pointer onclick=p10showNodeLocationDialog("'+q._id+'") title="Show device locations information">Location</a>&nbsp;'}if(((o&8)!=0)&&(n.mtype==2)){B+='<a style=cursor:pointer onclick=p10showMeshCmdDialog(1,"'+q._id+'") title="Traffic router used to connect to a device thru this server.">Router</a>&nbsp;'}if(((d&1)!=0)&&(clickOnce==true)&&(n.mtype==2)&&((o&8)!=0)){if((q.agent.id>0)&&(q.agent.id<5)){B+='<a style=cursor:pointer onclick=p10clickOnce("'+q._id+'","RDP2",3389) title="Requires Microsoft ClickOnce support in your browser.">RDP</a>&nbsp;'}if(q.agent.id>4){B+='<a style=cursor:pointer onclick=p10clickOnce("'+q._id+'","PSSH",22) title="Requires Microsoft ClickOnce support in your browser.">Putty</a>&nbsp;';B+='<a style=cursor:pointer onclick=p10clickOnce("'+q._id+'","WSCP",22) title="Requires Microsoft ClickOnce support in your browser.">WinSCP</a>&nbsp;'}}B+="</div><br>";QH("p10html3",B);var u=PowerStateStr(q.state);if((d&1)!=0){if(u.length>0){u+="<br/>"}u+='<span style=font-size:12px title="Agent connected">Agent connected</span>'}if((d&2)!=0){if(u.length>0){u+="<br/>"}u+='<span style=font-size:12px title="Intel&reg; AMT connected">Intel&reg; AMT connected</span>'}else{if((d&4)!=0){if(u.length>0){u+="<br/>"}u+='<span style=font-size:12px title="Intel&reg; AMT detected">Intel&reg; AMT detected</span>'}}if((u=="")&&q.lastconnect){u="<span style=font-size:12px>Last seen:<br />"+new Date(q.lastconnect).toLocaleDateString()+", "+new Date(q.lastconnect).toLocaleTimeString()+"</span>"}QH("MainComputerState",u);Q("MainComputerImage").setAttribute("src","images/icons200-"+q.icon+"-1.jpg");Q("MainComputerImage").className=((!q.conn)||(q.conn==0)?"gray":"");var A=((o==4294967295)||((o&512)==0));var k=((o==4294967295)||((o&1024)==0));var b=((o==4294967295)||((o&2048)==0));if(A){setupTerminal()}if(k){setupFiles()}var e=((o&16)!=0);if(e){setupConsole()}else{if(t==15){t=10}}QV("MainDevDesktop",((n.mtype==1)||(q.agent==null)||(q.agent.caps==null)||((q.agent.caps&1)!=0)||(q.intelamt&&(q.intelamt.state==2)))&&((o&8)||(o&256)));QV("MainDevTerminal",((n.mtype==1)||(q.agent==null)||(q.agent.caps==null)||((q.agent.caps&2)!=0)||(q.intelamt&&(q.intelamt.state==2)))&&(o&8)&&A);QV("MainDevFiles",((n.mtype==2)&&((q.agent==null)||(q.agent.caps==null)||((q.agent.caps&4)!=0)))&&(o&8)&&k);QV("MainDevAmt",(q.intelamt!=null)&&((q.intelamt.state==2)||(q.conn&2))&&(o&8)&&b);QV("MainDevConsole",(e&&(n.mtype==2)&&((q.agent==null)||(q.agent.caps==null)||((q.agent.caps&8)!=0)))&&(o&8));QV("p15uploadCore",(q.agent!=null)&&(q.agent.caps!=null)&&((q.agent.caps&16)!=0));QH("p15coreName",((q.agent!=null)&&(q.agent.core!=null))?q.agent.core:"");var c=Q("p14iframe").contentWindow.getCurrentMeshNode();if((c!=null)&&(c._id!=currentNode._id)){Q("p14iframe").contentWindow.disconnect()}var s=((q.conn&6)!=0)?true:false;Q("p14iframe").contentWindow.setConnectionState(s);Q("p14iframe").contentWindow.setFrameHeight("650px");Q("p14iframe").contentWindow.setAuthCallback(updateAmtCredentials);QV("deskActionsBtn",(o&72)!=0);QV("termActionsBtn",(o&72)!=0);QV("filesActionsBtn",(o&72)!=0);if((powerTimelineNode!=currentNode._id)&&(powerTimelineReq!=currentNode._id)){QH("p10html2","");powerTimelineReq=currentNode._id;meshserver.send({action:"powertimeline",nodeid:currentNode._id});meshserver.send({action:"lastconnect",nodeid:currentNode._id})}QV("DeskTools",false);showDeskToolsProcesses();refreshDeviceEvents();if((currentNode)&&(xxcurrentView>=10)&&(xxcurrentView<20)){document.title="MeshCentral - "+currentNode.name}else{document.title="MeshCentral"}}setupDesktop();if(!t){t=10}go(t)}function showNotes(b,a){if(xxdialogMode){return}setDialogMode(2,"Notes",2,showNotesEx,"<textarea id=d2devNotes ro="+b+" noteid="+a+" readonly style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll></textarea><span style=font-size:10px>Notes can be viewed and changed by other administrators.<span>",a);meshserver.send({action:"getNotes",id:decodeURIComponent(a)})}function showNotesEx(a,b){meshserver.send({action:"setNotes",id:decodeURIComponent(b),notes:encodeURIComponent(Q("d2devNotes").value)})}function deviceChat(){if(xxdialogMode){return}var a="/messenger?id=meshmessenger/"+encodeURIComponent(currentNode._id)+"/"+encodeURIComponent(userinfo._id)+"&title="+currentNode.name;if((authCookie!=null)&&(authCookie!="")){a+="&auth="+authCookie}window.open(a,"meshmessenger:"+currentNode._id);meshserver.send({action:"meshmessenger",nodeid:decodeURIComponent(currentNode._id)})}function deviceUrlFunction(){if(xxdialogMode){return}setDialogMode(2,"Open Page on Device",3,deviceUrlFunctionEx,'<input id=d2devurl placeholder="http://server.com" style=width:100%;overflow-y:scroll></input>')}function deviceUrlFunctionEx(){meshserver.send({action:"msg",type:"openUrl",nodeid:currentNode._id,url:Q("d2devurl").value})}function deviceToastFunction(){if(xxdialogMode){return}setDialogMode(2,"Device Notification",3,deviceToastFunctionEx,"<textarea id=d2devToast style=width:100%;height:80px;resize:none;overflow-y:scroll></textarea>")}function deviceToastFunctionEx(){meshserver.send({action:"toast",nodeids:[currentNode._id],title:"MeshCentral",msg:Q("d2devToast").value})}function deviceActionFunction(){if(xxdialogMode){return}var a=meshes[currentNode.meshid].links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;var b="Select an operation to perform on this device.<br /><br />";var c="<select id=d2deviceop style=float:right;width:250px>";if((a&64)!=0){c+="<option value=100>Wake-up</option>"}if((a&8)!=0){c+="<option value=4>Sleep</option><option value=3>Reset</option><option value=2>Power off</option>"}c+="</select>";b+=addHtmlValue("Operation",c);setDialogMode(2,"Device Action",3,deviceActionFunctionEx,b)}function deviceActionFunctionEx(){var a=Q("d2deviceop").value;if(a==100){meshserver.send({action:"wakedevices",nodeids:[currentNode._id]})}else{meshserver.send({action:"poweraction",nodeids:[currentNode._id],actiontype:a})}}function updateAmtCredentials(a){var b=getNodeFromId(currentNode._id);if((a==true)||(b.intelamt.user==null)||(b.intelamt.user=="")){editDeviceAmtSettings(currentNode._id,updateAmtCredentialsEx)}else{Q("p14iframe").contentWindow.connectButtonfunctionEx()}}function updateAmtCredentialsEx(a,b){Q("p14iframe").contentWindow.connectButtonfunctionEx()}function updateDeviceTimeline(){if((meshserver.State!=2)||(powerTimelineNode==null)||(powerTimelineUpdate==null)||(currentNode==null)){return}if((powerTimelineNode==powerTimelineReq)&&(currentNode._id==powerTimelineNode)&&(powerTimelineUpdate<Date.now())){powerTimelineUpdate=null;meshserver.send({action:"powertimeline",nodeid:currentNode._id});meshserver.send({action:"lastconnect",nodeid:currentNode._id})}}function drawDeviceTimeline(){if((currentNode==null)||(xxcurrentView<10)||(xxcurrentView>19)){return}var s=null,o=Date.now();if(currentNode._id==powerTimelineNode){s=powerTimeline}var e=new Date();e.setHours(0,0,0,0);e=new Date(e.getTime()-(1000*60*60*24*6));var u=e.getTime();var t=[];if(s!=null&&s.length>1){t.push([0,s[1],s[0]]);var c=s[1];for(var m=2;m<s.length;m+=2){var p=s[m],k=o;if(s.length>(m+1)){k=s[m+1]}t.push([c,c+k,p]);c=c+k}}var A="",b=1,h=new Date();var w=Q("masthead").offsetWidth-(160+9+9+14);h.setHours(0,0,0,0);for(var m=0;m<7;m++){var g="",q=h.getTime(),l=q+(1000*60*60*24);for(var n in t){var a=t[n];if(isTimeBlockInside(q,l,a[0],a[1])==true){var y=Math.max(q,a[0]);var r=Math.min(Math.min(l,a[1]),o);var z=Math.round(((r-y)*w)/86400000);if(z>0){var v=powerStateStrings2[a[2]]+" from "+new Date(y).toLocaleTimeString()+" to "+new Date(r).toLocaleTimeString()+".";g+='<div title="'+v+'" style=display:table-cell;width:'+z+"px;background-color:"+powerColor(a[2])+";height:16px></div>"}}}A+="<tr style="+(((b%2)==0)?"background-color:#DDD":"")+"><td><div>&nbsp;"+h.toLocaleDateString()+"<div></div></div></td><td><div>"+g+"</div></td></tr>";++b;h=new Date(h.getTime()-(1000*60*60*24))}QH("p10html2",'<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:center;width:150px>Day</th><th scope=col style=text-align:center>7 Day Power State</th></tr>'+A+"</tbody></table>")}function powerColor(a){if(a<powerColorTable.length){return powerColorTable[a]}return"yellow"}function isTimeBlockInside(d,c,b,a){if((b<d)&&(a>c)){return true}if((b>d)&&(b<c)){return true}if((a>d)&&(a<c)){return true}return false}function addDeviceAttribute(a,b){return"<tr><td class=style7 style=width:180px>"+a+"</td><td class=style9 style=max-width:400px;overflow:hidden>"+b+"</td></tr>"}function editDeviceAmtSettings(e,b){if(xxdialogMode){return}var g="",d=getNodeFromId(e),a=3,c=getNodeRights(e);if((c&4)==0){return}g+=addHtmlValue("Username",'<input id=dp10username style=width:230px maxlength=32 autocomplete=nope placeholder="admin" onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />');g+=addHtmlValue("Password","<input id=dp10password type=password style=width:230px autocomplete=nope maxlength=32 onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />");g+=addHtmlValue("Security","<select id=dp10tls style=width:236px><option value=0>No TLS security</option><option value=1>TLS security required</option></select>");if((d.intelamt.user!=null)&&(d.intelamt.user!="")){a=7}setDialogMode(2,"Edit Intel&reg; AMT credentials",a,editDeviceAmtSettingsEx,g,{node:d,func:b});if((d.intelamt.user!=null)&&(d.intelamt.user!="")){Q("dp10username").value=d.intelamt.user}else{Q("dp10username").value="admin"}Q("dp10tls").value=d.intelamt.tls;validateDeviceAmtSettings()}function validateDeviceAmtSettings(){QE("idx_dlgOkButton",passwordcheck(Q("dp10password").value))}function editDeviceAmtSettingsEx(c,d){if(c==2){meshserver.send({action:"changedevice",nodeid:d.node._id,intelamt:{user:"",pass:""}})}else{var b=Q("dp10username").value;if(b==""){b="admin"}var a=Q("dp10password").value;if(a==""){b=""}meshserver.send({action:"changedevice",nodeid:d.node._id,intelamt:{user:b,pass:a,tls:Q("dp10tls").value}});d.node.intelamt.user=b;d.node.intelamt.tls=Q("dp10tls").value;if(d.func){setTimeout(d.func,300)}}}function p10showChangeGroupDialog(e){if(xxdialogMode){return}var g=null;if(e.length==1){try{g=meshes[getNodeFromId(e[0])]._id}catch(b){}}var j="<select id=p10newGroup style=width:236px>",a=0;for(var c in meshes){var d=meshes[c].links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;if((meshes[c]._id!=g)&&(d&4)){a++;j+="<option value='"+meshes[c]._id+"'>"+meshes[c].name+"</option>"}}j+="</select>";if(a>0){var h=(e.length==1)?"Select a new group for this device<br /><br />":"Select a new group for selected devices<br /><br />";h+=addHtmlValue("New Device Group",j);setDialogMode(2,"Change Group",3,p10showChangeGroupDialogEx,h,e)}else{setDialogMode(2,"Change Group",1,null,"No other device group of same type exists.")}}function p10showChangeGroupDialogEx(a,c){meshserver.send({action:"changeDeviceMesh",nodeids:c,meshid:Q("p10newGroup").value})}function p10showDeleteNodeDialog(a){if(xxdialogMode){return}var b='Are you sure you want to delete node "'+EscapeHtml(currentNode.name)+'"?<br /><br />';b+="<label><input id=p10check type=checkbox onchange=p10validateDeleteNodeDialog() />Confirm</label>";setDialogMode(2,"Delete Node",3,p10showDeleteNodeDialogEx,b,a);p10validateDeleteNodeDialog()}function p10validateDeleteNodeDialog(){QE("idx_dlgOkButton",Q("p10check").checked)}function p10showDeleteNodeDialogEx(a,b){meshserver.send({action:"removedevices",nodeids:[b]})}function p10clickOnce(a,c,b){meshserver.send({action:"getcookie",nodeid:a,tcpport:b,tag:"clickonce",protocol:c})}var d2map=null;function p10showNodeLocationDialog(){if((xxdialogMode!=null)&&(xxdialogTag=="@xxmap")){setDialogMode(0)}else{if(xxdialogMode){return}}var m=[],n=["iploc","wifiloc","gpsloc","userloc"],a=null;for(var k in n){if(currentNode[n[k]]!=null){var j=currentNode[n[k]].split(","),h=parseFloat(j[0]),l=parseFloat(j[1]);if((h<90)&&(h>-90)&&(l<180)&&(l>-180)){var e=new ol.Feature({geometry:new ol.geom.Point(ol.proj.fromLonLat([l,h]))});e.setStyle(markerStyle(currentNode,parseInt(k)+1));m.push(e);if(a==null){a=[h,l,h,l,0]}else{if(h<a[0]){a[0]=h}if(l<a[1]){a[1]=l}if(h>a[2]){a[2]=h}if(l>a[3]){a[3]=l}}}}}var p=new ol.source.Vector({features:m});var o=new ol.layer.Vector({source:p});var q="<div id=d2map style=width:100%;height:300px></div>";setDialogMode(2,"Device Location",1,null,q,"@xxmap");var c=0,b=0,r=8;if(a!=null){var b=(a[0]+a[2])/2;var c=(a[1]+a[3])/2;var d=Math.max(Math.abs(a[0]-a[2]),Math.abs(a[1]-a[3]));var g=360,r=-2;while(g>d){r++;g=g/2}}if(m.length==1){r=8}d2map=new ol.Map({target:"d2map",interactions:ol.interaction.defaults({dragPan:false,mouseWheelZoom:false}),layers:[new ol.layer.Tile({source:new ol.source.OSM()}),o],view:new ol.View({center:ol.proj.fromLonLat([c,b]),zoom:r})})}function p10showNodeNetInfoDialog(){if(xxdialogMode){return}setDialogMode(2,"Network Interfaces",1,null,"<div id=d2netinfo>Loading...</div>","if"+currentNode._id);meshserver.send({action:"getnetworkinfo",nodeid:currentNode._id})}function p10showMeshCmdDialog(a,b){if(xxdialogMode){return}var d="<select id=aginsSelect onclick=meshCmdOsClick() style=width:236px>";d+="<option value=3>Windows (32bit)</option>";d+="<option value=4>Windows (64bit)</option>";d+="<option value=5>Linux x86 (32bit)</option>";d+="<option value=6>Linux x86 (64bit)</option>";d+="<option value=25>Linux ARM, Raspberry Pi (32bit)</option>";d+="</select>";var c="";if(a==0){c+="<div>MeshCmd is a command line tool that performs lots of different operations. The action file can optionally be downloaded and edited to provide server information and credentials.<br /><br />"}if(a==1){c+='<div>Download "meshcmd" with an action file to route traffic thru this server to this device. Make sure to edit meshaction.txt and add your account password or make any changes needed.<br /><br />'}c+=addHtmlValue("Operating System",d);c+=addHtmlValue("MeshCmd",'<a id=meshcmddownloadid style=cursor:pointer onclick=fileDownload("meshagents?meshcmd=","MeshCmd",2)></a>');if(a==0){c+=addHtmlValue("Action File",'<a style=cursor:pointer onclick=fileDownload("meshagents?meshaction=generic","MeshAction.txt")>MeshAction (.txt)</a>')}if(a==1){c+=addHtmlValue("Action File",'<a style=cursor:pointer onclick=fileDownload("meshagents?meshaction=route&nodeid='+b+'","MeshAction.txt")>MeshAction (.txt)</a>')}c+="</div>";setDialogMode(2,["Download MeshCmd","Network Router"][a],9,null,c,"fileDownload");meshCmdOsClick()}function meshCmdOsClick(){var a=Q("aginsSelect").value,b="";if(a==3){b="MeshCmd (Win32 executable)"}if(a==4){b="MeshCmd (Win64 executable)"}if(a==5){b="MeshCmd (Linux x86, 32bit)"}if(a==6){b="MeshCmd (Linux x86, 64bit)"}if(a==25){b="MeshCmd (Linux ARM, 32bit)"}QH("meshcmddownloadid",b)}function p10showiconselector(){if(xxdialogMode){return}var a=meshes[currentNode.meshid];var b=a.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;if((b&4)==0){return}var c="<br><div style=display:inline-block;width:40px></div>";c+="<div style=display:inline-block class=i1 onclick=p10setIcon(1)></div>";c+="<div style=display:inline-block class=i2 onclick=p10setIcon(2)></div>";c+="<div style=display:inline-block class=i3 onclick=p10setIcon(3)></div>";c+="<div style=display:inline-block class=i4 onclick=p10setIcon(4)></div>";c+="<div style=display:inline-block class=i5 onclick=p10setIcon(5)></div>";c+="<div style=display:inline-block class=i6 onclick=p10setIcon(6)></div><br><br>";setDialogMode(2,"Icon Selection",0,null,c);QV("id_dialogclose",true)}function p10setIcon(a){setDialogMode(0);meshserver.send({action:"changedevice",nodeid:currentNode._id,icon:a})}var showEditNodeValueDialog_modes=["Device Name","Hostname","Description","Tags"];var showEditNodeValueDialog_modes2=["name","host","desc","tags"];var showEditNodeValueDialog_modes3=["","","","Tag1, Tag2, Tag3"];function showEditNodeValueDialog(a){if(xxdialogMode){return}var c=addHtmlValue(showEditNodeValueDialog_modes[a],'<input id=dp10devicevalue style=width:230px maxlength=64 placeholder="'+showEditNodeValueDialog_modes3[a]+'" onchange=p10editdevicevalueValidate('+a+",event) onkeyup=p10editdevicevalueValidate("+a+",event) />");setDialogMode(2,"Edit Device",3,showEditNodeValueDialogEx,c,a);var b=currentNode[showEditNodeValueDialog_modes2[a]];if(b==null){b=""}if(Array.isArray(b)){b=b.join(", ")}Q("dp10devicevalue").value=b;p10editdevicevalueValidate();Q("dp10devicevalue").focus()}function showEditNodeValueDialogEx(a,b){var c={action:"changedevice",nodeid:currentNode._id};c[showEditNodeValueDialog_modes2[b]]=Q("dp10devicevalue").value;meshserver.send(c)}function p10editdevicevalueValidate(b,a){var c=((b>1)||(Q("dp10devicevalue").value.length>0));QE("idx_dlgOkButton",c);if((a!=null)&&(c==true)&&(a.keyCode==13)){dialogclose(1)}}var desktopNode;function setupDesktop(){if((desktopNode!=currentNode)&&(desktop!=null)){desktop.Stop();desktopNode=null;desktop=null}if((desktopNode!=currentNode)||(desktop==null)){var b=multiDesktop[currentNode._id];if(b!=null){QH("DeskParent","");var a=b.m.CanvasId;a.setAttribute("id","Desk");a.setAttribute("style","width:100%;-ms-touch-action:none;margin-left:0px");a.setAttribute("onmousedown","dmousedown(event)");a.setAttribute("onmouseup","dmouseup(event)");a.setAttribute("onmousemove","dmousemove(event)");a.removeAttribute("onclick");Q("DeskParent").appendChild(a);desktop=b;if(desktop.m.SendCompressionLevel){desktop.m.SendCompressionLevel(1,desktopsettings.quality,desktopsettings.scaling,desktopsettings.framerate)}desktop.onStateChanged=onDesktopStateChange;desktopNode=currentNode;onDesktopStateChange(desktop,desktop.State);delete multiDesktop[currentNode._id]}else{QH("DeskParent",'<canvas id=Desk width=640 height=480 style="width:100%;-ms-touch-action:none;margin-left:0px" oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></canvas>');desktopNode=currentNode}Q("Desk").addEventListener("DOMMouseScroll",function(c){return dmousewheel(c)});Q("Desk").addEventListener("mousewheel",function(c){return dmousewheel(c)})}desktopNode=currentNode;updateDesktopButtons();deskAdjust();if(!Q("Desk")["toBlob"]){QV("deskSaveBtn",false)}}function updateDesktopButtons(){var d=meshes[currentNode.meshid];var a=0;if(desktop!=null){a=desktop.State}var e=d.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;QV("disconnectbutton1span",(a!=0));QV("connectbutton1span",(a==0)&&((e&8)||(e&256))&&(d.mtype==2)&&(currentNode.agent.caps&1));QV("connectbutton1hspan",(a==0)&&(e&8)&&((currentNode.intelamt!=null)&&(d.mtype==1||currentNode.intelamt.state==2)&&((currentNode.intelamt.ver!=null)||(d.mtype==1))));QV("d7amtkvm",(currentNode.intelamt!=null&&((currentNode.intelamt.ver!=null)||(d.mtype==1)))&&((a==0)||(desktop.contype==2)));QV("d7meshkvm",(webRtcDesktop)||((d.mtype==2)&&(currentNode.agent.caps&1)&&((a==false)||(desktop.contype==1))));var c=(e==4294967295)||(((e&8)!=0)&&((e&256)==0)&&((e&4096)==0));var g=((currentNode.conn&1)!=0);QE("connectbutton1",g);var b=((currentNode.conn&6)!=0);QE("connectbutton1h",b);QE("deskSaveBtn",a==3);QV("deskFocusBtn",(desktop!=null)&&(desktop.contype==2)&&(a!=0)&&(desktopsettings.showfocus));QV("DeskCAD",c);QE("DeskCAD",a==3);QV("DeskWD",(currentNode.agent)&&(currentNode.agent.id<5)&&c);QE("DeskWD",a==3);QV("deskkeys",(currentNode.agent)&&(currentNode.agent.id<5)&&c);QE("deskkeys",a==3);QV("DeskToolsButton",(c)&&(d.mtype==2)&&g);QV("DeskChatButton",(browserfullscreen==false)&&(c)&&(d.mtype==2)&&g);QV("DeskNotifyButton",(browserfullscreen==false)&&(currentNode.agent)&&(currentNode.agent.id<5)&&(c)&&(d.mtype==2)&&g);QV("DeskOpenWebButton",(browserfullscreen==false)&&(c)&&(d.mtype==2)&&g);QV("DeskControlSpan",c);QV("deskActionsBtn",(browserfullscreen==false));QV("deskActionsSettings",(browserfullscreen==false));if(e&8){Q("DeskControl").checked=(getstore("DeskControl",1)==1)}else{Q("DeskControl").checked=false}if(g==false){QV("DeskTools",false)}}var autoConnectDesktopTimer=null;function autoConnectDesktop(a){if(autoConnectDesktopTimer==null){autoConnectDesktopTimer=setInterval(connectDesktop,100)}else{clearInterval(autoConnectDesktopTimer);autoConnectDesktopTimer=null}}function connectDesktop(b,a){if(desktop==null){desktopNode=currentNode;if(a==2){if((desktopNode.intelamt.user==null)||(desktopNode.intelamt.user=="")){editDeviceAmtSettings(desktopNode._id,connectDesktop);return}desktop=CreateAmtRedirect(CreateAmtRemoteDesktop("Desk"),authCookie);desktop.debugmode=debugmode;desktop.onStateChanged=onDesktopStateChange;desktop.m.bpp=(desktopsettings.encoding==1||desktopsettings.encoding==3)?1:2;desktop.m.useZRLE=(desktopsettings.encoding<3);desktop.m.localKeyMap=desktopsettings.localkeymap;desktop.m.showmouse=desktopsettings.showmouse;desktop.m.onScreenSizeChange=deskAdjust;desktop.m.onKvmData=function(h){if(h.length==0){if(!desktop.m._sentPresence){desktop.m._sentPresence=true;desktop.m.sendKvmData(JSON.stringify({action:"present",ver:1}))}return}var d=null;try{d=JSON.parse(h)}catch(g){}if((d!=null)&&(d.action!=null)){if(d.action=="restart"){webRtcDesktopReset();desktop.m.sendKvmData(JSON.stringify({action:"present",ver:1}))}else{if((d.action=="present")&&(webRtcDesktop==null)){webRtcDesktop={platform:d.platform};var c=null;if(typeof RTCPeerConnection!=="undefined"){webRtcDesktop.webrtc=new RTCPeerConnection(c)}else{if(typeof webkitRTCPeerConnection!=="undefined"){webRtcDesktop.webrtc=new webkitRTCPeerConnection(c)}}webRtcDesktop.webchannel=webRtcDesktop.webrtc.createDataChannel("DataChannel",{});webRtcDesktop.webchannel.onopen=function(){console.log("WebRTC Data Channel Open");Q("deskstatus").textContent=StatusStrs[desktop.State]+", Soft-KVM";desktop.m.hold(true);webRtcDesktop.webRtcActive=true;webRtcDesktop.softdesktop=CreateKvmDataChannel(webRtcDesktop.webchannel,CreateAgentRemoteDesktop("Desk",Q("id_mainarea")),desktop.m);webRtcDesktop.softdesktop.m.setRotation(desktop.m.rotation);webRtcDesktop.softdesktop.m.onScreenSizeChange=deskAdjust;if(desktopsettings.quality){webRtcDesktop.softdesktop.m.CompressionLevel=desktopsettings.quality}if(desktopsettings.scaling){webRtcDesktop.softdesktop.m.ScalingLevel=desktopsettings.scaling}webRtcDesktop.softdesktop.Start()};webRtcDesktop.webchannel.onclose=function(e){console.log("WebRTC Data Channel Closed");webRtcDesktopReset()};webRtcDesktop.webrtc.onicecandidate=function(j){if(j.candidate==null){desktop.m.sendKvmData(JSON.stringify({action:"offer",ver:1,sdp:webRtcDesktop.webrtcoffer.sdp}))}else{webRtcDesktop.webrtcoffer.sdp+=("a="+j.candidate.candidate+"\r\n")}};webRtcDesktop.webrtc.oniceconnectionstatechange=function(){if((webRtcDesktop!=null)&&(webRtcDesktop.webrtc!=null)&&((webRtcDesktop.webrtc.iceConnectionState=="disconnected")||(webRtcDesktop.webrtc.iceConnectionState=="failed"))){webRtcDesktopReset()}};webRtcDesktop.webrtc.createOffer(function(e){webRtcDesktop.webrtcoffer=e;webRtcDesktop.webrtc.setLocalDescription(e,function(){},webRtcDesktopReset)},webRtcDesktopReset,{mandatory:{OfferToReceiveAudio:false,OfferToReceiveVideo:false}})}else{if((d.action=="answer")&&(webRtcDesktop!=null)){webRtcDesktop.webrtc.setRemoteDescription(new RTCSessionDescription({type:"answer",sdp:d.sdp}),function(){},webRtcDesktopReset)}}}}};desktop.Start(desktopNode._id,16994,"*","*",0);desktop.contype=2}else{desktop=CreateAgentRedirect(meshserver,CreateAgentRemoteDesktop("Desk"),serverPublicNamePort,authCookie);desktop.debugmode=debugmode;desktop.m.debugmode=debugmode;desktop.attemptWebRTC=attemptWebRTC;desktop.onStateChanged=onDesktopStateChange;desktop.m.CompressionLevel=desktopsettings.quality;desktop.m.ScalingLevel=desktopsettings.scaling;desktop.m.FrameRateTimer=desktopsettings.framerate;desktop.m.onDisplayinfo=deskDisplayInfo;desktop.m.onScreenSizeChange=deskAdjust;desktop.Start(desktopNode._id);desktop.contype=1}}else{desktop.Stop();webRtcDesktopReset();desktopNode=desktop=null}}var webRtcDesktop=null;function webRtcDesktopReset(){if(webRtcDesktop==null){return}if(webRtcDesktop.softdesktop!=null){webRtcDesktop.softdesktop.Stop();webRtcDesktop.softdesktop=null}if(webRtcDesktop.webchannel!=null){try{webRtcDesktop.webchannel.close()}catch(a){}webRtcDesktop.webchannel=null}if(webRtcDesktop.webrtc!=null){try{webRtcDesktop.webrtc.close()}catch(a){}webRtcDesktop.webrtc=null}webRtcDesktop=null;if(desktop&&desktop.m){desktop.m.hold(false);Q("deskstatus").textContent=StatusStrs[desktop.State]}}function onDesktopStateChange(c,a){var d=a;if((d==3)&&(c.contype==2)){d++}var b=StatusStrs[d];if((desktop!=null)&&(desktop.webRtcActive==true)){b+=", WebRTC"}QH("deskstatus",b);switch(a){case 0:desktop.Stop();desktopNode=desktop=null;QV("DeskFocus",false);QV("termdisplays",false);deskFocusBtn.value="All Focus";if(fullscreen==true){deskToggleFull()}webRtcDesktopReset();break;case 2:break;default:break}updateDesktopButtons();deskAdjust();setTimeout(deskAdjust,50)}function showDesktopSettings(){if(xxdialogMode){return}applyDesktopSettings();updateDesktopButtons();setDialogMode(7,"Remote Desktop Settings",3,showDesktopSettingsChanged)}function showDesktopSettingsChanged(){desktopsettings.encoding=d7desktopmode.value;desktopsettings.showfocus=d7showfocus.checked;desktopsettings.showmouse=d7showcursor.checked;desktopsettings.quality=d7bitmapquality.value;desktopsettings.scaling=d7bitmapscaling.value;desktopsettings.framerate=d7framelimiter.value;desktopsettings.localkeymap=d7localKeyMap.checked;localStorage.setItem("desktopsettings",JSON.stringify(desktopsettings));applyDesktopSettings();if(desktop){if(desktop.contype==1){if(desktop.State!=0){desktop.m.SendCompressionLevel(1,desktopsettings.quality,desktopsettings.scaling,desktopsettings.framerate)}}if(desktop.contype==2){if(desktopsettings.showfocus==false){desktop.m.focusmode=0;deskFocusBtn.value="All Focus"}if(desktop.State!=0){desktop.Stop();setTimeout(function(){connectDesktop(null,2)},50)}}}}function applyDesktopSettings(){var c="",b=(features&512)?[90,80,70,60,50,40,30,20,10,5,1]:[60,50,40,30,20,10,5,1];for(var a in b){c+="<option value="+b[a]+">"+b[a]+"%</option>"}QH("d7bitmapquality",c);d7desktopmode.value=desktopsettings.encoding;d7showfocus.checked=desktopsettings.showfocus;d7showcursor.checked=desktopsettings.showmouse;d7bitmapquality.value=40;if(b.indexOf(parseInt(desktopsettings.quality))>=0){d7bitmapquality.value=desktopsettings.quality}d7bitmapscaling.value=desktopsettings.scaling;if(desktopsettings.framerate){d7framelimiter.value=desktopsettings.framerate}if(desktopsettings.localkeymap){d7localKeyMap.checked=desktopsettings.localkeymap}QV("deskFocusBtn",(desktop!=null)&&(desktop.contype==2)&&(desktop.state!=0)&&(desktopsettings.showfocus))}function enterBrowserFullscreen(a){if(a.requestFullscreen){a.requestFullscreen()}else{if(a.msRequestFullscreen){a.msRequestFullscreen()}else{if(a.mozRequestFullScreen){a.mozRequestFullScreen()}else{if(a.webkitRequestFullscreen){a.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}}}}}function exitBrowserFullscreen(){if(document.exitFullscreen){document.exitFullscreen()}else{if(document.msExitFullscreen){document.msExitFullscreen()}else{if(document.mozCancelFullScreen){document.mozCancelFullScreen()}else{if(document.webkitExitFullscreen){document.webkitExitFullscreen()}}}}}function isBrowserFullscreen(){if(!document.fullscreenElement&&!document.mozFullScreenElement&&!document.webkitFullscreenElement&&!document.msFullscreenElement){return false}else{return true}}var fullscreen=false;var browserfullscreen=false;function deskToggleFull(a){fullscreen=!fullscreen;QV("mastheadx",!fullscreen);QV("masthead",!fullscreen);QV("topbar",!fullscreen);QV("p11deviceNameHeader",!fullscreen);QV("footer",!fullscreen);QV("column_l_bottomgap",!fullscreen);QV("idx_deskFullBtn2",fullscreen);QV("deskFullBtn",!fullscreen);QV("page_leftbar",!fullscreen);if(fullscreen){if(a.shiftKey==true){enterBrowserFullscreen(Q("deskarea0"));browserfullscreen=true}QS("column_l").width="930px";QS("column_l").height="";QS("column_l")["margin-left"]="";QS("column_l")["overflow-y"]="";QS("container").position="";QS("page_content").position="";QV("MainMenuSpan",true);QS("container").width="100%";QS("container")["border-right"]="0";QS("container")["border-left"]="0";QS("column_l").padding="0";QS("column_l").width="100%";QS("column_l")["max-height"]=""}else{exitBrowserFullscreen();browserfullscreen=false;QS("container").width="960px";QS("container")["border-right"]="1px solid #b7b7b7";QS("container")["border-left"]="1px solid #b7b7b7";QS("column_l").padding="0 15px";QS("column_l").width="930px";toggleFullScreen()}deskAdjust();deskAdjust();updateDesktopButtons()}function deskToggleFocus(){desktop.m.focusmode=(desktop.m.focusmode+64)%192;Q("deskFocusBtn").value=["All Focus","Small Focus","Large Focus"][desktop.m.focusmode/64]}function deskAdjust(){var c=(Math.max(document.documentElement.clientHeight,window.innerHeight||0)-(Q("deskarea1").clientHeight+Q("deskarea2").clientHeight+Q("Desk").clientHeight+Q("deskarea4").clientHeight+2))/2;if(fullscreen){document.documentElement.style.overflow="hidden";QS("deskarea3x").height=null;if(c<0){var a=(Math.max(document.documentElement.clientHeight,window.innerHeight||0)-(Q("deskarea1").clientHeight+Q("deskarea2").clientHeight+Q("deskarea4").clientHeight));var b=9999;if(desktop){b=(desktop.m.width/desktop.m.height)*a}if(webRtcDesktop&&webRtcDesktop.softdesktop){b=(webRtcDesktop.softdesktop.m.width/webRtcDesktop.softdesktop.m.height)*a}QS("Desk")["max-height"]=a+"px";QS("Desk")["max-width"]=b+"px";c=0}else{QS("Desk")["max-height"]=null;QS("Desk")["max-width"]=null}QS("Desk")["margin-top"]=c+"px";QS("Desk")["margin-bottom"]=c+"px"}else{var b=9999,a=(Math.max(document.documentElement.clientHeight,window.innerHeight||0)-(webPageFullScreen?276:290));if(desktop){b=(desktop.m.width/desktop.m.height)*a}if(webRtcDesktop&&webRtcDesktop.softdesktop){b=(webRtcDesktop.softdesktop.m.width/webRtcDesktop.softdesktop.m.height)*a}document.documentElement.style.overflow="auto";QS("Desk")["max-height"]=a+"px";QS("Desk")["max-width"]=b+"px";QS("Desk")["margin-top"]="0";QS("Desk")["margin-bottom"]="0"}}function mdeskAdjust(c,h,g,a){if(!c||!h||!g||!a){return}if(a.id=="Desk"){deskAdjust();return}var k=[{x:180,y:101},{x:302,y:169},{x:454,y:255}][Q("sizeselect").selectedIndex];var e=k.x+2,j=Q("xdevices").clientWidth-30,l=Math.floor(j/e);l=e+Math.floor((j-(l*e))/l);k.y=k.y*(l/k.x);k.x=l;var b=k.y,d=k.x;if(c.State!=0){b=k.y;d=(h/g)*k.y}QS(a.id)["max-height"]=b+"px";QS(a.id)["max-width"]=d+"px";QS(a.id)["margin-top"]="0";QS(a.id)["margin-bottom"]="0"}function deskSendKeys(){if(xxdialogMode||desktop==null||desktop.State!=3){return}var a=Q("deskkeys").value;if(a==0){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[65364,1],[65364,0],[65511,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.DOWN,40],[desktop.m.KeyAction.UP,40],[desktop.m.KeyAction.EXUP,91]])}}else{if(a==1){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[65362,1],[65362,0],[65511,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.DOWN,38],[desktop.m.KeyAction.UP,38],[desktop.m.KeyAction.EXUP,91]])}}else{if(a==2){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[108,1],[108,0],[65511,0]])}else{desktop.sendCtrlMsg('{"action":"lock"}')}}else{if(a==3){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[109,1],[109,0],[65511,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.DOWN,77],[desktop.m.KeyAction.UP,77],[desktop.m.KeyAction.EXUP,91]])}}else{if(a==4){if(desktop.contype==2){desktop.m.sendkey([[65505,1],[65511,1],[109,1],[109,0],[65511,0],[65505,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.DOWN,16],[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.DOWN,77],[desktop.m.KeyAction.UP,77],[desktop.m.KeyAction.EXUP,91],[desktop.m.KeyAction.UP,16]])}}else{if(a==5){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[65511,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.EXUP,91]])}}else{if(a==6){if(desktop.contype==2){desktop.m.sendkey([[65511,1],[114,1],[114,0],[65511,0]])}else{desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,91],[desktop.m.KeyAction.DOWN,82],[desktop.m.KeyAction.UP,82],[desktop.m.KeyAction.EXUP,91]])}}}}}}}}}function showDeskClip(){if(xxdialogMode||desktop==null||desktop.State!=3){return}Q("DeskClip").blur();var a='<input id=dlgClipGet type=button value="Get Clipboard" style=width:120px onclick=showDeskClipGet()>';a+='<input id=dlgClipSet type=button value="Set Clipboard" style=width:120px onclick=showDeskClipSet()>';a+='<div id=dlgClipStatus style="display:inline-block;margin-left:8px" ></div>';a+='<textarea id=d2clipText style="width:100%;height:184px;resize:none" maxlength=65535></textarea>';a+='<input type=button value="Close" style=width:80px;float:right onclick=dialogclose(0)><div style=height:26px>&nbsp;</div>';setDialogMode(2,"Remote Clipboard",8,null,a,"clipboard");Q("d2clipText").focus()}function showDeskClipGet(){if(desktop==null||desktop.State!=3){return}meshserver.send({action:"msg",type:"getclip",nodeid:currentNode._id})}function showDeskClipSet(){if(desktop==null||desktop.State!=3){return}meshserver.send({action:"msg",type:"setclip",nodeid:currentNode._id,data:Q("d2clipText").value})}function sendCAD(){if(xxdialogMode||desktop==null||desktop.State!=3){return}desktop.m.sendcad()}function toggleDeskTools(){if(xxdialogMode){return}if(QS("DeskTools").display=="none"){QV("DeskTools",true);Q("DeskTools").nodeid=currentNode._id;refreshDeskTools()}else{QV("DeskTools",false)}}function refreshDeskTools(){QV("DeskToolsRefreshButton",false);setTimeout(refreshDeskToolsEx,500);meshserver.send({action:"msg",type:"ps",nodeid:currentNode._id})}function refreshDeskToolsEx(){QV("DeskToolsRefreshButton",true)}var deskTools={sort:1,msg:null};function sortProcess(a){deskTools.sort=a;showDeskToolsProcesses(deskTools.msg)}function sortProcessPid(c,d){if(c.p>d.p){return 1}if(c.p<d.p){return(-1)}return 0}function sortProcessName(c,d){if(c.d>d.d){return 1}if(c.d<d.d){return(-1)}return 0}function showDeskToolsProcesses(c){deskTools.msg=c;if(c==null){QH("DeskToolsProcesses","");return}if(Q("DeskTools").nodeid!=c.nodeid){return}var d=[],h=null;try{h=JSON.parse(c.value)}catch(a){}if(h!=null){for(var g in h){d.push({p:parseInt(g),c:h[g].cmd,d:h[g].cmd.toLowerCase(),u:h[g].user})}if(deskTools.sort==0){d.sort(sortProcessPid)}else{if(deskTools.sort==1){d.sort(sortProcessName)}}var j="";for(var b in d){if(d[b].p!=0){j+="<div class=deskToolsBar><div style=width:50px;float:left;text-align:right;padding-right:5px>"+d[b].p+'</div><a style=float:right;padding-right:5px;cursor:pointer title="Stop process" onclick=stopProcess('+d[b].p+',"'+d[b].c+'")><img width=10 height=10 src="images/trash.png"></a><div style=float:right;padding-right:5px>'+(d[b].u?d[b].u:"")+"</div><div>"+d[b].c+"</div></div>"}}QH("DeskToolsProcesses",j)}}function toggleKvmControl(){putstore("DeskControl",(Q("DeskControl").checked?1:0))}function deskSaveImage(){if(xxdialogMode||desktop==null||desktop.State!=3){return}var a=new Date(),b="Desktop-"+currentNode.name+"-"+a.getFullYear()+"-"+("0"+(a.getMonth()+1)).slice(-2)+"-"+("0"+a.getDate()).slice(-2)+"-"+("0"+a.getHours()).slice(-2)+"-"+("0"+a.getMinutes()).slice(-2);Q("Desk")["toBlob"](function(c){saveAs(c,b+".jpg")})}function deskDisplayInfo(e,a,c,d){var g=Q("termdisplays").value;if(a.length>0){var b="";for(var h in a){b+="<option"+((g==a[h])?" selected":"")+">"+a[h]+"</option>"}QH("termdisplays",b)}QV("termdisplays",a.length>0)}function deskGetDisplayNumbers(a){desktop.m.GetDisplayNumbers()}function deskSetDisplay(b){var a=0,c=Q("termdisplays").value;if(c=="All Displays"){a=65535}else{a=parseInt(c.substring(8))}desktop.m.SetDisplay(a)}var dblClickDetectArgs={t:0,x:0,y:0};function dblClickDetect(a){if(a.buttons!=1){return}var b=Date.now();if(((b-dblClickDetectArgs.t)<250)&&(Math.abs(a.clientX-dblClickDetectArgs.x)<2)&&(Math.abs(a.clientY-dblClickDetectArgs.y)<2)){if(!xxdialogMode&&desktop!=null&&Q("DeskControl").checked){if((webRtcDesktop!=null)&&(webRtcDesktop.softdesktop!=null)){webRtcDesktop.softdesktop.m.mousedblclick(a);desktop.m.sendKeepAlive()}else{desktop.m.mousedblclick(a)}}}dblClickDetectArgs.t=b;dblClickDetectArgs.x=a.clientX;dblClickDetectArgs.y=a.clientY}function dmousedown(a){if(!xxdialogMode&&desktop!=null&&Q("DeskControl").checked){if((webRtcDesktop!=null)&&(webRtcDesktop.softdesktop!=null)){webRtcDesktop.softdesktop.m.mousedown(a);desktop.m.sendKeepAlive()}else{desktop.m.mousedown(a)}}dblClickDetect(a)}function dmouseup(a){if(!xxdialogMode&&desktop!=null&&Q("DeskControl").checked){if((webRtcDesktop!=null)&&(webRtcDesktop.softdesktop!=null)){webRtcDesktop.softdesktop.m.mouseup(a);desktop.m.sendKeepAlive()}else{desktop.m.mouseup(a)}}}function dmousemove(a){if(!xxdialogMode&&desktop!=null&&Q("DeskControl").checked){if((webRtcDesktop!=null)&&(webRtcDesktop.softdesktop!=null)){webRtcDesktop.softdesktop.m.mousemove(a);desktop.m.sendKeepAlive()}else{desktop.m.mousemove(a)}}}function dmousewheel(a){if(!xxdialogMode&&desktop!=null&&Q("DeskControl").checked){if((webRtcDesktop!=null)&&(webRtcDesktop.softdesktop!=null)){webRtcDesktop.softdesktop.m.mousewheel(a);desktop.m.sendKeepAlive()}else{if(desktop.m.mousewheel){desktop.m.mousewheel(a)}}haltEvent(a);return true}return false}function drotate(a){if(!xxdialogMode&&desktop!=null){desktop.m.setRotation(desktop.m.rotation+a);deskAdjust();deskAdjust()}}function stopProcess(a,b){setDialogMode(2,"Process Control",3,stopProcessEx,"Stop process #"+a+' "'+b+'"?',a)}function stopProcessEx(a,b){meshserver.send({action:"msg",type:"pskill",nodeid:currentNode._id,value:b});setTimeout(refreshDeskTools,300)}var terminalNode;function setupTerminal(){if((terminalNode!=currentNode)&&(terminal!=null)){terminal.Stop();terminal=null}terminalNode=currentNode;updateTerminalButtons()}function updateTerminalButtons(){var b=meshes[terminalNode.meshid];var d=((terminal!=null)&&(terminal.state!=0));QV("disconnectbutton2span",(d==true));QV("connectbutton2span",(d==false)&&(b.mtype==2)&&(currentNode.agent.caps&2));QV("connectbutton2hspan",(d==false)&&((terminalNode.intelamt!=null)&&(b.mtype==1||terminalNode.intelamt.state==2)&&((terminalNode.intelamt.ver!=null)||(b.mtype==1))));var c=((terminalNode.conn&1)!=0);QE("connectbutton2",c);var a=((terminalNode.conn&6)!=0);QE("connectbutton2h",a);QE("ctrlcbutton",d);QE("ctrlxbutton",d);QE("escbutton",d);QE("bsbutton",d);QE("pastebutton",d);QE("specialkeylist",d);QE("specialkeylistinput",d);QV("terminalSettingsButtons",(terminal)&&(terminal.contype==2));if(terminal){Q("id_ttypebutton").value=terminalEmulations[terminal.m.terminalEmulation];Q("id_tfxkeysbutton").value=fxEmulations[terminal.m.fxEmulation];Q("id_tcrbutton").value=(terminal.m.lineFeed=="\r\n")?"CR+LF":"LF"}}function onTerminalStateChange(d,a){var c=a;if((c==3)&&(d.contype==2)){c++}var b=StatusStrs[c];if(terminal.webRtcActive==true){b+=", WebRTC"}QH("termstatus",b);switch(a){case 0:d.m.TermResetScreen();d.m.TermDraw();if(terminal!=null){terminal.Stop();terminal=null}break;case 3:break;default:break}updateTerminalButtons()}var autoConnectTerminalTimer=null;function autoConnectTerminal(a){if(autoConnectTerminalTimer==null){autoConnectTerminalTimer=setInterval(connectTerminal,100)}else{clearInterval(autoConnectTerminalTimer);autoConnectTerminalTimer=null}}function connectTerminal(b,a){if(!terminal){if(a==2){if((terminalNode.intelamt.user==null)||(terminalNode.intelamt.user=="")){editDeviceAmtSettings(terminalNode._id,connectTerminal);return}terminal=CreateAmtRedirect(CreateAmtRemoteTerminal("Term"),authCookie);terminal.debugmode=debugmode;terminal.m.debugmode=debugmode;terminal.onStateChanged=onTerminalStateChange;terminal.Start(terminalNode._id,16994,"*","*",0);terminal.contype=2;Q("id_ttypebutton").value=terminalEmulations[terminal.m.terminalEmulation]}else{terminal=CreateAgentRedirect(meshserver,CreateAmtRemoteTerminal("Term"),serverPublicNamePort,authCookie);terminal.debugmode=debugmode;terminal.m.debugmode=debugmode;terminal.m.lineFeed=([1,2,3,4,21,22].indexOf(currentNode.agent.id)>=0)?"\r\n":"\n";terminal.attemptWebRTC=attemptWebRTC;terminal.onStateChanged=onTerminalStateChange;terminal.Start(terminalNode._id);terminal.contype=1;terminal.m.terminalEmulation=0;terminal.m.fxEmulation=0;Q("id_ttypebutton").value=terminalEmulations[0]}}else{terminal.Stop();terminal=null}Q("connectbutton2").blur()}var terminalEmulations=["UTF8 Terminal","Extended ASCII","Intel ASCII"];function termToggleType(){if(!terminal||xxdialogMode){return}terminal.m.terminalEmulation=(terminal.m.terminalEmulation+1)%3;Q("id_ttypebutton").value=terminalEmulations[terminal.m.terminalEmulation];Q("id_ttypebutton").blur()}var fxEmulations=["Intel (F10 = ESC+[OM)","Alternate (F10 = ESC+0)","VT100+ (F10 = ESC+[OY)"];function termToggleFx(){if(!terminal||xxdialogMode){return}terminal.m.fxEmulation=(terminal.m.fxEmulation+1)%3;Q("id_tfxkeysbutton").value=fxEmulations[terminal.m.fxEmulation];Q("id_tfxkeysbutton").blur()}function termToggleCr(){if(!terminal||xxdialogMode){return}if(terminal.m.lineFeed=="\n"){terminal.m.lineFeed="\r\n"}else{terminal.m.lineFeed="\n"}Q("id_tcrbutton").value=(terminal.m.lineFeed=="\r\n")?"CR+LF":"LF"}function termSendKey(b,a){if(!terminal||xxdialogMode){return}terminal.m.TermSendKey(b);Q(a).blur()}function showTermPasteDialog(){if(!terminal||xxdialogMode){return}Q("pastebutton").blur();setDialogMode(2,"Paste",3,showTermPasteDialogEx,'<textarea id=d2pasteText style="width:100%;height:184px;resize:none"></textarea>');Q("d2pasteText").focus()}function showTermPasteDialogEx(){if(!terminal){return}terminal.m.TermSendKeys(Q("d2pasteText").value)}function sendSpecialKey(){terminal.m.TermSendKey(Q("specialkeylist").value);Q("specialkeylist").blur();Q("specialkeylistinput").blur()}var filesNode;function setupFiles(){var b=(filesNode==currentNode);filesNode=currentNode;var a=((filesNode.conn&1)!=0)?true:false;QE("p13Connect",a);if(((b==false)||(a==false))&&files){files.Stop();files=null}}function onFilesStateChange(c,a){p13Connect.value=(a==0)?"Connect":"Disconnect";var b=StatusStrs[a];if(files.webRtcActive==true){b+=", WebRTC"}Q("p13Status").textContent=b;switch(a){case 0:QH("p13files","");p13filetree=null;p13filetreelocation=[];QH("p13currentpath","");QE("p13FolderUp",false);p13setActions();if(files!=null){files.Stop();files=null}break;case 3:p13targetpath="";files.sendText({action:"ls",reqid:1,path:""});break;default:break}}function CreateRemoteFiles(b){var a={protocol:5};a.onFileUpdate=b;a.xxStateChange=function(c){};a.ProcessData=function(c){a.onFileUpdate(c)};return a}var autoConnectFilesTimer=null;function autoConnectFiles(a){if(autoConnectFilesTimer==null){autoConnectFilesTimer=setInterval(connectFiles,100)}else{clearInterval(autoConnectFilesTimer);autoConnectFilesTimer=null}}function connectFiles(a){if(!files){files=CreateAgentRedirect(meshserver,CreateRemoteFiles(p13gotFiles),serverPublicNamePort,authCookie);files.attemptWebRTC=attemptWebRTC;files.onStateChanged=onFilesStateChange;files.Start(filesNode._id)}else{files.Stop();files=null}p13clipboard=p13clipboardFolder=null;p13clipboardCut=0;p13updateClipview()}var p13filetree=null;var p13targetpath=null;var p13filetreelocation=[];function p13gotFiles(b){if((b.length>0)&&(b.charCodeAt(0)!=123)){p13gotDownloadBinaryData(b);return}b=JSON.parse(decode_utf8(b));if(b.action=="download"){p13gotDownloadCommand(b);return}b.path=b.path.replace(/\//g,"\\");if((p13filetree!=null)&&(b.path==p13filetree.path)){var a=p13getCheckedNames();p13filetree=b;p13updateFiles(a)}else{var c=b.path.replace(/\//g,"\\"),d=p13targetpath.replace(/\//g,"\\");while((c.length>0)&&(c[0]=="\\")){c=c.substring(1)}while((d.length>0)&&(d[0]=="\\")){d=d.substring(1)}if((c==d)||((b.path=="\\")&&(p13targetpath==""))){p13filetree=b;p13updateFiles()}}}function p13getCheckedNames(){var b=[],a=document.getElementsByName("fd");for(var c=0;c<a.length;c++){if(a[c].checked){b.push(p13filetree.dir[a[c].value].n)}}return b}function p13updateFiles(b){var n="",o="",c="<a style=cursor:pointer onclick=p13folderup(0)>Root</a>",l="Root";var w=p13filetree.path.split("\\");p13filetreelocation=[];for(var p in w){if(w[p]!=""){p13filetreelocation.push(w[p])}}for(var p in p13filetreelocation){c+=" / <a style=cursor:pointer onclick=p13folderup("+(parseInt(p)+1)+")>"+p13filetreelocation[p]+"</a>"}var s=p13filetreelocation.join("/");var j=p13sort_files(p13filetree.dir);for(var p in j){var d=j[p],r=d.n,u;u=r;if(r.length>70){u='<span title="'+EscapeHtml(r)+'">'+EscapeHtml(r.substring(0,70))+"...</span>"}else{u=EscapeHtml(r)}r=EscapeHtml(r);var g="";if(d.d!=null){var e=new Date(d.d),g=(e.getMonth()+1)+"/"+(e.getDate())+"/"+e.getFullYear()+" "+e.toLocaleTimeString()+"&nbsp;"}var k="";if(d.s!=null){k=getFileSizeStr(d.s)}var m="";if(d.t<3){var t="",v="";m="<div class=filelist file=999><input file=999 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value='"+d.nx+"'>&nbsp;<span style=float:right title=\""+v+'">'+t+"</span><span><div class=fileIcon"+d.t+' onclick=p13folderset("'+encodeURIComponent(d.nx)+'")></div><a style=cursor:pointer onclick=p13folderset("'+encodeURIComponent(d.nx)+'")>'+u+"</a></span></div>"}else{var q=u;if(d.s>0){q='<a rel="noreferrer noopener" target="_blank" style=cursor:pointer onclick="p13downloadfile(\''+encodeURIComponent(s+"/"+r)+"','"+encodeURIComponent(r)+"',"+d.s+')">'+u+"</a>"}m="<div class=filelist file=3><input file=3 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value='"+d.nx+"'>&nbsp;<span class=fsize>"+g+"</span><span style=float:right>"+k+"</span><span><div class=fileIcon"+d.t+"></div>"+q+"</span></div>"}if(d.t<3){n+=m}else{o+=m}}QH("p13files",n+o);QH("p13currentpath",c);QE("p13FolderUp",p13filetreelocation.length!=0);if(b!=null){var a=document.getElementsByName("fd");for(var p=0;p<a.length;p++){if(b.indexOf(p13filetree.dir[a[p].value].n)>=0){a[p].checked=true}}}p13setActions()}function p13folderset(a){p13targetpath=joinPaths(p13filetree.path,p13filetree.dir[a].n).split("\\").join("/");files.sendText({action:"ls",reqid:1,path:p13targetpath})}function p13folderup(a){if(a==null){p13filetreelocation.pop()}else{while(p13filetreelocation.length>a){p13filetreelocation.pop()}}p13targetpath=p13filetreelocation.join("/");files.sendText({action:"ls",reqid:1,path:p13targetpath})}var p13sortorder;function p13sort_filename(c,d){if(c.ln>d.ln){return(1*p13sortorder)}if(c.ln<d.ln){return(-1*p13sortorder)}return 0}function p13sort_timestamp(c,d){if(c.d>d.d){return(1*p13sortorder)}if(c.d<d.d){return(-1*p13sortorder)}return 0}function p13sort_bysize(c,d){if(c.s==d.s){return p13sort_filename(c,d)}return(((c.s-d.s))*p13sortorder)}function p13sort_files(a){var c=[],d=Q("p13sortdropdown").value;for(var b in a){a[b].nx=b;if(a[b].s==null){a[b].s=0}if(a[b].n==null){a[b].n=b}a[b].ln=a[b].n.toLowerCase();c.push(a[b])}p13sortorder=1;if(d>3){p13sortorder=-1;d-=3}if(d==1){c.sort(p13sort_filename)}else{if(d==2){c.sort(p13sort_bysize)}else{if(d==3){c.sort(p13sort_timestamp)}}}return c}function p13setActions(){if(p13filetree==null){QE("p13DeleteFileButton",false);QE("p13NewFolderButton",false);QE("p13UploadButton",false);QE("p13RenameFileButton",false);QE("p13SelectAllButton",false);Q("p13SelectAllButton").value="Select All";QE("p13RefreshButton",false);QE("p13CutButton",false);QE("p13CopyButton",false);QE("p13PasteButton",false)}else{var a=p13getFileSelCount(),c=p13getFileCount(),b=p13getFileSelCount(false);var d=((currentNode.agent.id>0)&&(currentNode.agent.id<5));QE("p13DeleteFileButton",(a>0)&&((p13filetreelocation.length>0)||(d==false)));QE("p13NewFolderButton",((p13filetreelocation.length>0)||(d==false)));QE("p13UploadButton",((p13filetreelocation.length>0)||(d==false)));QE("p13RenameFileButton",(a==1)&&((p13filetreelocation.length>0)||(d==false)));QE("p13SelectAllButton",c>0);Q("p13SelectAllButton").value=(a>0?"Select None":"Select All");QE("p13RefreshButton",true);QE("p13CutButton",(a>0)&&(a==b)&&((p13filetreelocation.length>0)||(d==false)));QE("p13CopyButton",(a>0)&&(a==b)&&((p13filetreelocation.length>0)||(d==false)));QE("p13PasteButton",((p13filetreelocation.length>0)||(d==false))&&((p13clipboard!=null)&&(p13clipboard.length>0)))}}function p13getFileSelCount(d){var a=0;var b=document.getElementsByName("fd");for(var c=0;c<b.length;c++){if((b[c].checked)&&((d!=false)||(b[c].attributes.file.value=="3"))){a++}}return a}function p13getFileSelDirCount(){var a=0,b=document.getElementsByName("fd");for(var c=0;c<b.length;c++){if((b[c].checked)&&(b[c].attributes.file.value=="999")){a++}}return a}function p13getFileCount(){var a=0;var b=document.getElementsByName("fd");return b.length}function p13selectallfile(){var c=(p13getFileSelCount()==0),a=document.getElementsByName("fd");for(var b=0;b<a.length;b++){a[b].checked=c}p13setActions()}function p13createfolder(){setDialogMode(2,"New Folder",3,p13createfolderEx,"<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% />");focusTextBox("p13renameinput");p13fileNameCheck()}function p13createfolderEx(){files.sendText({action:"mkdir",reqid:1,path:p13filetreelocation.join("/")+"/"+Q("p13renameinput").value});p13folderup(999)}function p13deletefile(){var a=p13getFileSelCount(),b=(p13getFileSelDirCount()>0)?"<br /><br /><input type=checkbox id=p13recdeleteinput>Recursive delete<br>":"<input type=checkbox id=p13recdeleteinput style='display:none'>";setDialogMode(2,"Delete",3,p13deletefileEx,(a>1)?("Delete "+a+" selected items?"+b):("Delete selected item?"+b))}function p13deletefileEx(){var b=[],a=document.getElementsByName("fd");for(var c=0;c<a.length;c++){if(a[c].checked){b.push(p13filetree.dir[a[c].value].n)}}files.sendText({action:"rm",reqid:1,path:p13filetreelocation.join("/"),delfiles:b,rec:Q("p13recdeleteinput").checked});p13folderup(999)}function p13renamefile(){var c,a=document.getElementsByName("fd");for(var b=0;b<a.length;b++){if(a[b].checked){c=p13filetree.dir[a[b].value].n}}setDialogMode(2,"Rename",3,p13renamefileEx,'<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% value="'+c+'" />',{action:"rename",path:p13filetreelocation.join("/"),oldname:c});focusTextBox("p13renameinput");p13fileNameCheck()}function p13renamefileEx(a,c){c.newname=Q("p13renameinput").value;files.sendText(c);p13folderup(999)}function p13fileNameCheck(a){var b=isFilenameValid(Q("p13renameinput").value);QE("idx_dlgOkButton",b);if((b==true)&&(a!=null)&&(a.keyCode==13)){dialogclose(1)}}function p13uploadFile(){setDialogMode(2,"Upload File",3,p13uploadFileEx,"<input type=file name=files id=p13uploadinput style=width:100% multiple=multiple onchange=\"updateUploadDialogOk('p13uploadinput')\" />");updateUploadDialogOk("p13uploadinput")}function p13uploadFileEx(){p13doUploadFiles(Q("p13uploadinput").files)}var p13clipboard=null,p13clipboardFolder=null,p13clipboardCut=0;function p13copyFile(b){var a=document.getElementsByName("fd");p13clipboard=[];p13clipboardCut=b,p13clipboardFolder=p13targetpath;for(var c=0;c<a.length;c++){if((a[c].checked)&&(a[c].attributes.file.value=="3")){p13clipboard.push(p13filetree.dir[a[c].value].n)}}p13updateClipview()}function p13pasteFile(){var a="";if((p13clipboard!=null)&&(p13clipboard.length>0)){a="Confim "+(p13clipboardCut==0?"copy":"move")+" of "+p13clipboard.length+" entrie"+((p13clipboard.length>1)?"s":"")+" to this location?"}setDialogMode(2,"Paste",3,p13pasteFileEx,a)}function p13pasteFileEx(){files.sendText({action:(p13clipboardCut==0?"copy":"move"),reqid:1,scpath:p13clipboardFolder,dspath:p13targetpath,names:p13clipboard});p13folderup(999);if(p13clipboardCut==1){p13clipboard=null,p13clipboardFolder=null,p13clipboardCut=0;p13updateClipview()}}function p13updateClipview(){var a="";if((p13clipboard!=null)&&(p13clipboard.length>0)){a="Holding "+p13clipboard.length+" entrie"+((p13clipboard.length>1)?"s":"")+" for "+(p13clipboardCut==0?"copy":"move")+", <a onclick=p13clearClip() style=cursor:pointer>Clear</a>."}QH("p13bottomstatus",a);p13setActions()}function p13clearClip(){p13clipboard=null;p13clipboardFolder=null;p13clipboardCut=0;p13updateClipview()}function p13fileDragDrop(a){haltEvent(a);QV("p13bigfail",false);QV("p13bigok",false);if(a.dataTransfer==null||a.dataTransfer.files.length==0||p13filetree==null){return}p13doUploadFiles(a.dataTransfer.files)}var p13dragtimer=null;function p13fileDragOver(b){haltEvent(b);if(p13dragtimer!=null){clearTimeout(p13dragtimer);p13dragtimer=null}var a=(p13filetree!=null);QV("p13bigok",a);QV("p13bigfail",!a)}function p13fileDragLeave(a){haltEvent(a);if(a.target.id!="p13filetable"){QV("p13bigfail",false);QV("p13bigok",false)}else{p13dragtimer=setTimeout(function(){QV("p13bigfail",false);QV("p13bigok",false);p13dragtimer=null},10)}}var downloadFile;function p13downloadfile(a,b,c){if(xxdialogMode||downloadFile||!files){return}downloadFile={path:decodeURIComponent(a),file:decodeURIComponent(b),size:c,tsize:0,data:"",state:0,id:Math.random()};files.sendText({action:"download",sub:"start",id:downloadFile.id,path:downloadFile.path});setDialogMode(2,"Download File",10,p13downloadFileCancel,"<div>"+downloadFile.file+"</div><br /><progress id=d2progressBar style=width:100% value=0 max="+c+" />")}function p13downloadFileCancel(){setDialogMode(0);files.sendText({action:"download",sub:"cancel",id:downloadFile.id});downloadFile=null}function p13gotDownloadCommand(a){if((downloadFile==null)||(a.id!=downloadFile.id)){return}if(a.sub=="start"){downloadFile.state=1;files.sendText({action:"download",sub:"startack",id:downloadFile.id})}else{if(a.sub=="cancel"){downloadFile=null;setDialogMode(0)}}}function p13gotDownloadBinaryData(a){if(!downloadFile||downloadFile.state==0){return}if(a.length>4){downloadFile.tsize+=(a.length-4);downloadFile.data+=a.substring(4);Q("d2progressBar").value=downloadFile.tsize}if((ReadInt(a,0)&1)!=0){saveAs(data2blob(downloadFile.data),downloadFile.file);downloadFile=null;setDialogMode(0)}else{files.sendText({action:"download",sub:"ack",id:downloadFile.id})}}var uploadFile;function p13doUploadFiles(a){if(xxdialogMode){return}uploadFile={};uploadFile.xpath=p13filetreelocation.join("/");uploadFile.xfiles=a;uploadFile.xfilePtr=-1;setDialogMode(2,"Upload File",10,p13uploadFileCancel,"<div id=p13dfileName>Connecting...</div><br /><progress id=d2progressBar style=width:100% value=0 max=0 />");p13uploadReconnect()}function onFileUploadStateChange(b,a){switch(a){case 0:p13folderup(9999);break;case 3:p13uploadNextFile();break;default:console.log("Unknown onFileUploadStateChange state",a);break}}function p13uploadReconnect(){uploadFile.ws=CreateAgentRedirect(meshserver,CreateRemoteFiles(p13gotUploadData),serverPublicNamePort,authCookie);uploadFile.ws.attemptWebRTC=false;uploadFile.ws.ctrlMsgAllowed=false;uploadFile.ws.onStateChanged=onFileUploadStateChange;uploadFile.ws.Start(filesNode._id)}function p13uploadNextFile(){uploadFile.xfilePtr++;if(uploadFile.xfiles.length>uploadFile.xfilePtr){uploadFile.xptr=0;var a=uploadFile.xfiles[uploadFile.xfilePtr];QH("p13dfileName",a.name);Q("d2progressBar").max=a.size;Q("d2progressBar").value=0;uploadFile.xreader=new FileReader();uploadFile.xreader.onload=function(){uploadFile.xdata=uploadFile.xreader.result;uploadFile.ws.sendText(JSON.stringify({action:"upload",reqid:uploadFile.xfilePtr,path:uploadFile.xpath,name:a.name,size:uploadFile.xdata.byteLength}))};uploadFile.xreader.readAsArrayBuffer(a)}else{p13uploadFileCancel()}}function p13uploadFileCancel(a,b){if(uploadFile!=null){if(uploadFile.ws!=null){uploadFile.ws.Stop();uploadFile.ws=null}uploadFile=null}setDialogMode(0)}function p13gotUploadData(b){var a=JSON.parse(b);if((uploadFile==null)||(parseInt(uploadFile.xfilePtr)!=parseInt(a.reqid))){return}if(a.action=="uploadstart"){p13uploadNextPart(false);for(var c=0;c<8;c++){p13uploadNextPart(true)}}else{if(a.action=="uploadack"){p13uploadNextPart(false)}else{if(a.action=="uploaderror"){p13uploadFileCancel()}}}}function p13uploadNextPart(c){var a=uploadFile.xdata;var e=uploadFile.xptr;var d=uploadFile.xptr+4096;if(d>a.byteLength){if(c==true){return}d=a.byteLength}if(e==a.byteLength){if(uploadFile.ws!=null){uploadFile.ws.Stop();uploadFile.ws=null}if(uploadFile.xfiles.length>uploadFile.xfilePtr+1){p13uploadReconnect()}else{p13uploadFileCancel()}}else{var b=a.slice(e,d);uploadFile.ws.send(b);uploadFile.xptr=d;Q("d2progressBar").value=d}}var currentDeviceEvents=null;function deviceEventsUpdate(){var h="",a=null;for(var c in currentDeviceEvents){var b=currentDeviceEvents[c];var g=new Date(b.time);if(g.toLocaleDateString()!=a){if(a!=null){h+="</table>"}h+="<table style=width:100% cellpadding=0 cellspacing=0><tr><td class=DevSt colspan=4>"+g.toLocaleDateString()+"</td></tr>";a=g.toLocaleDateString()}var d="si3";if(b.etype=="user"){d="m2"}if(b.etype=="server"){d="si3"}var e=b.msg.split("(R)").join("&reg;");h+="<tr><td style=width:18px><div class="+d+"></div></td><td class=g1 style=float:none>&nbsp;</td><td style=background-color:#C9C9C9>"+g.toLocaleTimeString()+" - "+e+"</td><td class=g2 style=float:none>&nbsp;</td></tr><tr style=height:2px></tr>"}if(a!=null){h+="</table>"}if(h==""){h="<br><i>No Events Found</i><br><br>"}QH("p16events",h)}function refreshDeviceEvents(){meshserver.send({action:"events",nodeid:currentNode._id,limit:parseInt(p16limitdropdown.value)})}function agentConsoleHandleKeys(b){if((b.ctrlKey)||(b.altKey)){return true}var d=0,a=Q("p15consoleText");if(b.key){if(b.keyCode==13&&consoleFocus==0){p15consoleSend(b);d=1}else{if(b.keyCode==8&&consoleFocus==0){var g=a.value;a.value=g.substring(0,g.length-1);d=1}else{if(b.keyCode==27){a.value="";d=1}else{if((b.keyCode==38)||(b.keyCode==40)){var c=consoleHistory.indexOf(a.value);if((b.keyCode==38)&&((consoleHistory.length-1)>c)){a.value=consoleHistory[c+1]}else{if((b.keyCode==40)&&(c>0)){a.value=consoleHistory[c-1]}else{if((b.keyCode==40)&&(c==0)){a.value=""}}}d=1}else{if(b.key.length===1){insertTextAtCursor(a,b.key);d=1}}}}}}else{if(b.charCode!=0&&consoleFocus==0){a.value=((a.value+String.fromCharCode(b.charCode)));d=1}}if(d>0){return haltEvent(b)}}function insertTextAtCursor(a,d){if(document.selection){a.focus();sel=document.selection.createRange();sel.text=d}else{if(a.selectionStart||a.selectionStart=="0"){var c=a.selectionStart,b=a.selectionEnd;a.value=a.value.substring(0,c)+d+a.value.substring(b,a.value.length);a.setSelectionRange(b+1,b+1)}else{a.value+=myValue}}}var consoleNode;var consoleServerText="";function setupConsole(){if(xxcurrentView==115){var d=(consoleNode=="server");consoleNode="server";QH("p15deviceName","My Server Console");QE("p15consoleText",true);QH("p15statetext","");QH("p15coreName","");if(d==false){QH("p15agentConsoleText",consoleServerText);Q("p15agentConsoleText").scrollTop=Q("p15agentConsoleText").scrollHeight}}else{var d=(consoleNode==currentNode);consoleNode=currentNode;var a=meshes[consoleNode.meshid];var b=a.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;if((b&16)!=0){if(consoleNode.consoleText==null){consoleNode.consoleText=""}if(d==false){QH("p15agentConsoleText",consoleNode.consoleText);Q("p15agentConsoleText").scrollTop=Q("p15agentConsoleText").scrollHeight}var c=((consoleNode.conn&1)!=0)?true:false;QH("p15statetext",c?"Agent is online":"Agent is offline");QE("p15consoleText",c);QE("p15uploadCore",c)}else{QH("p15statetext","Access Denied");QE("p15consoleText",false);QE("p15uploadCore",false)}}}function p15consoleClear(){QH("p15agentConsoleText","");Q("id_p15consoleClear").blur();if(xxcurrentView==115){consoleServerText=""}else{consoleNode.consoleText=""}}var consoleHistory=[];function p15consoleSend(a){if(a&&a.keyCode!=13){return}var d=Q("p15consoleText").value,c="<div style=color:green>&gt; "+EscapeHtml(Q("p15consoleText").value)+"<br/></div>";Q("p15agentConsoleText").innerHTML+=c;Q("p15agentConsoleText").scrollTop=Q("p15agentConsoleText").scrollHeight;Q("p15consoleText").value="";if(xxcurrentView==115){consoleServerText+=c;meshserver.send({action:"serverconsole",value:d})}else{consoleNode.consoleText+=c;meshserver.send({action:"msg",type:"console",nodeid:consoleNode._id,value:d})}if(d.length>0){var b=consoleHistory.indexOf(d);if(b>=0){consoleHistory.splice(b,1)}consoleHistory.unshift(d);consoleHistory.splice(10)}}function p15consoleReceive(b,a){a="<div>"+a+"</div>";if(b==="serverconsole"){consoleServerText+=a;if(consoleNode=="server"){Q("p15agentConsoleText").innerHTML+=a;Q("p15agentConsoleText").scrollTop=Q("p15agentConsoleText").scrollHeight}}else{if(b.consoleText==null){b.consoleText=a}else{b.consoleText+=a}if(consoleNode==b){Q("p15agentConsoleText").innerHTML+=a;Q("p15agentConsoleText").scrollTop=Q("p15agentConsoleText").scrollHeight}}}function p15uploadCore(a){if(xxdialogMode){return}if(a.shiftKey==true){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"default"})}else{if(a.altKey==true){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"clear"})}else{if(a.ctrlKey==true){p15uploadCore2()}else{setDialogMode(2,"Change Mesh Agent Core",3,p15uploadCoreEx,"<select id=d3coreMode style=float:right;width:260px><option value=1>Upload default server core</option><option value=2>Clear the core</option><option value=6>Upload recovery core</option><option value=3>Upload a core file</option><option value=4>Soft disconnect agent</option><option value=5>Hard disconnect agent</option></select><div>Change Core</div>")}}}}function p15uploadCoreEx(){if(Q("d3coreMode").value==1){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"default"})}else{if(Q("d3coreMode").value==2){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"clear"})}else{if(Q("d3coreMode").value==3){p15uploadCore2()}else{if(Q("d3coreMode").value==4){meshserver.send({action:"agentdisconnect",nodeid:consoleNode._id,disconnectMode:1})}else{if(Q("d3coreMode").value==5){meshserver.send({action:"agentdisconnect",nodeid:consoleNode._id,disconnectMode:2})}else{if(Q("d3coreMode").value==6){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"recovery"})}}}}}}}function p15uploadCore2(){if(xxdialogMode){return}Q("d3localmodeform").action="uploadmeshcorefile.ashx";Q("d3attrib").value=currentNode._id;setDialogMode(3,"Upload Mesh Agent Core",3,p15uploadCoreEx2);d3init()}function p15uploadCoreEx2(){var b=Q("d3uploadMode").value;if(b==1){Q("d3submit").click()}else{var a=d3getFileSel();if(a.length==1){meshserver.send({action:"uploadagentcore",nodeid:consoleNode._id,type:"custom",path:d3filetreelocation.join("/")+"/"+a[0]})}}}function account_manageAuthApp(){if(xxdialogMode||((features&4096)==0)){return}if(userinfo.otpsecret==1){account_removeOtp()}else{account_addOtp()}}function account_addOtp(){if(xxdialogMode||(userinfo.otpsecret==1)||((features&4096)==0)){return}setDialogMode(2,"Authenticator App",2,function(){meshserver.send({action:"otpauth-setup",secret:Q("d2optsecret").attributes.secret.value,token:Q("d2otpauthinput").value})},"<div id=d2optinfo>Loading...</div>","otpauth-request");meshserver.send({action:"otpauth-request"})}function account_addOtpCheck(a){var b=(Q("d2otpauthinput").value.length==6);QE("idx_dlgOkButton",b);if(a&&(a.keyCode==13)&&b){dialogclose(1)}}function account_removeOtp(){if(xxdialogMode||(userinfo.otpsecret!=1)||((features&4096)==0)){return}setDialogMode(2,"Authenticator App",3,function(){meshserver.send({action:"otpauth-clear"})},"Confirm removal of authenticator application 2-step login?")}function account_manageOtp(a){if((xxdialogMode==2)&&(xxdialogTag=="otpauth-manage")){dialogclose(0)}if(xxdialogMode||((features&4096)==0)){return}if((userinfo.otpsecret==1)||(userinfo.otphkeys>0)){meshserver.send({action:"otpauth-getpasswords",subaction:a})}}function account_manageHardwareOtp(){if((xxdialogMode==2)&&(xxdialogTag=="otpauth-hardware-manage")){dialogclose(0)}if(xxdialogMode||((features&4096)==0)){return}meshserver.send({action:"otp-hkey-get"})}function account_addhkey(a){if(a==1){var b="Type in the name of the key to add.<br /><br />";b+=addHtmlValue("Key Name",'<input id=dp1keyname style=width:230px maxlength=20 autocomplete=off placeholder="MyKey" onkeyup=account_addhkeyValidate(event,2) />')}else{if(a==2){var b="Type in a key name, select the OTP box and press the button on the YubiKey&trade;.<br /><br />";b+=addHtmlValue("Key Name",'<input id=dp1keyname style=width:230px maxlength=20 autocomplete=off placeholder="MyKey" onkeyup=account_addhkeyValidate(event,1) />');b+=addHtmlValue("YubiKey&trade; OTP","<input id=dp1key style=width:230px autocomplete=off onkeyup=account_addhkeyValidate(event,2) />")}}setDialogMode(2,"Add Security Key",3,account_addhkeyEx,b,a);Q("dp1keyname").focus()}function account_addhkeyValidate(b,a){if((b!=null)&&(b.keyCode==13)){if(a==2){dialogclose(1)}else{Q("dp1key").focus()}}}function account_addhkeyEx(a,c){var b=Q("dp1keyname").value;if(b==""){b="MyKey"}if(c==1){meshserver.send({action:"otp-hkey-setup-request",name:b})}else{if(c==2){meshserver.send({action:"otp-hkey-yubikey-add",name:b,otp:Q("dp1key").value});setDialogMode(2,"Add Security Key",0,null,"<br />Checking...<br /><br /><br />","otpauth-hardware-manage")}}}function account_removehkey(a){meshserver.send({action:"otp-hkey-remove",index:a});meshserver.send({action:"otp-hkey-get"})}function account_showVerifyEmail(){if(xxdialogMode||(userinfo.emailVerified==true)||(serverinfo.emailcheck!=true)){return}var a="Click ok to send a verification mail to:<br /><div style=padding:8px><b>"+EscapeHtml(userinfo.email)+"</b></div>Please wait a few minute to receive the verification.";setDialogMode(2,"Email Verification",3,account_showVerifyEmailEx,a)}function account_showVerifyEmailEx(){meshserver.send({action:"verifyemail",email:userinfo.email})}function account_showChangeEmail(){if(xxdialogMode){return}var a="Change your account email address here.<br /><br />";a+=addHtmlValue("Email","<input id=dp2email style=width:230px maxlength=256 onchange=account_validateEmail() onkeyup=account_validateEmail(event) />");setDialogMode(2,"Email Address Change",3,account_changeEmail,a);if(userinfo.email!=null){Q("dp2email").value=userinfo.email}account_validateEmail();Q("dp2email").focus()}function account_validateEmail(a,b){QE("idx_dlgOkButton",validateEmail(Q("dp2email").value)&&(Q("dp2email").value!=userinfo.email));if((a!=null)&&(a.keyCode==13)){dialogclose(1)}}function account_changeEmail(){meshserver.send({action:"changeemail",email:Q("dp2email").value})}function account_showDeleteAccount(){if(xxdialogMode){return}var a="To delete this account, type in the account password in both boxes below and hit ok.<br /><br />";a+="<form action='"+domainUrl+"deleteaccount' method=post><table style=margin-left:80px><tr>";a+="<td align=right>Password:</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateDeleteAccount() onkeyup=account_validateDeleteAccount() /></td>";a+="</tr><tr><td align=right>Password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateDeleteAccount() onkeyup=account_validateDeleteAccount() /></td>";a+="</tr></table><br /><div style=padding:10px;margin-bottom:4px>";a+="<input id=account_dlgCancelButton type=button value=Cancel style=float:right;width:80px;margin-left:5px onclick=dialogclose(0)>";a+='<input id=account_dlgOkButton type=submit value=OK style="float:right;width:80px" onclick=dialogclose(1)>';a+="</div><br /></form>";setDialogMode(2,"Delete Account",0,null,a);account_validateDeleteAccount();Q("apassword1").focus()}function account_showChangePassword(){if(xxdialogMode){return}var d="Change your account password by entering the old password and new password twice in the boxes below. Password hint can be used but is not recommanded.<br /><br />";d+="<table style=margin-left:60px>";d+="<tr><td align=right>Old password:</td><td><input id=apassword0 type=password name=apassword0 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b></b></td></tr>";d+="<tr><td align=right>New password:</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b><span id=dxPassWarn></span></b></td></tr>";d+="<tr><td align=right>New password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td></tr>";if(features&65536){d+="<tr><td align=right>Password hint:</td><td><input id=apasswordhint name=apasswordhint maxlength=250 type=text autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td></tr>"}d+="</table>";if(passRequirements){var b=[],c=0;for(var a in passRequirements){if((a!="reset")&&(a!="hint")){b.push(a+":"+passRequirements[a]);c++}}if(c>0){d+="<br /><span style=font-size:x-small>Requirements: "+b.join(", ")+".</span>"}}d+="<br />";setDialogMode(2,"Change Password",3,account_showChangePasswordEx,d);Q("apassword0").focus();account_validateNewPassword()}function account_showChangePasswordEx(){if(Q("apassword1").value==Q("apassword2").value){var a={action:"changepassword",oldpass:Q("apassword0").value,newpass:Q("apassword1").value};if(features&65536){a.hint=Q("apasswordhint").value}meshserver.send(a)}}function account_createMesh(){if(xxdialogMode){return}if((userinfo.emailVerified!==true)&&(serverinfo.emailcheck==true)&&(userinfo.siteadmin!=4294967295)){setDialogMode(2,"New Device Group",1,null,'Unable to create a new device group until a email address is verified. This is required for password recovery. Go to the "My Account" tab to change and verify an email address.');return}var a="Create a new device group using the options below.<br /><br />";a+=addHtmlValue("Name","<input id=dp2meshname style=width:230px maxlength=64 onchange=account_validateMeshCreate() onkeyup=account_validateMeshCreate() />");a+=addHtmlValue("Type","<div style=width:230px;margin:0;padding:0><select id=dp2meshtype style=width:100% onchange=account_validateMeshCreate() ><option value=2>Manage using a software agent</option><option value=1>Intel&reg; AMT only, no agent</option></select></div>");a+=addHtmlValue("Description","<div style=width:230px;margin:0;padding:0><textarea id=dp2meshdesc maxlength=1024 style=width:100%;resize:none></textarea></div>");setDialogMode(2,"New Device Group",3,account_createMeshEx,a);account_validateMeshCreate();Q("dp2meshname").focus()}function account_validateMeshCreate(){QE("idx_dlgOkButton",Q("dp2meshname").value.length>0)}function account_createMeshEx(a,b){meshserver.send({action:"createmesh",meshname:Q("dp2meshname").value,meshtype:Q("dp2meshtype").value,desc:Q("dp2meshdesc").value})}function account_validateDeleteAccount(){QE("account_dlgOkButton",(Q("apassword1").value.length>0)&&(Q("apassword1").value==Q("apassword2").value))}function account_validateNewPassword(){var d="",a=(Q("apassword0").value.length>0)&&(Q("apassword1").value.length>0)&&(Q("apassword1").value==Q("apassword2").value)&&(Q("apassword0").value!=Q("apassword1").value)&&(Q("apasswordhint").value!=Q("apassword1").value);if(Q("apassword1").value!=""){if(passRequirements==null||passRequirements==""){var c=checkPasswordStrength(Q("apassword1").value);if(c>=80){d="<span style=color:green>Strong<span>"}else{if(c>=60){d="<span style=color:blue>Good<span>"}else{d="<span style=color:red>Weak<span>"}}}else{var b=checkPasswordRequirements(Q("apassword1").value,passRequirements);if(b==false){a=false;d="<span style=color:red>Policy<span>"}}}QH("dxPassWarn",d);QE("idx_dlgOkButton",a)}function checkPasswordStrength(e){var g=0,d={},h=0,j={digits:/\d/.test(e),lower:/[a-z]/.test(e),upper:/[A-Z]/.test(e),nonWords:/\W/.test(e)};if(!e){return 0}for(var b=0;b<e.length;b++){d[e[b]]=(d[e[b]]||0)+1;g+=5/d[e[b]]}for(var a in j){h+=(j[a]==true)?1:0}return parseInt(g+(h-1)*10)}function checkPasswordRequirements(e,g){if((g==null)||(g=="")||(typeof g!="object")){return true}if(g.min){if(e.length<g.min){return false}}if(g.max){if(e.length>g.max){return false}}var d=0,b=0,h=0,c=0;for(var a=0;a<e.length;a++){if(/\d/.test(e[a])){d++}if(/[a-z]/.test(e[a])){b++}if(/[A-Z]/.test(e[a])){h++}if(/\W/.test(e[a])){c++}}if(g.num&&(d<g.num)){return false}if(g.lower&&(b<g.lower)){return false}if(g.upper&&(h<g.upper)){return false}if(g.nonalpha&&(c<g.nonalpha)){return false}return true}function updateMeshes(){var e="";var a=0,b=0;for(i in meshes){if(a>1){e+="</tr><tr>";a=0}a++;b++;var d=0;if(meshes[i].links["user/"+domain+"/"+userinfo.name.toLowerCase()]){d=meshes[i].links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights}var g="Partial Rights";if(d==4294967295){g="Full Administrator"}else{if(d==0){g="No Rights"}}e+="<div onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=display:inline-block;width:431px;height:50px;padding-top:1px;padding-bottom:1px;float:left><div style=float:left;width:30px;height:100%></div><div style=height:100%;cursor:pointer onclick=gotoMesh('"+i+"')><div class=mi style=float:left;width:50px;height:50px></div><div style=height:100%><div class=g1></div><div class=e2 style=width:300px><div class=e1>"+EscapeHtml(meshes[i].name)+"</div><div>"+g+"</div></div><div class=g2 style=float:left></div></div></div></div>"}meshcount=b;QH("p2meshes",e);QV("p2noMeshFound",b==0)}function gotoMesh(a){currentMesh=meshes[a];p20updateMesh();go(20)}function server_showRestoreDlg(){if(xxdialogMode){return}var a="Restore the server using a backup, <span style=color:red>this will delete the existing server data</span>. Only do this if you know what you are doing.<br /><br />";a+='<form action="/restoreserver.ashx" enctype="multipart/form-data" method="post"><div>';a+='<input id=account_dlgFileInput type=file name=datafile style=width:100% accept=".zip,application/octet-stream,application/zip,application/x-zip,application/x-zip-compressed" onchange=account_validateServerRestore()>';a+="<input id=account_dlgCancelButton type=button value=Cancel style=float:right;width:80px;margin-left:5px onclick=dialogclose(0)>";a+="<input id=account_dlgOkButton type=submit value=OK style=float:right;width:80px onclick=dialogclose(1)>";a+="</div><br /><br /></form>";setDialogMode(2,"Restore Server",0,null,a);account_validateServerRestore()}function account_validateServerRestore(){QE("account_dlgOkButton",Q("account_dlgFileInput").files.length==1)}function server_showVersionDlg(){if(xxdialogMode){return}setDialogMode(2,"MeshCentral Version",1,null,"Loading...","MeshCentralServerUpdate");meshserver.send({action:"serverversion"})}function server_showVersionDlgUpdate(){QE("idx_dlgOkButton",Q("d2updateCheck").checked)}function server_showVersionDlgEx(){meshserver.send({action:"serverupdate"})}function server_showErrorsDlg(){if(xxdialogMode){return}setDialogMode(2,"MeshCentral Errors",1,null,"Loading...","MeshCentralServerErrors");meshserver.send({action:"servererrors"})}function server_showErrorsDlgUpdate(){QE("idx_dlgOkButton",Q("d2updateCheck").checked)}function server_showErrorsDlgEx(){meshserver.send({action:"serverclearerrorlog"})}var currentMesh;function p20updateMesh(){if(currentMesh==null){return}QH("p20meshName",EscapeHtml(currentMesh.name));var j="Unknown #"+currentMesh.mtype;var h=0;try{h=currentMesh.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights}catch(c){}if(currentMesh.mtype==1){j="Intel&reg; AMT only, no agent"}if(currentMesh.mtype==2){j="Managed using a software agent"}var o="";o+=addHtmlValue("Name",addLinkConditional(EscapeHtml(currentMesh.name),"p20editmesh(1)",(h&1)!=0));o+=addHtmlValue("Description",addLinkConditional(((currentMesh.desc&&currentMesh.desc!="")?EscapeHtml(currentMesh.desc):"<i>None</i>"),"p20editmesh(2)",(h&1)!=0));var g=[];if(currentMesh.flags){if(currentMesh.flags&1){g.push("Auto-Remove")}}g=g.join(", ");if(g==""){g="<i>None</i>"}o+=addHtmlValue("Features",addLinkConditional(g,"p20editmeshfeatures()",(h&1)!=0));o+=addHtmlValue("Type",j);if(currentMesh.mtype==2){var e="No Policy";if(currentMesh.amt){if(currentMesh.amt.type==1){e="Deactivate Client Control Mode (CCM)"}else{if(currentMesh.amt.type==2){e="Simple Client Control Mode (CCM)";if(currentMesh.amt.cirasetup==2){e+=" + CIRA"}}}}o+=addHtmlValue("Intel&reg; AMT",addLinkConditional(e,"p20editMeshAmt()",(h&4294967295)!=0))}if(h&1){o+='<br><input type=button value=Notes title="View notes about this device group" onclick=showNotes(false,"'+encodeURIComponent(currentMesh._id)+'") />'}o+="<br style=clear:both><br>";var b=currentMesh.links["user/"+domain+"/"+userinfo.name.toLowerCase()];if(b&&((b.rights&2)!=0)){o+="<a onclick=p20showAddMeshUserDialog() style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> Add User</a>"}if((h&4)!=0){if(currentMesh.mtype==1){o+='<a onclick=addCiraDeviceToMesh("'+currentMesh._id+'") style=cursor:pointer;margin-right:10px title="Add a new Intel&reg; AMT computer that is located on the internet."><img src=images/icon-installmesh.png border=0 height=12 width=12> Install CIRA</a>';o+='<a onclick=addDeviceToMesh("'+currentMesh._id+'") style=cursor:pointer;margin-right:10px title="Add a new Intel&reg; AMT computer that is located on the local network."><img src=images/icon-installmesh.png border=0 height=12 width=12> Install local</a>'}if(currentMesh.mtype==2){o+='<a onclick=addAgentToMesh("'+currentMesh._id+'") style=cursor:pointer;margin-right:10px title="Add a new computer to this mesh by installing the mesh agent."><img src=images/icon-addnew.png border=0 height=12 width=12> Install</a>';if(features&64){o+='<a onclick=inviteAgentToMesh("'+currentMesh._id+'") style=cursor:pointer;margin-right:10px title="Invite someone to install the mesh agent on this mesh."><img src=images/icon-addnew.png border=0 height=12 width=12> Invite</a>'}}}o+='<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:left;width:430px>User Authorizations</th><th scope=col style=text-align:left></th></tr>';var a=1,m=[];for(var d in currentMesh.links){m.push({id:d,name:d.split("/")[2],rights:currentMesh.links[d].rights})}m.sort(function(p,q){if(p.name>q.name){return 1}if(p.name<q.name){return -1}return 0});for(var d in m){var n="",l="Partial Rights",k=m[d].rights;if(k==4294967295){l="Full Administrator"}else{if(k==0){l="No Rights"}}if((d!=userinfo._id)&&(h==4294967295||(((h&2)!=0)))){n='<a onclick=p20deleteUser(event,"'+encodeURIComponent(m[d].id)+'") title="Remote user rights to this mesh" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>'}o+='<tr onclick=p20viewuser("'+encodeURIComponent(m[d].id)+'") style=cursor:pointer'+(((a%2)==0)?";background-color:#DDD":"")+'><td><div title="User" class=m2></div><div>&nbsp;'+EscapeHtml(decodeURIComponent(m[d].name))+"<div></div></div></td><td><div style=float:right>"+n+"</div><div>"+l+"</div></td></tr>";++a}o+="</tbody></table>";if(h==4294967295){o+="<div style=font-size:x-small;text-align:right><span><a onclick=p20showDeleteMeshDialog() style=cursor:pointer>Delete Group</a></span></div>"}QH("p20info",o)}function p20editMeshAmt(){if(xxdialogMode){return}var a="";a+=addHtmlValue("Type","<select id=dp20amtpolicy style=width:230px onchange=p20editMeshAmtChange()><option value=0>No Policy</option><option value=1>Deactivate Client Control Mode (CCM)</option><option value=2>Simple Client Control Mode (CCM)</option></select>");a+="<div id=dp20amtpolicydiv></div>";setDialogMode(2,"Intel&reg; AMT Policy",3,p20editMeshAmtEx,a);if(currentMesh.amt){Q("dp20amtpolicy").value=currentMesh.amt.type}p20editMeshAmtChange();if(currentMesh.amt&&currentMesh.amt.type==2){Q("dp20amtpolicypass").value=currentMesh.amt.password;Q("dp20amtbadpass").value=currentMesh.amt.badpass;if((features&1024)==0){Q("dp20amtcira").value=currentMesh.amt.cirasetup}}dp20amtValidatePolicy()}function p20editMeshAmtChange(){var a=Q("dp20amtpolicy").value,b="";if(a==2){b=addHtmlValue("Password*","<input id=dp20amtpolicypass style=width:230px maxlength=32 onchange=dp20amtValidatePolicy() onkeyup=dp20amtValidatePolicy() />");b+=addHtmlValue("Password mismatch","<select id=dp20amtbadpass style=width:230px><option value=0>Do nothing</option><option value=1>Reactivate Intel&reg; AMT</option></select>");if((features&1024)==0){b+=addHtmlValue('<span title="Client Initiated Remote Access">CIRA</span>',"<select id=dp20amtcira style=width:230px><option value=0>Don't configure</option><option value=1>Don't connect to server</option><option value=2>Connect to server</option></select>")}b+='<br/><span style="font-size:10px">* Recommanded, leave blank to assign a random password to each device.</span><br/>';b+='<span style="font-size:10px">This policy will not impact devices with Intel&reg; AMT in ACM mode.</span><br/>';b+='<span style="font-size:10px">This is not a secure policy as agents will be performing activation.</span>'}QH("dp20amtpolicydiv",b)}function dp20amtValidatePolicy(){var a=true,c=Q("dp20amtpolicy").value;if(c==2){var b=Q("dp20amtpolicypass").value;a=(b=="")?true:passwordcheck(b)}QE("idx_dlgOkButton",a)}function p20editMeshAmtEx(){var b=parseInt(Q("dp20amtpolicy").value),a={type:b};if(b==2){a={type:b,password:Q("dp20amtpolicypass").value,badpass:parseInt(Q("dp20amtbadpass").value)};if((features&1024)==0){a.cirasetup=parseInt(Q("dp20amtcira").value)}else{a.cirasetup=1}}meshserver.send({action:"meshamtpolicy",meshid:currentMesh._id,amtpolicy:a})}function p20showDeleteMeshDialog(){if(xxdialogMode){return}var a='Are you sure you want to delete group "'+EscapeHtml(currentMesh.name)+'"? Deleting the device group will also delete all information about devices within this group.<br /><br />';a+="<input id=p20check type=checkbox onchange=p20validateDeleteMeshDialog() />Confirm";setDialogMode(2,"Delete Group",3,p20showDeleteMeshDialogEx,a);p20validateDeleteMeshDialog()}function p20validateDeleteMeshDialog(){QE("idx_dlgOkButton",Q("p20check").checked)}function p20showDeleteMeshDialogEx(a,b){meshserver.send({action:"deletemesh",meshid:currentMesh._id,meshname:currentMesh.name})}function p20editmesh(a){if(xxdialogMode){return}var b=addHtmlValue("Name","<input id=dp20meshname style=width:230px maxlength=32 onchange=p20editmeshValidate() onkeyup=p20editmeshValidate() />");b+=addHtmlValue("Description","<div style=width:230px;margin:0;padding:0><textarea id=dp20meshdesc maxlength=1024 style=width:100%;resize:none></textarea></div>");setDialogMode(2,"Edit Device Group",3,p20editmeshEx,b);Q("dp20meshname").value=currentMesh.name;if(currentMesh.desc){Q("dp20meshdesc").value=currentMesh.desc}p20editmeshValidate();if(a==2){Q("dp20meshdesc").focus()}else{Q("dp20meshname").focus()}}function p20editmeshEx(){meshserver.send({action:"editmesh",meshid:currentMesh._id,meshname:Q("dp20meshname").value,desc:Q("dp20meshdesc").value})}function p20editmeshValidate(){QE("idx_dlgOkButton",Q("dp20meshname").value.length>0)}function p20editmeshfeatures(){if(xxdialogMode){return}var a=(currentMesh.flags)?currentMesh.flags:0;var b="<div><input type=checkbox id=d20flag1 "+((a&1)?"checked":"")+">Remove device on disconnect<br></div>";setDialogMode(2,"Edit Device Group Features",3,p20editmeshfeaturesEx,b)}function p20editmeshfeaturesEx(){var a=0;if(Q("d20flag1").checked){a+=1}meshserver.send({action:"editmesh",meshid:currentMesh._id,flags:a})}function p20showAddMeshUserDialog(){if(xxdialogMode){return}var a="Allow a user to manage this device group and devices in this group<br /><br />";a+=addHtmlValue("User Name","<input id=dp20username style=width:230px maxlength=32 onchange=p20validateAddMeshUserDialog() onkeyup=p20validateAddMeshUserDialog() />");a+='<br><div style="height:120px;overflow-y:scroll;border:1px solid gray">';a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20fulladmin>Full Administrator<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20editmesh>Edit Device Group<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20manageusers>Manage Device Group Users<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20managecomputers>Manage Device Group Computers<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotecontrol>Remote Control<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remoteview style=margin-left:12px>Remote View Only<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotelimitedinput style=margin-left:12px>Limited Input Only<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20noterminal style=margin-left:12px>No Terminal Access<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20nofiles style=margin-left:12px>No File Access<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20noamt style=margin-left:12px>No Intel&reg; AMT<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshagentconsole>Mesh Agent Console<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshserverfiles>Server Files<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20wakedevices>Wake Devices<br>";a+="<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20editnotes>Edit Device Notes<br>";a+="</div>";setDialogMode(2,"Add User to Device Group",3,p20showAddMeshUserDialogEx,a);p20validateAddMeshUserDialog();Q("dp20username").focus()}function p20validateAddMeshUserDialog(){var a=currentMesh.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights;QE("idx_dlgOkButton",(Q("dp20username").value.length>0));QE("p20fulladmin",a==4294967295);QE("p20editmesh",(!Q("p20fulladmin").checked)&&(a==4294967295));QE("p20manageusers",!Q("p20fulladmin").checked);QE("p20managecomputers",!Q("p20fulladmin").checked);QE("p20remotecontrol",!Q("p20fulladmin").checked);QE("p20meshagentconsole",!Q("p20fulladmin").checked);QE("p20meshserverfiles",!Q("p20fulladmin").checked);QE("p20wakedevices",!Q("p20fulladmin").checked);QE("p20editnotes",!Q("p20fulladmin").checked);QE("p20remoteview",!Q("p20fulladmin").checked&&Q("p20remotecontrol").checked);QE("p20remotelimitedinput",!Q("p20fulladmin").checked&&Q("p20remotecontrol").checked&&!Q("p20remoteview").checked);QE("p20noterminal",!Q("p20fulladmin").checked&&Q("p20remotecontrol").checked);QE("p20nofiles",!Q("p20fulladmin").checked&&Q("p20remotecontrol").checked);QE("p20noamt",!Q("p20fulladmin").checked&&Q("p20remotecontrol").checked)}function p20showAddMeshUserDialogEx(){var a=0;if(Q("p20fulladmin").checked==true){a=4294967295}else{if(Q("p20editmesh").checked==true){a+=1}if(Q("p20manageusers").checked==true){a+=2}if(Q("p20managecomputers").checked==true){a+=4}if(Q("p20remotecontrol").checked==true){a+=8}if(Q("p20meshagentconsole").checked==true){a+=16}if(Q("p20meshserverfiles").checked==true){a+=32}if(Q("p20wakedevices").checked==true){a+=64}if(Q("p20editnotes").checked==true){a+=128}if(Q("p20remoteview").checked==true){a+=256}if(Q("p20noterminal").checked==true){a+=512}if(Q("p20nofiles").checked==true){a+=1024}if(Q("p20noamt").checked==true){a+=2048}if(Q("p20remotelimitedinput").checked==true){a+=4096}}meshserver.send({action:"addmeshuser",meshid:currentMesh._id,meshname:currentMesh.name,username:Q("dp20username").value,meshadmin:a})}function p20viewuser(e){if(xxdialogMode){return}e=decodeURIComponent(e);var d="",b=currentMesh.links["user/"+domain+"/"+userinfo.name.toLowerCase()].rights,c=currentMesh.links[e].rights;if(c==4294967295){d=", Full Administrator (all rights)"}else{if((c&1)!=0){d+=", Edit Device Group"}if((c&2)!=0){d+=", Manage Device Group Users"}if((c&4)!=0){d+=", Manage Device Group Computers"}if((c&8)!=0){d+=", Remote Control"}if((c&16)!=0){d+=", Agent Console"}if((c&32)!=0){d+=", Server Files"}if((c&64)!=0){d+=", Wake Devices"}if((c&128)!=0){d+=", Edit Notes"}if(((c&8)!=0)&&(c&256)!=0){d+=", Remote View Only"}if(((c&8)!=0)&&(c&512)!=0){d+=", No Terminal"}if(((c&8)!=0)&&(c&1024)!=0){d+=", No Files"}if(((c&8)!=0)&&(c&2048)!=0){d+=", No Intel&reg; AMT"}if(((c&8)!=0)&&((c&4096)!=0)&&((c&256)==0)){d+=", Limited Input"}}d=d.substring(2);if(d==""){d="No Rights"}var a=1,g=addHtmlValue("User Name",EscapeHtml(decodeURIComponent(e.split("/")[2])));g+=addHtmlValue("Permissions",d);if((("user/"+domain+"/"+userinfo.name.toLowerCase())!=e)&&(b==4294967295||(((b&2)!=0)&&(c!=4294967295)))){a+=4}setDialogMode(2,"Device Group User",a,p20viewuserEx,g,e)}function p20viewuserEx(a,b){if(a!=2){return}setDialogMode(2,"Remote Mesh User",3,p20viewuserEx2,"Confirm removal of user "+b.split("/")[2]+"?",b)}function p20deleteUser(a,b){haltEvent(a);p20viewuserEx(2,decodeURIComponent(b))}function p20viewuserEx2(a,b){meshserver.send({action:"removemeshuser",meshid:currentMesh._id,meshname:currentMesh.name,userid:b})}var filetreelinkpath;var filetreelocation=[];function updateFiles(){QV("MainMenuMyFiles",((features&8)==0));if((features&8)!=0){return}var q="",r="",c="<a style=cursor:pointer onclick=p5folderup(0)>Root</a>",o="Root",y,k=filetree,m=1;var j=[],v=filetreelinkpath,b=[],a=document.getElementsByName("fc");for(var s=0;s<a.length;s++){if(a[s].checked){b.push(a[s].value)}}filetreelinkpath="";for(var s in filetreelocation){if((k.f!=null)&&(k.f[filetreelocation[s]]!=null)){j.push(filetreelocation[s]);o+=" / "+filetreelocation[s];if((m==1)){var B=filetreelocation[s].split("/");y=window.location+B[0]+"files/"+B[2];filetreelinkpath+=filetreelocation[s]}else{if(filetreelinkpath!=""){filetreelinkpath+="/"+filetreelocation[s];if(m>2){y+="/"+filetreelocation[s]}}}k=k.f[filetreelocation[s]];c+=" / <a style=cursor:pointer onclick=p5folderup("+m+")>"+(k.n!=null?k.n:filetreelocation[s])+"</a>";m++}else{break}}filetreelocation=j;var w=o.toLowerCase().startsWith("root / "+userinfo._id+" / public");var l=p5sort_files(k.f);for(var s in l){var d=l[s],u=d.n,A;A=u;if(u.length>70){A='<span title="'+EscapeHtml(u)+'">'+EscapeHtml(u.substring(0,70))+"...</span>"}else{A=EscapeHtml(u)}u=EscapeHtml(u);var g="";if(d.d!=null){var e=new Date(d.d),g=(e.getMonth()+1)+"/"+(e.getDate())+"/"+e.getFullYear()+" "+e.toLocaleTimeString()+"&nbsp;"}var n="";if(d.s!=null){n=getFileSizeStr(d.s)}var p="";if(d.t<3||d.t==4){var z=(d.t==1||d.t==4)?p5getQuotabar(d):"",C="";p="<div class=filelist file=999><input file=999 style=float:left name=fc class=fcb type=checkbox onchange=p5setActions() value='"+u+"'>&nbsp;<span style=float:right title=\""+C+'">'+z+"</span><span><div class=fileIcon"+d.t+' onclick=p5folderset("'+encodeURIComponent(d.nx)+'")></div><a style=cursor:pointer onclick=p5folderset("'+encodeURIComponent(d.nx)+'")>'+A+"</a></span></div>"}else{var t=A;var x="";if(w){x=' (<a style=cursor:pointer title="Display public link" onclick=\'p5showPublicLink("'+y+"/"+d.nx+"\")'>Link</a>)"}if(d.s>0){t='<a rel="noreferrer noopener" target="_blank" href="downloadfile.ashx?link='+encodeURIComponent(filetreelinkpath+"/"+d.nx)+'">'+A+"</a>"+x}p="<div class=filelist file=3><input file=3 style=float:left name=fc class=fcb type=checkbox onchange=p5setActions() value='"+d.nx+"'>&nbsp;<span class=fsize>"+g+"</span><span style=float:right>"+n+"</span><span><div class=fileIcon"+d.t+"></div>"+t+"</span></div>"}if(d.t<3){q+=p}else{r+=p}}QH("p5rightOfButtons",p5getQuotabar(k));QH("p5files",q+r);QH("p5currentpath",c);QE("p5FolderUp",filetreelocation.length!=0);QV("p5PublicShare",w);if(v==filetreelinkpath){a=document.getElementsByName("fc");for(var s=0;s<a.length;s++){a[s].checked=(b.indexOf(a[s].value)>=0)}}p5setActions()}function getNiceSize(a){if(a<=0){return"Storage limit exceed"}if(a<2048){return a+" bytes remaining"}if(a<2097152){return Math.round(a/1024)+" kilobytes remaining"}if(a<2147483648){return Math.round(a/1024/1024)+" megabytes remaining"}return Math.round(a/1024/1024/1024)+" gigabytes remaining"}function getNiceSize2(a){if(a<=0){return"None"}if(a<2048){return a+" b"}if(a<2097152){return Math.round(a/1024)+" Kb"}if(a<2147483648){return Math.round(a/1024/1024)+" Mb"}return Math.round(a/1024/1024/1024)+" Gb"}function p5getQuotabar(a){while(a.t>1&&a.t!=4){a=a.parent}if((a.t!=1&&a.t!=4)||(a.maxbytes==null)){return""}var b=Math.floor(a.s/1024),c=(a.maxbytes-a.s);return'<span title="'+b+"k in "+a.c+" file"+(a.c>1?"s":"")+". "+(Math.floor(a.maxbytes/1024/1024))+'k maxinum">'+getNiceSize(c)+" <progress style=height:10px;width:100px value="+a.s+" max="+a.maxbytes+" /></span>"}function p5showPublicLink(a){setDialogMode(2,"Public Link",1,null,'<input type=text style=width:100% value="'+a+'" readonly />')}var sortorder;function p5sort_filename(c,d){if(c.ln>d.ln){return(1*sortorder)}if(c.ln<d.ln){return(-1*sortorder)}return 0}function p5sort_timestamp(c,d){if(c.d>d.d){return(1*sortorder)}if(c.d<d.d){return(-1*sortorder)}return 0}function p5sort_bysize(c,d){if(c.s==d.s){return p5sort_filename(c,d)}return(((c.s-d.s))*sortorder)}function p5sort_files(a){var c=[],d=Q("p5sortdropdown").value;for(var b in a){a[b].nx=b;if(a[b].n==null){a[b].n=b}a[b].ln=a[b].n.toLowerCase();c.push(a[b])}sortorder=1;if(d>3){sortorder=-1;d-=3}if(d==1){c.sort(p5sort_filename)}else{if(d==2){c.sort(p5sort_bysize)}else{if(d==3){c.sort(p5sort_timestamp)}}}return c}function p5setActions(){var a=getFileSelCount(),c=getFileCount(),b=getFileSelCount(false);QE("p5DeleteFileButton",(a>0)&&(filetreelocation.length>0));QE("p5NewFolderButton",filetreelocation.length>0);QE("p5UploadButton",filetreelocation.length>0);QE("p5RenameFileButton",(a==1)&&(filetreelocation.length>0));QE("p5SelectAllButton",c>0);Q("p5SelectAllButton").value=(a>0?"Select None":"Select All");QE("p5CutButton",(b>0)&&(a==b));QE("p5CopyButton",(b>0)&&(a==b));QE("p5PasteButton",(p5clipboard!=null)&&(p5clipboard.length>0)&&(filetreelocation.length>0))}function getFileSelCount(d){var a=0,b=document.getElementsByName("fc");for(var c=0;c<b.length;c++){if((b[c].checked)&&((d!=false)||(b[c].attributes.file.value=="3"))){a++}}return a}function getFileSelDirCount(){var a=0,b=document.getElementsByName("fc");for(var c=0;c<b.length;c++){if((b[c].checked)&&(b[c].attributes.file.value=="999")){a++}}return a}function getFileCount(){var a=0;var b=document.getElementsByName("fc");return b.length}function p5selectallfile(){var c=(getFileSelCount()==0),a=document.getElementsByName("fc");for(var b=0;b<a.length;b++){a[b].checked=c}p5setActions()}function setupBackPointers(d){if(d.f!=null){var b=0,a=0;for(var c in d.f){setupBackPointers(d.f[c]);d.f[c].parent=d;if(d.f[c].s){b+=d.f[c].s}if(d.f[c].c){a+=d.f[c].c}if(d.f[c].t==3){a++}}d.s=b;d.c=a}return d}function getFileSizeStr(a){if(a==1){return"1 byte"}return""+a+" bytes"}function p5folderup(a){if(a==null){filetreelocation.pop()}else{while(filetreelocation.length>a){filetreelocation.pop()}}updateFiles()}function p5folderset(a){filetreelocation.push(decodeURIComponent(a));updateFiles()}function p5createfolder(){setDialogMode(2,"New Folder",3,p5createfolderEx,"<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% />");focusTextBox("p5renameinput");p5fileNameCheck()}function p5createfolderEx(){meshserver.send({action:"fileoperation",fileop:"createfolder",path:filetreelocation,newfolder:Q("p5renameinput").value})}function p5deletefile(){var a=getFileSelCount(),b=(getFileSelDirCount()>0)?"<br /><br /><input type=checkbox id=p5recdeleteinput>Recursive delete<br>":"<input type=checkbox id=p5recdeleteinput style='display:none'>";setDialogMode(2,"Delete",3,p5deletefileEx,(a>1)?("Delete "+a+" selected items?"+b):("Delete selected item?"+b))}function p5deletefileEx(){var b=[],a=document.getElementsByName("fc");for(var c=0;c<a.length;c++){if(a[c].checked){b.push(a[c].value)}}meshserver.send({action:"fileoperation",fileop:"delete",path:filetreelocation,delfiles:b,rec:Q("p5recdeleteinput").checked})}function p5renamefile(){var c,a=document.getElementsByName("fc");for(var b=0;b<a.length;b++){if(a[b].checked){c=a[b].value}}setDialogMode(2,"Rename",3,p5renamefileEx,'<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% value="'+c+'" />',{action:"fileoperation",fileop:"rename",path:filetreelocation,oldname:c});focusTextBox("p5renameinput");p5fileNameCheck()}function p5renamefileEx(a,c){c.newname=Q("p5renameinput").value;meshserver.send(c)}function p5fileNameCheck(a){var b=isFilenameValid(Q("p5renameinput").value);QE("idx_dlgOkButton",b);if((b==true)&&(a&&a.keyCode==13)){dialogclose(1)}}var isFilenameValid=(function(){var b=/^[^\\/:\*\?"<>\|]+$/,c=/^\./,d=/^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i;return function a(e){return b.test(e)&&!c.test(e)&&!d.test(e)&&(e[0]!=".")}})();function p5uploadFile(){setDialogMode(2,"Upload File",3,p5uploadFileEx,'<form method=post enctype=multipart/form-data action=uploadfile.ashx target=fileUploadFrame><input type=text name=link style=display:none id=p5uploadpath value="'+encodeURIComponent(filetreelinkpath)+'" /><input type=file name=files id=p5uploadinput style=width:100% multiple=multiple onchange="updateUploadDialogOk(\'p5uploadinput\')" /><input type=submit id=p5loginSubmit style=display:none /></form>');updateUploadDialogOk("p5uploadinput")}function p5uploadFileEx(){Q("p5loginSubmit").click()}function updateUploadDialogOk(a){QE("idx_dlgOkButton",Q(a).value!="")}var p5clipboard=null,p5clipboardFolder=null,p5clipboardCut=0;function p5copyFile(b){var a=document.getElementsByName("fc");p5clipboard=[];p5clipboardCut=b,p5clipboardFolder=Clone(filetreelocation);for(var c=0;c<a.length;c++){if((a[c].checked)&&(a[c].attributes.file.value=="3")){p5clipboard.push(a[c].value)}}p5updateClipview()}function p5pasteFile(){var a="";if((p5clipboard!=null)&&(p5clipboard.length>0)){a="Confim "+(p5clipboardCut==0?"copy":"move")+" of "+p5clipboard.length+" entrie"+((p5clipboard.length>1)?"s":"")+" to this location?"}setDialogMode(2,"Paste",3,p5pasteFileEx,a)}function p5pasteFileEx(){meshserver.send({action:"fileoperation",fileop:(p5clipboardCut==0?"copy":"move"),scpath:p5clipboardFolder,path:filetreelocation,names:p5clipboard});p5folderup(999);if(p5clipboardCut==1){p5clipboard=null,p5clipboardFolder=null,p5clipboardCut=0;p5updateClipview()}}function p5updateClipview(){var a="";if((p5clipboard!=null)&&(p5clipboard.length>0)){a="Holding "+p5clipboard.length+" entrie"+((p5clipboard.length>1)?"s":"")+" for "+(p5clipboardCut==0?"copy":"move")+", <a onclick=p5clearClip() style=cursor:pointer>Clear</a>."}QH("p5bottomstatus",a);p5setActions()}function p5clearClip(){p5clipboard=null;p5clipboardFolder=null;p5clipboardCut=0;p5updateClipview()}function p5fileDragDrop(b){if(xxdialogMode){return}haltEvent(b);QV("bigfail",false);QV("bigok",false);var c=0;p5uploadFile();try{Q("p5uploadinput").files=b.dataTransfer.files}catch(d){c=1}if(c==0){p5uploadFileEx()}setDialogMode(0);if(c==1){if(b.dataTransfer==null||b.dataTransfer.files.length==0||filetreelocation.length==0){return}var j=[],m=[],o=[],a=[],l=b.dataTransfer.files.length,n=0;for(var h=0;h<b.dataTransfer.files.length;h++){n+=b.dataTransfer.files[h].size}if(n>1300000){p5uploadFile();return}for(var h=0;h<b.dataTransfer.files.length;h++){var k=new FileReader(),g=b.dataTransfer.files[h];j.push(g.name);m.push(g.size);o.push(g.type);k.onload=function(e){a.push(e.target.result);if(--l==0){Q("p5fileDragName").value=j.join("*");Q("p5fileDragSize").value=m.join("*");Q("p5fileDragType").value=o.join("*");Q("p5fileDragData").value=a.join("*");Q("p5fileDragLink").value=encodeURIComponent(filetreelinkpath);Q("p5loginSubmit2").click()}};k.readAsDataURL(g)}}}var p5dragtimer=null;function p5fileDragOver(b){if(xxdialogMode){return}haltEvent(b);if(p5dragtimer!=null){clearTimeout(p5dragtimer);p5dragtimer=null}var a=true;if(filetreelocation.length==0){a=false}QV("bigok",a);QV("bigfail",!a)}function p5fileDragLeave(a){if(xxdialogMode){return}haltEvent(a);if(a.target.id!="p5filetable"){QV("bigfail",false);QV("bigok",false)}else{p5dragtimer=setTimeout(function(){QV("bigfail",false);QV("bigok",false);p5dragtimer=null},10)}}function eventMouseHover(a,b){a.children[1].classList.remove("g1s");a.children[2].style["background-color"]=((b==0)?"#c9c9c9":"#b9b9b9");a.children[3].classList.remove("g2s");if(b==1){a.children[1].classList.add("g1s");a.children[3].classList.add("g2s")}}function eventsUpdate(){var h="",a=null;for(var c in events){var b=events[c],g=new Date(b.time);if(g.toLocaleDateString()!=a){if(a!=null){h+="</table>"}h+="<table style=width:100% cellpadding=0 cellspacing=0><tr><td colspan=4 class=DevSt>"+g.toLocaleDateString()+"</td></tr>";a=g.toLocaleDateString()}var d="si3";if(b.etype=="user"){d="m2"}if(b.etype=="server"){d="si3"}var e=b.msg.split("(R)").join("&reg;");if(b.username&&b.username!=userinfo.name){e+=": "+b.username}h+="<tr onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class="+d+"></div></td><td class=g1 style=float:none>&nbsp;</td><td style=background-color:#C9C9C9>"+g.toLocaleTimeString()+" - "+e+"</td><td class=g2 style=float:none>&nbsp;</td></tr><tr style=height:2px></tr>"}if(a!=null){h+="</table>"}if(h==""){h="<br><i>No Events Found</i><br><br>"}QH("p3events",h)}function showDeleteAllEventsDialog(){if(xxdialogMode){return}var a="Delete all events in the server event log?<br /><br />";a+="<input id=p3check type=checkbox onchange=validateDeleteAllEventsDialog() />Confirm";setDialogMode(2,"Delete All Events",3,showDeleteAllEventsDialogEx,a);validateDeleteAllEventsDialog()}function validateDeleteAllEventsDialog(){QE("idx_dlgOkButton",Q("p3check").checked)}function showDeleteAllEventsDialogEx(a,b){meshserver.send({action:"clearevents"})}function refreshEvents(){meshserver.send({action:"events",limit:parseInt(p3limitdropdown.value)})}function updateUsers(){QV("MainMenuMyUsers",(users!=null)&&((features&4)==0));QV("LeftMenuMyUsers",(users!=null)&&((features&4)==0));QV("UserNewAccountButton",((features&4)==0)&&(serverinfo.domainauth==false));if((users==null)||((features&4)!=0)){QH("p3users","");return}var h=[],e=100,c=0;for(var d in users){h.push(d)}h.sort();var k=Q("UserSearchInput").value.toLowerCase();var b=k;if(k.startsWith("email:")){k=null;b=b.substring(6)}else{if(k.startsWith("name:")){b=null;k=k.substring(5)}else{if(k.startsWith("e:")){k=null;b=b.substring(2)}else{if(k.startsWith("n:")){b=null;k=k.substring(2)}}}}var l="<table style=width:100% cellpadding=0 cellspacing=0>",a=true;l+="<th style=color:gray>Name<th style=color:gray;width:80px>Groups<th style=color:gray;width:120px>Last&nbsp;Access<th style=color:gray;width:120px>Permissions";for(var d in h){var j=users[h[d]],g=null;if(wssessions!=null){g=wssessions[j._id]}if((g!=null)&&((k!=null)&&((k=="")||(j.name.toLowerCase().indexOf(k)>=0))||((b!=null)&&((j.email!=null)&&(j.email.toLowerCase().indexOf(b)>=0))))){if(e>0){if(a){l+="<tr><td class=userTableHeader colspan=4>Online Users";a=false}l+=addUserHtml(j,g);e--}else{c++}}}a=true;for(var d in h){var j=users[h[d]],g=null;if(wssessions!=null){g=wssessions[j._id]}if((g==null)&&((k!=null)&&((k=="")||(j.name.toLowerCase().indexOf(k)>=0))||((b!=null)&&((j.email!=null)&&(j.email.toLowerCase().indexOf(b)>=0))))){if(e>0){if(a){l+="<tr><td class=userTableHeader colspan=4>Offline Users";a=false}l+=addUserHtml(j,g);e--}else{c++}}}l+="</table>";if(c==1){l+="<br />1 more user not shown, use search box to look for users...<br />"}else{if(c>1){l+="<br />"+c+" more users not shown, use search box to look for users...<br />"}}if(e==100){l+="<br />No users found.<br />"}QH("p3users",l);if((currentUser!=null)&&(xxcurrentView==30)){gotoUser(encodeURIComponent(currentUser._id),true)}}function addUserHtml(m,l){var o="",b=" gray",e="m2",h="",k=(m.name!=userinfo.name),g="",j="";if(l!=null){b="";if(k){h='<span style=float:right;margin-top:1px;margin-right:4px title=Chat><a onclick=userChat(event,"'+encodeURIComponent(m._id)+'","'+encodeURIComponent(m.name)+"\")><img src='images/icon-chat.png' height=16 width=16 style=padding-top:2px /></a></span>";h+='<span style=float:right;margin-top:1px;margin-left:4px;margin-right:4px title=Notify><a onclick=showUserAlertDialog(event,"'+encodeURIComponent(m._id)+"\")><img src='images/icon-notify.png' height=16 width=16 style=padding-top:2px /></a></span>"}if(l==1){g+="1&nbsp;session"}else{g+=l+"&nbsp;sessions"}}else{if(m.login){g+='<span title="Last login: '+new Date(m.login*1000).toLocaleString()+'">'+new Date(m.login*1000).toLocaleDateString()+"</span>"}}if(k){j+='<a style=cursor:pointer onclick=showUserAdminDialog(event,"'+encodeURIComponent(m._id)+'")>'}if((m.siteadmin!=null)&&((m.siteadmin&32)!=0)&&(m.siteadmin!=4294967295)){j+="Locked,&nbsp;"}j+="<span title='Server Permissions'>";if((m.siteadmin==null)||(m.siteadmin==0)||(m.siteadmin==32)){j+="User"}else{if(m.siteadmin==8){j+="User + Files"}else{if(m.siteadmin==4294967295){j+="Administrator"}else{j+="Partial"}}}j+="</span>";if(k){j+="</a>"}var c=0;if(m.links){for(var d in m.links){c++}}var n=EscapeHtml(m.name),a="";if(serverinfo.emailcheck==true){a=((m.emailVerified!=true)?' <b style=color:red title="Email is not verified">&#x1F5F4</b>':' <b style=color:green title="Email is verified">&#x1F5F8</b>')}if(m.email!=null){n+=', <a onclick=doemail(event,"'+m.email+'")>'+m.email+"</a>"+a}if((m.otpsecret>0)||(m.otphkeys>0)){n+=' <img src="images/key12.png" height=12 width=11 title="2nd factor authentication enabled" style="margin-top:2px" />'}if((m.siteadmin!=null)&&((m.siteadmin&32)!=0)&&(m.siteadmin!=4294967295)){n+=' <img src="images/padlock12.png" height=12 width=8 title="Account is locked" style="margin-top:2px" />'}o+='<tr onmouseover=userMouseHover(this,1) onmouseout=userMouseHover(this,0)><td style=cursor:pointer onclick=gotoUser("'+encodeURIComponent(m._id)+'")>';o+="<div class=bar style=height:24px;width:100%;font-size:medium>";o+='<div style=float:left;height:24px;width:24px;background-color:white><div class="'+e+b+'" style=width:16px;margin-top:4px;margin-left:2px;height:16px></div></div>';o+="<div class=g1 style=height:24px;float:left></div><div class=g2 style=height:24px;float:right></div>";o+="<div><span>"+n+"</span>"+h+"</div></div><td style=text-align:center>"+c+"<td style=text-align:center>"+g+"<td style=text-align:center>"+j;return o}function userMouseHover(b,c){var a=b.children[0].children[0];a.children[1].classList.remove("g1s");a.children[2].classList.remove("g2s");if(c==1){a.children[1].classList.add("g1s");a.children[2].classList.add("g2s")}b.children[0].children[0].style["background-color"]=((c==0)?"#c9c9c9":"#b9b9b9")}function userChat(a,d,b){haltEvent(a);var c="/messenger?id=meshmessenger/"+d+"/"+encodeURIComponent(userinfo._id)+"&title="+b;if((authCookie!=null)&&(authCookie!="")){c+="&auth="+authCookie}window.open(c,"meshmessenger:"+d);meshserver.send({action:"meshmessenger",userid:decodeURIComponent(d)});return false}function showUserAlertDialog(a,b){if(xxdialogMode){return}haltEvent(a);setDialogMode(2,"Notify "+EscapeHtml(users[decodeURIComponent(b)].name),3,showUserAlertDialogEx,'Send a text notification to this user.<textarea id=d2notifyText maxlength=2048 style="width:100%;height:184px;resize:none"></textarea>',b);Q("d2notifyText").focus();return false}function showUserAlertDialogEx(a,b){meshserver.send({action:"notifyuser",userid:decodeURIComponent(b),msg:Q("d2notifyText").value})}function doemail(b,a){if(xxdialogMode){return}haltEvent(b);window.open("mailto:"+a);return false}function showUserBroadcastDialog(){if(xxdialogMode){return}var a='Broadcast a message to all connected users.<textarea id=broadcastMessage value="" style=width:370px;height:100px;resize:none maxlength=256 /></textarea>';setDialogMode(2,"Broadcast Message",3,showUserBroadcastDialogEx,a);Q("broadcastMessage").focus()}function showUserBroadcastDialogEx(){meshserver.send({action:"userbroadcast",msg:Q("broadcastMessage").value})}function showCreateNewAccountDialog(){if(xxdialogMode){return}var d="";d+=addHtmlValue("Name","<input id=p4name style=width:230px maxlength=64 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />");d+=addHtmlValue("Email","<input id=p4email style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />");d+=addHtmlValue("Password","<input id=p4pass1 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />");d+=addHtmlValue("Password","<input id=p4pass2 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />");d+="<div><input id=p4resetNextLogin type=checkbox />Force password reset on next login.</div>";if(passRequirements){var b=[],c=0;for(var a in passRequirements){if((a!="reset")&&(a!="hint")){b.push(a+":"+passRequirements[a]);c++}}if(c>0){d+="<div style=font-size:x-small;padding:6px>Requirements: "+b.join(", ")+".</div>"}}setDialogMode(2,"Create Account",3,showCreateNewAccountDialogEx,d);showCreateNewAccountDialogValidate();Q("p4name").focus()}function showCreateNewAccountDialogValidate(b){if((b==null)&&(Q("p4email").value.length>0)&&(validateEmail(Q("p4email").value))==false){QE("idx_dlgOkButton",false);return}var a=(!Q("p4name")||((Q("p4name").value.length>0)&&(Q("p4name").value.indexOf(" ")==-1)))&&Q("p4pass1").value.length>0&&Q("p4pass1").value==Q("p4pass2").value&&checkPasswordRequirements(Q("p4pass1").value,passRequirements);if(a&&passRequirements){if(checkPasswordRequirements(Q("p4pass1").value,passRequirements)==false){a=false}}QE("idx_dlgOkButton",a)}function showCreateNewAccountDialogEx(){meshserver.send({action:"adduser",username:Q("p4name").value,email:Q("p4email").value,pass:Q("p4pass1").value,resetNextLogin:Q("p4resetNextLogin").checked})}function showUserAdminDialog(a,c){if(xxdialogMode){return}haltEvent(a);c=decodeURIComponent(c);var d="<div>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_fileaccess>Server Files, <input type=number onchange=showUserAdminDialogValidate() maxlength=10 style=width:80px;text-align:right id=ua_fileaccessquota>k max, blank for default<br><hr/>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_fulladmin>Full Administrator<br>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_serverbackup>Server Backup<br>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_serverrestore>Server Restore<br>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_serverupdate>Server Updates<br>";d+="<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_manageusers>Manage Users<br>";d+="<hr/><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_lockedaccount>Lock Account<br>";d+="</div>";var b=users[c.toLowerCase()];setDialogMode(2,"Server Permissions",3,showUserAdminDialogEx,d,b);if(b.siteadmin&&b.siteadmin!=0){Q("ua_fulladmin").checked=(b.siteadmin==4294967295);Q("ua_serverbackup").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&1)!=0));Q("ua_manageusers").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&2)!=0));Q("ua_serverrestore").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&4)!=0));Q("ua_fileaccess").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&8)!=0));Q("ua_serverupdate").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&16)!=0));Q("ua_lockedaccount").checked=((b.siteadmin!=4294967295)&&((b.siteadmin&32)!=0))}QE("ua_fulladmin",userinfo.siteadmin==4294967295);QE("ua_serverbackup",userinfo.siteadmin==4294967295);QE("ua_manageusers",userinfo.siteadmin==4294967295);QE("ua_serverrestore",userinfo.siteadmin==4294967295);QE("ua_fileaccess",userinfo.siteadmin==4294967295);QE("ua_serverupdate",userinfo.siteadmin==4294967295);Q("ua_fileaccessquota").value=(b.quota!=null)?(b.quota/1024):"";showUserAdminDialogValidate();return false}function showUserAdminDialogValidate(){if(userinfo.siteadmin==4294967295){QE("ua_serverbackup",!Q("ua_fulladmin").checked);QE("ua_manageusers",!Q("ua_fulladmin").checked);QE("ua_serverrestore",!Q("ua_fulladmin").checked);QE("ua_fileaccess",!Q("ua_fulladmin").checked);QE("ua_serverupdate",!Q("ua_fulladmin").checked);QE("ua_fileaccessquota",Q("ua_fileaccess").checked&&!Q("ua_fulladmin").checked)}}function showUserAdminDialogEx(a,d){var c=0,b=parseInt(Q("ua_fileaccessquota").value);if(Q("ua_fulladmin").checked==true){c=4294967295}else{if(Q("ua_serverbackup").checked==true){c+=1}if(Q("ua_manageusers").checked==true){c+=2}if(Q("ua_serverrestore").checked==true){c+=4}if(Q("ua_fileaccess").checked==true){c+=8}if(Q("ua_serverupdate").checked==true){c+=16}if(Q("ua_lockedaccount").checked==true){c+=32}}var e={action:"edituser",name:d.name,siteadmin:c};if(isNaN(b)==false){e.quota=(b*1024)}meshserver.send(e)}function onUserSearchInputChanged(){updateUsers()}var currentUser=null;function gotoUser(q,g){if(xxdialogMode&&!g){return}var p=currentUser=users[decodeURIComponent(q)];if(p==null){setDialogMode(0);go(4);return}QH("p30userName",p.name);QH("p31userName",p.name);var o=(p.name==userinfo.name),a=0;if(wssessions!=null&&wssessions[p._id]){a=wssessions[p._id]}Q("MainUserImage").classList.remove("gray");if(a==0){Q("MainUserImage").classList.add("gray")}var l="",n="";if((p.siteadmin!=null)&&((p.siteadmin&32)!=0)&&(p.siteadmin!=4294967295)){n='<img src="images/padlock12.png" height=12 width=8 title="Account is locked" style="margin-top:2px" /> ';l+="Locked account, "}if((p.siteadmin==null)||(p.siteadmin==0)||(p.siteadmin==32)){l+="No server rights"}else{if(p.siteadmin==8){l+="Access to server files"}else{if(p.siteadmin==4294967295){l+="Full administrator"}else{l+="Partial rights"}}}var r="<div style=min-height:80px><table style=width:100%>";var c=p.email?EscapeHtml(p.email):"<i>Not set</i>",d="";if(serverinfo.emailcheck){d=((p.emailVerified==true)?'<b style=color:green;cursor:pointer title="Email is verified">&#x1F5F8</b> ':'<b style=color:red;cursor:pointer title="Email not verified">&#x1F5F4</b> ')}r+=addDeviceAttribute("Email",d+'<a style=cursor:pointer onclick=p30showUserEmailChangeDialog(event,"'+q+'")>'+c+'</a> <a style=cursor:pointer onclick=doemail(event,"'+p.email+'")><img class=hoverButton width=10 height=10 src="images/link1.png" /></a>');r+=addDeviceAttribute("Server Rights",n+'<a style=cursor:pointer onclick=showUserAdminDialog(event,"'+q+'")>'+l+"</a>");if(p.quota){r+=addDeviceAttribute("Server Quota",EscapeHtml(parseInt(p.quota)/1024)+" k")}r+=addDeviceAttribute("Creation",new Date(p.creation*1000).toLocaleString());if(p.login){r+=addDeviceAttribute("Last Login",new Date(p.login*1000).toLocaleString())}if(p.passchange==-1){r+=addDeviceAttribute("Password","Will be changed on next login.")}else{if(p.passchange){r+=addDeviceAttribute("Password","Last changed: "+new Date(p.passchange*1000).toLocaleString())}}var j=0,k="<i>None<i>";if(p.links){for(var h in p.links){j++}if(j==1){k="1 group"}else{if(j>1){k=j+" groups"}}}r+=addDeviceAttribute("Device Groups",k);var m=0;if((p.otpsecret>0)||(p.otphkeys>0)){m=1;var e=[];if(p.otpsecret>0){e.push("Authentication App")}if(p.otphkeys>0){e.push("Security Key")}if(p.otpkeys>0){e.push("Backup Codes")}r+=addDeviceAttribute("Security",'<img src="images/key12.png" height=12 width=11 title="2nd factor authentication enabled" style="margin-top:2px" /> '+e.join(", "))}r+="</table></div><br />";r+='<input type=button value=Notes title="View notes about this user" onclick=showNotes(false,"'+q+'") />';if(!o&&(a>0)){r+='<input type=button value=Notify title="Send user notification" onclick=showUserAlertDialog(event,"'+q+'") />'}QH("p30html",r);drawUserTimeline();var b=true;if(p._id==userinfo._id){b=false}if(p.siteadmin&&p.siteadmin>0&&userinfo.siteadmin!=4294967295){b=false}r="<div style=float:right;font-size:x-small>";if(b){r+='<a style=cursor:pointer onclick=p30showDeleteUserDialog() title="Remove this user">Delete User</a>'}r+="</div><div style=font-size:x-small>";if(userinfo.siteadmin==4294967295){r+="<a style=cursor:pointer onclick=p30showUserChangePassDialog("+m+') title="Change the password for this user">Change Password</a>'}r+="</div><br>";QH("p30html3",r);r="";if(a==1){r="1 active session"}else{if(a>1){r=a+" active sessions"}}QH("MainUserState",r);go(30);QH("p31events","");refreshUsersEvents()}function p30showUserEmailChangeDialog(a){if(xxdialogMode){return}var b="";b+=addHtmlValue("Email","<input id=dp30email style=width:230px maxlength=32 onchange=p30validateEmail() onkeyup=p30validateEmail() />");if(serverinfo.emailcheck){b+=addHtmlValue("Status","<select id=dp30verified style=width:230px onchange=p30validateEmail()><option value=0>Not verified</option><option value=1>Verified</option></select>")}setDialogMode(2,"Change Email for "+EscapeHtml(currentUser.name),3,p30showUserEmailChangeDialogEx,b);Q("dp30email").focus();Q("dp30email").value=currentUser.email;if(serverinfo.emailcheck){Q("dp30verified").value=currentUser.emailVerified?1:0}p30validateEmail()}function p30validateEmail(){var a=Q("dp30email").value,b=a.split("@");b=(b.length==2)&&(b[0].length>0)&&(b[1].split(".").length>1)&&(b[1].length>2)&&(a.length<1024)&&((a!=userinfo.email)||((serverinfo.emailcheck==true)&&(Q("dp30verified").value!=(userinfo.emailVerified?1:0))));QE("idx_dlgOkButton",b)}function p30showUserEmailChangeDialogEx(){var a={action:"edituser",name:currentUser.name,email:Q("dp30email").value};if(serverinfo.emailcheck){a.emailVerified=(Q("dp30verified").value==1)}meshserver.send(a)}function p30showUserChangePassDialog(b){if(xxdialogMode){return}var e="";e+=addHtmlValue("Password","<input id=p4pass1 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=showCreateNewAccountDialogValidate(1)></input>");e+=addHtmlValue("Password","<input id=p4pass2 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=showCreateNewAccountDialogValidate(1)></input>");if(features&65536){e+=addHtmlValue("Password hint","<input id=p4hint type=text style=width:230px maxlength=256></input>")}if(passRequirements){var c=[],d=0;for(var a in passRequirements){if((a!="reset")&&(a!="hint")){c.push(a+":"+passRequirements[a]);d++}}if(d>0){e+="<div style=font-size:x-small;padding:6px>Requirements: "+c.join(", ")+".</div>"}}e+="<div><input id=p4resetNextLogin type=checkbox />Force password reset on next login.</div>";if(b==1){e+="<div><input id=p4twoFactorRemove type=checkbox />Remove all 2nd factor authentication.</div>"}setDialogMode(2,"Change Password for "+EscapeHtml(currentUser.name),3,p30showUserChangePassDialogEx,e,b);showCreateNewAccountDialogValidate(1);Q("p4pass1").focus()}function p30showUserChangePassDialogEx(a,e){var d=false;if((e==1)&&(Q("p4twoFactorRemove").checked==true)){d=true}if(Q("p4pass1").value==Q("p4pass2").value){var c={action:"changeuserpass",user:currentUser.name,pass:Q("p4pass1").value,removeMultiFactor:d,resetNextLogin:Q("p4resetNextLogin").checked};if(features&65536){c.hint=Q("p4hint").value}meshserver.send(c)}}function p30showDeleteUserDialog(){if(xxdialogMode){return}setDialogMode(2,"Delete User "+EscapeHtml(currentUser.name),3,p30showDeleteUserDialogEx,"Confirm deletion of user "+EscapeHtml(currentUser.name)+"?")}function p30showDeleteUserDialogEx(){meshserver.send({action:"deleteuser",userid:currentUser._id,username:currentUser.name})}function drawUserTimeline(){var s=null,o=Date.now();s=[];var e=new Date();e.setHours(0,0,0,0);e=new Date(e.getTime()-(1000*60*60*24*6));var u=e.getTime();var t=[];if(s!=null&&s.length>1){t.push([0,s[1],s[0]]);var c=s[1];for(var m=2;m<s.length;m+=2){var p=s[m],k=o;if(s.length>(m+1)){k=s[m+1]}t.push([c,c+k,p]);c=c+k}}var z="",b=1,h=new Date();h.setHours(0,0,0,0);for(var m=0;m<7;m++){var g="",q=h.getTime(),l=q+(1000*60*60*24);for(var n in t){var a=t[n];if(isTimeBlockInside(q,l,a[0],a[1])==true){var w=Math.max(q,a[0]);var r=Math.min(Math.min(l,a[1]),o);var y=Math.round((r-w)/112794);if(y>0){var v=powerStateStrings2[a[2]]+" from "+new Date(w).toLocaleTimeString()+" to "+new Date(r).toLocaleTimeString()+".";g+='<div title="'+v+'" style=display:table-cell;width:'+y+"px;background-color:"+powerColor(a[2])+";height:16px></div>"}}}z+="<tr style="+(((b%2)==0)?"background-color:#DDD":"")+"><td><div>&nbsp;"+h.toLocaleDateString()+"<div></div></div></td><td><div>"+g+"</div></td></tr>";++b;h=new Date(h.getTime()-(1000*60*60*24))}QH("p30html2",'<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:center;width:150px>Day</th><th scope=col style=text-align:center>7 Day Login State</th></tr>'+z+"</tbody></table>")}var currentUserEvents=null;function userEventsUpdate(){var h="",a=null;for(var c in currentUserEvents){var b=currentUserEvents[c];var g=new Date(b.time);if(g.toLocaleDateString()!=a){if(a!=null){h+="</table>"}h+="<table style=width:100% cellpadding=0 cellspacing=0><tr><td class=DevSt>"+g.toLocaleDateString()+"</td></tr>";a=g.toLocaleDateString()}var d="si3";if(b.etype=="user"){d="m2"}if(b.etype=="server"){d="si3"}var e=b.msg.split("(R)").join("&reg;");if(b.username&&b.username!=userinfo.name){e+=": "+b.username}h+="<tr><td><div class=bar18 style=height:18px;width:100%;font-size:medium>";h+="<div style=float:left;height:18px;width:18px;background-color:white><div class="+d+" style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>";h+="<div class=g1 style=height:18px;float:left></div><div class=g2 style=height:18px;float:right></div>";h+="<div style=font-size:14px><span style=width:300px>"+g.toLocaleTimeString()+" - "+e+"</span></div></div></td></tr>"}if(a!=null){h+="</table>"}if(h==""){h="<br><i>No Events Found</i><br><br>"}QH("p31events",h)}function refreshUsersEvents(){meshserver.send({action:"events",limit:parseInt(p31limitdropdown.value),user:currentUser.name})}function d3init(){Q("d3localFile").value="";d3modechange()}function d3modechange(){var a=Q("d3uploadMode").value;QV("d3localmode",a==1);QV("d3servermode",a==2);if(a==1){d3setActions()}else{d3updatefiles()}}var d3filetreelinkpath;var d3filetreelocation=[];function d3updatefiles(){if(Q("d3uploadMode").value==1){return}var m="",n="",e=filetree,j=1;var c=[],r=d3filetreelinkpath,b=[],a=document.getElementsByName("fc");for(var o=0;o<a.length;o++){if(a[o].checked){b.push(a[o].value)}}d3filetreelinkpath="";for(var o in d3filetreelocation){if((e.f!=null)&&(e.f[d3filetreelocation[o]]!=null)){c.push(d3filetreelocation[o]);if((j==1)){var t=d3filetreelocation[o].split("/");publicPath=window.location+t[0]+"files/"+t[2];if(d3filetreelocation[o]===userinfo._id){d3filetreelinkpath+="self"}else{d3filetreelinkpath+=(t[0]+"/"+t[2])}}else{if(d3filetreelinkpath!=""){d3filetreelinkpath+="/"+d3filetreelocation[o];if(j>2){publicPath+="/"+d3filetreelocation[o]}}}e=e.f[d3filetreelocation[o]];j++}else{break}}d3filetreelocation=c;var g=p5sort_files(e.f);for(var o in g){var d=g[o],q=d.n,s;s=q;if(q.length>70){s='<span title="'+EscapeHtml(q)+'">'+EscapeHtml(q.substring(0,70))+"...</span>"}else{s=EscapeHtml(q)}q=EscapeHtml(q);var k="";if(d.s!=null){k=getFileSizeStr(d.s)}var l="";if(d.t<3){var u="";l='<div class=filelist file=999><span style=float:right title="'+u+'"></span><span><div class=fileIcon'+d.t+' onclick=d3folderset("'+encodeURIComponent(d.nx)+'")></div>&nbsp;<a style=cursor:pointer onclick=d3folderset("'+encodeURIComponent(d.nx)+'")>'+s+"</a></span></div>"}else{var p=s;l="<div class=filelist file=3><input style=float:left name=fcx class=fcb type=checkbox onchange=d3setActions() value='"+d.nx+"'>&nbsp;<span style=float:right>"+k+"</span><span><div class=fileIcon"+d.t+"></div>"+p+"</span></div>"}if(d.t<3){m+=l}else{n+=l}}QH("d3serverfiles",m+n);QE("p3FolderUp",d3filetreelocation.length>0);d3setActions()}function d3folderset(a){d3filetreelocation.push(decodeURIComponent(a));d3updatefiles()}function d3folderup(a){if(a==null){d3filetreelocation.pop()}else{while(d3filetreelocation.length>a){d3filetreelocation.pop()}}d3updatefiles()}function d3getFileSel(){var a=[];var b=document.getElementsByName("fcx");for(var c=0;c<b.length;c++){if(b[c].checked){a.push(b[c].value)}}return a}function d3setActions(){var a=Q("d3uploadMode").value;if(a==1){QE("idx_dlgOkButton",Q("d3localFile").value.length>0)}else{QE("idx_dlgOkButton",d3getFileSel().length==1)}}var notifications=[];function clickNotificationIcon(a){if(a==true){QV("notifiyBox",true)}else{if(a==false){QV("notifiyBox",false)}else{QV("notifiyBox",QS("notifiyBox")["display"]=="none")}}drawNotifications()}function setNotificationCount(a){if(parseInt(Q("notificationCount").innerHTML)==a){return}QH("notificationCount",a);QS("notificationCount")["background-color"]=(a==0)?"lightblue":"orange";QV("notificationCount",a>0)}function drawNotifications(){var j="";if(notifications.length==0){j="<div style=margin:5px>There are currently no notifications</div>"}else{for(var c in notifications){var g=notifications[c];var k="";var a=new Date(g.time);var e=0;if(g.nodeid!=null){var h=getNodeFromId(g.nodeid);if(h!=null){e=h.icon;k="<b>"+h.name+"</b>: "}}j+='<div title="Occured at '+a.toLocaleString()+'" id="notifyx'+g.id+'" class=notification style="cursor:pointer;border-top:1px solid '+((j=="")?"transparent":"orange")+'"><div class=j'+e+' onclick="notificationSelected('+g.id+')" style=margin:5px;float:left></div><div onclick="notificationDelete('+g.id+')" class=unselectable title="Clear this notification" style=margin:5px;float:right;color:orange><b>X</b></div><div onclick="notificationSelected('+g.id+')" style=margin:5px>'+k+g.text+"</div></div>"}}var b="";if(notifications.length>1){b='<div id="notifyRemoveAll" onclick="deleteAllNotifications()" style="cursor:pointer;border-top:1px solid orange;margin:5px;color:orange;text-align:right;padding-right:3px">Clear all</div>'}QH("notifiyBox",'<div class=customScroll style="max-height:170px;overflow-y:auto;margin:5px">'+j+"</div>"+b)}function notificationSelected(b){var c=-1;for(var a in notifications){if(notifications[a].id==b){c=a}}if(c!=-1){var d=notifications[c];if(d.nodeid!=null){if(d.tag=="desktop"){gotoDevice(d.nodeid,12)}else{if(d.tag=="terminal"){gotoDevice(d.nodeid,11)}else{if(d.tag=="files"){gotoDevice(d.nodeid,13)}else{if(d.tag=="intelamt"){gotoDevice(d.nodeid,14)}else{if(d.tag=="console"){gotoDevice(d.nodeid,15)}else{gotoDevice(d.nodeid,10)}}}}}}else{if(d.tag.startsWith("meshmessenger/")){window.open("/messenger?id="+d.tag+"&title="+encodeURIComponent(d.username),d.tag.split("/")[2]);notificationDelete(b)}}}}function notificationDelete(c){var d=-1,a=Q("notifyx"+c);if(a!=null){for(var b in notifications){if(notifications[b].id==c){d=b}}if(d!=-1){notifications.splice(d,1);a.parentNode.removeChild(a);setNotificationCount(notifications.length);if(notifications.length==0){QV("notifiyBox",false)}if(notifications.length==1){QV("notifyRemoveAll",false)}if((notifications.length>0)&&(d==0)){var g=notifications[0];QS("notifyx"+g.id)["border-top"]="1px solid transparent"}}}}function addNotification(a){if(a.time==null){a.time=Date.now()}if(a.id==null){a.id=Math.random()}notifications.unshift(a);setNotificationCount(notifications.length);Q("chimes").play();clickNotificationIcon(true)}function deleteAllNotifications(){notifications=[];setNotificationCount(0);drawNotifications();QV("notifiyBox",false)}function setupServerStats(){window.serverStatCpu=new Chart(document.getElementById("serverCpuChart").getContext("2d"),{type:"doughnut",data:{datasets:[{data:[0,0],backgroundColor:["#AAAAAA","#00AA00"]}],labels:["Used","Free"]},options:{responsive:true,legend:{position:"none",},animation:{animateScale:true,animateRotate:true},width:"60px"}});window.serverStatMemory=new Chart(document.getElementById("serverMemoryChart").getContext("2d"),{type:"doughnut",data:{datasets:[{data:[0,0],backgroundColor:["#AAAAAA","#00AA00"]}],labels:["Used","Free"]},options:{responsive:true,legend:{position:"none",},animation:{animateScale:true,animateRotate:true},width:"60px"}})}var lastServerStats=null;function updateServerStats(d){if(d!=null){lastServerStats=d}else{d=lastServerStats}if(d==null){return}if(typeof d.cpuavg=="object"){var c=Math.min(d.cpuavg[0],1);window.serverStatCpu.config.data.datasets[0].data=[c,1-c];QH("serverCpuChartText",'<div style=margin-bottom:5px>CPU Load</div><div><b title="CPU load in the last minute">'+(Math.round(d.cpuavg[0]*100)/100)+'</b>, <b title="CPU load in the last 5 minutes">'+(Math.round(d.cpuavg[1]*100)/100)+'</b>, <b title="CPU load in the 15 minutes">'+(Math.round(d.cpuavg[2]*100)/100)+"</b></div>");QS("serverCpuChartView")["display"]="inline-block";window.serverStatCpu.update()}if((typeof d.totalmem=="number")&&(typeof d.freemem=="number")){window.serverStatMemory.config.data.datasets[0].data=[d.totalmem-d.freemem,d.freemem];QH("serverMemoryChartText","<div style=margin-bottom:5px>Memory</div><div><b>"+getNiceSize2(d.freemem)+"</b> free, <b>"+getNiceSize2(d.totalmem)+"</b> total</div>");QS("serverMemoryChartView")["display"]="inline-block";window.serverStatMemory.update()}var e="<div style=width:100% cellpadding=0 cellspacing=0>";if(typeof d.values=="object"){for(var a in d.values){e+="<div class=userTableHeader style=margin-bottom:4px;width:200px>"+a+"</div>";for(var b in d.values[a]){e+="<div style=display:inline-block><table style=width:300px;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0><tr><td class=h1></td><td><span>"+b+"</span><span style=float:right>"+d.values[a][b]+"</span></td><td class=h2></td></tr></table></div>"}}}e+="</div>";QH("serverStatsTable",e)}var xxdialogMode;var xxdialogFunc;var xxdialogButtons;var xxdialogTag;var xxcurrentView=-1;function setDialogMode(j,k,a,e,d,h){xxdialogMode=j;xxdialogFunc=e;xxdialogButtons=a;xxdialogTag=h;QE("idx_dlgOkButton",true);QV("idx_dlgOkButton",a&1);QV("idx_dlgCancelButton",a&2);QV("id_dialogclose",(a&2)||(a&8));QV("idx_dlgDeleteButton",a&4);QV("idx_dlgButtonBar",a&7);if(k){QH("id_dialogtitle",k)}for(var g=1;g<24;g++){QV("dialog"+g,g==j)}QV("dialog",j);if(d){if(j==2){QH("id_dialogOptions",d)}else{QH("id_dialogMessage",d)}}}function dialogclose(e){var c=xxdialogFunc,a=xxdialogButtons,d=xxdialogTag;setDialogMode();if(((a&8)||e)&&c){c(e,d)}}function center(){if(xxcurrentView==11){deskAdjust()}else{if(xxcurrentView==10){masterUpdate(256)}else{if(xxcurrentView==1){masterUpdate(4)}}}}function messagebox(b,a){QH("id_dialogMessage",a);setDialogMode(1,b,1)}function statusbox(b,a){QH("id_dialogMessage",a);setDialogMode(1,b)}function goBack(){if(xxdialogMode){return}if((xxcurrentView>=10)&&(xxcurrentView<20)){go(1)}if((xxcurrentView>=20)&&(xxcurrentView<30)){go(2)}if((xxcurrentView>=30)&&(xxcurrentView<40)){go(4)}}function go(d){if(xxdialogMode||xxcurrentView==d){return}for(var a=0;a<32;a++){QV("p"+a,a==d)}xxcurrentView=d;var b=["LeftMenuMyDevices","LeftMenuMyAccount","LeftMenuMyEvents","LeftMenuMyFiles","LeftMenuMyUsers","LeftMenuMyServer"];for(var a in b){Q(b[a]).classList.remove("lbbuttonsel");Q(b[a]).classList.remove("lbbuttonsel2")}QV("topbar",d!=0);if(d>=10&&d<20){QS("MainMenuMyDevices").backgroundColor="#606060"}else{QS("MainMenuMyDevices").backgroundColor=((d==1)?"#003366":"#808080")}if(d==1||(d>=10&&d<20)){Q("LeftMenuMyDevices").classList.add("lbbuttonsel")}if(d==1){Q("LeftMenuMyDevices").classList.add("lbbuttonsel2")}if(d>=20&&d<30){QS("MainMenuMyAccount").backgroundColor="#606060"}else{QS("MainMenuMyAccount").backgroundColor=((d==2)?"#003366":"#808080")}if(d==2||(d>=20&&d<30)){Q("LeftMenuMyAccount").classList.add("lbbuttonsel")}if(d==2){Q("LeftMenuMyAccount").classList.add("lbbuttonsel2")}QS("MainMenuMyEvents").backgroundColor=((d==3)?"#003366":"#808080");if(d==3){Q("LeftMenuMyEvents").classList.add("lbbuttonsel","lbbuttonsel2")}if(d>=30&&d<40){QS("MainMenuMyUsers").backgroundColor="#606060"}else{QS("MainMenuMyUsers").backgroundColor=((d==4)?"#003366":"#808080")}if(d==4||(d>=30&&d<40)){Q("LeftMenuMyUsers").classList.add("lbbuttonsel")}if(d==4){Q("LeftMenuMyUsers").classList.add("lbbuttonsel2")}QS("MainMenuMyFiles").backgroundColor=((d==5)?"#003366":"#808080");if(d==5){Q("LeftMenuMyFiles").classList.add("lbbuttonsel","lbbuttonsel2")}QS("MainMenuMyServer").backgroundColor=(((d==6)||(d==115))?"#003366":"#808080");if(((d==6)||(d==115))){Q("LeftMenuMyServer").classList.add("lbbuttonsel","lbbuttonsel2")}if(webPageFullScreen){QS("column_l")["max-height"]="calc(100vh - 135px)"}else{QS("column_l")["max-height"]=(d>=10)?"calc(100vh - 159px)":"calc(100vh - 135px)"}if((d==0)&&(webPageFullScreen)){QS("page_content").position="";QV("page_leftbar",false);QS("column_l").height="calc(100vh - 110px)";QS("column_l")["max-height"]=""}QV("MainSubMenuSpan",d>=10&&d<20);QV("UserDummyMenuSpan",(d<10)&&(d!=6)&&webPageFullScreen);QV("MeshSubMenuSpan",d>=20&&d<30);QV("UserSubMenuSpan",d>=30&&d<40);QV("ServerSubMenuSpan",d==6||d==115);var c={10:"MainDev",11:"MainDevDesktop",12:"MainDevTerminal",13:"MainDevFiles",14:"MainDevAmt",15:"MainDevConsole",20:"MeshGeneral",30:"UserGeneral",31:"UserEvents",6:"ServerGeneral",115:"ServerConsole"};for(var a in c){Q(c[a]).classList.remove("style3x");Q(c[a]).classList.remove("style3sel");Q(c[a]).classList.add((d==a)?"style3sel":"style3x")}if(d==115){QV("p15",true)}QV("p15uploadCore",d!=115);QV("p15BackButton",d!=115);if((d==15)||(d==115)){setupConsole()}if(d==1){masterUpdate(4)}if((currentNode)&&(d>=10)&&(d<20)){document.title="MeshCentral - "+currentNode.name}else{document.title="MeshCentral"}}function joinPaths(){var c=[];for(var a in arguments){var b=arguments[a];if((b!=null)&&(b!="")){while(b.endsWith("/")||b.endsWith("\\")){b=b.substring(0,b.length-1)}while(b.startsWith("/")||b.startsWith("\\")){b=b.substring(1)}c.push(b)}}return c.join("/")}function putstore(b,c){try{if(typeof(localStorage)==="undefined"){return}localStorage.setItem(b,c)}catch(a){}}function getstore(b,d){try{if(typeof(localStorage)==="undefined"){return d}var c=localStorage.getItem(b);if((c==null)||(c==null)){return d}return c}catch(a){return d}}function addLink(b,a){return"<span style=cursor:pointer;text-decoration:none onclick='"+a+"'>"+b+" <img class=hoverButton width=10 height=10 src=images/link5.png></span>"}function addLinkConditional(d,b,a){if(a){return addLink(d,b)}return d}function haltEvent(a){if(a.preventDefault){a.preventDefault()}if(a.stopPropagation){a.stopPropagation()}return false}function addOption(c,d,a){var b=document.createElement("option");b.text=d;b.value=a;Q(c).add(b)}function passwordcheck(a){return(a.length>7)&&(/\d/.test(a))&&(/[a-z]/.test(a))&&(/[A-Z]/.test(a))&&(/\W/.test(a))}function methodcheck(a){if(a&&a!=null&&a.Body&&a.Body.ReturnValueStr!="SUCCESS"){messagebox("Call Error",a.Header.Method+": "+a.Body.ReturnValueStr.replace("_"," "));return true}return false}function TableStart(){return"<table cellpadding=0 cellspacing=0 style=width:100%;border-radius:8px><tr><td width=200px><p><td>"}function TableStart2(){return"<table cellpadding=0 cellspacing=0 style=width:100%;border-radius:8px><tr><td><p><td>"}function TableEntry(a,b){return"<tr><td><p>"+a+"<td>"+b}function FullTable(c,a){var b=TableStart();for(i in c){if(i&&c[i]){b+=TableEntry(i,c[i])}}return b+TableEnd(a)}function TableEnd(a){return"<tr><td colspan=2><p>"+(a?a:"")+"</table>"}function AddButton(b,a){return"<input type=button value='"+b+"' onclick='"+a+"' style=margin:4px>"}function AddButton2(b,a){return"<input type=button value='"+b+"' onclick='"+a+"'>"}function AddRefreshButton(a){return"<input type=button name=refreshbtn value=Refresh onclick='refreshButtons(false);"+a+"' style=margin:4px "+(refreshButtonsState==false?"disabled":"")+">"}function MoreStart(){return'<a style=cursor:pointer;color:blue id=morexxx1 onclick=QV("morexxx1",false);QV("morexxx2",true)>&#x25BC; More</a><div id=morexxx2 style=display:none><br><hr>'}function MoreEnd(){return'<a style=cursor:pointer;color:blue onclick=QV("morexxx2",false);QV("morexxx1",true)>&#x25B2; Less</a></div>'}function getSelectedOptions(e){var d=[],c;for(var a=0,b=e.options.length;a<b;a++){c=e.options[a];if(c.selected){d.push(c.value)}}return d}function getInstance(b,c){for(var a in b){if(b[a]["InstanceID"]==c){return b[a]}}return null}function getItem(b,c,d){for(var a in b){if(b[a][c]==d){return b[a]}}return null}function guidToStr(a){return a.substring(6,8)+a.substring(4,6)+a.substring(2,4)+a.substring(0,2)+"-"+a.substring(10,12)+a.substring(8,10)+"-"+a.substring(14,16)+a.substring(12,14)+"-"+a.substring(16,20)+"-"+a.substring(20)}function getUrlVars(){var d,a,e=[],b=window.location.href.slice(window.location.href.indexOf("?")+1).split("&");for(var c=0;c<b.length;c++){d=b[c].indexOf("=");if(d>0){e[b[c].substring(0,d)]=b[c].substring(d+1,b[c].length)}}return e}function addHtmlValue(a,b){return"<table><td style=width:120px>"+a+"<td><b>"+b+"</b></table>"}function addHtmlValue2(a,b){return"<div><div style=display:inline-block;float:right>"+b+"</div><div style=display:inline-block>"+a+"</div></div>"}function parseUriArgs(){var a,c={},b=window.document.location.href.split(/[\?&|\=]/);b.splice(0,1);for(d in b){switch(d%2){case 0:a=decodeURIComponent(b[d]);break;case 1:c[a]=decodeURIComponent(b[d]);var d=parseInt(c[a]);if(d==c[a]){c[a]=d}break;default:break}}return c}function focusTextBox(a){setTimeout(function(){Q(a).selectionStart=Q(a).selectionEnd=65535;Q(a).focus()},0)}function validateEmail(b){var a=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;return a.test(b)}function isPrivateIP(b){return(b.startsWith("10.")||b.startsWith("172.16.")||b.startsWith("192.168."))}function u2fSupported(){return(window.u2f&&((navigator.userAgent.indexOf("Chrome/")>0)||(navigator.userAgent.indexOf("Firefox/")>0)||(navigator.userAgent.indexOf("Opera/")>0)||(navigator.userAgent.indexOf("Safari/")>0)))};</script></body></html>
\ No newline at end of file
views/default.handlebars
+95 -35
@@ -922,7 +922,7 @@
922 QV('p13AutoConnect', debugmode); // Files
923 QV('autoconnectbutton2', debugmode); // Terminal
924 QV('autoconnectbutton1', debugmode); // Desktop
925 - QV('DeskClip', debugmode); // Clipboard feature, not completed so show in in debug mode only.
925 + //QV('DeskClip', debugmode); // Clipboard feature, not completed so show in in debug mode only.
926
927 toggleFullScreen();
928
@@ -2050,34 +2050,42 @@
2050 var deviceBoxWidth = Math.floor(totalDeviceViewWidth / 301);
2051 deviceBoxWidth = 301 + Math.floor((totalDeviceViewWidth - (deviceBoxWidth * 301)) / deviceBoxWidth);
2052
2053 + if (view == 2) {
2054 + r += '<table style=width:100%;margin-top:4px cellpadding=0 cellspacing=0><th style=color:gray><th style=color:gray;width:120px>User<th style=color:gray;width:120px>Address<th style=color:gray;width:100px>Connectivity'; //<th style=color:gray;width:100px>State';
2055 + }
2056 +
2057 // Go thru the list of nodes and display them
2058 for (var i in nodes) {
2055 - if (nodes[i].v == false) continue;
2056 - var mesh2 = meshes[nodes[i].meshid], meshlinks = mesh2.links['user/' + domain + '/' + userinfo.name.toLowerCase()];
2059 + var node = nodes[i];
2060 + if (node.v == false) continue;
2061 + var mesh2 = meshes[node.meshid], meshlinks = mesh2.links['user/' + domain + '/' + userinfo.name.toLowerCase()];
2062 if (meshlinks == null) continue;
2063 var meshrights = meshlinks.rights;
2064 if ((view == 3) && (mesh2.mtype == 1)) continue;
2065 if (sort == 0) {
2066 // Mesh header
2062 - if (nodes[i].meshid != current) {
2067 + if (node.meshid != current) {
2068 deviceHeaderSet();
2069 var extra = '';
2065 - if (meshes[nodes[i].meshid].mtype == 1) { extra = '<span class=devHeaderx>, Intel&reg; AMT only</span>'; }
2070 + if (view == 2) { r += '<tr><td colspan=5>'; }
2071 + if (meshes[node.meshid].mtype == 1) { extra = '<span class=devHeaderx>, Intel&reg; AMT only</span>'; }
2072 if ((view == 1) && (current != null)) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } if (r != '') { r += '</tr></table>'; } }
2073 + if (view == 2) { r += '<div>'; }
2074 r += '<div class=DevSt style=width:100%;padding-top:4px><span style=float:right>';
2075 r += getMeshActions(mesh2, meshrights);
2069 - r += '</span><span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + nodes[i].meshid + '")>' + EscapeHtml(meshes[nodes[i].meshid].name) + '</span>' + extra + '<span id=DevxHeader' + deviceHeaderId + ' class=devHeaderx></span></div>';
2070 - current = nodes[i].meshid;
2076 + r += '</span><span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + node.meshid + '")>' + EscapeHtml(meshes[node.meshid].name) + '</span>' + extra + '<span id=DevxHeader' + deviceHeaderId + ' class=devHeaderx></span></div>';
2077 + if (view == 2) { r += '</div>'; }
2078 + current = node.meshid;
2079 displayedMeshes[current] = 1;
2080 c = 0;
2081 }
2082 } else if (sort == 1) {
2083 // Power header
2076 - var pwr = nodes[i].pwr?nodes[i].pwr:0;
2084 + var pwr = node.pwr?node.pwr:0;
2085 if (pwr !== current) {
2086 deviceHeaderSet();
2087 if ((view == 1) && (current !== null)) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } if (r != '') { r += '</tr></table>'; } }
2080 - r += '<div class=DevSt style=width:100%;padding-top:4px><span>' + PowerStateStr2(nodes[i].pwr) + '</span><span id=DevxHeader' + deviceHeaderId + ' class="devHeaderx"></span></div>';
2088 + r += '<div class=DevSt style=width:100%;padding-top:4px><span>' + PowerStateStr2(node.pwr) + '</span><span id=DevxHeader' + deviceHeaderId + ' class="devHeaderx"></span></div>';
2089 current = pwr;
2090 c = 0;
2091 }
@@ -2087,41 +2095,52 @@
2095 }
2096
2097 count++;
2090 - var title = EscapeHtml(nodes[i].name);
2098 + var title = EscapeHtml(node.name);
2099 if (title.length == 0) { title = '<i>None</i>'; }
2092 - if ((nodes[i].rname != null) && (nodes[i].rname.length > 0)) { title += " / " + EscapeHtml(nodes[i].rname); }
2093 - var name = EscapeHtml(nodes[i].name);
2094 - if (showRealNames == true && nodes[i].rname != null) name = EscapeHtml(nodes[i].rname);
2100 + if ((node.rname != null) && (node.rname.length > 0)) { title += " / " + EscapeHtml(node.rname); }
2101 + var name = EscapeHtml(node.name);
2102 + if (showRealNames == true && node.rname != null) name = EscapeHtml(node.rname);
2103 if (name.length == 0) { name = '<i>None</i>'; }
2104
2105 // Node
2098 - var icon = nodes[i].icon;
2099 - var nodestate = NodeStateStr(nodes[i]);
2100 - if ((!nodes[i].conn) || (nodes[i].conn == 0)) { icon += ' gray'; }
2106 + var icon = node.icon;
2107 + if ((!node.conn) || (node.conn == 0)) { icon += ' gray'; }
2108 if (view == 1) {
2102 - r += '<div id=devs onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=display:inline-block;width:' + deviceBoxWidth + 'px;height:50px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:12px><input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox></div><div style=height:100%;cursor:pointer onclick=gotoDevice(\'' + nodes[i]._id + '\',null,null,event)><div class="i' + icon + '" style=width:50px;float:left></div><div style=height:100%><div class=g1></div><div class=e2><div class=e1 style=width:' + (deviceBoxWidth - 100) + 'px title="' + title + '">' + name + '</div><div>' + nodestate + '</div></div><div class=g2></div></div></div></div>';
2109 + r += '<div id=devs onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=display:inline-block;width:' + deviceBoxWidth + 'px;height:50px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:12px><input class="' + node.meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + node._id + ' type=checkbox></div><div style=height:100%;cursor:pointer onclick=gotoDevice(\'' + node._id + '\',null,null,event)><div class="i' + icon + '" style=width:50px;float:left></div><div style=height:100%><div class=g1></div><div class=e2><div class=e1 style=width:' + (deviceBoxWidth - 100) + 'px title="' + title + '">' + name + '</div><div>' + NodeStateStr(node) + '</div></div><div class=g2></div></div></div></div>';
2110 } else if (view == 2) {
2111 + var states = [];
2112 + if (node.conn) {
2113 + if ((node.conn & 1) != 0) { states.push('<span title="Mesh agent is connected and ready for use.">Agent</span>'); }
2114 + if ((node.conn & 2) != 0) { states.push('<span title="Intel&reg; AMT CIRA is connected and ready for use.">CIRA</span>'); }
2115 + else if ((node.conn & 4) != 0) { states.push('<span title="Intel&reg; AMT is routable.">AMT</span>'); }
2116 + if ((node.conn & 8) != 0) { states.push('<span title="Mesh agent is reachable using another agent as relay.">Relay</span>'); }
2117 + }
2118 r += '<tr><td><div id=devs class=bar18 onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=height:18px;width:100%;font-size:medium>';
2105 - r += '<div style=width:22px;float:left;background-color:white><input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox></div>';
2106 - r += '<div style=float:left;height:18px;width:18px;background-color:white onclick=gotoDevice(\'' + nodes[i]._id + '\',null,null,event)><div class=j' + icon + ' style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>';
2119 + r += '<div style=width:22px;float:left;background-color:white><input class="' + node.meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + node._id + ' type=checkbox></div>';
2120 + r += '<div style=float:left;height:18px;width:18px;background-color:white onclick=gotoDevice(\'' + node._id + '\',null,null,event)><div class=j' + icon + ' style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>';
2121 r += '<div class=g1 style=height:18px;float:left></div><div class=g2 style=height:18px;float:right></div>';
2108 - r += '<div style=cursor:pointer;font-size:14px title="' + title + '" onclick=gotoDevice(\'' + nodes[i]._id + '\',null,null,event)><span style=float:right>' + nodestate + '</span><span style=width:300px>' + name + '</span></div></div></td></tr>';
2109 - } 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.
2110 - if ((multiDesktopFilter.length == 0) || (multiDesktopFilter.indexOf('devid_' + nodes[i]._id) >= 0)) {
2111 - r += '<div id=devs style=display:inline-block;margin:1px;background-color:lightgray;border-radius:5px;position:relative><div style=padding:3px;cursor:pointer onclick=gotoDevice(\'' + nodes[i]._id + '\',11,null,event)>';
2112 - //r += '<input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox style=float:left>';
2122 + r += '<div style=cursor:pointer;font-size:14px title="' + title + '" onclick=gotoDevice(\'' + node._id + '\',null,null,event)><span style=width:300px>' + name + '</span></div></div></td>';
2123 + r += '<td style=text-align:center>' + getUserShortStr(node);
2124 + r += '<td style=text-align:center>' + (node.ip != null ? node.ip : '');
2125 + r += '<td style=text-align:center>' + states.join('&nbsp;+&nbsp;');
2126 + //r += '<td style=text-align:center>' + (node.pwr != null ? powerStateStrings[node.pwr] : '');
2127 + r += '</tr>';
2128 + } 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.
2129 + if ((multiDesktopFilter.length == 0) || (multiDesktopFilter.indexOf('devid_' + node._id) >= 0)) {
2130 + r += '<div id=devs style=display:inline-block;margin:1px;background-color:lightgray;border-radius:5px;position:relative><div style=padding:3px;cursor:pointer onclick=gotoDevice(\'' + node._id + '\',11,null,event)>';
2131 + //r += '<input class="' + node.meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + node._id + ' type=checkbox style=float:left>';
2132 r += '<div class="j' + icon + '" style=width:16px;float:left></div>&nbsp;' + name + '</div>';
2114 - r += '<span onclick=gotoDevice(\'' + nodes[i]._id + '\',null,null,event)></span><div id=xkvmid_' + nodes[i]._id.split('/')[2] + '><div id=skvmid_' + nodes[i]._id.split('/')[2] + ' style="position:absolute;color:white;left:5px;top:27px;text-shadow:0px 0px 5px #000;z-index:1000;cursor:default" onclick=toggleKvmDevice(\'' + nodes[i]._id + '\')>Disconnected</div></div>';
2133 + r += '<span onclick=gotoDevice(\'' + node._id + '\',null,null,event)></span><div id=xkvmid_' + node._id.split('/')[2] + '><div id=skvmid_' + node._id.split('/')[2] + ' style="position:absolute;color:white;left:5px;top:27px;text-shadow:0px 0px 5px #000;z-index:1000;cursor:default" onclick=toggleKvmDevice(\'' + node._id + '\')>Disconnected</div></div>';
2134 r += '</div>';
2116 - kvmDivs.push(nodes[i]._id);
2135 + kvmDivs.push(node._id);
2136 }
2137 }
2138
2139 // If we are displaying devices by group, put the device in the right group.
2140 if ((sort == 3) && (r != '')) {
2122 - if (nodes[i].tags) {
2123 - for (var j in nodes[i].tags) {
2124 - var tag = nodes[i].tags[j];
2141 + if (node.tags) {
2142 + for (var j in node.tags) {
2143 + var tag = node.tags[j];
2144 if (groups[tag] == null) { groups[tag] = r; groupCount[tag] = 1; } else { groups[tag] += r; groupCount[tag] += 1; }
2145 if (view == 3) break;
2146 }
@@ -2130,7 +2149,7 @@
2149 }
2150
2151 deviceHeaderTotal++;
2133 - if (typeof deviceHeaderCount[nodes[i].state] == 'undefined') { deviceHeaderCount[nodes[i].state] = 1; } else { deviceHeaderCount[nodes[i].state]++; }
2152 + if (typeof deviceHeaderCount[node.state] == 'undefined') { deviceHeaderCount[node.state] = 1; } else { deviceHeaderCount[node.state]++; }
2153 }
2154
2155 // If displaying devices by groups, sort the group names and display the devices.
@@ -2278,6 +2297,16 @@
2297 }
2298 }
2299
2300 + function getUserShortStr(node) {
2301 + if (node == null || node.users == null || node.users.length == 0) return '';
2302 + if (node.users.length > 1) { return '<span title="' + EscapeHtml(node.users.join(', ')) + '">' + node.users.length + '&nbsp;users</span>'; }
2303 + var u = node.users[0], su = u, i = u.indexOf('\\');
2304 + if (i > 0) { su = u.substring(i + 1); }
2305 + su = EscapeHtml(su);
2306 + if (su.length > 15) { su = su.substring(0, 14) + '&#8230;'; }
2307 + return '<span title="' + EscapeHtml(u) + '">' + su + '</span>';
2308 + }
2309 +
2310 function autoConnectDesktops() { if (Q('autoConnectDesktopCheckbox').checked == true) { connectAllKvmFunction(); } }
2311 function connectAllKvmFunction() { for (var i in nodes) { if (multiDesktop[nodes[i]._id] == null) { toggleKvmDevice(nodes[i]._id); } } }
2312 function disconnectAllKvmFunction() { for (var nodeid in multiDesktop) { multiDesktop[nodeid].Stop(); } multiDesktop = {}; }
@@ -2728,9 +2757,30 @@
2757
2758 function onSearchInputChanged() {
2759 var x = Q('SearchInput').value.toLowerCase().trim(); putstore("search", x);
2760 + var userSearch = null, ipSearch = null, groupSearch = null;
2761 + if (x.startsWith('user:')) { userSearch = x.substring(5); }
2762 + else if (x.startsWith('u:')) { userSearch = x.substring(2); }
2763 + else if (x.startsWith('ip:')) { ipSearch = x.substring(3); }
2764 + else if (x.startsWith('group:')) { groupSearch = x.substring(6); }
2765 + else if (x.startsWith('g:')) { groupSearch = x.substring(2); }
2766 +
2767 if (x == '') {
2768 + // No search
2769 for (var d in nodes) { nodes[d].v = true; }
2770 + } else if (ipSearch != null) {
2771 + // IP address search
2772 + for (var d in nodes) { nodes[d].v = ((nodes[d].ip != null) && (nodes[d].ip.indexOf(ipSearch) >= 0)); }
2773 + } else if (groupSearch != null) {
2774 + // Group filter
2775 + for (var d in nodes) { nodes[d].v = (meshes[nodes[d].meshid].name.toLowerCase().indexOf(groupSearch) >= 0); }
2776 + } else if (userSearch != null) {
2777 + // User search
2778 + for (var d in nodes) {
2779 + nodes[d].v = false;
2780 + 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; } } }
2781 + }
2782 } else {
2783 + // Device name search
2784 try {
2785 var rs = x.split(/\s+/).join('|'), rx = new RegExp(rs); // In some cases (like +), this can throw an exception.
2786 for (var d in nodes) {
@@ -4124,8 +4174,8 @@
4174 QV('deskFocusBtn', (desktop != null) && (desktop.contype == 2) && (deskState != 0) && (desktopsettings.showfocus));
4175 QV('DeskCAD', inputAllowed);
4176 QE('DeskCAD', deskState == 3);
4127 - //QV('DeskClip', (desktop != null) && (desktop.contype == 1));
4128 - QE('DeskClip', deskState == 3);
4177 + //QV('DeskClip', (desktop == null) || (desktop.contype != 2));
4178 + //QE('DeskClip', deskState == 3);
4179 QV('DeskWD', (currentNode.agent) && (currentNode.agent.id < 5) && inputAllowed);
4180 QE('DeskWD', deskState == 3);
4181 QV('deskkeys', (currentNode.agent) && (currentNode.agent.id < 5) && inputAllowed);
@@ -6404,17 +6454,24 @@
6454
6455 // Get search
6456 var userSearch = Q('UserSearchInput').value.toLowerCase();
6457 + var emailSearch = userSearch;
6458 + if (userSearch.startsWith('email:')) { userSearch = null; emailSearch = emailSearch.substring(6); }
6459 + else if (userSearch.startsWith('name:')) { emailSearch = null; userSearch = userSearch.substring(5); }
6460 + else if (userSearch.startsWith('e:')) { userSearch = null; emailSearch = emailSearch.substring(2); }
6461 + else if (userSearch.startsWith('n:')) { emailSearch = null; userSearch = userSearch.substring(2); }
6462
6463 // Display the users using the sorted list
6464 var x = '<table style=width:100% cellpadding=0 cellspacing=0>', addHeader = true;
6410 -
6465 x += '<th style=color:gray>Name<th style=color:gray;width:80px>Groups<th style=color:gray;width:120px>Last&nbsp;Access<th style=color:gray;width:120px>Permissions';
6466
6467 // Online users
6468 for (var i in sortedUserIds) {
6469 var user = users[sortedUserIds[i]], sessions = null;
6470 if (wssessions != null) { sessions = wssessions[user._id]; }
6417 - if ((sessions != null) && (user.name.toLowerCase().indexOf(userSearch) >= 0)) {
6471 + if ((sessions != null) &&
6472 + ((userSearch != null) && ((userSearch == '') || (user.name.toLowerCase().indexOf(userSearch) >= 0)) ||
6473 + ((emailSearch != null) && ((user.email != null) && (user.email.toLowerCase().indexOf(emailSearch) >= 0))))
6474 + ) {
6475 if (maxUsers > 0) {
6476 if (addHeader) { x += '<tr><td class=userTableHeader colspan=4>Online Users'; addHeader = false; }
6477 x += addUserHtml(user, sessions);
@@ -6429,7 +6486,10 @@
6486 for (var i in sortedUserIds) {
6487 var user = users[sortedUserIds[i]], sessions = null;
6488 if (wssessions != null) { sessions = wssessions[user._id]; }
6432 - if ((sessions == null) && (user.name.toLowerCase().indexOf(userSearch) >= 0)) {
6489 + if ((sessions == null) &&
6490 + ((userSearch != null) && ((userSearch == '') || (user.name.toLowerCase().indexOf(userSearch) >= 0)) ||
6491 + ((emailSearch != null) && ((user.email != null) && (user.email.toLowerCase().indexOf(emailSearch) >= 0))))
6492 + ) {
6493 if (maxUsers > 0) {
6494 if (addHeader) { x += '<tr><td class=userTableHeader colspan=4>Offline Users'; addHeader = false; }
6495 x += addUserHtml(user, sessions);