Improved message routing access control.

Ylian Saint-Hilaire committed Jul 14, 2020 at 11:53 UTC 44d6d2cd298c256c5631b9fc27d7e257d0dafaab
1 file changed +15 -2
meshuser.js
+15 -2
@@ -175,7 +175,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
175 }
176
177 // Route a command to a target node
178 - function routeCommandToNode(command, func) {
178 + function routeCommandToNode(command, requiredRights, requiredNonRights, func) {
179 if (common.validateString(command.nodeid, 8, 128) == false) { if (func) { func(false); } return false; }
180 var splitnodeid = command.nodeid.split('/');
181 // Check that we are in the same domain and the user has rights over this node.
@@ -187,6 +187,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
187 parent.GetNodeWithRights(domain, user, agent.dbNodeKey, function (node, rights, visible) {
188 var mesh = parent.meshes[agent.dbMeshKey];
189 if ((node != null) && (mesh != null) && ((rights & MESHRIGHT_REMOTECONTROL) || (rights & MESHRIGHT_REMOTEVIEWONLY))) { // 8 is remote control permission, 256 is desktop read only
190 + if ((requiredRights != null) && ((rights & requiredRights) == 0)) { if (func) { func(false); return; } } // Check Required Rights
191 + if ((requiredNonRights != null) && (rights != MESHRIGHT_ADMIN) && ((rights & requiredNonRights) != 0)) { if (func) { func(false); return; } } // Check Required None Rights
192 +
193 command.sessionid = ws.sessionId; // Set the session id, required for responses
194 command.rights = rights; // Add user rights flags to the message
195 command.consent = 0;
@@ -209,6 +212,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
212 if (routing != null) {
213 // Check if we have permission to send a message to that node
214 parent.GetNodeWithRights(domain, user, agent.dbNodeKey, function (node, rights, visible) {
215 + if ((requiredRights != null) && ((rights & requiredRights) == 0)) { if (func) { func(false); return; } } // Check Required Rights
216 + if ((requiredNonRights != null) && (rights != MESHRIGHT_ADMIN) && ((rights & requiredNonRights) != 0)) { if (func) { func(false); return; } } // Check Required None Rights
217 +
218 var mesh = parent.meshes[routing.meshid];
219 if ((node != null) && (mesh != null) && ((rights & MESHRIGHT_REMOTECONTROL) || (rights & MESHRIGHT_REMOTEVIEWONLY))) { // 8 is remote control permission
220 command.fromSessionid = ws.sessionId; // Set the session id, required for responses
@@ -1182,6 +1188,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1188 }
1189 case 'msg':
1190 {
1191 + // Rights check
1192 + var requiredRights = null, requiredNonRights = null;
1193 +
1194 // Before routing this command, let's do some security checking.
1195 // If this is a tunnel request, we need to make sure the NodeID in the URL matches the NodeID in the command.
1196 if (command.type == 'tunnel') {
@@ -1191,6 +1200,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1200 if (url == null) break; // Bad URL
1201 if (url.query && url.query.nodeid && (url.query.nodeid != command.nodeid)) break; // Bad NodeID in URL query string
1202
1203 + // Check rights
1204 + if (url.query.p == '1') { requiredNonRights = MESHRIGHT_NOTERMINAL; }
1205 + else if ((url.query.p == '4') || (url.query.p == '5')) { requiredNonRights = MESHRIGHT_NOFILES; }
1206 +
1207 // Add user consent messages
1208 command.soptions = {};
1209 if (typeof domain.consentmessages == 'object') {
@@ -1212,7 +1225,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1225 if (command.responseid != null) { func = function (r) { try { ws.send(JSON.stringify({ action: 'msg', result: r ? 'OK' : 'Unable to route', tag: command.tag, responseid: command.responseid })); } catch (ex) { } } }
1226
1227 // Route this command to a target node
1215 - routeCommandToNode(command, func);
1228 + routeCommandToNode(command, requiredRights, requiredNonRights, func);
1229 break;
1230 }
1231 case 'events':