mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-03-09 15:40:18 +00:00
Added MQTT authentication.
This commit is contained in:
parent
5b69657b11
commit
4f014fc218
6 changed files with 123 additions and 13 deletions
|
@ -16,26 +16,46 @@ module.exports.CreateMQTTBroker = function (parent, db, args) {
|
|||
obj.handle = obj.aedes.handle;
|
||||
obj.connections = {}; // NodesID --> client array
|
||||
|
||||
// Generate a username and password for MQTT login
|
||||
obj.generateLogin = function (meshid, nodeid) {
|
||||
const meshidsplit = meshid.split('/'), nodeidsplit = nodeid.split('/');
|
||||
const xmeshid = meshidsplit[2], xnodeid = nodeidsplit[2], xdomainid = meshidsplit[1];
|
||||
const username = 'MCAuth1:' + xnodeid + ':' + xmeshid + ':' + xdomainid;
|
||||
const nonce = Buffer.from(parent.crypto.randomBytes(9), 'binary').toString('base64');
|
||||
return { meshid: meshid, nodeid: nodeid, user: username, pass: parent.config.settings.mqtt.auth.keyid + ':' + nonce + ':' + parent.crypto.createHash('sha384').update(username + ':' + nonce + ':' + parent.config.settings.mqtt.auth.key).digest("base64") };
|
||||
}
|
||||
|
||||
// Connection Authentication
|
||||
obj.aedes.authenticate = function (client, username, password, callback) {
|
||||
// TODO: add authentication handler
|
||||
obj.parent.debug("mqtt", "Authentication with " + username + ":" + password + ":" + client.id + ", " + client.conn.xtransport + "://" + cleanRemoteAddr(client.conn.xip));
|
||||
obj.parent.debug("mqtt", "Authentication User:" + username + ", Pass:" + password.toString() + ", ClientID:" + client.id + ", " + client.conn.xtransport + "://" + cleanRemoteAddr(client.conn.xip));
|
||||
|
||||
// Parse the username and password
|
||||
var usersplit = username.split(':');
|
||||
if (usersplit.length != 5) { callback(null, false); return; }
|
||||
var passsplit = password.toString().split(':');
|
||||
if ((usersplit.length !== 4) || (passsplit.length !== 3)) { obj.parent.debug("mqtt", "Invalid user/pass format, " + client.conn.xtransport + "://" + cleanRemoteAddr(client.conn.xip)); callback(null, false); return; }
|
||||
if (usersplit[0] !== 'MCAuth1') { obj.parent.debug("mqtt", "Invalid auth method, " + client.conn.xtransport + "://" + cleanRemoteAddr(client.conn.xip)); callback(null, false); return; }
|
||||
|
||||
// Check authentication
|
||||
if (passsplit[0] !== parent.config.settings.mqtt.auth.keyid) { obj.parent.debug("mqtt", "Invalid auth keyid, " + client.conn.xtransport + "://" + cleanRemoteAddr(client.conn.xip)); callback(null, false); return; }
|
||||
if (parent.crypto.createHash('sha384').update(username + ':' + passsplit[1] + ':' + parent.config.settings.mqtt.auth.key).digest("base64") !== passsplit[2]) { obj.parent.debug("mqtt", "Invalid password, " + client.conn.xtransport + "://" + cleanRemoteAddr(client.conn.xip)); callback(null, false); return; }
|
||||
|
||||
// Setup the identifiers
|
||||
var xnodeid = usersplit[1];
|
||||
const xnodeid = usersplit[1];
|
||||
var xmeshid = usersplit[2];
|
||||
var xdomainid = usersplit[3];
|
||||
const xdomainid = usersplit[3];
|
||||
|
||||
// Check the domain
|
||||
if ((typeof client.conn.xdomain == 'object') && (xdomainid != client.conn.xdomain.id)) { obj.parent.debug("mqtt", "Invalid domain connection, " + client.conn.xtransport + "://" + cleanRemoteAddr(client.conn.xip)); callback(null, false); return; }
|
||||
|
||||
// Convert meshid from HEX to Base64 if needed
|
||||
if (xmeshid.length == 96) { xmeshid = Buffer.from(xmeshid, 'hex').toString('base64'); }
|
||||
if ((xmeshid.length != 64) || (xnodeid.length != 64)) { callback(null, false); return; }
|
||||
if (xmeshid.length === 96) { xmeshid = Buffer.from(xmeshid, 'hex').toString('base64'); }
|
||||
if ((xmeshid.length !== 64) || (xnodeid.length != 64)) { callback(null, false); return; }
|
||||
|
||||
client.xdbNodeKey = 'node/' + xdomainid + '/' + xnodeid;
|
||||
client.xdbMeshKey = 'mesh/' + xdomainid + '/' + xmeshid;
|
||||
|
||||
//console.log(obj.generateLogin(client.xdbMeshKey, client.xdbNodeKey));
|
||||
|
||||
// Check if this node exists in the database
|
||||
db.Get(client.xdbNodeKey, function (err, nodes) {
|
||||
if ((nodes == null) || (nodes.length != 1)) { callback(null, false); return; } // Node does not exist
|
||||
|
@ -75,6 +95,7 @@ module.exports.CreateMQTTBroker = function (parent, db, args) {
|
|||
// Check if a client can publish a packet
|
||||
obj.aedes.authorizePublish = function (client, packet, callback) {
|
||||
// TODO: add authorized publish control
|
||||
//console.log(packet);
|
||||
obj.parent.debug("mqtt", "AuthorizePublish, " + client.conn.xtransport + "://" + cleanRemoteAddr(client.conn.xip));
|
||||
callback(null);
|
||||
}
|
||||
|
@ -82,13 +103,14 @@ module.exports.CreateMQTTBroker = function (parent, db, args) {
|
|||
// Check if a client can publish a packet
|
||||
obj.aedes.authorizeSubscribe = function (client, sub, callback) {
|
||||
// TODO: add subscription control here
|
||||
obj.parent.debug("mqtt", "AuthorizeSubscribe, " + client.conn.xtransport + "://" + cleanRemoteAddr(client.conn.xip));
|
||||
obj.parent.debug("mqtt", "AuthorizeSubscribe \"" + sub.topic + "\", " + client.conn.xtransport + "://" + cleanRemoteAddr(client.conn.xip));
|
||||
callback(null, sub);
|
||||
}
|
||||
|
||||
// Check if a client can publish a packet
|
||||
// Check if a client can forward a packet
|
||||
obj.aedes.authorizeForward = function (client, packet) {
|
||||
// TODO: add forwarding control
|
||||
//console.log(packet);
|
||||
obj.parent.debug("mqtt", "AuthorizeForward, " + client.conn.xtransport + "://" + cleanRemoteAddr(client.conn.xip));
|
||||
//return packet;
|
||||
return packet;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue