Added server console, KVM jumbo accumulator.

This commit is contained in:
Ylian Saint-Hilaire 2019-02-04 18:06:01 -08:00
parent 0ed26d55cf
commit cebb0ce63e
17 changed files with 275 additions and 130 deletions

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2018-2019 Intel Corporation Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -187,14 +187,9 @@ function serviceHost(serviceName)
console.log(e); console.log(e);
process.exit(); process.exit();
} }
if (process.platform == 'win32' || process.platform == 'darwin')
{ console.log(this._ServiceOptions.name + ' installed');
// Only do this on Windows/MacOS, becuase Linux is async... It'll complete later process.exit();
console.log(this._ServiceOptions.name + ' installed');
process.exit();
}
i = process.argv.length;
serviceOperation = 1;
break; break;
case '-uninstall': case '-uninstall':
if (!this._svcManager) { this._svcManager = new serviceManager(); } if (!this._svcManager) { this._svcManager = new serviceManager(); }
@ -301,9 +296,6 @@ function serviceHost(serviceName)
} }
process.exit(); process.exit();
break; break;
default:
// Unknown arguments, skip it.
break;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2018-2019 Intel Corporation Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -46,9 +46,6 @@ function parseServiceStatus(token)
case 0x00000001: case 0x00000001:
j.state = 'STOPPED'; j.state = 'STOPPED';
break; break;
default:
// Unknown service state
break;
} }
var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE(); var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE();
j.controlsAccepted = []; j.controlsAccepted = [];
@ -295,13 +292,14 @@ function serviceManager()
require('fs').chmodSync('/etc/init.d/' + options.name, m); require('fs').chmodSync('/etc/init.d/' + options.name, m);
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._moduleName = options.name; this._update._moduleName = options.name;
this._update.on('exit', function onUpdateRC_d() { console.log(this._moduleName + ' installed'); process.exit(); });
this._update.stdout.on('data', function (chunk) { }); this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('update-rc.d ' + options.name + ' defaults\n'); this._update.stdin.write('update-rc.d ' + options.name + ' defaults\n');
this._update.stdin.write('exit\n'); this._update.stdin.write('exit\n');
//update-rc.d meshagent defaults # creates symlinks for rc.d //update-rc.d meshagent defaults # creates symlinks for rc.d
//service meshagent start //service meshagent start
this._update.waitExit();
break; break;
case 'systemd': case 'systemd':
var serviceDescription = options.description ? options.description : 'MeshCentral Agent'; var serviceDescription = options.description ? options.description : 'MeshCentral Agent';
@ -313,11 +311,10 @@ function serviceManager()
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' }); require('fs').writeFileSync('/lib/systemd/system/' + options.name + '.service', '[Unit]\nDescription=' + serviceDescription + '\n[Service]\nExecStart=/usr/local/mesh/' + options.name + '\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=' + options.name + '.service\n', { flags: 'w' });
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._moduleName = options.name; this._update._moduleName = options.name;
this._update.on('exit', function onUpdateRC_d() { console.log(this._moduleName + ' installed'); process.exit(); });
this._update.stdout.on('data', function (chunk) { }); this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('systemctl enable ' + options.name + '.service\n'); this._update.stdin.write('systemctl enable ' + options.name + '.service\n');
this._update.stdin.write('exit\n'); this._update.stdin.write('exit\n');
this._update.waitExit();
break; break;
default: // unknown platform service type default: // unknown platform service type
break; break;
@ -416,41 +413,39 @@ function serviceManager()
{ {
case 'init': case 'init':
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._svcname = name;
this._update.on('exit', function onUninstallExit() {
try {
require('fs').unlinkSync('/etc/init.d/' + this._svcname);
console.log(this._svcname + ' uninstalled');
}
catch (e) {
console.log(this._svcname + ' could not be uninstalled')
}
process.exit();
});
this._update.stdout.on('data', function (chunk) { }); this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('service ' + name + ' stop\n'); this._update.stdin.write('service ' + name + ' stop\n');
this._update.stdin.write('update-rc.d -f ' + name + ' remove\n'); this._update.stdin.write('update-rc.d -f ' + name + ' remove\n');
this._update.stdin.write('exit\n'); this._update.stdin.write('exit\n');
this._update.waitExit();
try
{
require('fs').unlinkSync('/etc/init.d/' + name);
console.log(name + ' uninstalled');
}
catch (e)
{
console.log(name + ' could not be uninstalled', e)
}
break; break;
case 'systemd': case 'systemd':
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._svcname = name;
this._update.on('exit', function onUninstallExit() {
try {
require('fs').unlinkSync('/usr/local/mesh/' + this._svcname);
require('fs').unlinkSync('/lib/systemd/system/' + this._svcname + '.service');
console.log(this._svcname + ' uninstalled');
}
catch (e) {
console.log(this._svcname + ' could not be uninstalled')
}
process.exit();
});
this._update.stdout.on('data', function (chunk) { }); this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('systemctl stop ' + name + '.service\n'); this._update.stdin.write('systemctl stop ' + name + '.service\n');
this._update.stdin.write('systemctl disable ' + name + '.service\n'); this._update.stdin.write('systemctl disable ' + name + '.service\n');
this._update.stdin.write('exit\n'); this._update.stdin.write('exit\n');
this._update.waitExit();
try
{
require('fs').unlinkSync('/usr/local/mesh/' + name);
require('fs').unlinkSync('/lib/systemd/system/' + name + '.service');
console.log(name + ' uninstalled');
}
catch (e)
{
console.log(name + ' could not be uninstalled', e)
}
break; break;
default: // unknown platform service type default: // unknown platform service type
break; break;

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2018-2019 Intel Corporation Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -77,7 +77,8 @@ function SMBiosTables()
var SMData; var SMData;
var structcount = 0; var structcount = 0;
while (SMData && i < SMData.length) { while (SMData && i < SMData.length)
{
var SMtype = SMData[i]; var SMtype = SMData[i];
var SMlength = SMData[i + 1]; var SMlength = SMData[i + 1];
@ -88,12 +89,20 @@ function SMBiosTables()
ret[SMtype].peek()._strings = []; ret[SMtype].peek()._strings = [];
while (SMData[i] != 0) { while (SMData[i] != 0 && i <= SMData.length)
{
var strstart = i; var strstart = i;
// Start of String, find end of string // Start of String, find end of string
while (SMData[i++] != 0); while (SMData[i++] != 0 && i <= SMData.length);
ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim()); try
{
ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim());
}
catch (ee)
{
console.log('oops');
}
} }
i += (ret[SMtype].peek()._strings.length == 0) ? 2 : 1; i += (ret[SMtype].peek()._strings.length == 0) ? 2 : 1;
++structcount; ++structcount;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2018-2019 Intel Corporation Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -46,9 +46,6 @@ function parseServiceStatus(token)
case 0x00000001: case 0x00000001:
j.state = 'STOPPED'; j.state = 'STOPPED';
break; break;
default:
// Unknown service status.
break;
} }
var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE(); var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE();
j.controlsAccepted = []; j.controlsAccepted = [];
@ -295,13 +292,14 @@ function serviceManager()
require('fs').chmodSync('/etc/init.d/' + options.name, m); require('fs').chmodSync('/etc/init.d/' + options.name, m);
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._moduleName = options.name; this._update._moduleName = options.name;
this._update.on('exit', function onUpdateRC_d() { console.log(this._moduleName + ' installed'); process.exit(); });
this._update.stdout.on('data', function (chunk) { }); this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('update-rc.d ' + options.name + ' defaults\n'); this._update.stdin.write('update-rc.d ' + options.name + ' defaults\n');
this._update.stdin.write('exit\n'); this._update.stdin.write('exit\n');
//update-rc.d meshagent defaults # creates symlinks for rc.d //update-rc.d meshagent defaults # creates symlinks for rc.d
//service meshagent start //service meshagent start
this._update.waitExit();
break; break;
case 'systemd': case 'systemd':
var serviceDescription = options.description ? options.description : 'MeshCentral Agent'; var serviceDescription = options.description ? options.description : 'MeshCentral Agent';
@ -313,13 +311,12 @@ function serviceManager()
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' }); require('fs').writeFileSync('/lib/systemd/system/' + options.name + '.service', '[Unit]\nDescription=' + serviceDescription + '\n[Service]\nExecStart=/usr/local/mesh/' + options.name + '\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=' + options.name + '.service\n', { flags: 'w' });
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._moduleName = options.name; this._update._moduleName = options.name;
this._update.on('exit', function onUpdateRC_d() { console.log(this._moduleName + ' installed'); process.exit(); });
this._update.stdout.on('data', function (chunk) { }); this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('systemctl enable ' + options.name + '.service\n'); this._update.stdin.write('systemctl enable ' + options.name + '.service\n');
this._update.stdin.write('exit\n'); this._update.stdin.write('exit\n');
this._update.waitExit();
break; break;
default: // Unknown platform service type default: // unknown platform service type
break; break;
} }
} }
@ -416,43 +413,41 @@ function serviceManager()
{ {
case 'init': case 'init':
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._svcname = name;
this._update.on('exit', function onUninstallExit() {
try {
require('fs').unlinkSync('/etc/init.d/' + this._svcname);
console.log(this._svcname + ' uninstalled');
}
catch (e) {
console.log(this._svcname + ' could not be uninstalled')
}
process.exit();
});
this._update.stdout.on('data', function (chunk) { }); this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('service ' + name + ' stop\n'); this._update.stdin.write('service ' + name + ' stop\n');
this._update.stdin.write('update-rc.d -f ' + name + ' remove\n'); this._update.stdin.write('update-rc.d -f ' + name + ' remove\n');
this._update.stdin.write('exit\n'); this._update.stdin.write('exit\n');
this._update.waitExit();
try
{
require('fs').unlinkSync('/etc/init.d/' + name);
console.log(name + ' uninstalled');
}
catch (e)
{
console.log(name + ' could not be uninstalled', e)
}
break; break;
case 'systemd': case 'systemd':
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._svcname = name;
this._update.on('exit', function onUninstallExit() {
try {
require('fs').unlinkSync('/usr/local/mesh/' + this._svcname);
require('fs').unlinkSync('/lib/systemd/system/' + this._svcname + '.service');
console.log(this._svcname + ' uninstalled');
}
catch (e) {
console.log(this._svcname + ' could not be uninstalled')
}
process.exit();
});
this._update.stdout.on('data', function (chunk) { }); this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('systemctl stop ' + name + '.service\n'); this._update.stdin.write('systemctl stop ' + name + '.service\n');
this._update.stdin.write('systemctl disable ' + name + '.service\n'); this._update.stdin.write('systemctl disable ' + name + '.service\n');
this._update.stdin.write('exit\n'); this._update.stdin.write('exit\n');
this._update.waitExit();
try
{
require('fs').unlinkSync('/usr/local/mesh/' + name);
require('fs').unlinkSync('/lib/systemd/system/' + name + '.service');
console.log(name + ' uninstalled');
}
catch (e)
{
console.log(name + ' could not be uninstalled', e)
}
break; break;
default: // Unknown platform service type default: // unknown platform service type
break; break;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2018-2019 Intel Corporation Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -77,7 +77,8 @@ function SMBiosTables()
var SMData; var SMData;
var structcount = 0; var structcount = 0;
while (SMData && i < SMData.length) { while (SMData && i < SMData.length)
{
var SMtype = SMData[i]; var SMtype = SMData[i];
var SMlength = SMData[i + 1]; var SMlength = SMData[i + 1];
@ -88,12 +89,20 @@ function SMBiosTables()
ret[SMtype].peek()._strings = []; ret[SMtype].peek()._strings = [];
while (SMData[i] != 0) { while (SMData[i] != 0 && i <= SMData.length)
{
var strstart = i; var strstart = i;
// Start of String, find end of string // Start of String, find end of string
while (SMData[i++] != 0); while (SMData[i++] != 0 && i <= SMData.length);
ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim()); try
{
ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim());
}
catch (ee)
{
console.log('oops');
}
} }
i += (ret[SMtype].peek()._strings.length == 0) ? 2 : 1; i += (ret[SMtype].peek()._strings.length == 0) ? 2 : 1;
++structcount; ++structcount;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -187,7 +187,7 @@ function CreateMeshCentralServer(config, args) {
} }
} }
}); });
xprocess.stdout.on('data', function (data) { if (data[data.length - 1] == '\n') { data = data.substring(0, data.length - 1); } if (data.indexOf('Updating settings folder...') >= 0) { xprocess.xrestart = 1; } else if (data.indexOf('Updating server certificates...') >= 0) { xprocess.xrestart = 1; } else if (data.indexOf('Server Ctrl-C exit...') >= 0) { xprocess.xrestart = 2; } else if (data.indexOf('Starting self upgrade...') >= 0) { xprocess.xrestart = 3; } console.log(data); }); xprocess.stdout.on('data', function (data) { if (data[data.length - 1] == '\n') { data = data.substring(0, data.length - 1); } if (data.indexOf('Updating settings folder...') >= 0) { xprocess.xrestart = 1; } else if (data.indexOf('Updating server certificates...') >= 0) { xprocess.xrestart = 1; } else if (data.indexOf('Server Ctrl-C exit...') >= 0) { xprocess.xrestart = 2; } else if (data.indexOf('Starting self upgrade...') >= 0) { xprocess.xrestart = 3; } else if (data.indexOf('Server restart...') >= 0) { xprocess.xrestart = 1; } console.log(data); });
xprocess.stderr.on('data', function (data) { xprocess.stderr.on('data', function (data) {
if (data.startsWith('le.challenges[tls-sni-01].loopback')) { return; } // Ignore this error output from GreenLock if (data.startsWith('le.challenges[tls-sni-01].loopback')) { return; } // Ignore this error output from GreenLock
if (data[data.length - 1] == '\n') { data = data.substring(0, data.length - 1); } if (data[data.length - 1] == '\n') { data = data.substring(0, data.length - 1); }

View File

@ -404,6 +404,55 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
} }
break; break;
} }
case 'serverconsole':
{
// This is a server console message, only process this if full administrator
if (user.siteadmin != 0xFFFFFFFF) break;
var r = '';
var args = splitArgs(command.value);
if (args.length == 0) break;
const cmd = args[0].toLowerCase();
args = parseArgs(args);
switch (cmd) {
case 'help': {
r = 'Available commands: help, args, resetserver, showconfig, usersessions.';
break;
}
case 'args': {
r = cmd + ': ' + JSON.stringify(args);
break;
}
case 'usersessions': {
for (var i in obj.parent.wssessions) {
r += (i + ', ' + obj.parent.wssessions[i].length + ' session' + ((obj.parent.wssessions[i].length > 1) ? 'a' : '') + '.<br />');
for (var j in obj.parent.wssessions[i]) {
var addr = obj.parent.wssessions[i][j]._socket.remoteAddress;
if (addr.startsWith('::ffff:')) { addr = addr.substring(7); }
r += ' ' + addr + ' --> ' + obj.parent.wssessions[i][j].sessionId + '.<br />';
}
}
break;
}
case 'resetserver': {
console.log('Server restart...');
process.exit(0);
break;
}
case 'showconfig': {
r = JSON.stringify(obj.parent.parent.config, null, 4);
break;
}
default: { // This is an unknown command, return an error message
r = 'Unknown command \"' + cmd + '\", type \"help\" for list of avaialble commands.';
break;
}
}
if (r != '') { try { ws.send(JSON.stringify({ action: 'serverconsole', value: r, tag: command.tag })); } catch (ex) { } }
break;
}
case 'msg': case 'msg':
{ {
// Route this command to a target node // Route this command to a target node
@ -893,7 +942,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
obj.db.Set(obj.common.escapeLinksFieldName(mesh)); obj.db.Set(obj.common.escapeLinksFieldName(mesh));
// Notify mesh change // Notify mesh change
obj.parent.parent.DispatchEvent(['*', mesh._id, user._id, command.userid], obj, { etype: 'mesh', username: user.name, userid: deluser.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + deluser.name + ' from group ' + mesh.name, domain: domain.id }); if (deluser != null) {
obj.parent.parent.DispatchEvent(['*', mesh._id, user._id, command.userid], obj, { etype: 'mesh', username: user.name, userid: deluser.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + deluser.name + ' from group ' + mesh.name, domain: domain.id });
} else {
obj.parent.parent.DispatchEvent(['*', mesh._id, user._id, command.userid], obj, { etype: 'mesh', username: user.name, userid: (deluserid.split('/')[2]), meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + (deluserid.split('/')[2]) + ' from group ' + mesh.name, domain: domain.id });
}
} }
} }
break; break;
@ -1565,5 +1618,25 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
function EscapeHtml(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; } function EscapeHtml(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
//function EscapeHtmlBreaks(x) { if (typeof x == "string") return x.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 x == "boolean") return x; if (typeof x == "number") return x; } //function EscapeHtmlBreaks(x) { if (typeof x == "string") return x.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 x == "boolean") return x; if (typeof x == "number") return x; }
// Split a string taking into account the quoats. Used for command line parsing
function splitArgs(str) { var myArray = [], myRegexp = /[^\s"]+|"([^"]*)"/gi; do { var match = myRegexp.exec(str); if (match != null) { myArray.push(match[1] ? match[1] : match[0]); } } while (match != null); return myArray; }
function toNumberIfNumber(x) { if ((typeof x == 'string') && (+parseInt(x) === x)) { x = parseInt(x); } return x; }
// Parse arguments string array into an object
function parseArgs(argv) {
var results = { '_': [] }, current = null;
for (var i = 1, len = argv.length; i < len; i++) {
var x = argv[i];
if (x.length > 2 && x[0] == '-' && x[1] == '-') {
if (current != null) { results[current] = true; }
current = x.substring(2);
} else {
if (current != null) { results[current] = toNumberIfNumber(x); current = null; } else { results['_'].push(toNumberIfNumber(x)); }
}
}
if (current != null) { results[current] = true; }
return results;
}
return obj; return obj;
}; };

View File

@ -51,9 +51,11 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
obj.onDebugMessage = null; obj.onDebugMessage = null;
obj.onTouchEnabledChanged = null; obj.onTouchEnabledChanged = null;
obj.onDisplayinfo = null; obj.onDisplayinfo = null;
obj.accumulator = null;
obj.Start = function () { obj.Start = function () {
obj.State = 0; obj.State = 0;
obj.accumulator = null;
} }
obj.Stop = function () { obj.Stop = function () {
@ -178,6 +180,11 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
} }
obj.ProcessDataEx = function (str) { obj.ProcessDataEx = function (str) {
if (obj.accumulator != null) {
str = obj.accumulator + str;
console.log('KVM using accumulated data, total size is now ' + str.length + ' bytes.');
obj.accumulator = null;
}
if (obj.debugmode > 1) { console.log("KRecv(" + str.length + "): " + rstr2hex(str.substring(0, Math.min(str.length, 40)))); } if (obj.debugmode > 1) { console.log("KRecv(" + str.length + "): " + rstr2hex(str.substring(0, Math.min(str.length, 40)))); }
if (str.length < 4) return; if (str.length < 4) return;
var cmdmsg = null, X = 0, Y = 0, command = ReadShort(str, 0), cmdsize = ReadShort(str, 2), jumboAdd = 0; var cmdmsg = null, X = 0, Y = 0, command = ReadShort(str, 0), cmdsize = ReadShort(str, 2), jumboAdd = 0;
@ -186,14 +193,23 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
if (str.length < 12) return; if (str.length < 12) return;
command = ReadShort(str, 8) command = ReadShort(str, 8)
cmdsize = ReadInt(str, 4); cmdsize = ReadInt(str, 4);
console.log('JUMBO cmd=' + command + ', cmdsize=' + cmdsize + ', data received=' + str.length);
if ((cmdsize + 8) > str.length) {
console.log('KVM accumulator set to ' + str.length + ' bytes, need ' + cmdsize + ' bytes.');
obj.accumulator = str;
return;
}
str = str.substring(8); str = str.substring(8);
jumboAdd = 8; jumboAdd = 8;
//console.log('JUMBO', command, cmdsize, str.length);
} }
if ((cmdsize != str.length) && (obj.debugmode > 0)) { console.log(cmdsize, str.length, cmdsize == str.length); } if ((cmdsize != str.length) && (obj.debugmode > 0)) { console.log(cmdsize, str.length, cmdsize == str.length); }
if ((command >= 18) && (command != 65)) { console.error("Invalid KVM command " + command + " of size " + cmdsize); console.log("Invalid KVM data", str.length, str, rstr2hex(str)); return; } if ((command >= 18) && (command != 65)) { console.error("Invalid KVM command " + command + " of size " + cmdsize); console.log("Invalid KVM data", str.length, str, rstr2hex(str)); return; }
if (cmdsize > str.length) { console.error("KVM invalid command size", cmdsize, str.length); return; } if (cmdsize > str.length) {
//meshOnDebug("KVM Command: " + command + " Len:" + cmdsize); console.log('KVM accumulator set to ' + str.length + ' bytes, need ' + cmdsize + ' bytes.');
obj.accumulator = str;
return;
}
//console.log("KVM Command: " + command + " Len:" + cmdsize);
if (command == 3 || command == 4 || command == 7) { if (command == 3 || command == 4 || command == 7) {
cmdmsg = str.substring(4, cmdsize); cmdmsg = str.substring(4, cmdsize);

View File

@ -99,7 +99,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
obj.webchannel = obj.webrtc.createDataChannel("DataChannel", {}); // { ordered: false, maxRetransmits: 2 } obj.webchannel = obj.webrtc.createDataChannel("DataChannel", {}); // { ordered: false, maxRetransmits: 2 }
obj.webchannel.onmessage = function (event) { obj.xxOnMessage({ data: event.data }); }; obj.webchannel.onmessage = function (event) { obj.xxOnMessage({ data: event.data }); };
obj.webchannel.onopen = function () { obj.webRtcActive = true; performWebRtcSwitch(); }; obj.webchannel.onopen = function () { obj.webRtcActive = true; performWebRtcSwitch(); };
obj.webchannel.onclose = function (event) { /*console.log('WebRTC close');*/ if (obj.webRtcActive) { obj.Stop(); } } obj.webchannel.onclose = function (event) { if (obj.webRtcActive) { obj.Stop(); } }
obj.webrtc.onicecandidate = function (e) { obj.webrtc.onicecandidate = function (e) {
if (e.candidate == null) { if (e.candidate == null) {
try { obj.socket.send(JSON.stringify(obj.webrtcoffer)); } catch (ex) { } // End of candidates, send the offer try { obj.socket.send(JSON.stringify(obj.webrtcoffer)); } catch (ex) { } // End of candidates, send the offer

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -136,6 +136,15 @@
</tr> </tr>
</table> </table>
</div> </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> <div id=UserDummyMenuSpan>
<table id=UserDummyMenu style=width:100%;height:22px cellpadding=0 cellspacing=0 class=style1> <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> <tr><td class=style3 style="text-align:right;height:24px">&nbsp;</td></tr>
@ -604,7 +613,7 @@
<div id=p15 style=display:none> <div id=p15 style=display:none>
<div id="p15title"> <div id="p15title">
<div id="p15BackButton" style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div> <div id="p15BackButton" style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div>
<h1>Console - <span id=p15deviceName></span></h1> <h1><span id=p15deviceName></span></h1>
</div> </div>
<table cellpadding=0 cellspacing=0 style="width:100%;padding:0px;padding:0px;margin-top:0px"> <table cellpadding=0 cellspacing=0 style="width:100%;padding:0px;padding:0px;margin-top:0px">
<tr> <tr>
@ -1334,6 +1343,10 @@
} }
break; break;
} }
case 'serverconsole': {
p15consoleReceive('serverconsole', message.value);
break;
}
case 'events': { case 'events': {
if ((message.nodeid != null) && (message.nodeid == currentNode._id)) { if ((message.nodeid != null) && (message.nodeid == currentNode._id)) {
currentDeviceEvents = message.events; currentDeviceEvents = message.events;
@ -1676,7 +1689,7 @@
function ondockeypress(e) { function ondockeypress(e) {
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) return desktop.m.handleKeys(e); if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) return desktop.m.handleKeys(e);
if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) return terminal.m.TermHandleKeys(e); if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) return terminal.m.TermHandleKeys(e);
if (!xxdialogMode && xxcurrentView == 15) return agentConsoleHandleKeys(e); if (!xxdialogMode && ((xxcurrentView == 15) || (xxcurrentView == 115))) return agentConsoleHandleKeys(e);
if (!xxdialogMode && xxcurrentView == 4) { if (!xxdialogMode && xxcurrentView == 4) {
if (e.ctrlKey == true || e.altKey == true || e.metaKey == true) return; if (e.ctrlKey == true || e.altKey == true || e.metaKey == true) return;
var processed = 0; var processed = 0;
@ -1725,7 +1738,7 @@
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) { return desktop.m.handleKeyDown(e); } if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) { return desktop.m.handleKeyDown(e); }
if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) { return terminal.m.TermHandleKeyDown(e); } if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) { return terminal.m.TermHandleKeyDown(e); }
if (!xxdialogMode && xxcurrentView == 13 && e.keyCode == 116 && p13filetree != null) { haltEvent(e); return false; } // F5 Refresh on files if (!xxdialogMode && xxcurrentView == 13 && e.keyCode == 116 && p13filetree != null) { haltEvent(e); return false; } // F5 Refresh on files
if (!xxdialogMode && xxcurrentView == 15) { return agentConsoleHandleKeys(e); } if (!xxdialogMode && ((xxcurrentView == 15) || (xxcurrentView == 115))) { return agentConsoleHandleKeys(e); }
if (!xxdialogMode && xxcurrentView == 4) { if (!xxdialogMode && xxcurrentView == 4) {
if (e.keyCode === 8 && userSearchFocus == 0) { var x = Q('UserSearchInput').value; Q('UserSearchInput').value = (x.substring(0, x.length - 1)); processed = 1; } if (e.keyCode === 8 && userSearchFocus == 0) { var x = Q('UserSearchInput').value; Q('UserSearchInput').value = (x.substring(0, x.length - 1)); processed = 1; }
if (e.keyCode === 27) { Q('UserSearchInput').value = ''; processed = 1; } if (e.keyCode === 27) { Q('UserSearchInput').value = ''; processed = 1; }
@ -3209,7 +3222,7 @@
QH('p12deviceName', nname); QH('p12deviceName', nname);
QH('p13deviceName', nname); QH('p13deviceName', nname);
QH('p14deviceName', nname); QH('p14deviceName', nname);
QH('p15deviceName', nname); QH('p15deviceName', 'Console - ' + nname);
QH('p16deviceName', nname); QH('p16deviceName', nname);
// Node attributes // Node attributes
@ -5022,27 +5035,43 @@
} }
var consoleNode; var consoleNode;
var consoleServerText = '';
function setupConsole() { function setupConsole() {
// Setup the console if (xxcurrentView == 115) {
var samenode = (consoleNode == currentNode); // Setup server console
consoleNode = currentNode; var samenode = (consoleNode == 'server');
consoleNode = 'server';
QH('p15deviceName', 'My Server Console');
QH('p15statetext', '');
QH('p15coreName', '');
var mesh = meshes[consoleNode.meshid];
var meshrights = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights;
if ((meshrights & 16) != 0) {
if (consoleNode.consoleText == null) { consoleNode.consoleText = ''; }
if (samenode == false) { if (samenode == false) {
QH('p15agentConsoleText', consoleNode.consoleText); QH('p15agentConsoleText', consoleServerText);
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight; Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight;
} }
var online = ((consoleNode.conn & 1) != 0)?true:false;
QH('p15statetext', online?"Agent is online":"Agent is offline");
QE('p15consoleText', online);
QE('p15uploadCore', online);
} else { } else {
QH('p15statetext', 'Access Denied'); // Setup the console
QE('p15consoleText', false); var samenode = (consoleNode == currentNode);
QE('p15uploadCore', false); consoleNode = currentNode;
var mesh = meshes[consoleNode.meshid];
var meshrights = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights;
if ((meshrights & 16) != 0) {
if (consoleNode.consoleText == null) { consoleNode.consoleText = ''; }
if (samenode == false) {
QH('p15agentConsoleText', consoleNode.consoleText);
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight;
}
var online = ((consoleNode.conn & 1) != 0) ? true : false;
QH('p15statetext', online ? "Agent is online" : "Agent is offline");
QE('p15consoleText', online);
QE('p15uploadCore', online);
} else {
QH('p15statetext', 'Access Denied');
QE('p15consoleText', false);
QE('p15uploadCore', false);
}
} }
} }
@ -5050,7 +5079,11 @@
function p15consoleClear() { function p15consoleClear() {
QH('p15agentConsoleText', ''); QH('p15agentConsoleText', '');
Q('id_p15consoleClear').blur(); Q('id_p15consoleClear').blur();
consoleNode.consoleText = ''; if (xxcurrentView == 115) {
consoleServerText = '';
} else {
consoleNode.consoleText = '';
}
} }
// Send a command to the agent // Send a command to the agent
@ -5059,12 +5092,18 @@
if (e && e.keyCode != 13) return; if (e && e.keyCode != 13) return;
var v = Q('p15consoleText').value, t = '<div style=color:green>&gt; ' + EscapeHtml(Q('p15consoleText').value) + '<br/></div>'; var v = Q('p15consoleText').value, t = '<div style=color:green>&gt; ' + EscapeHtml(Q('p15consoleText').value) + '<br/></div>';
Q('p15agentConsoleText').innerHTML += t; Q('p15agentConsoleText').innerHTML += t;
consoleNode.consoleText += t;
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight; Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight;
Q('p15consoleText').value = ''; Q('p15consoleText').value = '';
// Send the command to the mesh agent if (xxcurrentView == 115) {
meshserver.send({ action: 'msg', type:'console', nodeid: consoleNode._id, value: v }); // Send the command to the server - TODO: In the future, we may support multiple servers.
consoleServerText += t;
meshserver.send({ action: 'serverconsole', value: v });
} else {
// Send the command to the mesh agent
consoleNode.consoleText += t;
meshserver.send({ action: 'msg', type: 'console', nodeid: consoleNode._id, value: v });
}
// Add command to history list // Add command to history list
if (v.length > 0) { if (v.length > 0) {
@ -5079,10 +5118,20 @@
// Handle Mesh Agent console data // Handle Mesh Agent console data
function p15consoleReceive(node, data) { function p15consoleReceive(node, data) {
data = '<div>' + data + '</div>' data = '<div>' + data + '</div>'
if (node.consoleText == null) { node.consoleText = data; } else { node.consoleText += data; } if (node === 'serverconsole') {
if (consoleNode == node) { // Server console data
Q('p15agentConsoleText').innerHTML += data; consoleServerText += data;
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight; if (consoleNode == 'server') {
Q('p15agentConsoleText').innerHTML += data;
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight;
}
} else {
// Agent console data
if (node.consoleText == null) { node.consoleText = data; } else { node.consoleText += data; }
if (consoleNode == node) {
Q('p15agentConsoleText').innerHTML += data;
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight;
}
} }
} }
@ -6627,8 +6676,8 @@
if (x == 5) { Q('LeftMenuMyFiles').classList.add('lbbuttonsel', 'lbbuttonsel2'); } if (x == 5) { Q('LeftMenuMyFiles').classList.add('lbbuttonsel', 'lbbuttonsel2'); }
// My Server // My Server
QS('MainMenuMyServer').backgroundColor = ((x == 6) ? "#003366" : "#808080"); QS('MainMenuMyServer').backgroundColor = (((x == 6) || (x == 115)) ? "#003366" : "#808080");
if (x == 6) { Q('LeftMenuMyServer').classList.add('lbbuttonsel', 'lbbuttonsel2'); } if (((x == 6) || (x == 115))) { Q('LeftMenuMyServer').classList.add('lbbuttonsel', 'lbbuttonsel2'); }
// column_l max-height // column_l max-height
if (webPageFullScreen) { if (webPageFullScreen) {
@ -6644,16 +6693,23 @@
} }
QV('MainSubMenuSpan', x >= 10 && x < 20); QV('MainSubMenuSpan', x >= 10 && x < 20);
QV('UserDummyMenuSpan', (x < 10) && webPageFullScreen); QV('UserDummyMenuSpan', (x < 10) && (x != 6) && webPageFullScreen);
QV('MeshSubMenuSpan', x >= 20 && x < 30); QV('MeshSubMenuSpan', x >= 20 && x < 30);
QV('UserSubMenuSpan', x >= 30 && x < 40); QV('UserSubMenuSpan', x >= 30 && x < 40);
var panels = { 10: 'MainDev', 11: 'MainDevDesktop', 12: 'MainDevTerminal', 13: 'MainDevFiles', 14: 'MainDevAmt', 15: 'MainDevConsole', 20: 'MeshGeneral', 30: 'UserGeneral', 31: 'UserEvents' }; QV('ServerSubMenuSpan', x == 6 || x == 115);
var panels = { 10: 'MainDev', 11: 'MainDevDesktop', 12: 'MainDevTerminal', 13: 'MainDevFiles', 14: 'MainDevAmt', 15: 'MainDevConsole', 20: 'MeshGeneral', 30: 'UserGeneral', 31: 'UserEvents', 6: 'ServerGeneral', 115: 'ServerConsole' };
for (var i in panels) { for (var i in panels) {
Q(panels[i]).classList.remove('style3x'); Q(panels[i]).classList.remove('style3x');
Q(panels[i]).classList.remove('style3sel'); Q(panels[i]).classList.remove('style3sel');
Q(panels[i]).classList.add((x == i) ? 'style3sel' : 'style3x'); Q(panels[i]).classList.add((x == i) ? 'style3sel' : 'style3x');
} }
// Panel 115 is weird, it's panel 15 for device console but used as a server console.
if (x == 115) { QV('p15', true); }
QV('p15uploadCore', x != 115);
QV('p15BackButton', x != 115);
if ((x == 15) || (x == 115)) { setupConsole(); }
if (x == 1) masterUpdate(4); if (x == 1) masterUpdate(4);
// Update the web page title // Update the web page title