Added server warnings in MyServer tab.

This commit is contained in:
Ylian Saint-Hilaire 2019-11-26 14:11:09 -08:00
parent e786962482
commit 65d20c3c78
8 changed files with 71 additions and 17 deletions

View File

@ -68,6 +68,7 @@ function CreateMeshCentralServer(config, args) {
obj.serverStatsCounter = Math.floor(Math.random() * 1000); obj.serverStatsCounter = Math.floor(Math.random() * 1000);
obj.taskLimiter = obj.common.createTaskLimiterQueue(50, 20, 60); // (maxTasks, maxTaskTime, cleaningInterval) This is a task limiter queue to smooth out server work. obj.taskLimiter = obj.common.createTaskLimiterQueue(50, 20, 60); // (maxTasks, maxTaskTime, cleaningInterval) This is a task limiter queue to smooth out server work.
obj.agentUpdateBlockSize = 65531; // MeshAgent update block size obj.agentUpdateBlockSize = 65531; // MeshAgent update block size
obj.serverWarnings = []; // List of warnings that should be shown to administrators
try { obj.currentVer = JSON.parse(obj.fs.readFileSync(obj.path.join(__dirname, 'package.json'), 'utf8')).version; } catch (e) { } // Fetch server version try { obj.currentVer = JSON.parse(obj.fs.readFileSync(obj.path.join(__dirname, 'package.json'), 'utf8')).version; } catch (e) { } // Fetch server version
// Setup the default configuration and files paths // Setup the default configuration and files paths
@ -391,7 +392,7 @@ function CreateMeshCentralServer(config, args) {
//wincmd.list(function (svc) { console.log(svc); }, true); //wincmd.list(function (svc) { console.log(svc); }, true);
// Check top level configuration for any unreconized values // Check top level configuration for any unreconized values
if (config) { for (var i in config) { if ((typeof i == 'string') && (i.length > 0) && (i[0] != '_') && (['settings', 'domains', 'configfiles', 'smtp', 'letsencrypt', 'peers'].indexOf(i) == -1)) { console.log('WARNING: unrecognized configuration option \"' + i + '\".'); } } } if (config) { for (var i in config) { if ((typeof i == 'string') && (i.length > 0) && (i[0] != '_') && (['settings', 'domains', 'configfiles', 'smtp', 'letsencrypt', 'peers'].indexOf(i) == -1)) { addServerWarning('WARNING: unrecognized configuration option \"' + i + '\".'); } } }
if (typeof obj.args.userallowedip == 'string') { if (obj.args.userallowedip == '') { obj.args.userallowedip = null; } else { obj.args.userallowedip = obj.args.userallowedip.split(','); } } if (typeof obj.args.userallowedip == 'string') { if (obj.args.userallowedip == '') { obj.args.userallowedip = null; } else { obj.args.userallowedip = obj.args.userallowedip.split(','); } }
if (typeof obj.args.userblockedip == 'string') { if (obj.args.userblockedip == '') { obj.args.userblockedip = null; } else { obj.args.userblockedip = obj.args.userblockedip.split(','); } } if (typeof obj.args.userblockedip == 'string') { if (obj.args.userblockedip == '') { obj.args.userblockedip = null; } else { obj.args.userblockedip = obj.args.userblockedip.split(','); } }
@ -759,9 +760,9 @@ function CreateMeshCentralServer(config, args) {
// Look at passed in arguments // Look at passed in arguments
if ((obj.args.user != null) && (typeof obj.args.user != 'string')) { delete obj.args.user; } if ((obj.args.user != null) && (typeof obj.args.user != 'string')) { delete obj.args.user; }
if ((obj.args.ciralocalfqdn != null) && ((obj.args.lanonly == true) || (obj.args.wanonly == true))) { console.log("WARNING: CIRA local FQDN's ignored when server in LAN-only or WAN-only mode."); } if ((obj.args.ciralocalfqdn != null) && ((obj.args.lanonly == true) || (obj.args.wanonly == true))) { addServerWarning("CIRA local FQDN's ignored when server in LAN-only or WAN-only mode."); }
if ((obj.args.ciralocalfqdn != null) && (obj.args.ciralocalfqdn.split(',').length > 4)) { console.log("WARNING: Can't have more than 4 CIRA local FQDN's. Ignoring value."); obj.args.ciralocalfqdn = null; } if ((obj.args.ciralocalfqdn != null) && (obj.args.ciralocalfqdn.split(',').length > 4)) { addServerWarning("Can't have more than 4 CIRA local FQDN's. Ignoring value."); obj.args.ciralocalfqdn = null; }
if (obj.args.ignoreagenthashcheck === true) { console.log("WARNING: Agent hash checking is being skipped, this is unsafe."); } if (obj.args.ignoreagenthashcheck === true) { addServerWarning("Agent hash checking is being skipped, this is unsafe."); }
if (obj.args.port == null || typeof obj.args.port != 'number') { if (obj.args.notls == null) { obj.args.port = 443; } else { obj.args.port = 80; } } if (obj.args.port == null || typeof obj.args.port != 'number') { if (obj.args.notls == null) { obj.args.port = 443; } else { obj.args.port = 80; } }
if (obj.args.aliasport != null && (typeof obj.args.aliasport != 'number')) obj.args.aliasport = null; if (obj.args.aliasport != null && (typeof obj.args.aliasport != 'number')) obj.args.aliasport = null;
if (obj.args.mpsport == null || typeof obj.args.mpsport != 'number') obj.args.mpsport = 4433; if (obj.args.mpsport == null || typeof obj.args.mpsport != 'number') obj.args.mpsport = 4433;
@ -843,7 +844,7 @@ function CreateMeshCentralServer(config, args) {
if ((obj.config) && (obj.config.settings) && (obj.config.settings.plugins != null)) { if ((obj.config) && (obj.config.settings) && (obj.config.settings.plugins != null)) {
const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
if (nodeVersion < 7) { if (nodeVersion < 7) {
console.log("WARNING: Plugin support requires Node 7 or higher."); addServerWarning("Plugin support requires Node v7.0 or higher.");
delete obj.config.settings.plugins; delete obj.config.settings.plugins;
} else { } else {
obj.pluginHandler = require('./pluginHandler.js').pluginHandler(obj); obj.pluginHandler = require('./pluginHandler.js').pluginHandler(obj);
@ -981,7 +982,7 @@ function CreateMeshCentralServer(config, args) {
if ((obj.config.smtp != null) && (obj.config.smtp.host != null) && (obj.config.smtp.from != null)) { if ((obj.config.smtp != null) && (obj.config.smtp.host != null) && (obj.config.smtp.from != null)) {
obj.mailserver = require('./meshmail.js').CreateMeshMail(obj); obj.mailserver = require('./meshmail.js').CreateMeshMail(obj);
obj.mailserver.verify(); obj.mailserver.verify();
if (obj.args.lanonly == true) { console.log("WARNING: SMTP server has limited use in LAN mode."); } if (obj.args.lanonly == true) { addServerWarning("SMTP server has limited use in LAN mode."); }
} }
// Start periodic maintenance // Start periodic maintenance
@ -1931,6 +1932,7 @@ function CreateMeshCentralServer(config, args) {
function logInfoEvent(msg) { if (obj.servicelog != null) { obj.servicelog.info(msg); } console.log(msg); } function logInfoEvent(msg) { if (obj.servicelog != null) { obj.servicelog.info(msg); } console.log(msg); }
function logWarnEvent(msg) { if (obj.servicelog != null) { obj.servicelog.warn(msg); } console.log(msg); } function logWarnEvent(msg) { if (obj.servicelog != null) { obj.servicelog.warn(msg); } console.log(msg); }
function logErrorEvent(msg) { if (obj.servicelog != null) { obj.servicelog.error(msg); } console.error(msg); } function logErrorEvent(msg) { if (obj.servicelog != null) { obj.servicelog.error(msg); } console.error(msg); }
obj.getServerWarnings = function() { return serverWarnings; }
// Return the path of a file into the meshcentral-data path // Return the path of a file into the meshcentral-data path
obj.getConfigFilePath = function (filename) { obj.getConfigFilePath = function (filename) {
@ -2036,10 +2038,14 @@ function InstallModule(modulename, func, tag1, tag2) {
// Detect CTRL-C on Linux and stop nicely // Detect CTRL-C on Linux and stop nicely
process.on('SIGINT', function () { if (meshserver != null) { meshserver.Stop(); meshserver = null; } console.log('Server Ctrl-C exit...'); process.exit(); }); process.on('SIGINT', function () { if (meshserver != null) { meshserver.Stop(); meshserver = null; } console.log('Server Ctrl-C exit...'); process.exit(); });
// Add a server warning, warnings will be shown to the administrator on the web application
var serverWarnings = [];
function addServerWarning(msg, print) { serverWarnings.push(msg); if (print !== false) { console.log("WARNING: " + msg); } }
// Load the really basic modules // Load the really basic modules
var meshserver = null; var meshserver = null;
var childProcess = null; var childProcess = null;
var previouslyInstalledModules = { }; var previouslyInstalledModules = {};
function mainStart() { function mainStart() {
// Check the NodeJS is version 6 or better. // Check the NodeJS is version 6 or better.
if (Number(process.version.match(/^v(\d+\.\d+)/)[1]) < 6) { console.log("MeshCentral requires Node v6.x or above, current version is " + process.version + "."); return; } if (Number(process.version.match(/^v(\d+\.\d+)/)[1]) < 6) { console.log("MeshCentral requires Node v6.x or above, current version is " + process.version + "."); return; }
@ -2076,7 +2082,7 @@ function mainStart() {
var modules = ['ws', 'cbor', 'nedb', 'https', 'yauzl', 'xmldom', 'ipcheck', 'express', 'archiver', 'multiparty', 'node-forge', 'express-ws', 'compression', 'body-parser', 'connect-redis', 'cookie-session', 'express-handlebars']; var modules = ['ws', 'cbor', 'nedb', 'https', 'yauzl', 'xmldom', 'ipcheck', 'express', 'archiver', 'multiparty', 'node-forge', 'express-ws', 'compression', 'body-parser', 'connect-redis', 'cookie-session', 'express-handlebars'];
if (require('os').platform() == 'win32') { modules.push('node-windows'); if (sspi == true) { modules.push('node-sspi'); } } // Add Windows modules if (require('os').platform() == 'win32') { modules.push('node-windows'); if (sspi == true) { modules.push('node-sspi'); } } // Add Windows modules
if (ldap == true) { modules.push('ldapauth-fork'); } if (ldap == true) { modules.push('ldapauth-fork'); }
if (config.letsencrypt != null) { if ((nodeVersion < 10) || (require('crypto').generateKeyPair == null)) { if (!args.launch) { console.log("WARNING: Let's Encrypt support requires Node v10.12.0 or higher."); } } else { modules.push('greenlock'); } } // Add Greenlock Module if (config.letsencrypt != null) { if ((nodeVersion < 10) || (require('crypto').generateKeyPair == null)) { addServerWarning("Let's Encrypt support requires Node v10.12 or higher.", !args.launch); } else { modules.push('greenlock'); } } // Add Greenlock Module
if (config.settings.mqtt != null) { modules.push('aedes'); } // Add MQTT Modules if (config.settings.mqtt != null) { modules.push('aedes'); } // Add MQTT Modules
if (config.settings.mongodb != null) { modules.push('mongodb'); } // Add MongoDB, official driver. if (config.settings.mongodb != null) { modules.push('mongodb'); } // Add MongoDB, official driver.
if (config.settings.vault != null) { modules.push('node-vault'); } // Add official HashiCorp's Vault module. if (config.settings.vault != null) { modules.push('node-vault'); } // Add official HashiCorp's Vault module.

View File

@ -355,9 +355,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Send user information to web socket, this is the first thing we send // Send user information to web socket, this is the first thing we send
try { ws.send(JSON.stringify({ action: 'userinfo', userinfo: parent.CloneSafeUser(parent.users[user._id]) })); } catch (ex) { } try { ws.send(JSON.stringify({ action: 'userinfo', userinfo: parent.CloneSafeUser(parent.users[user._id]) })); } catch (ex) { }
// Send server tracing information
if (user.siteadmin == 0xFFFFFFFF) { if (user.siteadmin == 0xFFFFFFFF) {
// Send server tracing information
try { ws.send(JSON.stringify({ action: 'traceinfo', traceSources: parent.parent.debugRemoteSources })); } catch (ex) { } try { ws.send(JSON.stringify({ action: 'traceinfo', traceSources: parent.parent.debugRemoteSources })); } catch (ex) { }
// Send any server warnings if any
var serverWarnings = parent.parent.getServerWarnings();
if (serverWarnings.length > 0) { try { ws.send(JSON.stringify({ action: 'serverwarnings', warnings: serverWarnings })); } catch (ex) { } }
} }
// See how many times bad login attempts where made since the last login // See how many times bad login attempts where made since the last login

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.4.4-y", "version": "0.4.5-a",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

View File

@ -810,7 +810,7 @@ NoMeshesPanel img {
padding-left: 15px; padding-left: 15px;
} }
#p2noMeshFound, #serverStats { #p2noMeshFound, #serverStats, #serverWarnings {
margin-left: 40px; margin-left: 40px;
} }

File diff suppressed because one or more lines are too long

View File

@ -414,6 +414,10 @@
</div><br /><br /> </div><br /><br />
<div id="serverStatsTable"></div> <div id="serverStatsTable"></div>
</div> </div>
<div id="serverWarningsDiv" style="display:none">
<br /><strong>Server Warnings</strong><br /><br />
<div id="serverWarnings"></div>
</div>
</div> </div>
<div id=p10 style="display:none"> <div id=p10 style="display:none">
<table style="width:100%" cellpadding="0" cellspacing="0"> <table style="width:100%" cellpadding="0" cellspacing="0">
@ -469,7 +473,7 @@
<div id="idx_deskFullBtn2" onclick=deskToggleFull(event)>&nbsp;&#x2716;</div> <div id="idx_deskFullBtn2" onclick=deskToggleFull(event)>&nbsp;&#x2716;</div>
<input type="button" id="autoconnectbutton1" value="AutoConnect" onclick=autoConnectDesktop(event) onkeypress="return false" onkeydown="return false" style="display:none" /> <input type="button" id="autoconnectbutton1" value="AutoConnect" onclick=autoConnectDesktop(event) onkeypress="return false" onkeydown="return false" style="display:none" />
<span id=connectbutton1span><input type=button id=connectbutton1 value="Connect" onclick=connectDesktop(event,1) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span> <span id=connectbutton1span><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=connectbutton1hspan>&nbsp;<input type=button id=connectbutton1h value="HW Connect" title="Connect using Intel AMT hardware KVM" 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> <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> &nbsp;<span id="deskstatus">Disconnected</span>
</div> </div>
@ -564,7 +568,7 @@
<div> <div>
<input type="button" id="autoconnectbutton2" value="AutoConnect" onclick=autoConnectTerminal(event) onkeypress="return false" onkeydown="return false" style="display:none" /> <input type="button" id="autoconnectbutton2" value="AutoConnect" onclick=autoConnectTerminal(event) onkeypress="return false" onkeydown="return false" style="display:none" />
<span id="connectbutton2span"><input type="button" id="connectbutton2" value="Connect" onclick=connectTerminal(event,1) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span> <span id="connectbutton2span"><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="connectbutton2hspan">&nbsp;<input type="button" id="connectbutton2h" value="HW Connect" title="Connect using Intel AMT hardware KVM" 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> <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><span id="termtitle"></span> &nbsp;<span id="termstatus">Disconnected</span><span id="termtitle"></span>
</div> </div>
@ -1504,6 +1508,15 @@
updateGeneralServerStats(message); updateGeneralServerStats(message);
break; break;
} }
case 'serverwarnings': {
if ((message.warnings != null) && (message.warnings.length > 0)) {
var x = '';
for (var i in message.warnings) { x += '<div style=color:red;padding-bottom:6px><b>' + "WARNING: " + message.warnings[i] + '</b></div>'; }
QH('serverWarnings', x);
QV('serverWarningsDiv', true);
}
break;
}
case 'servertimelinestats': { case 'servertimelinestats': {
setServerTimelineStats(message.events); setServerTimelineStats(message.events);
break; break;

File diff suppressed because one or more lines are too long

View File

@ -412,6 +412,10 @@
</div><br><br> </div><br><br>
<div id="serverStatsTable"></div> <div id="serverStatsTable"></div>
</div> </div>
<div id="serverWarningsDiv" style="display:none">
<br><strong>Server Warnings</strong><br><br>
<div id="serverWarnings"></div>
</div>
</div> </div>
<div id="p10" style="display:none"> <div id="p10" style="display:none">
<table style="width:100%" cellpadding="0" cellspacing="0"> <table style="width:100%" cellpadding="0" cellspacing="0">
@ -467,7 +471,7 @@
<div id="idx_deskFullBtn2" onclick="deskToggleFull(event)">&nbsp;✖</div> <div id="idx_deskFullBtn2" onclick="deskToggleFull(event)">&nbsp;✖</div>
<input type="button" id="autoconnectbutton1" value="AutoConnect" onclick="autoConnectDesktop(event)" onkeypress="return false" onkeydown="return false" style="display:none"> <input type="button" id="autoconnectbutton1" value="AutoConnect" onclick="autoConnectDesktop(event)" onkeypress="return false" onkeydown="return false" style="display:none">
<span id="connectbutton1span"><input type="button" id="connectbutton1" value="Connect" onclick="connectDesktop(event,1)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="connectbutton1span"><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="connectbutton1hspan">&nbsp;<input type="button" id="connectbutton1h" value="HW Connect" title="Connect using Intel AMT hardware KVM" 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> <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> &nbsp;<span id="deskstatus">Disconnected</span>
</div> </div>
@ -562,7 +566,7 @@
<div> <div>
<input type="button" id="autoconnectbutton2" value="AutoConnect" onclick="autoConnectTerminal(event)" onkeypress="return false" onkeydown="return false" style="display:none"> <input type="button" id="autoconnectbutton2" value="AutoConnect" onclick="autoConnectTerminal(event)" onkeypress="return false" onkeydown="return false" style="display:none">
<span id="connectbutton2span"><input type="button" id="connectbutton2" value="Connect" onclick="connectTerminal(event,1)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="connectbutton2span"><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="connectbutton2hspan">&nbsp;<input type="button" id="connectbutton2h" value="HW Connect" title="Connect using Intel AMT hardware KVM" 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> <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><span id="termtitle"></span> &nbsp;<span id="termstatus">Disconnected</span><span id="termtitle"></span>
</div> </div>
@ -1502,6 +1506,15 @@
updateGeneralServerStats(message); updateGeneralServerStats(message);
break; break;
} }
case 'serverwarnings': {
if ((message.warnings != null) && (message.warnings.length > 0)) {
var x = '';
for (var i in message.warnings) { x += '<div style=color:red;padding-bottom:6px><b>' + "WARNING: " + message.warnings[i] + '</b></div>'; }
QH('serverWarnings', x);
QV('serverWarningsDiv', true);
}
break;
}
case 'servertimelinestats': { case 'servertimelinestats': {
setServerTimelineStats(message.events); setServerTimelineStats(message.events);
break; break;