diff --git a/agents/MeshCmd-signed.exe b/agents/MeshCmd-signed.exe index 72e03d9a..c8609c70 100644 Binary files a/agents/MeshCmd-signed.exe and b/agents/MeshCmd-signed.exe differ diff --git a/agents/MeshCmd64-signed.exe b/agents/MeshCmd64-signed.exe index 2e04c399..9215c9a2 100644 Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ diff --git a/agents/meshcmd.js b/agents/meshcmd.js index f216fa5b..2e0a2b41 100644 --- a/agents/meshcmd.js +++ b/agents/meshcmd.js @@ -70,7 +70,7 @@ function onVerifyServer(clientName, certs) { if (certs == null) { certs = clientName; } // Temporary thing until we fix duktape // If we have the serverid, used delayed server authentication - if (settings.serverid != null) { settings.meshServerTlsHash = certs[certs.length - 1].fingerprint.split(':').join(''); return; } + if (settings.serverid != null) { settings.meshServerTlsHash = certs[certs.length - 1].fingerprint.replace(/:/g, ''); return; } // Otherwise, use server HTTPS certificate hash try { for (var i in certs) { if (certs[i].fingerprint.replace(/:/g, '') == settings.serverhttpshash) { return; } } } catch (e) { } @@ -2064,6 +2064,11 @@ function OnServerWebSocket(msg, s, head) { var signDataHash = hasher.syncHash(Buffer.concat([Buffer.from(settings.serverAuthClientNonce, 'base64'), Buffer.from(settings.meshServerTlsHash, 'hex'), Buffer.from(command.nonce, 'base64')])); if (require('RSA').verify(require('RSA').TYPES.SHA384, cert, signDataHash, Buffer.from(command.signature, 'base64')) == false) { console.log("Unable to authenticate the server, invalid signature."); process.exit(1); return; } + // Switch to using HTTPS TLS certificate for authentication + delete settings.serverid; + settings.serverhttpshash = settings.meshServerTlsHash; + delete settings.meshServerTlsHash; + // Figure out the 2FA token to use if any var xtoken = null; if (settings.emailtoken) { xtoken = '**email**'; } diff --git a/meshcentral.js b/meshcentral.js index fbf5095e..b0f632f3 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -3115,7 +3115,7 @@ function mainStart() { if (passport != null) { modules.push(...passport); } if (sessionRecording == true) { modules.push('image-size'); } // Need to get the remote desktop JPEG sizes to index the recodring file. if (config.letsencrypt != null) { if (nodeVersion < 8) { addServerWarning("Let's Encrypt support requires Node v8.x or higher.", !args.launch); } else { modules.push('acme-client'); } } // Add acme-client module - if (config.settings.mqtt != null) { modules.push('aedes'); } // Add MQTT Modules + if (config.settings.mqtt != null) { modules.push('aedes@0.39.0'); } // Add MQTT Modules if (config.settings.mysql != null) { modules.push('mysql'); } // Add MySQL. //if (config.settings.mysql != null) { modules.push('@mysql/xdevapi'); } // Add MySQL, official driver (https://dev.mysql.com/doc/dev/connector-nodejs/8.0/) if (config.settings.mongodb != null) { modules.push('mongodb'); modules.push('saslprep'); } // Add MongoDB, official driver. diff --git a/meshuser.js b/meshuser.js index dc405e1b..e3b95265 100644 --- a/meshuser.js +++ b/meshuser.js @@ -5146,7 +5146,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Get the node and the rights for this node parent.GetNodeWithRights(domain, user, command.nodeids[i], function (node, rights, visible) { // If this device is connected on MQTT, send a wake action. - if (rights != 0) { parent.parent.mqttbroker.publish(node._id, command.topic, command.msg); } + if (rights != 0) { + parent.parent.mqttbroker.publish(node._id, command.topic, command.msg); + } }); } diff --git a/mqttbroker.js b/mqttbroker.js index 87494d97..26a9ca4f 100644 --- a/mqttbroker.js +++ b/mqttbroker.js @@ -13,9 +13,9 @@ module.exports.CreateMQTTBroker = function (parent, db, args) { obj.db = db; obj.args = args; obj.connections = {}; // NodesID --> client array - const aedes = require("aedes")(); + const aedes = require('aedes')(); obj.handle = aedes.handle; - const allowedSubscriptionTopics = [ 'presence' ]; + const allowedSubscriptionTopics = ['presence', 'console', 'powerAction']; const denyError = new Error('denied'); var authError = new Error('Auth error') authError.returnCode = 1 @@ -127,7 +127,9 @@ module.exports.CreateMQTTBroker = function (parent, db, args) { if (typeof message == 'string') { message = Buffer.from(message); } for (var i in clients) { // Only publish to client that subscribe to the topic - if (clients[i].subscriptions[topic] != null) { clients[i].publish({ cmd: 'publish', qos: 0, topic: topic, payload: message, retain: false }); } + if (clients[i].subscriptions[topic] != null) { + clients[i].publish({ cmd: 'publish', qos: 0, topic: topic, payload: message, retain: false }, function () { }); + } } } diff --git a/package.json b/package.json index 47c4f48f..c18d3dd1 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,9 @@ "sample-config-advanced.json" ], "dependencies": { + "aedes": "^0.45.0", + "archiver": "^4.0.2", + "archiver-zip-encrypted": "^1.0.8", "body-parser": "^1.19.0", "cbor": "~5.2.0", "compression": "^1.7.4", @@ -44,14 +47,23 @@ "express": "^4.17.0", "express-handlebars": "^3.1.0", "express-ws": "^4.0.0", + "image-size": "^0.9.7", "ipcheck": "^0.1.0", + "loadavg-windows": "^1.1.1", "minimist": "^1.2.0", + "mongodb": "^3.6.5", "multiparty": "^4.2.1", "nedb": "^1.8.0", "node-forge": "^0.10.0", + "node-rdpjs-2": "^0.3.5", + "node-windows": "^1.0.0-beta.5", + "otplib": "^10.2.3", + "saslprep": "^1.0.3", + "web-push": "^3.4.4", "ws": "^6.2.1", "xmldom": "^0.5.0", - "yauzl": "^2.10.0" + "yauzl": "^2.10.0", + "yubikeyotp": "^0.2.0" }, "repository": { "type": "git",