diff --git a/apprelays.js b/apprelays.js index cd6bc5fad5..8a0ee63950 100644 --- a/apprelays.js +++ b/apprelays.js @@ -57,6 +57,7 @@ const MESHRIGHT_RESETOFF = 0x00040000; // 262144 const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288 const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576 const MESHRIGHT_RELAY = 0x00200000; // 2097152 +const MESHRIGHT_HIDERDPSESSIONS = 0x00400000; // 4194304 const MESHRIGHT_ADMIN = 0xFFFFFFFF; // SerialTunnel object is used to embed TLS within another connection. diff --git a/meshagent.js b/meshagent.js index 7169b9ffa9..27da4ea719 100644 --- a/meshagent.js +++ b/meshagent.js @@ -1214,6 +1214,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { obj.consoleKickValue = command.value; } } + else if (command.type == 'userSessions') { + const rights = parent.GetNodeRights(parent.wssessions2[command.sessionid].userid, obj.dbMeshKey, obj.dbNodeKey); + if ((rights !== 0xFFFFFFFF) && (rights & 0x00400000)) { + command.data = Object.fromEntries(Object.entries(command.data).filter(([k,v]) => (!v.StationName.toUpperCase().startsWith('RDP-')))); + console.log(rights.toString(16).padStart(8,'0'), command); + } + } // Route a message parent.routeAgentCommand(command, obj.domain.id, obj.dbNodeKey, obj.dbMeshKey); diff --git a/meshcentral-config-schema.json b/meshcentral-config-schema.json index 91cec3b8c3..d733c22402 100644 --- a/meshcentral-config-schema.json +++ b/meshcentral-config-schema.json @@ -1522,6 +1522,11 @@ ] } }, + "applyFeaturePermissionsToRouterAndWebTools": { + "type": "boolean", + "default": true, + "description": "Hides RDP, SSH or SCP links if access to Desktop, Terminal or Files is denied." + }, "deviceMeshRouterLinks": { "type": "object", "properties": { @@ -1929,6 +1934,15 @@ "default": true, "description": "When enabled, activates the built-in web-based VNC client." }, + "novncargs": { + "type": "string", + "default": "show_dot=1", + "description": "Additional arguments for nVNC. URL-encoded and sparated by ampersand (&)." + }, + "novncViewOnlyPort": { + "type": ["number", "array"], + "description": "TCP port where a VNC server is listening in view-only mode. Single number or array in Object.fromEntries()-compatible format." + }, "mstsc": { "type": "boolean", "default": true, @@ -2324,7 +2338,7 @@ "viewonly": { "type": "boolean", "description": "When set to true, the remote desktop feature is view only.", - "default": "false" + "default": false } } }, diff --git a/meshcentral.js b/meshcentral.js index a792dda56f..9493c8b77f 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -3216,6 +3216,8 @@ function CreateMeshCentralServer(config, args) { // Sign windows agents obj.signMeshAgents = function (domain, func) { + // Skip signing to speed up debugging + if ('MESHCENTRAL_DEV_NO_AGENT_SIGNING' in process.env && (()=> { try { return require('node:inspector').url() !== undefined; } catch (_) { return false; } }).call()) { return void func(); } // Setup the domain is specified var objx = domain, suffix = ''; if (domain.id == '') { objx = obj; } else { suffix = '-' + domain.id; objx.meshAgentBinaries = {}; } diff --git a/meshipkvm.js b/meshipkvm.js index 2623eb9040..d6e2879ea6 100644 --- a/meshipkvm.js +++ b/meshipkvm.js @@ -34,6 +34,8 @@ function CreateIPKVMManager(parent) { const MESHRIGHT_RESETOFF = 0x00040000; // 262144 const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288 const MESHRIGHT_DEVICEDETAILS = 0x00100000; // ?1048576? + const MESHRIGHT_RELAY = 0x00200000; // 2097152 + const MESHRIGHT_HIDERDPSESSIONS = 0x00400000; // 4194304 const MESHRIGHT_ADMIN = 0xFFFFFFFF; // Subscribe for mesh creation events diff --git a/meshrelay.js b/meshrelay.js index 7f91904df8..bf58046821 100644 --- a/meshrelay.js +++ b/meshrelay.js @@ -36,6 +36,7 @@ const MESHRIGHT_RESETOFF = 0x00040000; // 262144 const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288 const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576 const MESHRIGHT_RELAY = 0x00200000; // 2097152 +const MESHRIGHT_HIDERDPSESSIONS = 0x00400000; // 4194304 const MESHRIGHT_ADMIN = 0xFFFFFFFF; // Protocol: @@ -874,14 +875,31 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) { parent.db.Get(cookie.nodeid, function (err, docs) { if (docs.length == 0) { console.log('ERR: Node not found'); try { obj.close(); } catch (e) { } return; } // Disconnect websocket const node = docs[0]; + const rights = parent.GetNodeRights(obj.user, node.meshid, node._id); // 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; } + if ((obj.nouser !== true) && ((rights & 0x00200008) == 0)) { console.log('ERR: Access denied (1)'); try { obj.close(); } catch (ex) { } return; } // Set nodeid and meshid obj.nodeid = node._id; obj.meshid = node.meshid; + function getNoVncViewOnlyPort(rfbport = 5900) { + let novncvop = domain.novncviewonlyport; + if (typeof novncvop === 'number') { return novncvop; } + if (Array.isArray(novncvop)) { novncvop = domain.novncviewonlyport = Object.fromEntries(novncvop); } + const tokens = [obj.meshid, `mesh/${domain.id}/${parent.meshes[obj.meshid].name}`, obj.nodeid, `node/${domain.id}/${node.name}`, '*']; + tokens.some((val) => ((val = +novncvop[val]) ? ((rfbport = val), true) : false)); + return rfbport; + } + if (domain.applyfeaturepermissionstorouterandwebtools !== false) { + switch (cookie.tcpport) { + // don't know why, but we have to terminate() the websocket to close the connection. or is a feature to avoid DoS? + case node.rdpport ?? 3389: { if ((rights !== 0xFFFFFFFF) && (rights & MESHRIGHT_REMOTEVIEWONLY)) { console.log('ERR: Access denied (1)'); try { obj.close(); /*ws.terminate();*/ } catch (ex) { } return; } break; } + case node.rfbport ?? 5900: { if ((rights !== 0xFFFFFFFF) && (rights & MESHRIGHT_REMOTEVIEWONLY)) { cookie.tcpport = getNoVncViewOnlyPort(node.rfbport); } break; } + } + } + // Send connection request to agent const rcookieData = {}; if (user != null) { rcookieData.ruserid = user._id; } else if (obj.nouser === true) { rcookieData.nouser = 1; } diff --git a/meshuser.js b/meshuser.js index ac237dfdf6..ca5a55bb51 100644 --- a/meshuser.js +++ b/meshuser.js @@ -53,6 +53,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288 const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576 const MESHRIGHT_RELAY = 0x00200000; // 2097152 + const MESHRIGHT_HIDERDPSESSIONS = 0x00400000; // 4194304 const MESHRIGHT_ADMIN = 0xFFFFFFFF; // Site rights @@ -547,7 +548,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Build server information object const allFeatures = parent.getDomainUserFeatures(domain, user, req); - var serverinfo = { domain: domain.id, name: domain.dns ? domain.dns : parent.certificates.CommonName, mpsname: parent.certificates.AmtMpsName, mpsport: mpsport, mpspass: args.mpspass, port: httpport, emailcheck: ((domain.mailserver != null) && (domain.auth != 'sspi') && (domain.auth != 'ldap') && (args.lanonly != true) && (parent.certificates.CommonName != null) && (parent.certificates.CommonName.indexOf('.') != -1) && (user._id.split('/')[2].startsWith('~') == false)), domainauth: (domain.auth == 'sspi'), serverTime: Date.now(), features: allFeatures.features, features2: allFeatures.features2 }; + var serverinfo = { domain: domain.id, name: domain.dns ? domain.dns : parent.certificates.CommonName, mpsname: parent.certificates.AmtMpsName, mpsport: mpsport, mpspass: args.mpspass, port: httpport, emailcheck: ((domain.mailserver != null) && (domain.auth != 'sspi') && (domain.auth != 'ldap') && (args.lanonly != true) && (parent.certificates.CommonName != null) && (parent.certificates.CommonName.indexOf('.') != -1) && (user._id.split('/')[2].startsWith('~') == false)), domainauth: (domain.auth == 'sspi'), serverTime: Date.now(), features: allFeatures.features, features2: allFeatures.features2, features3: allFeatures.features3 }; serverinfo.languages = parent.renderLanguages; serverinfo.tlshash = Buffer.from(parent.webCertificateFullHashs[domain.id], 'binary').toString('hex').toUpperCase(); // SHA384 of server HTTPS certificate serverinfo.agentCertHash = parent.agentCertificateHashBase64; @@ -4722,7 +4723,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } else { try { parent.parent.pluginHandler.plugins[command.plugin].serveraction(command, obj, parent); - } catch (ex) { console.log('Error loading plugin handler (' + ex + ')'); } + } catch (ex) { console.log('Error executing plugin serveraction (' + ex + ')', ex.stack); } } break; } @@ -6411,6 +6412,18 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) { if ((node == null) || ((rights & MESHRIGHT_REMOTECONTROL) == 0) || (visible == false)) return; // Access denied. + const applyfeaturepermissions = obj.domain.applyfeaturepermissionstorouterandwebtools !== false; + switch (command.tag) { + case 'novnc': { + let novncargs = domain.novncargs ?? 'show_dot=1'; + if (applyfeaturepermissions) { novncargs += '&view_only=' +!!(rights & MESHRIGHT_REMOTEVIEWONLY); } + command.qsappend = novncargs.charAt(0) === '&' ? novncargs.slice(1) : novncargs; + break; + } + case 'mstsc': { if (applyfeaturepermissions && (rights & MESHRIGHT_REMOTEVIEWONLY)) { return; } break; } + case 'ssh': { if (applyfeaturepermissions && (rights & MESHRIGHT_NOTERMINAL)) { return; }; break; } + } + // Add a user authentication cookie to a url var cookieContent = { userid: user._id, domainid: user.domain }; if (command.nodeid) { cookieContent.nodeid = command.nodeid; } diff --git a/sample-config-advanced.json b/sample-config-advanced.json index 3b7836f030..1b54e0461b 100644 --- a/sample-config-advanced.json +++ b/sample-config-advanced.json @@ -581,6 +581,17 @@ "_footer": "Test", "_certUrl": "https://192.168.2.106:443/" }, + "_domain_with_novncViewOnlyPort": { + "_novnc": true, + "_1_novncViewOnlyPort": 5901, + "_2_novncViewOnlyPort": [ + ["#_node//Oqj4ExG@mcz9ZmXMuy7YncqEKuVA1rD5o8ZUWQ8F$mA$33zwfXz$XQ5mrUYdJbss", 5901], + ["#_node//my-dev-box", 5902], + ["#_mesh//KbvW2V18kiZSNQ5zkT8Qk2s7aADf0MwS1cXUlc$WzqwbwEVYMTopJFR1uxxZzE79", 5903], + ["#_mesh//playground--connect", 5904], + ["*", 5905] + ] + }, "_info": { "_share": "C:\\ExtraWebSite" } diff --git a/views/default.handlebars b/views/default.handlebars index 8b11665a77..aa4b48006a 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -1550,6 +1550,7 @@ var debugLevel = parseInt('{{{debuglevel}}}'); var features = parseInt('{{{features}}}'); var features2 = parseInt('{{{features2}}}'); + var features3 = parseInt('{{{features3}}}'); var sessionTime = parseInt('{{{sessiontime}}}'); var webRelayPort = parseInt('{{{webRelayPort}}}'); var webRelayDns = '{{{webRelayDns}}}'; @@ -2356,6 +2357,7 @@ if (updateNaggleFlags & 16384) { updateUsers(); } if (updateNaggleFlags & 32768) { updateRecordings(); } if (updateNaggleFlags & 65536) { updateLoginTokens(); } + if (currentNode && (updateNaggleFlags & 131072)) { updateDesktopButtons(); } updateNaggleTimer = null; updateNaggleFlags = 0; gotoStartViewPage(); @@ -3006,18 +3008,18 @@ //console.log(url); downloadFile(url, ''); } else if (message.tag == 'novnc') { - var vncurl = window.location.origin + domainUrl + 'novnc/vnc.html?ws=wss%3A%2F%2F' + window.location.host + encodeURIComponentEx(domainUrl) + (message.localRelay?'local':'mesh') + 'relay.ashx%3Fauth%3D' + message.cookie + '&show_dot=1' + (urlargs.key?('&key=' + urlargs.key):'') + '&l={{{lang}}}'; + var vncurl = window.location.origin + domainUrl + 'novnc/vnc.html?ws=wss%3A%2F%2F' + window.location.host + encodeURIComponentEx(domainUrl) + (message.localRelay ? 'local' : 'mesh') + 'relay.ashx%3Fauth%3D' + message.cookie + (urlargs.key?('&key=' + urlargs.key):'') + '&l={{{lang}}}' + (message.qsappend ? '&' + message.qsappend : ''); var node = getNodeFromId(message.nodeid); if (node != null) { vncurl += '&name=' + encodeURIComponentEx(node.name); } safeNewWindow(vncurl, 'mcnovnc/' + message.nodeid); } else if (message.tag == 'mstsc') { - var rdpurl = window.location.origin + domainUrl + 'mstsc.html?ws=' + message.cookie + (urlargs.key?('&key=' + urlargs.key):''); + var rdpurl = window.location.origin + domainUrl + 'mstsc.html?ws=' + message.cookie + (urlargs.key ? ('&key=' + urlargs.key) : '') + (message.qsappend ? '&' + message.qsappend : ''); var node = getNodeFromId(message.nodeid); if (node != null) { rdpurl += '&name=' + encodeURIComponentEx(node.name); } if (message.localRelay) { rdpurl += '&local=1'; } safeNewWindow(rdpurl, 'mcmstsc/' + message.nodeid); } else if (message.tag == 'ssh') { - var sshurl = window.location.origin + domainUrl + 'ssh.html?ws=' + message.cookie + (urlargs.key?('&key=' + urlargs.key):''); + var sshurl = window.location.origin + domainUrl + 'ssh.html?ws=' + message.cookie + (urlargs.key ? ('&key=' + urlargs.key) : '') + (message.qsappend ? '&' + message.qsappend : ''); var node = getNodeFromId(message.nodeid); if (node != null) { sshurl += '&name=' + encodeURIComponentEx(node.name); } if (message.localRelay) { sshurl += '&local=1'; } @@ -3463,6 +3465,7 @@ // If we are looking at a node that is no longer visible, move back to "My Devices" if ((xxcurrentView >= 10) && (xxcurrentView < 20) && currentNode && !IsNodeViewable(currentNode)) { setDialogMode(0); go(1); } } + mainUpdate(131072); } mainUpdate(4 + 128 + 8192 + 16384); if (currentNode && !IsNodeViewable(currentNode)) { currentNode = null; if ((xxcurrentView >= 10) && (xxcurrentView < 20)) { go(1); } } @@ -6515,12 +6518,12 @@ QV('cxfiles', (node.mtype != 4) && ((node.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (rights & 8) && fileAccess); QV('cxevents', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (rights & 8)); QV('cxdetails', node.mtype < 3); - QV('cxwebvnc', ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights & 8) != 0) && ((features & 0x20000000) == 0))); - QV('cxwebrdp', ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights & 8) != 0) && ((features & 0x40000000) == 0))); - QV('cxwebssh', ((features2 & 0x200) && (((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights & 8) != 0))); + QV('cxwebvnc', ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights == 0xFFFFFFFF) || ((rights & (8 | (features3 & 0x00000001 ? 65536 : 0))) == 8)) && ((features & 0x20000000) == 0))); + QV('cxwebrdp', ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights == 0xFFFFFFFF) || ((rights & (8 | (features3 & 0x00000001 ? 256 | 65536 : 0))) == 8)) && ((features & 0x40000000) == 0))); + QV('cxwebssh', ((features2 & 0x200) && (((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights == 0xFFFFFFFF) || ((rights & (8 | (features3 & 0x00000001 ? 512 : 0))) == 8)))); QV('cxconsole', (consoleRights && (node.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0))) && (rights & 8)); QV('cxrdp', false); // always have the RDP hidden - if ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights & 8) != 0)) { + if ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights == 0xFFFFFFFF) || ((rights & (8 | (features3 & 0x00000001 ? 256 | 65536 : 0))) == 8))) { if ((node.agent.id > 0) && (node.agent.id < 5)) { if (navigator.platform.toLowerCase() == 'win32') { if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.rdp != false)) { @@ -7829,19 +7832,19 @@ } if ((node.agent.id > 0) && (node.agent.id < 5)) { if (navigator.platform.toLowerCase() == 'win32') { - if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.rdp != false)) { + if (((meshrights == 0xFFFFFFFF) || ((meshrights & (8 | (features3 & 0x00000001 ? 256 | 65536 : 0))) == 8)) && ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.rdp != false))) { x += '' + "RDP" + ((node.rdpport && (node.rdpport != 3389)) ? '/' + node.rdpport : '') + ' '; } } } if (node.agent.id > 4) { - if ((navigator.platform.toLowerCase() == 'win32') || (navigator.platform.toLowerCase() == 'macintel')) { + if (((meshrights == 0xFFFFFFFF) || ((meshrights & ( 8 | (features3 & 0x00000001 ? 512 : 0))) == 8)) && ((navigator.platform.toLowerCase() == 'win32') || (navigator.platform.toLowerCase() == 'macintel'))) { if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.ssh != false)) { x += '' + "SSH" + ((node.sshport && (node.sshport != 22)) ? '/' + node.sshport : '') + ' '; } } if (navigator.platform.toLowerCase() == 'win32') { - if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.scp != false)) { + if (((meshrights == 0xFFFFFFFF) || ((meshrights & (8 | (features3 & 0x00000001 ? 1024 : 0))) == 8)) && ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.scp != false))) { x += '' + "SCP" + ((node.sshport && (node.sshport != 22)) ? '/' + node.sshport : '') + ' '; } } @@ -7861,17 +7864,17 @@ } // noVNC link - if ((((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights & 8) != 0) && ((features & 0x20000000) == 0)) { + if ((((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights == 0xFFFFFFFF) || ((meshrights & (8 | (features3 & 0x00000001 ? 65536 : 0))) == 8 )) && ((features & 0x20000000) == 0)) { x += '' + "Web-VNC" + ' '; } // MSTSC.js link - if ((((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights & 8) != 0) && ((features & 0x40000000) == 0)) { + if ((((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights == 0xFFFFFFFF) || ((meshrights & (8 | (features3 & 0x00000001 ? 256 | 65536 : 0))) == 8)) && ((features & 0x40000000) == 0)) { x += '' + "Web-RDP" + ' '; } // SSH link - if ((features2 & 0x200) && (((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights & 8) != 0)) { + if ((features2 & 0x200) && (((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights == 0xFFFFFFFF) || ((meshrights & (8 | (features3 & 0x00000001 ? 512 : 0))) == 8))) { x += '' + "Web-SSH" + ' '; } @@ -8184,6 +8187,7 @@ if (rights & 512) str1.push("No Terminal"); if (rights & 1024) str1.push("No Files"); if (rights & 2048) str1.push("No AMT"); + if (rights & 4194304) str1.push("Hide RDP"); if (rights & 4096) str1.push("Limited Input"); if (rights & 65536) str1.push("No Desktop"); if ((rights & 524288) && (serverinfo.guestdevicesharing !== false)) str1.push("Guest Share"); @@ -8218,6 +8222,7 @@ if (rights & 1024) str1.push("No Files"); if (rights & 2048) str1.push("No AMT"); if (rights & 4096) str1.push("Limited Input"); + if (rights & 4194304) str1.push("Hide RDP"); if (rights & 65536) str1.push("No Desktop"); if ((rights & 524288) && (serverinfo.guestdevicesharing !== false)) str1.push("Guest Share"); if (str1.length > 0) { str.push('Control (' + str1.join(', ') + ')'); } else { str.push("Control"); } @@ -9186,7 +9191,7 @@ // Show the right buttons QV('disconnectbutton1span', (deskState != 0)); QV('connectbutton1span', (deskState == 0) && ((rights & 8) || (rights & 256)) && (currentNode.agent != null) && (currentNode.agent.caps & 1)); - QV('connectbutton1rspan', ((features & 0x40000000) == 0) && (deskState == 0) && (rights & 8) && (currentNode.agent != null) && ((currentNode.agent.id == 3) || (currentNode.agent.id == 4))); + QV('connectbutton1rspan', ((features & 0x40000000) == 0) && (deskState == 0) && ((rights == 0XFFFFFFFF) || ((rights & (8 | (features3 & 0x00000001 ? 256 : 0))) == 8)) && (currentNode.agent != null) && ((currentNode.agent.id == 3) || (currentNode.agent.id == 4))); if (mtype == 1) { QV('connectbutton1hspan', (deskState == 0) && @@ -14196,6 +14201,7 @@ x += '
'; x += '
'; x += '
'; + x += '
'; if (serverinfo.guestdevicesharing !== false) { x += '
'; } x += '
'; x += '
'; @@ -14277,6 +14283,7 @@ if (urights & 1024) { Q('p20nofiles').checked = true; } if (urights & 2048) { Q('p20noamt').checked = true; } if (urights & 4096) { Q('p20remotelimitedinput').checked = true; } + if (urights & 4194304) { Q('p20hiderdpsessions').checked = true; } } if (urights & 16) { Q('p20meshagentconsole').checked = true; } if (urights & 32) { Q('p20meshserverfiles').checked = true; } @@ -14330,6 +14337,7 @@ Q('p20nofiles').checked = ((devrights & 1024) != 0); Q('p20noamt').checked = ((devrights & 2048) != 0); Q('p20remotelimitedinput').checked = ((devrights & 4096) != 0); + Q('p20hiderdpsessions').checked = ((devrights & 4194304) != 0); Q('p20limitevents').checked = ((devrights & 8192) != 0); Q('p20chatnotify').checked = ((devrights & 16384) != 0); Q('p20uninstall').checked = ((devrights & 32768) != 0); @@ -14411,6 +14419,7 @@ QE('p20remoteview', nc && Q('p20remotecontrol').checked); if (serverinfo.guestdevicesharing !== false) { QE('p20guestshare', nc && Q('p20remotecontrol').checked && (Q('p20remoteview').checked || !Q('p20remotelimitedinput').checked)); } QE('p20remotelimitedinput', nc && Q('p20remotecontrol').checked && !Q('p20remoteview').checked); + QE('p20hiderdpsessions', nc && Q('p20remotecontrol').checked); QE('p20nodesktop', nc && Q('p20remotecontrol').checked); QE('p20noterminal', nc && Q('p20remotecontrol').checked); QE('p20nofiles', nc && Q('p20remotecontrol').checked); @@ -14443,6 +14452,7 @@ if (Q('p20nofiles').checked == true) meshadmin += 1024; if (Q('p20noamt').checked == true) meshadmin += 2048; if ((Q('p20remotelimitedinput').checked == true) && (!Q('p20remoteview').checked)) meshadmin += 4096; + if ((Q('p20hiderdpsessions').checked == true)) meshadmin += 4194304; if (Q('p20limitevents').checked == true) meshadmin += 8192; if (Q('p20chatnotify').checked == true) meshadmin += 16384; if (Q('p20uninstall').checked == true) meshadmin += 32768; @@ -14455,13 +14465,14 @@ // Clean up incorrect rights. If Remote Control is not selected, remove flags that don't make sense. if ((meshadmin & 8) == 0) { - // Remove 256, 512, 1024, 2048, 4096, 65536 + // Remove 256, 512, 1024, 2048, 4096, 65536, 4194304 if (meshadmin & 256) { meshadmin -= 256; } if (meshadmin & 512) { meshadmin -= 512; } if (meshadmin & 1024) { meshadmin -= 1024; } if (meshadmin & 2048) { meshadmin -= 2048; } if (meshadmin & 4096) { meshadmin -= 4096; } if (meshadmin & 65536) { meshadmin -= 65536; } + if (meshadmin & 4194304) { meshadmin -= 4194304; } } // Send the action to the server @@ -14524,11 +14535,13 @@ if ((meshrights & 64) != 0) r.push("Wake Devices"); if ((meshrights & 128) != 0) r.push("Edit Notes"); if (((meshrights & 8) != 0) && (meshrights & 256) != 0) r.push("Remote View Only"); + if (((meshrights & 8) != 0) && (meshrights & 4194304) != 0) r.push("Hide RDP Sessionss"); if (((meshrights & 8) != 0) && (meshrights & 65536) != 0) r.push("No Desktop"); if (((meshrights & 8) != 0) && (meshrights & 512) != 0) r.push("No Terminal"); if (((meshrights & 8) != 0) && (meshrights & 1024) != 0) r.push("No Files"); if (((meshrights & 8) != 0) && (meshrights & 2048) != 0) r.push("No Intel® AMT"); if (((meshrights & 8) != 0) && ((meshrights & 4096) != 0) && ((meshrights & 256) == 0)) r.push("Limited Input"); + if (((meshrights & 8) != 0) && ((meshrights & 4194304) != 0) && ((meshrights & 256) == 0)) r.push("Hide RDP"); if ((meshrights & 8192) != 0) r.push("Self Events Only"); if ((meshrights & 16384) != 0) r.push("Chat & Notify"); if ((meshrights & 32768) != 0) r.push("Uninstall"); @@ -16459,8 +16472,8 @@ var cr = 0, mesh = omeshes[i], r = currentUserGroup.links[mesh._id].rights, trash = '', rights = makeDeviceGroupRightsString(r); if ((userinfo.links) && (userinfo.links[mesh._id] != null) && (userinfo.links[mesh._id].rights != null)) { cr = userinfo.links[mesh._id].rights; } var meshname = '' + "Unknown Device Group" + ''; - if (mesh) { meshname = '' + mesh.name + ''; } else {} - if ((cr & 2) != 0) { + if (mesh) { meshname = '' + mesh.name + ''; } else { } + if ((userinfo.siteadmin == 0xFFFFFFFF) || ((cr & 2) != 0)) { trash = ''; rights = '' + rights + ' '; } @@ -16760,8 +16773,11 @@ if ((serverinfo.usersSessionRecording == 1) && (user.flags) && (user.flags & 2)) { userFeatures.push("Record Sessions"); } if (user.removeRights) { if ((user.removeRights & 0x00000008) != 0) { userFeatures.push("No Remote Control"); } else { - if ((user.removeRights & 0x00010000) != 0) { userFeatures.push("No Desktop"); } - else if ((user.removeRights & 0x00000100) != 0) { userFeatures.push("Desktop View Only"); } + if ((user.removeRights & 0x00010000) != 0) { userFeatures.push("No Desktop"); } else { + if ((user.removeRights & 0x00000100) != 0) { userFeatures.push("Desktop View Only"); } + else if ((user.removeRights & 0x00001000) != 0) { userFeatures.push("Limited Input"); } + if ((user.removeRights & 0x00400000) != 0) { userFeatures.push("Hide RDP"); } + } if ((user.removeRights & 0x00000200) != 0) { userFeatures.push("No Terminal"); } if ((user.removeRights & 0x00000400) != 0) { userFeatures.push("No Files"); } } @@ -16986,6 +17002,8 @@ x += '

'; x += '

'; x += '

'; + x += '

'; + x += '

'; x += '

'; x += '

'; x += '

'; @@ -17002,6 +17020,8 @@ QE('d20flag3', !Q('d20flag7').checked && !Q('d20flag2').checked); QE('d20flag4', !Q('d20flag7').checked); QE('d20flag5', !Q('d20flag7').checked); + QE('d20flag12', !Q('d20flag7').checked && !Q('d20flag2').checked && !Q('d20flag3').checked); + QE('d20flag13', !Q('d20flag7').checked && !Q('d20flag2').checked); } // Send to the server the new user's real name @@ -17015,7 +17035,11 @@ var r = 0; if (Q('d20flag7').checked) { r += 0x00000008; } else { if (Q('d20flag2').checked) { r += 0x00010000; } - else if (Q('d20flag3').checked) { r += 0x00000100; } + else { + if (Q('d20flag3').checked) { r += 0x00000100; } + else if (Q('d20flag12').checked) { r += 0x00001000; } + if (Q('d20flag13').checked) { r += 0x00400000; } + } if (Q('d20flag4').checked) { r += 0x00000200; } if (Q('d20flag5').checked) { r += 0x00000400; } } @@ -17158,7 +17182,7 @@ if ((userinfo.links) && (userinfo.links[mesh._id] != null) && (userinfo.links[mesh._id].rights != null)) { cr = userinfo.links[mesh._id].rights; } var meshname = '' + "Unknown Device Group" + ''; if (mesh) { meshname = '' + EscapeHtml(mesh.name) + ''; } - if ((currentUser._id != userinfo._id) && ((cr & 2) != 0)) { // 2 = MESHRIGHT_MANAGEUSERS + if ((userinfo.siteadmin == 0xFFFFFFFF) || ((currentUser._id != userinfo._id) && ((cr & 2) != 0))) { // 2 = MESHRIGHT_MANAGEUSERS trash = ''; rights = '' + rights + ' '; } @@ -19002,6 +19026,8 @@ if ((userinfo.removeRights & 0x00000100) != 0) { add += 0x00000100; } // Desktop View Only if ((userinfo.removeRights & 0x00000200) != 0) { add += 0x00000200; } // No Terminal if ((userinfo.removeRights & 0x00000400) != 0) { add += 0x00000400; } // No Files + if ((userinfo.removeRights & 0x00001000) != 0) { add += 0x00001000; } // Limited Input Only + if ((userinfo.removeRights & 0x00400000) != 0) { add += 0x00400000; } // Hide RDP Sessions if ((userinfo.removeRights & 0x00000010) != 0) { substract += 0x00000010; } // No Console if ((userinfo.removeRights & 0x00008000) != 0) { substract += 0x00008000; } // No Uninstall if ((userinfo.removeRights & 0x00020000) != 0) { substract += 0x00020000; } // No Remote Command diff --git a/views/default3.handlebars b/views/default3.handlebars index b3cd7ba78b..2404a5164e 100644 --- a/views/default3.handlebars +++ b/views/default3.handlebars @@ -1977,6 +1977,7 @@ var debugLevel = parseInt('{{{debuglevel}}}'); var features = parseInt('{{{features}}}'); var features2 = parseInt('{{{features2}}}'); + var features3 = parseInt('{{{features3}}}'); var sessionTime = parseInt('{{{sessiontime}}}'); var webRelayPort = parseInt('{{{webRelayPort}}}'); var webRelayDns = '{{{webRelayDns}}}'; @@ -2806,6 +2807,7 @@ if (updateNaggleFlags & 16384) { updateUsers(); } if (updateNaggleFlags & 32768) { updateRecordings(); } if (updateNaggleFlags & 65536) { updateLoginTokens(); } + if (currentNode && (updateNaggleFlags & 131072)) { updateDesktopButtons(); } updateNaggleTimer = null; updateNaggleFlags = 0; gotoStartViewPage(); @@ -3461,18 +3463,18 @@ //console.log(url); downloadFile(url, ''); } else if (message.tag == 'novnc') { - var vncurl = window.location.origin + domainUrl + 'novnc/vnc.html?ws=wss%3A%2F%2F' + window.location.host + encodeURIComponentEx(domainUrl) + (message.localRelay ? 'local' : 'mesh') + 'relay.ashx%3Fauth%3D' + message.cookie + '&show_dot=1' + (urlargs.key ? ('&key=' + urlargs.key) : '') + '&l={{{lang}}}'; + var vncurl = window.location.origin + domainUrl + 'novnc/vnc.html?ws=wss%3A%2F%2F' + window.location.host + encodeURIComponentEx(domainUrl) + (message.localRelay ? 'local' : 'mesh') + 'relay.ashx%3Fauth%3D' + message.cookie + (urlargs.key?('&key=' + urlargs.key):'') + '&l={{{lang}}}' + (message.qsappend ? '&' + message.qsappend : ''); var node = getNodeFromId(message.nodeid); if (node != null) { vncurl += '&name=' + encodeURIComponentEx(node.name); } safeNewWindow(vncurl, 'mcnovnc/' + message.nodeid); } else if (message.tag == 'mstsc') { - var rdpurl = window.location.origin + domainUrl + 'mstsc.html?ws=' + message.cookie + (urlargs.key ? ('&key=' + urlargs.key) : ''); + var rdpurl = window.location.origin + domainUrl + 'mstsc.html?ws=' + message.cookie + (urlargs.key ? ('&key=' + urlargs.key) : '') + (message.qsappend ? '&' + message.qsappend : ''); var node = getNodeFromId(message.nodeid); if (node != null) { rdpurl += '&name=' + encodeURIComponentEx(node.name); } if (message.localRelay) { rdpurl += '&local=1'; } safeNewWindow(rdpurl, 'mcmstsc/' + message.nodeid); } else if (message.tag == 'ssh') { - var sshurl = window.location.origin + domainUrl + 'ssh.html?ws=' + message.cookie + (urlargs.key ? ('&key=' + urlargs.key) : ''); + var sshurl = window.location.origin + domainUrl + 'ssh.html?ws=' + message.cookie + (urlargs.key ? ('&key=' + urlargs.key) : '') + (message.qsappend ? '&' + message.qsappend : ''); var node = getNodeFromId(message.nodeid); if (node != null) { sshurl += '&name=' + encodeURIComponentEx(node.name); } if (message.localRelay) { sshurl += '&local=1'; } @@ -3925,6 +3927,7 @@ // If we are looking at a node that is no longer visible, move back to "My Devices" if ((xxcurrentView >= 10) && (xxcurrentView < 20) && currentNode && !IsNodeViewable(currentNode)) { setDialogMode(0); go(1); } } + mainUpdate(131072); } mainUpdate(4 + 128 + 8192 + 16384); if (currentNode && !IsNodeViewable(currentNode)) { currentNode = null; if ((xxcurrentView >= 10) && (xxcurrentView < 20)) { go(1); } } @@ -7173,12 +7176,12 @@ QV('cxfiles', (node.mtype != 4) && ((node.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (rights & 8) && fileAccess); QV('cxevents', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (rights & 8)); QV('cxdetails', node.mtype < 3); - QV('cxwebvnc', ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights & 8) != 0) && ((features & 0x20000000) == 0))); - QV('cxwebrdp', ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights & 8) != 0) && ((features & 0x40000000) == 0))); - QV('cxwebssh', ((features2 & 0x200) && (((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights & 8) != 0))); + QV('cxwebvnc', ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights == 0xFFFFFFFF) || ((rights & (8 | (features3 & 0x00000001 ? 65536 : 0))) == 8)) && ((features & 0x20000000) == 0))); + QV('cxwebrdp', ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights == 0xFFFFFFFF) || ((rights & (8 | (features3 & 0x00000001 ? 256 | 65536 : 0))) == 8)) && ((features & 0x40000000) == 0))); + QV('cxwebssh', ((features2 & 0x200) && (((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights == 0xFFFFFFFF) || ((rights & (8 | (features3 & 0x00000001 ? 512 : 0))) == 8)))); QV('cxconsole', (consoleRights && (node.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0))) && (rights & 8)); QV('cxrdp', false); // always have the RDP hidden - if ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights & 8) != 0)) { + if ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((rights == 0xFFFFFFFF) || ((rights & (8 | (features3 & 0x00000001 ? 256 | 65536 : 0))) == 8))) { if ((node.agent.id > 0) && (node.agent.id < 5)) { if (navigator.platform.toLowerCase() == 'win32') { if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.rdp != false)) { @@ -8497,19 +8500,19 @@ } if ((node.agent.id > 0) && (node.agent.id < 5)) { if (navigator.platform.toLowerCase() == 'win32') { - if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.rdp != false)) { + if (((meshrights == 0xFFFFFFFF) || ((meshrights & (8 | (features3 & 0x00000001 ? 256 | 65536 : 0))) == 8)) && ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.rdp != false))) { x += '' + "RDP" + ((node.rdpport && (node.rdpport != 3389)) ? '/' + node.rdpport : '') + ' '; } } } if (node.agent.id > 4) { - if ((navigator.platform.toLowerCase() == 'win32') || (navigator.platform.toLowerCase() == 'macintel')) { + if (((meshrights == 0xFFFFFFFF) || ((meshrights & ( 8 | (features3 & 0x00000001 ? 512 : 0))) == 8)) && ((navigator.platform.toLowerCase() == 'win32') || (navigator.platform.toLowerCase() == 'macintel'))) { if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.ssh != false)) { x += '' + "SSH" + ((node.sshport && (node.sshport != 22)) ? '/' + node.sshport : '') + ' '; } } if (navigator.platform.toLowerCase() == 'win32') { - if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.scp != false)) { + if (((meshrights == 0xFFFFFFFF) || ((meshrights & (8 | (features3 & 0x00000001 ? 1024 : 0))) == 8)) && ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.scp != false))) { x += '' + "SCP" + ((node.sshport && (node.sshport != 22)) ? '/' + node.sshport : '') + ' '; } } @@ -8529,17 +8532,17 @@ } // noVNC link - if ((((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights & 8) != 0) && ((features & 0x20000000) == 0)) { + if ((((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights == 0xFFFFFFFF) || ((meshrights & (8 | (features3 & 0x00000001 ? 65536 : 0))) == 8 )) && ((features & 0x20000000) == 0)) { x += '' + "Web-VNC" + ' '; } // MSTSC.js link - if ((((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights & 8) != 0) && ((features & 0x40000000) == 0)) { + if ((((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights == 0xFFFFFFFF) || ((meshrights & (8 | (features3 & 0x00000001 ? 256 | 65536 : 0))) == 8)) && ((features & 0x40000000) == 0)) { x += '' + "Web-RDP" + ' '; } // SSH link - if ((features2 & 0x200) && (((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights & 8) != 0)) { + if ((features2 & 0x200) && (((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights == 0xFFFFFFFF) || ((meshrights & (8 | (features3 & 0x00000001 ? 512 : 0))) == 8))) { x += '' + "Web-SSH" + ' '; } @@ -8857,6 +8860,7 @@ if (rights & 512) str1.push("No Terminal"); if (rights & 1024) str1.push("No Files"); if (rights & 2048) str1.push("No AMT"); + if (rights & 4194304) str1.push("Hide RDP"); if (rights & 4096) str1.push("Limited Input"); if (rights & 65536) str1.push("No Desktop"); if ((rights & 524288) && (serverinfo.guestdevicesharing !== false)) str1.push("Guest Share"); @@ -8891,6 +8895,7 @@ if (rights & 1024) str1.push("No Files"); if (rights & 2048) str1.push("No AMT"); if (rights & 4096) str1.push("Limited Input"); + if (rights & 4194304) str1.push("Hide RDP"); if (rights & 65536) str1.push("No Desktop"); if ((rights & 524288) && (serverinfo.guestdevicesharing !== false)) str1.push("Guest Share"); if (str1.length > 0) { str.push('Control (' + str1.join(', ') + ')'); } else { str.push("Control"); } @@ -9945,7 +9950,7 @@ // Show the right buttons QV('disconnectbutton1span', (deskState != 0)); QV('connectbutton1span', (deskState == 0) && ((rights & 8) || (rights & 256)) && (currentNode.agent != null) && (currentNode.agent.caps & 1)); - QV('connectbutton1rspan', ((features & 0x40000000) == 0) && (deskState == 0) && (rights & 8) && (currentNode.agent != null) && ((currentNode.agent.id == 3) || (currentNode.agent.id == 4))); + QV('connectbutton1rspan', ((features & 0x40000000) == 0) && (deskState == 0) && ((rights == 0XFFFFFFFF) || ((rights & (8 | (features3 & 0x00000001 ? 256 : 0))) == 8)) && (currentNode.agent != null) && ((currentNode.agent.id == 3) || (currentNode.agent.id == 4))); if (mtype == 1) { QV('connectbutton1hspan', (deskState == 0) && @@ -15272,6 +15277,7 @@ x += '
'; x += '
'; x += '
'; + x += '
'; if (serverinfo.guestdevicesharing !== false) { x += '
'; } x += '
'; x += '
'; @@ -15390,6 +15396,7 @@ if (urights & 1024) { Q('p20nofiles').checked = true; } if (urights & 2048) { Q('p20noamt').checked = true; } if (urights & 4096) { Q('p20remotelimitedinput').checked = true; } + if (urights & 4194304) { Q('p20hiderdpsessions').checked = true; } } if (urights & 16) { Q('p20meshagentconsole').checked = true; } if (urights & 32) { Q('p20meshserverfiles').checked = true; } @@ -15443,6 +15450,7 @@ Q('p20nofiles').checked = ((devrights & 1024) != 0); Q('p20noamt').checked = ((devrights & 2048) != 0); Q('p20remotelimitedinput').checked = ((devrights & 4096) != 0); + Q('p20hiderdpsessions').checked = ((devrights & 4194304) != 0); Q('p20limitevents').checked = ((devrights & 8192) != 0); Q('p20chatnotify').checked = ((devrights & 16384) != 0); Q('p20uninstall').checked = ((devrights & 32768) != 0); @@ -15524,6 +15532,7 @@ QE('p20remoteview', nc && Q('p20remotecontrol').checked); if (serverinfo.guestdevicesharing !== false) { QE('p20guestshare', nc && Q('p20remotecontrol').checked && (Q('p20remoteview').checked || !Q('p20remotelimitedinput').checked)); } QE('p20remotelimitedinput', nc && Q('p20remotecontrol').checked && !Q('p20remoteview').checked); + QE('p20hiderdpsessions', nc && Q('p20remotecontrol').checked); QE('p20nodesktop', nc && Q('p20remotecontrol').checked); QE('p20noterminal', nc && Q('p20remotecontrol').checked); QE('p20nofiles', nc && Q('p20remotecontrol').checked); @@ -15556,6 +15565,7 @@ if (Q('p20nofiles').checked == true) meshadmin += 1024; if (Q('p20noamt').checked == true) meshadmin += 2048; if ((Q('p20remotelimitedinput').checked == true) && (!Q('p20remoteview').checked)) meshadmin += 4096; + if ((Q('p20hiderdpsessions').checked == true)) meshadmin += 4194304; if (Q('p20limitevents').checked == true) meshadmin += 8192; if (Q('p20chatnotify').checked == true) meshadmin += 16384; if (Q('p20uninstall').checked == true) meshadmin += 32768; @@ -15568,13 +15578,14 @@ // Clean up incorrect rights. If Remote Control is not selected, remove flags that don't make sense. if ((meshadmin & 8) == 0) { - // Remove 256, 512, 1024, 2048, 4096, 65536 + // Remove 256, 512, 1024, 2048, 4096, 65536, 4194304 if (meshadmin & 256) { meshadmin -= 256; } if (meshadmin & 512) { meshadmin -= 512; } if (meshadmin & 1024) { meshadmin -= 1024; } if (meshadmin & 2048) { meshadmin -= 2048; } if (meshadmin & 4096) { meshadmin -= 4096; } if (meshadmin & 65536) { meshadmin -= 65536; } + if (meshadmin & 4194304) { meshadmin -= 4194304; } } // Send the action to the server @@ -15637,11 +15648,13 @@ if ((meshrights & 64) != 0) r.push("Wake Devices"); if ((meshrights & 128) != 0) r.push("Edit Notes"); if (((meshrights & 8) != 0) && (meshrights & 256) != 0) r.push("Remote View Only"); + if (((meshrights & 8) != 0) && (meshrights & 4194304) != 0) r.push("Hide RDP Sessionss"); if (((meshrights & 8) != 0) && (meshrights & 65536) != 0) r.push("No Desktop"); if (((meshrights & 8) != 0) && (meshrights & 512) != 0) r.push("No Terminal"); if (((meshrights & 8) != 0) && (meshrights & 1024) != 0) r.push("No Files"); if (((meshrights & 8) != 0) && (meshrights & 2048) != 0) r.push("No Intel® AMT"); if (((meshrights & 8) != 0) && ((meshrights & 4096) != 0) && ((meshrights & 256) == 0)) r.push("Limited Input"); + if (((meshrights & 8) != 0) && ((meshrights & 4194304) != 0) && ((meshrights & 256) == 0)) r.push("Hide RDP"); if ((meshrights & 8192) != 0) r.push("Self Events Only"); if ((meshrights & 16384) != 0) r.push("Chat & Notify"); if ((meshrights & 32768) != 0) r.push("Uninstall"); @@ -17673,7 +17686,7 @@ if ((userinfo.links) && (userinfo.links[mesh._id] != null) && (userinfo.links[mesh._id].rights != null)) { cr = userinfo.links[mesh._id].rights; } var meshname = '' + "Unknown Device Group" + ''; if (mesh) { meshname = '' + mesh.name + ''; } else { } - if ((cr & 2) != 0) { + if ((userinfo.siteadmin == 0xFFFFFFFF) || ((cr & 2) != 0)) { trash = ''; rights = '' + rights + ' '; } @@ -17988,8 +18001,11 @@ if ((serverinfo.usersSessionRecording == 1) && (user.flags) && (user.flags & 2)) { userFeatures.push("Record Sessions"); } if (user.removeRights) { if ((user.removeRights & 0x00000008) != 0) { userFeatures.push("No Remote Control"); } else { - if ((user.removeRights & 0x00010000) != 0) { userFeatures.push("No Desktop"); } - else if ((user.removeRights & 0x00000100) != 0) { userFeatures.push("Desktop View Only"); } + if ((user.removeRights & 0x00010000) != 0) { userFeatures.push("No Desktop"); } else { + if ((user.removeRights & 0x00000100) != 0) { userFeatures.push("Desktop View Only"); } + else if ((user.removeRights & 0x00001000) != 0) { userFeatures.push("Limited Input"); } + if ((user.removeRights & 0x00400000) != 0) { userFeatures.push("Hide RDP"); } + } if ((user.removeRights & 0x00000200) != 0) { userFeatures.push("No Terminal"); } if ((user.removeRights & 0x00000400) != 0) { userFeatures.push("No Files"); } } @@ -18218,6 +18234,8 @@ x += '

'; x += '

'; x += '

'; + x += '

'; + x += '

'; x += '

'; x += '

'; x += '

'; @@ -18237,6 +18255,8 @@ QE('d20flag3', !Q('d20flag7').checked && !Q('d20flag2').checked); QE('d20flag4', !Q('d20flag7').checked); QE('d20flag5', !Q('d20flag7').checked); + QE('d20flag12', !Q('d20flag7').checked && !Q('d20flag2').checked && !Q('d20flag3').checked); + QE('d20flag13', !Q('d20flag7').checked && !Q('d20flag2').checked); } // Send to the server the new user's real name @@ -18250,7 +18270,11 @@ var r = 0; if (Q('d20flag7').checked) { r += 0x00000008; } else { if (Q('d20flag2').checked) { r += 0x00010000; } - else if (Q('d20flag3').checked) { r += 0x00000100; } + else { + if (Q('d20flag3').checked) { r += 0x00000100; } + else if (Q('d20flag12').checked) { r += 0x00001000; } + if (Q('d20flag13').checked) { r += 0x00400000; } + } if (Q('d20flag4').checked) { r += 0x00000200; } if (Q('d20flag5').checked) { r += 0x00000400; } } @@ -18404,7 +18428,7 @@ if ((userinfo.links) && (userinfo.links[mesh._id] != null) && (userinfo.links[mesh._id].rights != null)) { cr = userinfo.links[mesh._id].rights; } var meshname = '' + "Unknown Device Group" + ''; if (mesh) { meshname = '' + EscapeHtml(mesh.name) + ''; } - if ((currentUser._id != userinfo._id) && ((cr & 2) != 0)) { // 2 = MESHRIGHT_MANAGEUSERS + if ((userinfo.siteadmin == 0xFFFFFFFF) || ((currentUser._id != userinfo._id) && ((cr & 2) != 0))) { // 2 = MESHRIGHT_MANAGEUSERS trash = ''; rights = '' + rights + ' '; } @@ -20310,6 +20334,8 @@ if ((userinfo.removeRights & 0x00000100) != 0) { add += 0x00000100; } // Desktop View Only if ((userinfo.removeRights & 0x00000200) != 0) { add += 0x00000200; } // No Terminal if ((userinfo.removeRights & 0x00000400) != 0) { add += 0x00000400; } // No Files + if ((userinfo.removeRights & 0x00001000) != 0) { add += 0x00001000; } // Limited Input Only + if ((userinfo.removeRights & 0x00400000) != 0) { add += 0x00400000; } // Hide RDP Sessions if ((userinfo.removeRights & 0x00000010) != 0) { substract += 0x00000010; } // No Console if ((userinfo.removeRights & 0x00008000) != 0) { substract += 0x00008000; } // No Uninstall if ((userinfo.removeRights & 0x00020000) != 0) { substract += 0x00020000; } // No Remote Command diff --git a/webserver.js b/webserver.js index 60c7cc5c4d..579436771a 100644 --- a/webserver.js +++ b/webserver.js @@ -124,6 +124,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF const MESHRIGHT_REMOTECOMMAND = 0x00020000; const MESHRIGHT_RESETOFF = 0x00040000; const MESHRIGHT_GUESTSHARING = 0x00080000; + const MESHRIGHT_DEVICEDETAILS = 0x00100000; + const MESHRIGHT_RELAY = 0x00200000; + const MESHRIGHT_HIDERDPSESSIONS = 0x00400000; const MESHRIGHT_ADMIN = 0xFFFFFFFF; // Site rights @@ -3206,6 +3209,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF serverfeatures: serverFeatures, features: allFeatures.features, features2: allFeatures.features2, + features3: allFeatures.features3, sessiontime: (args.sessiontime) ? args.sessiontime : 60, mpspass: args.mpspass, passRequirements: passRequirements, @@ -3271,6 +3275,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF obj.getDomainUserFeatures = function (domain, user, req) { var features = 0; var features2 = 0; + var features3 = 0; if (obj.args.wanonly == true) { features += 0x00000001; } // WAN-only mode if (obj.args.lanonly == true) { features += 0x00000002; } // LAN-only mode if (obj.args.nousers == true) { features += 0x00000004; } // Single user mode @@ -3343,7 +3348,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF if (domain.devicesearchbargroupname === true) { features2 += 0x10000000; } // Search bar will find by group name too if (((typeof domain.passwordrequirements != 'object') || (domain.passwordrequirements.duo2factor != false)) && (typeof domain.duo2factor == 'object') && (typeof domain.duo2factor.integrationkey == 'string') && (typeof domain.duo2factor.secretkey == 'string') && (typeof domain.duo2factor.apihostname == 'string')) { features2 += 0x20000000; } // using Duo for 2FA is allowed if (domain.showmodernuitoggle == true) { features2 += 0x40000000; } // Indicates that the new UI should be shown - return { features: features, features2: features2 }; + if (domain.applyfeaturepermissionstorouterandwebtools !== false) {features3 += 0x00000001; } + return { features: features, features2: features2, features3 }; } function handleRootRequestLogin(req, res, domain, hardwareKeyChallenge, passRequirements) { @@ -8664,6 +8670,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF if ((user.removeRights & 0x00000100) != 0) { add += 0x00000100; } // Desktop View Only if ((user.removeRights & 0x00000200) != 0) { add += 0x00000200; } // No Terminal if ((user.removeRights & 0x00000400) != 0) { add += 0x00000400; } // No Files + if ((user.removeRights & 0x00001000) != 0) { add += 0x00001000; } // Limited Input Only + if ((user.removeRights & 0x00400000) != 0) { add += 0x00400000; } // Hide RDP Sessions if ((user.removeRights & 0x00000010) != 0) { substract += 0x00000010; } // No Console if ((user.removeRights & 0x00008000) != 0) { substract += 0x00008000; } // No Uninstall if ((user.removeRights & 0x00020000) != 0) { substract += 0x00020000; } // No Remote Command