Added relay right and fixed relay permissions (#4682)

This commit is contained in:
Ylian Saint-Hilaire 2022-11-01 16:05:36 -07:00
parent 390ddd9fd6
commit e74a308113
6 changed files with 75 additions and 59 deletions

View File

@ -35,28 +35,29 @@ const PROTOCOL_WEBSFTP = 203;
const PROTOCOL_WEBVNC = 204;
// Mesh Rights
const MESHRIGHT_EDITMESH = 0x00000001; // 1
const MESHRIGHT_MANAGEUSERS = 0x00000002; // 2
const MESHRIGHT_MANAGECOMPUTERS = 0x00000004; // 4
const MESHRIGHT_REMOTECONTROL = 0x00000008; // 8
const MESHRIGHT_AGENTCONSOLE = 0x00000010; // 16
const MESHRIGHT_SERVERFILES = 0x00000020; // 32
const MESHRIGHT_WAKEDEVICE = 0x00000040; // 64
const MESHRIGHT_SETNOTES = 0x00000080; // 128
const MESHRIGHT_REMOTEVIEWONLY = 0x00000100; // 256
const MESHRIGHT_NOTERMINAL = 0x00000200; // 512
const MESHRIGHT_NOFILES = 0x00000400; // 1024
const MESHRIGHT_NOAMT = 0x00000800; // 2048
const MESHRIGHT_DESKLIMITEDINPUT = 0x00001000; // 4096
const MESHRIGHT_LIMITEVENTS = 0x00002000; // 8192
const MESHRIGHT_CHATNOTIFY = 0x00004000; // 16384
const MESHRIGHT_UNINSTALL = 0x00008000; // 32768
const MESHRIGHT_NODESKTOP = 0x00010000; // 65536
const MESHRIGHT_REMOTECOMMAND = 0x00020000; // 131072
const MESHRIGHT_RESETOFF = 0x00040000; // 262144
const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288
const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576
const MESHRIGHT_ADMIN = 0xFFFFFFFF;
const MESHRIGHT_EDITMESH = 0x00000001; // 1
const MESHRIGHT_MANAGEUSERS = 0x00000002; // 2
const MESHRIGHT_MANAGECOMPUTERS = 0x00000004; // 4
const MESHRIGHT_REMOTECONTROL = 0x00000008; // 8
const MESHRIGHT_AGENTCONSOLE = 0x00000010; // 16
const MESHRIGHT_SERVERFILES = 0x00000020; // 32
const MESHRIGHT_WAKEDEVICE = 0x00000040; // 64
const MESHRIGHT_SETNOTES = 0x00000080; // 128
const MESHRIGHT_REMOTEVIEWONLY = 0x00000100; // 256
const MESHRIGHT_NOTERMINAL = 0x00000200; // 512
const MESHRIGHT_NOFILES = 0x00000400; // 1024
const MESHRIGHT_NOAMT = 0x00000800; // 2048
const MESHRIGHT_DESKLIMITEDINPUT = 0x00001000; // 4096
const MESHRIGHT_LIMITEVENTS = 0x00002000; // 8192
const MESHRIGHT_CHATNOTIFY = 0x00004000; // 16384
const MESHRIGHT_UNINSTALL = 0x00008000; // 32768
const MESHRIGHT_NODESKTOP = 0x00010000; // 65536
const MESHRIGHT_REMOTECOMMAND = 0x00020000; // 131072
const MESHRIGHT_RESETOFF = 0x00040000; // 262144
const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288
const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576
const MESHRIGHT_RELAY = 0x00200000; // 2097152
const MESHRIGHT_ADMIN = 0xFFFFFFFF;
// SerialTunnel object is used to embed TLS within another connection.
function SerialTunnel(options) {
@ -2332,6 +2333,6 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user
function checkRelayRights(parent, domain, user, relayNodeId, func) {
if (relayNodeId == null) { func(true); return; } // No relay, do nothing.
parent.GetNodeWithRights(domain, user, relayNodeId, function (node, rights, visible) {
func((node != null) && (rights == 0xFFFFFFFF));
func((node != null) && ((rights & 0x00200008) != 0)); // MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights
});
}

View File

@ -14,27 +14,29 @@
"use strict";
// Mesh Rights
const MESHRIGHT_EDITMESH = 0x00000001;
const MESHRIGHT_MANAGEUSERS = 0x00000002;
const MESHRIGHT_MANAGECOMPUTERS = 0x00000004;
const MESHRIGHT_REMOTECONTROL = 0x00000008;
const MESHRIGHT_AGENTCONSOLE = 0x00000010;
const MESHRIGHT_SERVERFILES = 0x00000020;
const MESHRIGHT_WAKEDEVICE = 0x00000040;
const MESHRIGHT_SETNOTES = 0x00000080;
const MESHRIGHT_REMOTEVIEWONLY = 0x00000100;
const MESHRIGHT_NOTERMINAL = 0x00000200;
const MESHRIGHT_NOFILES = 0x00000400;
const MESHRIGHT_NOAMT = 0x00000800;
const MESHRIGHT_DESKLIMITEDINPUT = 0x00001000;
const MESHRIGHT_LIMITEVENTS = 0x00002000;
const MESHRIGHT_CHATNOTIFY = 0x00004000;
const MESHRIGHT_UNINSTALL = 0x00008000;
const MESHRIGHT_NODESKTOP = 0x00010000;
const MESHRIGHT_REMOTECOMMAND = 0x00020000;
const MESHRIGHT_RESETOFF = 0x00040000;
const MESHRIGHT_GUESTSHARING = 0x00080000;
const MESHRIGHT_ADMIN = 0xFFFFFFFF;
const MESHRIGHT_EDITMESH = 0x00000001; // 1
const MESHRIGHT_MANAGEUSERS = 0x00000002; // 2
const MESHRIGHT_MANAGECOMPUTERS = 0x00000004; // 4
const MESHRIGHT_REMOTECONTROL = 0x00000008; // 8
const MESHRIGHT_AGENTCONSOLE = 0x00000010; // 16
const MESHRIGHT_SERVERFILES = 0x00000020; // 32
const MESHRIGHT_WAKEDEVICE = 0x00000040; // 64
const MESHRIGHT_SETNOTES = 0x00000080; // 128
const MESHRIGHT_REMOTEVIEWONLY = 0x00000100; // 256
const MESHRIGHT_NOTERMINAL = 0x00000200; // 512
const MESHRIGHT_NOFILES = 0x00000400; // 1024
const MESHRIGHT_NOAMT = 0x00000800; // 2048
const MESHRIGHT_DESKLIMITEDINPUT = 0x00001000; // 4096
const MESHRIGHT_LIMITEVENTS = 0x00002000; // 8192
const MESHRIGHT_CHATNOTIFY = 0x00004000; // 16384
const MESHRIGHT_UNINSTALL = 0x00008000; // 32768
const MESHRIGHT_NODESKTOP = 0x00010000; // 65536
const MESHRIGHT_REMOTECOMMAND = 0x00020000; // 131072
const MESHRIGHT_RESETOFF = 0x00040000; // 262144
const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288
const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576
const MESHRIGHT_RELAY = 0x00200000; // 2097152
const MESHRIGHT_ADMIN = 0xFFFFFFFF;
// Protocol:
// 1 = Terminal
@ -868,8 +870,8 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
if (docs.length == 0) { console.log('ERR: Node not found'); try { obj.close(); } catch (e) { } return; } // Disconnect websocket
const node = docs[0];
// Check if this user has permission to manage this computer
if ((obj.nouser !== true) && ((parent.GetNodeRights(user, node.meshid, node._id) & MESHRIGHT_REMOTECONTROL) == 0)) { console.log('ERR: Access denied (1)'); try { obj.close(); } catch (e) { } return; }
// Check if this user has permission to relay thru this computer (MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights)
if ((obj.nouser !== true) && ((parent.GetNodeRights(obj.user, node.meshid, node._id) & 0x00200008) == 0)) { console.log('ERR: Access denied (1)'); try { obj.close(); } catch (ex) { } return; }
// Set nodeid and meshid
obj.nodeid = node._id;
@ -907,8 +909,8 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
if (docs.length == 0) { console.log('ERR: Node not found'); try { obj.close(); } catch (e) { } return; } // Disconnect websocket
const node = docs[0];
// Check if this user has permission to manage this computer
if ((parent.GetNodeRights(user, node.meshid, node._id) & MESHRIGHT_REMOTECONTROL) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (e) { } return; }
// Check if this user has permission to relay thru this computer (MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights)
if ((parent.GetNodeRights(obj.user, node.meshid, node._id) & 0x00200008) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (ex) { } return; }
// Set nodeid and meshid
obj.nodeid = node._id;
@ -963,8 +965,8 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
if (docs.length == 0) { console.log('ERR: Node not found'); try { obj.close(); } catch (e) { } return; } // Disconnect websocket
const node = docs[0];
// Check if this user has permission to manage this computer
if ((obj.nouser !== true) && ((parent.GetNodeRights(user, node.meshid, node._id) & MESHRIGHT_REMOTECONTROL) == 0)) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (e) { } return; }
// Check if this user has permission to relay thru this computer (MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights)
if ((obj.nouser !== true) && ((parent.GetNodeRights(obj.user, node.meshid, node._id) & 0x00200008) == 0)) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (ex) { } return; }
// Set nodeid and meshid
obj.nodeid = node._id;
@ -1017,8 +1019,8 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
if (docs.length == 0) { console.log('ERR: Node not found'); try { obj.close(); } catch (e) { } return; } // Disconnect websocket
const node = docs[0];
// Check if this user has permission to manage this computer
if ((parent.GetNodeRights(user, node.meshid, node._id) & MESHRIGHT_REMOTECONTROL) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (e) { } return; }
// Check if this user has permission to relay thru this computer (MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights)
if ((parent.GetNodeRights(obj.user, node.meshid, node._id) & 0x00200008) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (ex) { } return; }
// Set nodeid and meshid
obj.nodeid = node._id;
@ -1263,8 +1265,8 @@ function CreateLocalRelayEx(parent, ws, req, domain, user, cookie) {
obj.host = node.host;
obj.meshid = node.meshid;
// Check if this user has permission to manage this computer
if ((parent.GetNodeRights(obj.user, node.meshid, node._id) & MESHRIGHT_REMOTECONTROL) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (e) { } return; }
// Check if this user has permission to relay thru this computer (MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights)
if ((parent.GetNodeRights(obj.user, node.meshid, node._id) & 0x00200008) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (ex) { } return; }
// Setup TCP client
obj.client = new net.Socket();

View File

@ -52,6 +52,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
const MESHRIGHT_RESETOFF = 0x00040000; // 262144
const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288
const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576
const MESHRIGHT_RELAY = 0x00200000; // 2097152
const MESHRIGHT_ADMIN = 0xFFFFFFFF;
// Site rights

View File

@ -7762,6 +7762,9 @@
if (rights & 32768) str.push("Uninstall");
if (rights & 131072) str.push("Commands");
if (rights & 262144) str.push("Reset/Off");
if (rights & 524288) str.push("Sharing");
if (rights & 1048576) str.push("Details");
if (rights & 2097152) str.push("Relay");
if (str.length == 0) return "No Rights";
return str.join(', ');
}
@ -7792,6 +7795,9 @@
if (rights & 32768) str.push("Uninstall");
if (rights & 131072) str.push("Commands");
if (rights & 262144) str.push("Reset/Off");
if (rights & 524288) str.push("Sharing");
if (rights & 1048576) str.push("Details");
if (rights & 2097152) str.push("Relay");
if (str.length == 0) return "No Rights";
return str.join(', ');
}
@ -13234,7 +13240,7 @@
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20manageusers>' + "Manage Device Group Users" + '</label><br>';
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20managecomputers>' + "Manage Device Group Computers" + '</label><br>';
}
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotecontrol>' + "Remote Control" + '</label><br>';
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotecontrol>' + "Remote Control & Relay" + '</label><br>';
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remoteview style=margin-left:12px>' + "Remote View Only" + '</label><br>';
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotelimitedinput style=margin-left:12px>' + "Limited Input Only" + '</label><br>';
if (serverinfo.guestdevicesharing !== false) { x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20guestshare style=margin-left:12px>' + "Guest Sharing" + '</label><br>'; }
@ -13252,6 +13258,7 @@
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20commands>' + "Remote Commands" + '</label><br>';
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20resetoff>' + "Reset / Power Off" + '</label><br>';
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20details>' + "Device Details" + '</label><br>';
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20relay>' + "Use as Relay" + '</label><br>';
x += '</div>';
if (userid == null) {
@ -13329,6 +13336,7 @@
if (urights & 262144) { Q('p20resetoff').checked = true; }
if ((urights & 524288) && (serverinfo.guestdevicesharing !== false)) { Q('p20guestshare').checked = true; }
if (urights & 1048576) { Q('p20details').checked = true; }
if (urights & 2097152) { Q('p20relay').checked = true; }
}
p20validateAddMeshUserDialog(userid);
@ -13377,6 +13385,7 @@
Q('p20resetoff').checked = ((devrights & 262144) != 0);
if (serverinfo.guestdevicesharing !== false) { Q('p20guestshare').checked = ((devrights & 524288) != 0); }
Q('p20details').checked = ((devrights & 1048576) != 0);
Q('p20relay').checked = ((devrights & 2097152) != 0);
ok = (nodeid != '');
}
@ -13458,6 +13467,7 @@
QE('p20commands', nc);
QE('p20resetoff', nc);
QE('p20details', nc);
QE('p20relay', nc);
}
function p20showAddMeshUserDialogEx(b, t) {
@ -13487,6 +13497,7 @@
if (Q('p20resetoff').checked == true) meshadmin += 262144;
if ((serverinfo.guestdevicesharing !== false) && (Q('p20guestshare').checked == true) && (Q('p20remoteview').checked || (!Q('p20remoteview').checked && !Q('p20remotelimitedinput').checked))) meshadmin += 524288;
if (Q('p20details').checked == true) meshadmin += 1048576;
if (Q('p20relay').checked == true) meshadmin += 2097152;
}
// Clean up incorrect rights. If Remote Control is not selected, remove flags that don't make sense.
@ -13572,6 +13583,7 @@
if ((meshrights & 262144) != 0) r.push("Reset/Off");
if ((meshrights & 524288) != 0) r.push("Sharing");
if ((meshrights & 1048576) != 0) r.push("Details");
if ((meshrights & 2097152) != 0) r.push("Relay");
}
if (r.length == 0) { r.push("No Rights"); }
var uname = xuserid.split('/')[2];

View File

@ -252,8 +252,8 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
// Check that the user has rights to access this device
parent.webserver.GetNodeWithRights(domain, userid, nodeid, function (node, rights, visible) {
// If there is no remote control rights, reject this web relay
if ((rights & 8) == 0) { res.sendStatus(404); return; }
// If there is no remote control or relay rights, reject this web relay
if ((rights & 0x00200008) == 0) { res.sendStatus(404); return; } // MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY
// There is a relay session, but it's not correct, close it.
if (xrelaySession != null) { xrelaySession.close(); delete relaySessions[webSessionId]; }

View File

@ -6845,8 +6845,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
// Check that the user has rights to access this device
parent.webserver.GetNodeWithRights(domain, userid, nodeid, function (node, rights, visible) {
// If there is no remote control rights, reject this web relay
if ((rights & 8) == 0) { res.sendStatus(404); return; }
// If there is no remote control or relay rights, reject this web relay
if ((rights & 0x00200008) == 0) { res.sendStatus(404); return; } // MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY
// Check if there is a free relay DNS name we can use
var selectedHost = null;