Added per user and per device, user consent settings.

This commit is contained in:
Ylian Saint-Hilaire 2020-04-12 14:05:34 -07:00
parent ce56df33ae
commit afd6bca476
7 changed files with 1302 additions and 1209 deletions

View File

@ -12,8 +12,7 @@
Hola [[[NAME]]],
</p>
</area-name>
<p>Usuario [[[USERNAME]]] en servidor <a href="[[[SERVERURL]]]">[[[SERVERNAME]]]</a> le solicita que instale software para iniciar una sesión de control remoto.
</p>
<p>Usuario [[[USERNAME]]] en servidor <a href="[[[SERVERURL]]]">[[[SERVERNAME]]]</a> le solicita que instale software para iniciar una sesión de control remoto.</p>
<area-msg>
<p>
Mensaje: <b notrans="1">[[[MSG]]]</b>

View File

@ -80,36 +80,44 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
var agent = parent.wsagents[command.nodeid];
if (agent != null) {
// Check if we have permission to send a message to that node
rights = parent.GetNodeRights(user, agent.dbMeshKey, agent.dbNodeKey);
mesh = parent.meshes[agent.dbMeshKey];
if ((rights != null) && (mesh != null) || ((rights & 16) != 0)) { // TODO: 16 is console permission, may need more gradular permission checking
if (ws.sessionId) { command.sessionid = ws.sessionId; } // Set the session id, required for responses.
command.rights = rights.rights; // Add user rights flags to the message
command.consent = mesh.consent; // Add user consent
if (typeof domain.userconsentflags == 'number') { command.consent |= domain.userconsentflags; } // Add server required consent flags
command.username = user.name; // Add user name
if (typeof domain.desktopprivacybartext == 'string') { command.privacybartext = domain.desktopprivacybartext; } // Privacy bar text
delete command.nodeid; // Remove the nodeid since it's implyed.
agent.send(JSON.stringify(command));
return true;
}
parent.GetNodeWithRights(domain, user, agent.dbNodeKey, function (node, rights, visible) {
mesh = parent.meshes[agent.dbMeshKey];
if ((node != null) && (rights != null) && (mesh != null) || ((rights & 16) != 0)) { // TODO: 16 is console permission, may need more gradular permission checking
if (ws.sessionId) { command.sessionid = ws.sessionId; } // Set the session id, required for responses.
command.rights = rights.rights; // Add user rights flags to the message
command.consent = 0;
if (typeof domain.userconsentflags == 'number') { command.consent |= domain.userconsentflags; } // Add server required consent flags
if (typeof mesh.consent == 'number') { command.consent |= mesh.consent; } // Add device group user consent
if (typeof node.consent == 'number') { command.consent |= node.consent; } // Add node user consent
if (typeof user.consent == 'number') { command.consent |= user.consent; } // Add user consent
command.username = user.name; // Add user name
if (typeof domain.desktopprivacybartext == 'string') { command.privacybartext = domain.desktopprivacybartext; } // Privacy bar text
delete command.nodeid; // Remove the nodeid since it's implyed.
agent.send(JSON.stringify(command));
return true;
}
});
} else {
// Check if a peer server is connected to this agent
var routing = parent.parent.GetRoutingServerId(command.nodeid, 1); // 1 = MeshAgent routing type
if (routing != null) {
// Check if we have permission to send a message to that node
rights = parent.GetNodeRights(user, routing.meshid, command.nodeid);
mesh = parent.meshes[routing.meshid];
if (rights != null || ((rights & 16) != 0)) { // TODO: 16 is console permission, may need more gradular permission checking
if (ws.sessionId) { command.fromSessionid = ws.sessionId; } // Set the session id, required for responses.
command.rights = rights.rights; // Add user rights flags to the message
command.consent = mesh.consent; // Add user consent
if (typeof domain.userconsentflags == 'number') { command.consent |= domain.userconsentflags; } // Add server required consent flags
command.username = user.name; // Add user name
if (typeof domain.desktopprivacybartext == 'string') { command.privacybartext = domain.desktopprivacybartext; } // Privacy bar text
parent.parent.multiServer.DispatchMessageSingleServer(command, routing.serverid);
return true;
}
parent.GetNodeWithRights(domain, user, agent.dbNodeKey, function (node, rights, visible) {
mesh = parent.meshes[routing.meshid];
if ((node != null) && (rights != null) && (mesh != null) || ((rights & 16) != 0)) { // TODO: 16 is console permission, may need more gradular permission checking
if (ws.sessionId) { command.fromSessionid = ws.sessionId; } // Set the session id, required for responses.
command.rights = rights.rights; // Add user rights flags to the message
command.consent = 0;
if (typeof domain.userconsentflags == 'number') { command.consent |= domain.userconsentflags; } // Add server required consent flags
if (typeof mesh.consent == 'number') { command.consent |= mesh.consent; } // Add device group user consent
if (typeof node.consent == 'number') { command.consent |= node.consent; } // Add node user consent
if (typeof user.consent == 'number') { command.consent |= user.consent; } // Add user consent
command.username = user.name; // Add user name
if (typeof domain.desktopprivacybartext == 'string') { command.privacybartext = domain.desktopprivacybartext; } // Privacy bar text
parent.parent.multiServer.DispatchMessageSingleServer(command, routing.serverid);
return true;
}
});
}
}
}

View File

@ -162,40 +162,46 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
var agent = parent.wsagents[command.nodeid];
if (agent != null) {
// Check if we have permission to send a message to that node
//var meshrights = parent.GetMeshRights(user, agent.dbMeshKey); // TODO: We will need to get the rights for this specific node.
var mesh = parent.meshes[agent.dbMeshKey];
var meshrights = parent.GetNodeRights(user, mesh, agent.dbNodeKey);
if ((mesh != null) && ((meshrights & MESHRIGHT_REMOTECONTROL) || (meshrights & MESHRIGHT_REMOTEVIEWONLY))) { // 8 is remote control permission, 256 is desktop read only
command.sessionid = ws.sessionId; // Set the session id, required for responses
command.rights = meshrights; // Add user rights flags to the message
command.consent = mesh.consent; // Add user consent
if (typeof domain.userconsentflags == 'number') { command.consent |= domain.userconsentflags; } // Add server required consent flags
command.username = user.name; // Add user name
command.userid = user._id; // Add user id
command.remoteaddr = cleanRemoteAddr(req.ip); // User's IP address
if (typeof domain.desktopprivacybartext == 'string') { command.privacybartext = domain.desktopprivacybartext; } // Privacy bar text
delete command.nodeid; // Remove the nodeid since it's implied
try { agent.send(JSON.stringify(command)); } catch (ex) { }
}
parent.GetNodeWithRights(domain, user, agent.dbNodeKey, function (node, rights, visible) {
var mesh = parent.meshes[agent.dbMeshKey];
if ((node != null) && (mesh != null) && ((rights & MESHRIGHT_REMOTECONTROL) || (rights & MESHRIGHT_REMOTEVIEWONLY))) { // 8 is remote control permission, 256 is desktop read only
command.sessionid = ws.sessionId; // Set the session id, required for responses
command.rights = rights; // Add user rights flags to the message
command.consent = 0;
if (typeof domain.userconsentflags == 'number') { command.consent |= domain.userconsentflags; } // Add server required consent flags
if (typeof mesh.consent == 'number') { command.consent |= mesh.consent; } // Add device group user consent
if (typeof node.consent == 'number') { command.consent |= node.consent; } // Add node user consent
if (typeof user.consent == 'number') { command.consent |= user.consent; } // Add user consent
command.username = user.name; // Add user name
command.userid = user._id; // Add user id
command.remoteaddr = cleanRemoteAddr(req.ip); // User's IP address
if (typeof domain.desktopprivacybartext == 'string') { command.privacybartext = domain.desktopprivacybartext; } // Privacy bar text
delete command.nodeid; // Remove the nodeid since it's implied
try { agent.send(JSON.stringify(command)); } catch (ex) { }
}
});
} else {
// Check if a peer server is connected to this agent
var routing = parent.parent.GetRoutingServerId(command.nodeid, 1); // 1 = MeshAgent routing type
if (routing != null) {
// Check if we have permission to send a message to that node
//var meshrights = parent.GetMeshRights(user, routing.meshid); // TODO: We will need to get the rights for this specific node.
var mesh = parent.meshes[routing.meshid];
var meshrights = parent.GetNodeRights(user, mesh, agent.dbNodeKey);
if ((mesh != null) && ((meshrights & MESHRIGHT_REMOTECONTROL) || (meshrights & MESHRIGHT_REMOTEVIEWONLY))) { // 8 is remote control permission
command.fromSessionid = ws.sessionId; // Set the session id, required for responses
command.rights = meshrights; // Add user rights flags to the message
command.consent = mesh.consent; // Add user consent
if (typeof domain.userconsentflags == 'number') { command.consent |= domain.userconsentflags; } // Add server required consent flags
command.username = user.name; // Add user name
command.userid = user._id; // Add user id
command.remoteaddr = cleanRemoteAddr(req.ip); // User's IP address
if (typeof domain.desktopprivacybartext == 'string') { command.privacybartext = domain.desktopprivacybartext; } // Privacy bar text
parent.parent.multiServer.DispatchMessageSingleServer(command, routing.serverid);
}
parent.GetNodeWithRights(domain, user, agent.dbNodeKey, function (node, rights, visible) {
var mesh = parent.meshes[routing.meshid];
if ((node != null) && (mesh != null) && ((rights & MESHRIGHT_REMOTECONTROL) || (rights & MESHRIGHT_REMOTEVIEWONLY))) { // 8 is remote control permission
command.fromSessionid = ws.sessionId; // Set the session id, required for responses
command.rights = rights; // Add user rights flags to the message
command.consent = 0;
if (typeof domain.userconsentflags == 'number') { command.consent |= domain.userconsentflags; } // Add server required consent flags
if (typeof mesh.consent == 'number') { command.consent |= mesh.consent; } // Add device group user consent
if (typeof node.consent == 'number') { command.consent |= node.consent; } // Add node user consent
if (typeof user.consent == 'number') { command.consent |= user.consent; } // Add user consent
command.username = user.name; // Add user name
command.userid = user._id; // Add user id
command.remoteaddr = cleanRemoteAddr(req.ip); // User's IP address
if (typeof domain.desktopprivacybartext == 'string') { command.privacybartext = domain.desktopprivacybartext; } // Privacy bar text
parent.parent.multiServer.DispatchMessageSingleServer(command, routing.serverid);
}
});
}
}
}
@ -1586,6 +1592,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Make changes
if ((command.emailVerified === true || command.emailVerified === false) && (chguser.emailVerified != command.emailVerified)) { chguser.emailVerified = command.emailVerified; change = 1; }
if ((common.validateInt(command.quota, 0) || command.quota == null) && (command.quota != chguser.quota)) { chguser.quota = command.quota; if (chguser.quota == null) { delete chguser.quota; } change = 1; }
if ((command.consent != null) && (typeof command.consent == 'number')) { if (command.consent == 0) { delete chguser.consent; } else { chguser.consent = command.consent; } change = 1; }
// Site admins can change any server rights, user managers can only change AccountLock, NoMeshCmd and NoNewGroups
if (chguser._id !== user._id) { // We can't change our own siteadmin permissions.
@ -1593,7 +1600,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if (((user.siteadmin == 0xFFFFFFFF) || ((user.siteadmin & 2) && (((chgusersiteadmin ^ command.siteadmin) & 0xFFFFFF1F) == 0))) && common.validateInt(command.siteadmin) && (chguser.siteadmin != command.siteadmin)) { chguser.siteadmin = command.siteadmin; change = 1; }
}
// Went sending a notification about a group change, we need to send to all the previous and new groups.
// When sending a notification about a group change, we need to send to all the previous and new groups.
var allTargetGroups = chguser.groups;
if ((Array.isArray(command.groups)) && ((user._id != command.id) || (user.siteadmin == 0xFFFFFFFF))) {
if (command.groups.length == 0) {
@ -3037,9 +3044,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if ((args.wanonly == true) && (command.host)) { delete command.host; }
// Look for a change
if (command.icon && (command.icon != node.icon)) { change = 1; node.icon = command.icon; changes.push('icon'); }
if (command.name && (command.name != node.name)) { change = 1; node.name = command.name; changes.push('name'); }
if (command.host && (command.host != node.host)) { change = 1; node.host = command.host; changes.push('host'); }
if ((typeof command.icon == 'number') && (command.icon != node.icon)) { change = 1; node.icon = command.icon; changes.push('icon'); }
if ((typeof command.name == 'string') && (command.name != node.name)) { change = 1; node.name = command.name; changes.push('name'); }
if ((typeof command.host == 'string') && (command.host != node.host)) { change = 1; node.host = command.host; changes.push('host'); }
if (typeof command.consent == 'number') { if (((command.consent != 0) && ((node.consent == null) || (node.consent == 0))) || ((command.consent == 0) && (node.consent != null) && (node.consent != 0))) { change = 1; if (command.consent == 0) { delete node.consent; } else { node.consent = command.consent; } changes.push('consent'); } }
if ((typeof command.rdpport == 'number') && (command.rdpport > 0) && (command.rdpport < 65536)) {
if ((command.rdpport == 3389) && (node.rdpport != null)) {
delete node.rdpport; change = 1; changes.push('rdpport'); // Delete the RDP port

View File

@ -1,6 +1,6 @@
{
"name": "meshcentral",
"version": "0.5.1-n",
"version": "0.5.1-o",
"keywords": [
"Remote Management",
"Intel AMT",

File diff suppressed because it is too large Load Diff

View File

@ -1074,6 +1074,7 @@
node.tags = message.event.node.tags;
node.userloc = message.event.node.userloc;
node.rdpport = message.event.node.rdpport;
node.consent = message.event.node.consent;
if (message.event.node.agent != null) {
if (node.agent == null) node.agent = {};
if (message.event.node.agent.ver != null) { node.agent.ver = message.event.node.agent.ver; }

View File

@ -2427,6 +2427,7 @@
node.tags = message.event.node.tags;
node.userloc = message.event.node.userloc;
node.rdpport = message.event.node.rdpport;
node.consent = message.event.node.consent;
if (message.event.node.links != null) { node.links = message.event.node.links; } else { delete node.links; }
if (message.event.node.agent != null) {
if (node.agent == null) node.agent = {};
@ -4911,6 +4912,23 @@
// Active Users
if (node.users && node.conn && (node.users.length > 0) && (node.conn & 1)) { x += addDeviceAttribute(format("Active User{0}", ((node.users.length > 1)?'s':'')), node.users.join(', ')); }
// Display device user consent
if (node.agent != null) {
var meshFeatures = [];
var consent = 0;
if (node.consent) { consent = node.consent; }
if (serverinfo.consent) { consent |= serverinfo.consent; }
if ((consent & 0x0040) && (consent & 0x0008)) { meshFeatures.push("Desktop Prompt+Toolbar"); } else if (consent & 0x0040) { meshFeatures.push("Desktop Toolbar"); } else if (consent & 0x0008) { meshFeatures.push("Desktop Prompt"); } else { if (consent & 0x0001) { meshFeatures.push("Desktop Notify"); } }
if (consent & 0x0010) { meshFeatures.push("Terminal Prompt"); } else { if (consent & 0x0002) { meshFeatures.push("Terminal Notify"); } }
if (consent & 0x0020) { meshFeatures.push("Files Prompt"); } else { if (consent & 0x0004) { meshFeatures.push("Files Notify"); } }
if (consent == 7) { meshFeatures = ["Always Notify"]; }
if ((consent & 56) == 56) { meshFeatures = ["Always Prompt"]; }
meshFeatures = meshFeatures.join(', ');
if (meshFeatures == '') { meshFeatures = '<i>' + "None" + '</i>'; }
x += addDeviceAttribute("User Consent", addLinkConditional(meshFeatures, 'p20editmeshconsent(3)', meshrights & 1));
}
// Attribute: Connectivity (Only show this if more than just the agent is connected).
var connectivity = node.conn;
if (connectivity && connectivity > 1) {
@ -8215,9 +8233,9 @@
x += addHtmlValue("Features", addLinkConditional(meshFeatures, 'p20editmeshfeatures()', meshrights & 1));
}
// Display user consent
// Display device group user consent
if (currentMesh.mtype == 2) {
meshFeatures = [];
var meshFeatures = [];
var consent = 0;
if (currentMesh.consent) { consent = currentMesh.consent; }
if (serverinfo.consent) { consent |= serverinfo.consent; }
@ -8229,7 +8247,7 @@
meshFeatures = meshFeatures.join(', ');
if (meshFeatures == '') { meshFeatures = '<i>' + "None" + '</i>'; }
x += addHtmlValue("User Consent", addLinkConditional(meshFeatures, 'p20editmeshconsent()', meshrights & 1));
x += addHtmlValue("User Consent", addLinkConditional(meshFeatures, 'p20editmeshconsent(1)', meshrights & 1));
}
// Display user notification
@ -8444,9 +8462,13 @@
if (e && e.key == 'Enter') { Q('dp20meshdesc').focus(); }
}
function p20editmeshconsent() {
// editType: 1 = currentMesh, 2 = currentUser, 3 = currentDevice
function p20editmeshconsent(editType) {
if (xxdialogMode) return;
var x = '', consent = (currentMesh.consent) ? currentMesh.consent : 0;
var x = '', consent = 0, title = '';
if (editType == 1) { consent = (currentMesh.consent) ? currentMesh.consent : 0; title = "Edit Device Group User Consent"; }
if (editType == 2) { consent = (currentUser.consent) ? currentUser.consent : 0; title = "Edit User Consent"; }
if (editType == 3) { consent = (currentNode.consent) ? currentNode.consent : 0; title = "Edit Device User Consent"; }
x += '<div style="width:100%;border-bottom:1px solid gray;margin-bottom:5px"><b>' + "Desktop" + '</b></div>';
x += '<div><label><input type=checkbox id=d20flag1 ' + ((consent & 0x0001) ? 'checked' : '') + '>' + "Notify user" + '</label></div>';
x += '<div><label><input type=checkbox id=d20flag2 ' + ((consent & 0x0008) ? 'checked' : '') + '>' + "Prompt for user consent" + '</label></div>';
@ -8457,7 +8479,7 @@
x += '<div style="width:100%;border-bottom:1px solid gray;margin-bottom:5px;margin-top:8px"><b>' + "Files" + '</b></div>';
x += '<div><label><input type=checkbox id=d20flag5 ' + ((consent & 0x0004) ? 'checked' : '') + '>' + "Notify user" + '</label></div>';
x += '<div><label><input type=checkbox id=d20flag6 ' + ((consent & 0x0020) ? 'checked' : '') + '>' + "Prompt for user consent" + '</label></div>';
setDialogMode(2, "Edit Device Group User Consent", 3, p20editmeshconsentEx, x);
setDialogMode(2, title, 3, p20editmeshconsentEx, x, editType);
if (serverinfo.consent) {
if (serverinfo.consent & 0x0001) { Q('d20flag1').checked = true; }
if (serverinfo.consent & 0x0008) { Q('d20flag2').checked = true; }
@ -8476,7 +8498,7 @@
}
}
function p20editmeshconsentEx() {
function p20editmeshconsentEx(b, editType) {
var consent = 0;
if (Q('d20flag1').checked) { consent += 0x0001; }
if (Q('d20flag2').checked) { consent += 0x0008; }
@ -8485,7 +8507,9 @@
if (Q('d20flag5').checked) { consent += 0x0004; }
if (Q('d20flag6').checked) { consent += 0x0020; }
if (Q('d20flag7').checked) { consent += 0x0040; }
meshserver.send({ action: 'editmesh', meshid: currentMesh._id, consent: consent });
if (editType == 1) { meshserver.send({ action: 'editmesh', meshid: currentMesh._id, consent: consent }); }
if (editType == 2) { meshserver.send({ action: 'edituser', id: currentUser._id, consent: consent }); }
if (editType == 3) { meshserver.send({ action: 'changedevice', nodeid: currentNode._id, consent: consent }); }
}
function p20editmeshfeatures() {
@ -10303,6 +10327,22 @@
x += addDeviceAttribute("Admin Realms", addLinkConditional(xuserGroups, 'showUserGroupDialog(event,\"' + userid + '\")', (userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.groups == null) && (userinfo._id != user._id) && (user.siteadmin != 0xFFFFFFFF))));
}
// Display device user consent
{
var meshFeatures = [], consent = 0;
if (user.consent) { consent = user.consent; }
if (serverinfo.consent) { consent |= serverinfo.consent; }
if ((consent & 0x0040) && (consent & 0x0008)) { meshFeatures.push("Desktop Prompt+Toolbar"); } else if (consent & 0x0040) { meshFeatures.push("Desktop Toolbar"); } else if (consent & 0x0008) { meshFeatures.push("Desktop Prompt"); } else { if (consent & 0x0001) { meshFeatures.push("Desktop Notify"); } }
if (consent & 0x0010) { meshFeatures.push("Terminal Prompt"); } else { if (consent & 0x0002) { meshFeatures.push("Terminal Notify"); } }
if (consent & 0x0020) { meshFeatures.push("Files Prompt"); } else { if (consent & 0x0004) { meshFeatures.push("Files Notify"); } }
if (consent == 7) { meshFeatures = ["Always Notify"]; }
if ((consent & 56) == 56) { meshFeatures = ["Always Prompt"]; }
meshFeatures = meshFeatures.join(', ');
if (meshFeatures == '') { meshFeatures = '<i>' + "None" + '</i>'; }
x += addDeviceAttribute("User Consent", addLinkConditional(meshFeatures, 'p20editmeshconsent(2)', true));
}
var multiFactor = 0;
if ((user.otpsecret > 0) || (user.otphkeys > 0)) {
multiFactor = 1;