diff --git a/meshcentral.js b/meshcentral.js index 1796776f..7729abbe 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -1217,10 +1217,17 @@ function CreateMeshCentralServer(config, args) { obj.DispatchEvent(['*'], obj, { etype: 'server', action: 'started', msg: 'Server started' }); // Plugin hook. Need to run something at server startup? This is the place. - if (obj.pluginHandler) { obj.pluginHandler.callHook("server_startup"); } + if (obj.pluginHandler) { obj.pluginHandler.callHook('server_startup'); } - // Load the login cookie encryption key from the database if allowed - if ((obj.config) && (obj.config.settings) && (obj.config.settings.allowlogintoken == true)) { + // Setup the login cookie encryption key + if ((obj.config) && (obj.config.settings) && (typeof obj.config.settings.logincookieencryptionkey == 'string')) { + // We have a string, hash it and use that as a key + try { obj.loginCookieEncryptionKey = Buffer.from(obj.config.settings.logincookieencryptionkey, 'hex'); } catch (ex) { } + if ((obj.loginCookieEncryptionKey == null) || (obj.loginCookieEncryptionKey.length != 80)) { addServerWarning("Invalid \"LoginCookieEncryptionKey\" in config.json."); obj.loginCookieEncryptionKey = null; } + } + + // Login cookie encryption key not set, use one from the database + if (obj.loginCookieEncryptionKey == null) { obj.db.Get('LoginCookieEncryptionKey', function (err, docs) { if ((docs.length > 0) && (docs[0].key != null) && (obj.args.logintokengen == null) && (docs[0].key.length >= 160)) { obj.loginCookieEncryptionKey = Buffer.from(docs[0].key, 'hex'); diff --git a/meshuser.js b/meshuser.js index f8531607..4403a625 100644 --- a/meshuser.js +++ b/meshuser.js @@ -700,26 +700,30 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use break; } case 'badlogins': { - if (typeof parent.parent.config.settings.maxinvalidlogin.coolofftime == 'number') { - r = "Max is " + parent.parent.config.settings.maxinvalidlogin.count + " bad login(s) in " + parent.parent.config.settings.maxinvalidlogin.time + " minute(s), " + parent.parent.config.settings.maxinvalidlogin.coolofftime + " minute(s) cooloff.\r\n"; + if (parent.parent.config.settings.maxinvalidlogin == false) { + r = 'Bad login filter is disabled.'; } else { - r = "Max is " + parent.parent.config.settings.maxinvalidlogin.count + " bad login(s) in " + parent.parent.config.settings.maxinvalidlogin.time + " minute(s).\r\n"; - } - var badLoginCount = 0; - parent.cleanBadLoginTable(); - for (var i in parent.badLoginTable) { - badLoginCount++; - if (typeof parent.badLoginTable[i] == 'number') { - r += "Cooloff for " + Math.floor((parent.badLoginTable[i] - Date.now()) / 60000) + " minute(s)\r\n"; + if (typeof parent.parent.config.settings.maxinvalidlogin.coolofftime == 'number') { + r = "Max is " + parent.parent.config.settings.maxinvalidlogin.count + " bad login(s) in " + parent.parent.config.settings.maxinvalidlogin.time + " minute(s), " + parent.parent.config.settings.maxinvalidlogin.coolofftime + " minute(s) cooloff.\r\n"; } else { - if (parent.badLoginTable[i].length > 1) { - r += (i + ' - ' + parent.badLoginTable[i].length + " records\r\n"); + r = "Max is " + parent.parent.config.settings.maxinvalidlogin.count + " bad login(s) in " + parent.parent.config.settings.maxinvalidlogin.time + " minute(s).\r\n"; + } + var badLoginCount = 0; + parent.cleanBadLoginTable(); + for (var i in parent.badLoginTable) { + badLoginCount++; + if (typeof parent.badLoginTable[i] == 'number') { + r += "Cooloff for " + Math.floor((parent.badLoginTable[i] - Date.now()) / 60000) + " minute(s)\r\n"; } else { - r += (i + ' - ' + parent.badLoginTable[i].length + " record\r\n"); + if (parent.badLoginTable[i].length > 1) { + r += (i + ' - ' + parent.badLoginTable[i].length + " records\r\n"); + } else { + r += (i + ' - ' + parent.badLoginTable[i].length + " record\r\n"); + } } } + if (badLoginCount == 0) { r += 'No bad logins.'; } } - if (badLoginCount == 0) { r += 'No bad logins.'; } break; } case 'dispatchtable': { diff --git a/package.json b/package.json index f34f84f2..56bf2e37 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.4.9-i", + "version": "0.4.9-j", "keywords": [ "Remote Management", "Intel AMT", diff --git a/webserver.js b/webserver.js index e4abcc63..88b885c9 100644 --- a/webserver.js +++ b/webserver.js @@ -2676,8 +2676,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { // Fetch the mesh object ws.meshid = 'mesh/' + domain.id + '/' + req.query.id; const mesh = obj.meshes[ws.meshid]; - if (mesh == null) { delete ws.meshid; ws.send(JSON.stringify({ errorText: 'Invalid device group' })); ws.close(); return; } - if (mesh.mtype != 1) { ws.send(JSON.stringify({ errorText: 'Invalid device group type' })); ws.close(); return; } + if (mesh == null) { delete ws.meshid; ws.send(JSON.stringify({ errorText: 'Invalid device group: ' + ws.meshid })); ws.close(); return; } + if (mesh.mtype != 1) { ws.send(JSON.stringify({ errorText: 'Invalid device group type:' + ws.meshid })); ws.close(); return; } // Fetch the remote IP:Port for logging ws.remoteaddr = cleanRemoteAddr(req.ip); @@ -4516,11 +4516,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { obj.badLoginTable = {}; obj.badLoginTableLastClean = 0; if (parent.config.settings == null) { parent.config.settings = {}; } - if (parent.config.settings.maxinvalidlogin == null) { parent.config.settings.maxinvalidlogin = { time: 10, count: 10 }; } - if (typeof parent.config.settings.maxinvalidlogin.time != 'number') { parent.config.settings.maxinvalidlogin.time = 10; } - if (typeof parent.config.settings.maxinvalidlogin.count != 'number') { parent.config.settings.maxinvalidlogin.count = 10; } - if ((typeof parent.config.settings.maxinvalidlogin.coolofftime != 'number') || (parent.config.settings.maxinvalidlogin.coolofftime < 1)) { parent.config.settings.maxinvalidlogin.coolofftime = null; } + if (parent.config.settings.maxinvalidlogin !== false) { + if (typeof parent.config.settings.maxinvalidlogin != 'object') { parent.config.settings.maxinvalidlogin = { time: 10, count: 10 }; } + if (typeof parent.config.settings.maxinvalidlogin.time != 'number') { parent.config.settings.maxinvalidlogin.time = 10; } + if (typeof parent.config.settings.maxinvalidlogin.count != 'number') { parent.config.settings.maxinvalidlogin.count = 10; } + if ((typeof parent.config.settings.maxinvalidlogin.coolofftime != 'number') || (parent.config.settings.maxinvalidlogin.coolofftime < 1)) { parent.config.settings.maxinvalidlogin.coolofftime = null; } + } obj.setbadLogin = function (ip) { // Set an IP address that just did a bad login request + if (parent.config.settings.maxinvalidlogin === false) return; if (typeof ip == 'object') { ip = cleanRemoteAddr(ip.ip); } var splitip = ip.split('.'); if (splitip.length == 4) { ip = (splitip[0] + '.' + splitip[1] + '.' + splitip[2] + '.*'); } @@ -4532,6 +4535,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { } } obj.checkAllowLogin = function (ip) { // Check if an IP address is allowed to login + if (parent.config.settings.maxinvalidlogin === false) return true; if (typeof ip == 'object') { ip = cleanRemoteAddr(ip.ip); } var splitip = ip.split('.'); if (splitip.length == 4) { ip = (splitip[0] + '.' + splitip[1] + '.' + splitip[2] + '.*'); } // If this is IPv4, keep only the 3 first @@ -4544,6 +4548,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { return (ipTable.length < parent.config.settings.maxinvalidlogin.count); // No more than x bad logins in x minutes } obj.cleanBadLoginTable = function () { // Clean up the IP address login blockage table, we do this occasionaly. + if (parent.config.settings.maxinvalidlogin === false) return; var cutoffTime = Date.now() - (parent.config.settings.maxinvalidlogin.time * 60000); // Time in minutes for (var ip in obj.badLoginTable) { var ipTable = obj.badLoginTable[ip];