From 7cc52184229e42556c5732a68a8f66a715820692 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 21 Sep 2016 15:02:50 +0200 Subject: [PATCH] Messages are now verified by the users instead of the server --- NetfluxWebsocketSrv.js | 44 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/NetfluxWebsocketSrv.js b/NetfluxWebsocketSrv.js index 499a3cde8..fb826a3f3 100644 --- a/NetfluxWebsocketSrv.js +++ b/NetfluxWebsocketSrv.js @@ -13,6 +13,7 @@ const USE_FILE_BACKUP_STORAGE = true; let dropUser; +let historyKeeperKeys = {}; const now = function () { return (new Date()).getTime(); }; @@ -28,21 +29,22 @@ const sendMsg = function (ctx, user, msg) { const sendChannelMessage = function (ctx, channel, msgStruct) { msgStruct.unshift(0); - if (msgStruct[2] === 'MSG' && channel.validateKey) { - let msg = Nacl.util.decodeBase64(msgStruct[4]); - let validated = Nacl.sign.open(msg, channel.validateKey); - if (!validated) { - console.log("Unsigned message rejected"); - return; - } - msgStruct[4] = Nacl.util.encodeUTF8(validated); - } channel.forEach(function (user) { if(msgStruct[2] !== 'MSG' || user.id !== msgStruct[1]) { // We don't want to send back a message to its sender, in order to save bandwidth sendMsg(ctx, user, msgStruct); } }); if (USE_HISTORY_KEEPER && msgStruct[2] === 'MSG') { + if (historyKeeperKeys[channel.id]) { + let signedMsg = msgStruct[4].replace(/^cp\|/, ''); + signedMsg = Nacl.util.decodeBase64(signedMsg); + let validateKey = Nacl.util.decodeBase64(historyKeeperKeys[channel.id]); + let validated = Nacl.sign.open(signedMsg, validateKey); + if (!validated) { + console.log("Signed message rejected"); + return; + } + } ctx.store.message(channel.id, JSON.stringify(msgStruct), function (err) { if (err && typeof(err) !== 'function') { // ignore functions because older datastores @@ -78,6 +80,7 @@ dropUser = function (ctx, user) { if (chan.length === 0) { console.log("Removing empty channel ["+chanName+"]"); delete ctx.channels[chanName]; + delete historyKeeperKeys[chanName]; /* Call removeChannel if it is a function and channel removal is set to true in the config file */ @@ -130,7 +133,7 @@ const getHistory = function (ctx, channelName, handler, cb) { // no checkpoints. for (var x = msgBuff2.pop(); x; x = msgBuff2.pop()) { handler(x); } } - cb(); + cb(messageBuf); }); }; @@ -159,17 +162,6 @@ const handleMessage = function (ctx, user, msg) { clearTimeout(ctx.timeouts[chanName]); } - // validation key? - if (json[2]) { - if (chan.validateKey && Nacl.util.encodeBase64(chan.validateKey) !== json[2]) { - sendMsg(ctx, user, [seq, 'ERROR', 'INVALID_KEY', obj]); - return; - } - if (!chan.validateKey) { - chan.validateKey = Nacl.util.decodeBase64(json[2]); - } - } - chan.id = chanName; if (USE_HISTORY_KEEPER) { sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'JOIN', chanName]); @@ -185,9 +177,17 @@ const handleMessage = function (ctx, user, msg) { try { parsed = JSON.parse(json[2]); } catch (err) { console.error(err); return; } if (parsed[0] === 'GET_HISTORY') { sendMsg(ctx, user, [seq, 'ACK']); + if (historyKeeperKeys[parsed[1]]) { + var key = {channel: parsed[1], validateKey: historyKeeperKeys[parsed[1]]}; + sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'MSG', user.id, JSON.stringify(key)]) + } getHistory(ctx, parsed[1], function (msg) { sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'MSG', user.id, JSON.stringify(msg)]); - }, function () { + }, function (messages) { + // parsed[2] is a validation key if it exists + if (messages.length === 0 && parsed[2] && !historyKeeperKeys[parsed[1]]) { + historyKeeperKeys[parsed[1]] = parsed[2]; + } sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'MSG', user.id, 0]); }); }