Added relay right and fixed relay permissions (#4682)
Ylian Saint-Hilaire committed
Nov 1, 2022 at 16:05 UTC
e74a3081139e7fb9d68e342cd84e23818ec97d21
6 files changed
+75
-59
apprelays.js
+24
-23
@@ -35,28 +35,29 @@ const PROTOCOL_WEBSFTP = 203;
35
const PROTOCOL_WEBVNC = 204;
36
37
// Mesh Rights
38
-const MESHRIGHT_EDITMESH = 0x00000001; // 1
39
-const MESHRIGHT_MANAGEUSERS = 0x00000002; // 2
40
-const MESHRIGHT_MANAGECOMPUTERS = 0x00000004; // 4
41
-const MESHRIGHT_REMOTECONTROL = 0x00000008; // 8
42
-const MESHRIGHT_AGENTCONSOLE = 0x00000010; // 16
43
-const MESHRIGHT_SERVERFILES = 0x00000020; // 32
44
-const MESHRIGHT_WAKEDEVICE = 0x00000040; // 64
45
-const MESHRIGHT_SETNOTES = 0x00000080; // 128
46
-const MESHRIGHT_REMOTEVIEWONLY = 0x00000100; // 256
47
-const MESHRIGHT_NOTERMINAL = 0x00000200; // 512
48
-const MESHRIGHT_NOFILES = 0x00000400; // 1024
49
-const MESHRIGHT_NOAMT = 0x00000800; // 2048
50
-const MESHRIGHT_DESKLIMITEDINPUT = 0x00001000; // 4096
51
-const MESHRIGHT_LIMITEVENTS = 0x00002000; // 8192
52
-const MESHRIGHT_CHATNOTIFY = 0x00004000; // 16384
53
-const MESHRIGHT_UNINSTALL = 0x00008000; // 32768
54
-const MESHRIGHT_NODESKTOP = 0x00010000; // 65536
55
-const MESHRIGHT_REMOTECOMMAND = 0x00020000; // 131072
56
-const MESHRIGHT_RESETOFF = 0x00040000; // 262144
57
-const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288
58
-const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576
59
-const MESHRIGHT_ADMIN = 0xFFFFFFFF;
38
+const MESHRIGHT_EDITMESH = 0x00000001; // 1
39
+const MESHRIGHT_MANAGEUSERS = 0x00000002; // 2
40
+const MESHRIGHT_MANAGECOMPUTERS = 0x00000004; // 4
41
+const MESHRIGHT_REMOTECONTROL = 0x00000008; // 8
42
+const MESHRIGHT_AGENTCONSOLE = 0x00000010; // 16
43
+const MESHRIGHT_SERVERFILES = 0x00000020; // 32
44
+const MESHRIGHT_WAKEDEVICE = 0x00000040; // 64
45
+const MESHRIGHT_SETNOTES = 0x00000080; // 128
46
+const MESHRIGHT_REMOTEVIEWONLY = 0x00000100; // 256
47
+const MESHRIGHT_NOTERMINAL = 0x00000200; // 512
48
+const MESHRIGHT_NOFILES = 0x00000400; // 1024
49
+const MESHRIGHT_NOAMT = 0x00000800; // 2048
50
+const MESHRIGHT_DESKLIMITEDINPUT = 0x00001000; // 4096
51
+const MESHRIGHT_LIMITEVENTS = 0x00002000; // 8192
52
+const MESHRIGHT_CHATNOTIFY = 0x00004000; // 16384
53
+const MESHRIGHT_UNINSTALL = 0x00008000; // 32768
54
+const MESHRIGHT_NODESKTOP = 0x00010000; // 65536
55
+const MESHRIGHT_REMOTECOMMAND = 0x00020000; // 131072
56
+const MESHRIGHT_RESETOFF = 0x00040000; // 262144
57
+const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288
58
+const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576
59
+const MESHRIGHT_RELAY = 0x00200000; // 2097152
60
+const MESHRIGHT_ADMIN = 0xFFFFFFFF;
61
62
// SerialTunnel object is used to embed TLS within another connection.
63
function SerialTunnel(options) {
@@ -2332,6 +2333,6 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user
2333
function checkRelayRights(parent, domain, user, relayNodeId, func) {
2334
if (relayNodeId == null) { func(true); return; } // No relay, do nothing.
2335
parent.GetNodeWithRights(domain, user, relayNodeId, function (node, rights, visible) {
2335
- func((node != null) && (rights == 0xFFFFFFFF));
2336
+ func((node != null) && ((rights & 0x00200008) != 0)); // MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights
2337
});
2338
}
meshrelay.js
+33
-31
@@ -14,27 +14,29 @@
14
"use strict";
15
16
// Mesh Rights
17
-const MESHRIGHT_EDITMESH = 0x00000001;
18
-const MESHRIGHT_MANAGEUSERS = 0x00000002;
19
-const MESHRIGHT_MANAGECOMPUTERS = 0x00000004;
20
-const MESHRIGHT_REMOTECONTROL = 0x00000008;
21
-const MESHRIGHT_AGENTCONSOLE = 0x00000010;
22
-const MESHRIGHT_SERVERFILES = 0x00000020;
23
-const MESHRIGHT_WAKEDEVICE = 0x00000040;
24
-const MESHRIGHT_SETNOTES = 0x00000080;
25
-const MESHRIGHT_REMOTEVIEWONLY = 0x00000100;
26
-const MESHRIGHT_NOTERMINAL = 0x00000200;
27
-const MESHRIGHT_NOFILES = 0x00000400;
28
-const MESHRIGHT_NOAMT = 0x00000800;
29
-const MESHRIGHT_DESKLIMITEDINPUT = 0x00001000;
30
-const MESHRIGHT_LIMITEVENTS = 0x00002000;
31
-const MESHRIGHT_CHATNOTIFY = 0x00004000;
32
-const MESHRIGHT_UNINSTALL = 0x00008000;
33
-const MESHRIGHT_NODESKTOP = 0x00010000;
34
-const MESHRIGHT_REMOTECOMMAND = 0x00020000;
35
-const MESHRIGHT_RESETOFF = 0x00040000;
36
-const MESHRIGHT_GUESTSHARING = 0x00080000;
37
-const MESHRIGHT_ADMIN = 0xFFFFFFFF;
17
+const MESHRIGHT_EDITMESH = 0x00000001; // 1
18
+const MESHRIGHT_MANAGEUSERS = 0x00000002; // 2
19
+const MESHRIGHT_MANAGECOMPUTERS = 0x00000004; // 4
20
+const MESHRIGHT_REMOTECONTROL = 0x00000008; // 8
21
+const MESHRIGHT_AGENTCONSOLE = 0x00000010; // 16
22
+const MESHRIGHT_SERVERFILES = 0x00000020; // 32
23
+const MESHRIGHT_WAKEDEVICE = 0x00000040; // 64
24
+const MESHRIGHT_SETNOTES = 0x00000080; // 128
25
+const MESHRIGHT_REMOTEVIEWONLY = 0x00000100; // 256
26
+const MESHRIGHT_NOTERMINAL = 0x00000200; // 512
27
+const MESHRIGHT_NOFILES = 0x00000400; // 1024
28
+const MESHRIGHT_NOAMT = 0x00000800; // 2048
29
+const MESHRIGHT_DESKLIMITEDINPUT = 0x00001000; // 4096
30
+const MESHRIGHT_LIMITEVENTS = 0x00002000; // 8192
31
+const MESHRIGHT_CHATNOTIFY = 0x00004000; // 16384
32
+const MESHRIGHT_UNINSTALL = 0x00008000; // 32768
33
+const MESHRIGHT_NODESKTOP = 0x00010000; // 65536
34
+const MESHRIGHT_REMOTECOMMAND = 0x00020000; // 131072
35
+const MESHRIGHT_RESETOFF = 0x00040000; // 262144
36
+const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288
37
+const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576
38
+const MESHRIGHT_RELAY = 0x00200000; // 2097152
39
+const MESHRIGHT_ADMIN = 0xFFFFFFFF;
40
41
// Protocol:
42
// 1 = Terminal
@@ -868,8 +870,8 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
870
if (docs.length == 0) { console.log('ERR: Node not found'); try { obj.close(); } catch (e) { } return; } // Disconnect websocket
871
const node = docs[0];
872
871
- // Check if this user has permission to manage this computer
872
- 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; }
873
+ // Check if this user has permission to relay thru this computer (MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights)
874
+ 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; }
875
876
// Set nodeid and meshid
877
obj.nodeid = node._id;
@@ -907,8 +909,8 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
909
if (docs.length == 0) { console.log('ERR: Node not found'); try { obj.close(); } catch (e) { } return; } // Disconnect websocket
910
const node = docs[0];
911
910
- // Check if this user has permission to manage this computer
911
- if ((parent.GetNodeRights(user, node.meshid, node._id) & MESHRIGHT_REMOTECONTROL) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (e) { } return; }
912
+ // Check if this user has permission to relay thru this computer (MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights)
913
+ if ((parent.GetNodeRights(obj.user, node.meshid, node._id) & 0x00200008) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (ex) { } return; }
914
915
// Set nodeid and meshid
916
obj.nodeid = node._id;
@@ -963,8 +965,8 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
965
if (docs.length == 0) { console.log('ERR: Node not found'); try { obj.close(); } catch (e) { } return; } // Disconnect websocket
966
const node = docs[0];
967
966
- // Check if this user has permission to manage this computer
967
- 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; }
968
+ // Check if this user has permission to relay thru this computer (MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights)
969
+ 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; }
970
971
// Set nodeid and meshid
972
obj.nodeid = node._id;
@@ -1017,8 +1019,8 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
1019
if (docs.length == 0) { console.log('ERR: Node not found'); try { obj.close(); } catch (e) { } return; } // Disconnect websocket
1020
const node = docs[0];
1021
1020
- // Check if this user has permission to manage this computer
1021
- if ((parent.GetNodeRights(user, node.meshid, node._id) & MESHRIGHT_REMOTECONTROL) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (e) { } return; }
1022
+ // Check if this user has permission to relay thru this computer (MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights)
1023
+ if ((parent.GetNodeRights(obj.user, node.meshid, node._id) & 0x00200008) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (ex) { } return; }
1024
1025
// Set nodeid and meshid
1026
obj.nodeid = node._id;
@@ -1263,8 +1265,8 @@ function CreateLocalRelayEx(parent, ws, req, domain, user, cookie) {
1265
obj.host = node.host;
1266
obj.meshid = node.meshid;
1267
1266
- // Check if this user has permission to manage this computer
1267
- if ((parent.GetNodeRights(obj.user, node.meshid, node._id) & MESHRIGHT_REMOTECONTROL) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (e) { } return; }
1268
+ // Check if this user has permission to relay thru this computer (MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY rights)
1269
+ if ((parent.GetNodeRights(obj.user, node.meshid, node._id) & 0x00200008) == 0) { console.log('ERR: Access denied (2)'); try { obj.close(); } catch (ex) { } return; }
1270
1271
// Setup TCP client
1272
obj.client = new net.Socket();
meshuser.js
+1
@@ -52,6 +52,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
52
const MESHRIGHT_RESETOFF = 0x00040000; // 262144
53
const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288
54
const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576
55
+ const MESHRIGHT_RELAY = 0x00200000; // 2097152
56
const MESHRIGHT_ADMIN = 0xFFFFFFFF;
57
58
// Site rights
views/default.handlebars
+13
-1
@@ -7762,6 +7762,9 @@
7762
if (rights & 32768) str.push("Uninstall");
7763
if (rights & 131072) str.push("Commands");
7764
if (rights & 262144) str.push("Reset/Off");
7765
+ if (rights & 524288) str.push("Sharing");
7766
+ if (rights & 1048576) str.push("Details");
7767
+ if (rights & 2097152) str.push("Relay");
7768
if (str.length == 0) return "No Rights";
7769
return str.join(', ');
7770
}
@@ -7792,6 +7795,9 @@
7795
if (rights & 32768) str.push("Uninstall");
7796
if (rights & 131072) str.push("Commands");
7797
if (rights & 262144) str.push("Reset/Off");
7798
+ if (rights & 524288) str.push("Sharing");
7799
+ if (rights & 1048576) str.push("Details");
7800
+ if (rights & 2097152) str.push("Relay");
7801
if (str.length == 0) return "No Rights";
7802
return str.join(', ');
7803
}
@@ -13234,7 +13240,7 @@
13240
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20manageusers>' + "Manage Device Group Users" + '</label><br>';
13241
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20managecomputers>' + "Manage Device Group Computers" + '</label><br>';
13242
}
13237
- x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotecontrol>' + "Remote Control" + '</label><br>';
13243
+ x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotecontrol>' + "Remote Control & Relay" + '</label><br>';
13244
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remoteview style=margin-left:12px>' + "Remote View Only" + '</label><br>';
13245
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotelimitedinput style=margin-left:12px>' + "Limited Input Only" + '</label><br>';
13246
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 @@
13258
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20commands>' + "Remote Commands" + '</label><br>';
13259
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20resetoff>' + "Reset / Power Off" + '</label><br>';
13260
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20details>' + "Device Details" + '</label><br>';
13261
+ x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20relay>' + "Use as Relay" + '</label><br>';
13262
x += '</div>';
13263
13264
if (userid == null) {
@@ -13329,6 +13336,7 @@
13336
if (urights & 262144) { Q('p20resetoff').checked = true; }
13337
if ((urights & 524288) && (serverinfo.guestdevicesharing !== false)) { Q('p20guestshare').checked = true; }
13338
if (urights & 1048576) { Q('p20details').checked = true; }
13339
+ if (urights & 2097152) { Q('p20relay').checked = true; }
13340
}
13341
13342
p20validateAddMeshUserDialog(userid);
@@ -13377,6 +13385,7 @@
13385
Q('p20resetoff').checked = ((devrights & 262144) != 0);
13386
if (serverinfo.guestdevicesharing !== false) { Q('p20guestshare').checked = ((devrights & 524288) != 0); }
13387
Q('p20details').checked = ((devrights & 1048576) != 0);
13388
+ Q('p20relay').checked = ((devrights & 2097152) != 0);
13389
ok = (nodeid != '');
13390
}
13391
@@ -13458,6 +13467,7 @@
13467
QE('p20commands', nc);
13468
QE('p20resetoff', nc);
13469
QE('p20details', nc);
13470
+ QE('p20relay', nc);
13471
}
13472
13473
function p20showAddMeshUserDialogEx(b, t) {
@@ -13487,6 +13497,7 @@
13497
if (Q('p20resetoff').checked == true) meshadmin += 262144;
13498
if ((serverinfo.guestdevicesharing !== false) && (Q('p20guestshare').checked == true) && (Q('p20remoteview').checked || (!Q('p20remoteview').checked && !Q('p20remotelimitedinput').checked))) meshadmin += 524288;
13499
if (Q('p20details').checked == true) meshadmin += 1048576;
13500
+ if (Q('p20relay').checked == true) meshadmin += 2097152;
13501
}
13502
13503
// Clean up incorrect rights. If Remote Control is not selected, remove flags that don't make sense.
@@ -13572,6 +13583,7 @@
13583
if ((meshrights & 262144) != 0) r.push("Reset/Off");
13584
if ((meshrights & 524288) != 0) r.push("Sharing");
13585
if ((meshrights & 1048576) != 0) r.push("Details");
13586
+ if ((meshrights & 2097152) != 0) r.push("Relay");
13587
}
13588
if (r.length == 0) { r.push("No Rights"); }
13589
var uname = xuserid.split('/')[2];
webrelayserver.js
+2
-2
@@ -252,8 +252,8 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
252
253
// Check that the user has rights to access this device
254
parent.webserver.GetNodeWithRights(domain, userid, nodeid, function (node, rights, visible) {
255
- // If there is no remote control rights, reject this web relay
256
- if ((rights & 8) == 0) { res.sendStatus(404); return; }
255
+ // If there is no remote control or relay rights, reject this web relay
256
+ if ((rights & 0x00200008) == 0) { res.sendStatus(404); return; } // MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY
257
258
// There is a relay session, but it's not correct, close it.
259
if (xrelaySession != null) { xrelaySession.close(); delete relaySessions[webSessionId]; }
webserver.js
+2
-2
@@ -6845,8 +6845,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6845
6846
// Check that the user has rights to access this device
6847
parent.webserver.GetNodeWithRights(domain, userid, nodeid, function (node, rights, visible) {
6848
- // If there is no remote control rights, reject this web relay
6849
- if ((rights & 8) == 0) { res.sendStatus(404); return; }
6848
+ // If there is no remote control or relay rights, reject this web relay
6849
+ if ((rights & 0x00200008) == 0) { res.sendStatus(404); return; } // MESHRIGHT_REMOTECONTROL or MESHRIGHT_RELAY
6850
6851
// Check if there is a free relay DNS name we can use
6852
var selectedHost = null;