From 49c41cb02c8dd7a6c64c4bfcd0c6b43d530b4fae Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Tue, 3 Nov 2020 02:58:29 -0800 Subject: [PATCH] Fixes for MeshCore and MariaDB. --- agents/meshcore.js | 13 +++++++++---- db.js | 17 +++++++---------- meshcentral.js | 6 +++--- webserver.js | 2 +- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/agents/meshcore.js b/agents/meshcore.js index 1d135ac3..8b8d59c5 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -2579,7 +2579,7 @@ function createMeshCore(agent) { var response = null; switch (cmd) { case 'help': { // Displays available commands - var fin = '', f = '', availcommands = 'coreinfo, coredump,service,fdsnapshot,fdcount,startupoptions,alert,agentsize,versions,help,info,osinfo,args,print,type,dbkeys,dbget,dbset,dbcompact,eval,parseuri,httpget,nwslist,plugin,wsconnect,wssend,wsclose,notify,ls,ps,kill,netinfo,location,power,wakeonlan,setdebug,smbios,rawsmbios,toast,lock,users,openurl,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,wallpaper,agentmsg'; + var fin = '', f = '', availcommands = 'coreinfo,coredump,service,fdsnapshot,fdcount,startupoptions,alert,agentsize,versions,help,info,osinfo,args,print,type,dbkeys,dbget,dbset,dbcompact,eval,parseuri,httpget,nwslist,plugin,wsconnect,wssend,wsclose,notify,ls,ps,kill,netinfo,location,power,wakeonlan,setdebug,smbios,rawsmbios,toast,lock,users,openurl,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,wallpaper,agentmsg'; if (process.platform == 'win32') { availcommands += ',safemode,wpfhwacceleration,uac'; } if (amt != null) { availcommands += ',amt,amtconfig,amtevents'; } if (process.platform != 'freebsd') { availcommands += ',vm';} @@ -3647,7 +3647,7 @@ function createMeshCore(agent) { // Update the server on with basic info, logged in users and more advanced stuff, like Intel ME and Network Settings meInfoStr = null; - sendPeriodicServerUpdate(); + sendPeriodicServerUpdate(null, true); if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes // Send any state messages @@ -3708,7 +3708,10 @@ function createMeshCore(agent) { if (force) { meshCoreObj = sortObjRec(meshCoreObj); var x = JSON.stringify(meshCoreObj); - if (x != LastPeriodicServerUpdate) { LastPeriodicServerUpdate = x; mesh.SendCommand(meshCoreObj); } + if (x != LastPeriodicServerUpdate) { + LastPeriodicServerUpdate = x; + mesh.SendCommand(meshCoreObj); + } } } @@ -3720,7 +3723,9 @@ function createMeshCore(agent) { PeriodicServerUpdateNagleTimer = null; meshCoreObj = sortObjRec(meshCoreObj); var x = JSON.stringify(meshCoreObj); - if (x != LastPeriodicServerUpdate) { LastPeriodicServerUpdate = x; mesh.SendCommand(meshCoreObj); } + if (x != LastPeriodicServerUpdate) { + try { LastPeriodicServerUpdate = x; mesh.SendCommand(meshCoreObj); } catch (ex) { } + } } function sortObjRec(o) { if ((typeof o != 'object') || (Array.isArray(o))) return o; for (var i in o) { if (typeof o[i] == 'object') { o[i] = sortObjRec(o[i]); } } return sortObj(o); } diff --git a/db.js b/db.js index 5814949e..e82290a9 100644 --- a/db.js +++ b/db.js @@ -261,6 +261,7 @@ module.exports.CreateDB = function (parent, func) { function performTypedRecordDecrypt(data) { if ((data == null) || (obj.dbRecordsDecryptKey == null) || (typeof data != 'object')) return data; for (var i in data) { + if (data[i] == null) continue; if (data[i].type == 'user') { data[i] = performPartialRecordDecrypt(data[i]); } else if ((data[i].type == 'node') && (data[i].intelamt != null)) { @@ -762,7 +763,7 @@ module.exports.CreateDB = function (parent, func) { .then(function (rows) { conn.release(); const docs = []; - for (var i in rows) { if (rows[i].doc) { docs.push(performTypedRecordDecrypt(JSON.parse(rows[i].doc))); } } + for (var i in rows) { if (rows[i].doc) { docs.push(performTypedRecordDecrypt((typeof rows[i].doc == 'object')? rows[i].doc : JSON.parse(rows[i].doc))); } } if (func) try { func(null, docs); } catch (ex) { console.log('SQLERR1', ex); } }) .catch(function (err) { conn.release(); if (func) try { func(err); } catch (ex) { console.log('SQLERR2', ex); } }); @@ -827,16 +828,12 @@ module.exports.CreateDB = function (parent, func) { obj.Set = function (value, func) { var extra = null, extraex = null; value = common.escapeLinksFieldNameEx(value); - if (value.meshid) { extra = value.meshid; } else if (value.email) { extra = 'email/' + value.email; } + if (value.meshid) { extra = value.meshid; } else if (value.email) { extra = 'email/' + value.email; } else if (value.nodeid) { extra = value.nodeid; } if ((value.type == 'node') && (value.intelamt != null) && (value.intelamt.uuid != null)) { extraex = 'uuid/' + value.intelamt.uuid; } + if (value._id == null) { value._id = require('crypto').randomBytes(16).toString('hex'); } sqlDbQuery('REPLACE INTO meshcentral.main VALUE (?, ?, ?, ?, ?, ?)', [value._id, (value.type ? value.type : null), ((value.domain != null) ? value.domain : null), extra, extraex, JSON.stringify(performTypedRecordEncrypt(value))], func); } - obj.Get = function (_id, func) { - sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ?', [_id], function (err, docs) { - if ((docs != null) && (docs.length > 0) && (docs[0].links != null)) { docs[0] = common.unEscapeLinksFieldName(docs[0]); } - func(err, docs); - }); - } + obj.Get = function (_id, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ?', [_id], function (err, docs) { if ((docs != null) && (docs.length > 0) && (docs[0].links != null)) { docs[0] = common.unEscapeLinksFieldName(docs[0]); } func(err, docs); }); } obj.GetAll = function (func) { sqlDbQuery('SELECT domain, doc FROM meshcentral.main', null, func); } obj.GetHash = function (id, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ?', [id], func); } obj.GetAllTypeNoTypeField = function (type, domain, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = ? AND domain = ?', [type, domain], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, docs); }); }; @@ -853,9 +850,9 @@ module.exports.CreateDB = function (parent, func) { }; obj.GetAllTypeNodeFiltered = function (nodes, domain, type, id, func) { if (id && (id != '')) { - sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ? AND type = ? AND domain = ? AND nodeid IN (?)', [id, type, domain, nodes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, docs); }); + sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ? AND type = ? AND domain = ? AND extra IN (?)', [id, type, domain, nodes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, docs); }); } else { - sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = ? AND domain = ? AND nodeid IN (?)', [type, domain, nodes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, docs); }); + sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = ? AND domain = ? AND extra IN (?)', [type, domain, nodes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, docs); }); } }; obj.GetAllType = function (type, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = ?', [type], func); } diff --git a/meshcentral.js b/meshcentral.js index 7630a291..da24097c 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -1156,7 +1156,7 @@ function CreateMeshCentralServer(config, args) { // Read or setup database configuration values obj.db.Get('dbconfig', function (err, dbconfig) { - if (dbconfig.length == 1) { obj.dbconfig = dbconfig[0]; } else { obj.dbconfig = { _id: 'dbconfig', version: 1 }; } + if ((dbconfig != null) && (dbconfig.length == 1)) { obj.dbconfig = dbconfig[0]; } else { obj.dbconfig = { _id: 'dbconfig', version: 1 }; } if (obj.dbconfig.amtWsEventSecret == null) { obj.crypto.randomBytes(32, function (err, buf) { obj.dbconfig.amtWsEventSecret = buf.toString('hex'); obj.db.Set(obj.dbconfig); }); } // This is used by the user to create a username/password for a Intel AMT WSMAN event subscription @@ -1384,7 +1384,7 @@ function CreateMeshCentralServer(config, args) { // 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)) { + if ((docs != null) && (docs.length > 0) && (docs[0].key != null) && (obj.args.logintokengen == null) && (docs[0].key.length >= 160)) { obj.loginCookieEncryptionKey = Buffer.from(docs[0].key, 'hex'); } else { obj.loginCookieEncryptionKey = obj.generateCookieKey(); obj.db.Set({ _id: 'LoginCookieEncryptionKey', key: obj.loginCookieEncryptionKey.toString('hex'), time: Date.now() }); @@ -1394,7 +1394,7 @@ function CreateMeshCentralServer(config, args) { // Load the invitation link encryption key from the database obj.db.Get('InvitationLinkEncryptionKey', function (err, docs) { - if ((docs.length > 0) && (docs[0].key != null) && (docs[0].key.length >= 160)) { + if ((docs != null) && (docs.length > 0) && (docs[0].key != null) && (docs[0].key.length >= 160)) { obj.invitationLinkEncryptionKey = Buffer.from(docs[0].key, 'hex'); } else { obj.invitationLinkEncryptionKey = obj.generateCookieKey(); obj.db.Set({ _id: 'InvitationLinkEncryptionKey', key: obj.invitationLinkEncryptionKey.toString('hex'), time: Date.now() }); diff --git a/webserver.js b/webserver.js index 8a9abf63..17b38d6f 100644 --- a/webserver.js +++ b/webserver.js @@ -1167,7 +1167,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { } else { // Check if this email was already verified obj.db.GetUserWithVerifiedEmail(domain.id, req.body.email, function (err, docs) { - if (docs.length > 0) { + if ((docs != null) && (docs.length > 0)) { parent.debug('web', 'handleCreateAccountRequest: Existing account with this email address'); req.session.loginmode = '2'; req.session.messageid = 102; // Existing account with this email address.