mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-26 07:05:52 -05:00
More improvements to MeshCtrl
This commit is contained in:
parent
7527a3f440
commit
0c445a473e
@ -96,6 +96,7 @@
|
|||||||
<Compile Include="exeHandler.js" />
|
<Compile Include="exeHandler.js" />
|
||||||
<Compile Include="letsencrypt.js" />
|
<Compile Include="letsencrypt.js" />
|
||||||
<Compile Include="meshaccelerator.js" />
|
<Compile Include="meshaccelerator.js" />
|
||||||
|
<Compile Include="meshctrl.js" />
|
||||||
<Compile Include="meshmail.js" />
|
<Compile Include="meshmail.js" />
|
||||||
<Compile Include="meshscanner.js" />
|
<Compile Include="meshscanner.js" />
|
||||||
<Compile Include="certoperations.js" />
|
<Compile Include="certoperations.js" />
|
||||||
|
77
meshctrl.js
77
meshctrl.js
@ -3,7 +3,7 @@
|
|||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
var settings = {};
|
var settings = {};
|
||||||
const args = require('minimist')(process.argv.slice(2));
|
const args = require('minimist')(process.argv.slice(2));
|
||||||
const possibleCommands = ['listusers', 'listdevicegroups', 'serverinfo', 'userinfo', 'adduser', 'removeuser', 'adddevicegroup', 'removedevicegroup', 'broadcast'];
|
const possibleCommands = ['listusers', 'listdevicegroups', 'serverinfo', 'userinfo', 'adduser', 'removeuser', 'adddevicegroup', 'removedevicegroup', 'broadcast', 'addusertodevicegroup', 'removeuserfromdevicegroup'];
|
||||||
//console.log(args);
|
//console.log(args);
|
||||||
|
|
||||||
if (args['_'].length == 0) {
|
if (args['_'].length == 0) {
|
||||||
@ -20,6 +20,8 @@ if (args['_'].length == 0) {
|
|||||||
console.log(" RemoveUser - Delete a user account.");
|
console.log(" RemoveUser - Delete a user account.");
|
||||||
console.log(" AddDeviceGroup - Create a new device group.");
|
console.log(" AddDeviceGroup - Create a new device group.");
|
||||||
console.log(" RemoveDeviceGroup - Delete a device group.");
|
console.log(" RemoveDeviceGroup - Delete a device group.");
|
||||||
|
console.log(" AddUserToDeviceGroup - Add a user to a device group.");
|
||||||
|
console.log(" RemoveUserFromDeviceGroup - Remove a user from a device group.");
|
||||||
console.log(" Broadcast - Display a message to all online users.");
|
console.log(" Broadcast - Display a message to all online users.");
|
||||||
console.log("\r\nSupported login arguments:");
|
console.log("\r\nSupported login arguments:");
|
||||||
console.log(" --url [wss://server] - Server url, wss://localhost:443 is default.");
|
console.log(" --url [wss://server] - Server url, wss://localhost:443 is default.");
|
||||||
@ -41,6 +43,18 @@ if (args['_'].length == 0) {
|
|||||||
case 'userinfo': { ok = true; break; }
|
case 'userinfo': { ok = true; break; }
|
||||||
case 'listusers': { ok = true; break; }
|
case 'listusers': { ok = true; break; }
|
||||||
case 'listdevicegroups': { ok = true; break; }
|
case 'listdevicegroups': { ok = true; break; }
|
||||||
|
case 'addusertodevicegroup': {
|
||||||
|
if (args.userid == null) { console.log("Add user to group missing useid, use --userid [userid]"); }
|
||||||
|
else if (args.id == null) { console.log("Add user to group missing group id, use --id [groupid]"); }
|
||||||
|
else { ok = true; }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'removeuserfromdevicegroup': {
|
||||||
|
if (args.userid == null) { console.log("Remove user from group missing useid, use --userid [userid]"); }
|
||||||
|
else if (args.id == null) { console.log("Remove user from group missing group id, use --id [groupid]"); }
|
||||||
|
else { ok = true; }
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'adddevicegroup': {
|
case 'adddevicegroup': {
|
||||||
if (args.name == null) { console.log("Message group name, use --name [name]"); }
|
if (args.name == null) { console.log("Message group name, use --name [name]"); }
|
||||||
else { ok = true; }
|
else { ok = true; }
|
||||||
@ -149,11 +163,43 @@ if (args['_'].length == 0) {
|
|||||||
}
|
}
|
||||||
case 'removedevicegroup': {
|
case 'removedevicegroup': {
|
||||||
console.log("Remove a device group, Example usages:\r\n");
|
console.log("Remove a device group, Example usages:\r\n");
|
||||||
console.log(" MeshCtrl RemoteDeviceGroup --id groupid");
|
console.log(" MeshCtrl RemoveDeviceGroup --id groupid");
|
||||||
console.log("\r\nRequired arguments:\r\n");
|
console.log("\r\nRequired arguments:\r\n");
|
||||||
console.log(" --id [groupid] - The group identifier.");
|
console.log(" --id [groupid] - The group identifier.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'addusertodevicegroup': {
|
||||||
|
console.log("Add a user to a device group, Example usages:\r\n");
|
||||||
|
console.log(" MeshCtrl AddUserToDeviceGroup --id groupid --userid userid --fullrights");
|
||||||
|
console.log(" MeshCtrl AddUserToDeviceGroup --id groupid --userid userid --editgroup --manageusers");
|
||||||
|
console.log("\r\nRequired arguments:\r\n");
|
||||||
|
console.log(" --id [groupid] - The group identifier.");
|
||||||
|
console.log(" --userid [userid] - The user identifier.");
|
||||||
|
console.log("\r\nOptional arguments:\r\n");
|
||||||
|
console.log(" --fullrights - Allow full rights over this device group.");
|
||||||
|
console.log(" --editgroup - Allow the user to edit group information.");
|
||||||
|
console.log(" --manageusers - Allow the user to add/remove users.");
|
||||||
|
console.log(" --managedevices - Allow the user to edit device information.");
|
||||||
|
console.log(" --remotecontrol - Allow device remote control operations.");
|
||||||
|
console.log(" --agentconsole - Allow agent console operations.");
|
||||||
|
console.log(" --serverfiles - Allow access to group server files.");
|
||||||
|
console.log(" --wakedevices - Allow device wake operation.");
|
||||||
|
console.log(" --notes - Allow editing of device notes.");
|
||||||
|
console.log(" --desktopviewonly - Restrict user to view-only remote desktop.");
|
||||||
|
console.log(" --limiteddesktop - Limit remote desktop keys.");
|
||||||
|
console.log(" --noterminal - Hide the terminal tab from this user.");
|
||||||
|
console.log(" --nofiles - Hide the files tab from this user.");
|
||||||
|
console.log(" --noamt - Hide the Intel AMT tab from this user.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'removeuserfromdevicegroup': {
|
||||||
|
console.log("Remove a user from a device group, Example usages:\r\n");
|
||||||
|
console.log(" MeshCtrl RemoveuserFromDeviceGroup --id groupid --userid userid");
|
||||||
|
console.log("\r\nRequired arguments:\r\n");
|
||||||
|
console.log(" --id [groupid] - The group identifier.");
|
||||||
|
console.log(" --userid [userid] - The user identifier.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'broadcast': {
|
case 'broadcast': {
|
||||||
console.log("Display a message to all logged in users, Example usages:\r\n");
|
console.log("Display a message to all logged in users, Example usages:\r\n");
|
||||||
console.log(" MeshCtrl Broadcast --msg \"This is a test\"");
|
console.log(" MeshCtrl Broadcast --msg \"This is a test\"");
|
||||||
@ -267,6 +313,31 @@ function serverConnect() {
|
|||||||
ws.send(JSON.stringify(op));
|
ws.send(JSON.stringify(op));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'addusertodevicegroup': {
|
||||||
|
var meshrights = 0;
|
||||||
|
if (args.fullrights) { meshrights = 0xFFFFFFFF; }
|
||||||
|
if (args.editgroup) { meshrights |= 1; }
|
||||||
|
if (args.manageusers) { meshrights |= 2; }
|
||||||
|
if (args.managedevices) { meshrights |= 4; }
|
||||||
|
if (args.remotecontrol) { meshrights |= 8; }
|
||||||
|
if (args.agentconsole) { meshrights |= 16; }
|
||||||
|
if (args.serverfiles) { meshrights |= 32; }
|
||||||
|
if (args.wakedevices) { meshrights |= 64; }
|
||||||
|
if (args.notes) { meshrights |= 128; }
|
||||||
|
if (args.desktopviewonly) { meshrights |= 256; }
|
||||||
|
if (args.noterminal) { meshrights |= 512; }
|
||||||
|
if (args.nofiles) { meshrights |= 1024; }
|
||||||
|
if (args.noamt) { meshrights |= 2048; }
|
||||||
|
if (args.limiteddesktop) { meshrights |= 4096; }
|
||||||
|
var op = { action: 'addmeshuser', meshid: args.id, usernames: [args.userid], meshadmin: meshrights, responseid: 'meshctrl' };
|
||||||
|
ws.send(JSON.stringify(op));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'removeuserfromdevicegroup': {
|
||||||
|
var op = { action: 'removemeshuser', meshid: args.id, userid: args.userid, responseid: 'meshctrl' };
|
||||||
|
ws.send(JSON.stringify(op));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'broadcast': {
|
case 'broadcast': {
|
||||||
var op = { action: 'userbroadcast', msg: args.msg, responseid: 'meshctrl' };
|
var op = { action: 'userbroadcast', msg: args.msg, responseid: 'meshctrl' };
|
||||||
ws.send(JSON.stringify(op));
|
ws.send(JSON.stringify(op));
|
||||||
@ -309,6 +380,8 @@ function serverConnect() {
|
|||||||
case 'deleteuser': // REMOVEUSER
|
case 'deleteuser': // REMOVEUSER
|
||||||
case 'createmesh': // ADDDEVICEGROUP
|
case 'createmesh': // ADDDEVICEGROUP
|
||||||
case 'deletemesh': // REMOVEDEVICEGROUP
|
case 'deletemesh': // REMOVEDEVICEGROUP
|
||||||
|
case 'addmeshuser': //
|
||||||
|
case 'removemeshuser': //
|
||||||
case 'userbroadcast': { // BROADCAST
|
case 'userbroadcast': { // BROADCAST
|
||||||
if (data.responseid == 'meshctrl') {
|
if (data.responseid == 'meshctrl') {
|
||||||
if (data.meshid) { console.log(data.result, data.meshid); }
|
if (data.meshid) { console.log(data.result, data.meshid); }
|
||||||
|
67
meshuser.js
67
meshuser.js
@ -1590,18 +1590,27 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||||||
}
|
}
|
||||||
case 'addmeshuser':
|
case 'addmeshuser':
|
||||||
{
|
{
|
||||||
if (common.validateString(command.meshid, 1, 1024) == false) break; // Check the meshid
|
var err = null;
|
||||||
if (common.validateInt(command.meshadmin) == false) break; // Mesh rights must be an integer
|
try {
|
||||||
if (common.validateStrArray(command.usernames, 1, 64) == false) break; // Username is between 1 and 64 characters
|
if (common.validateString(command.meshid, 1, 1024) == false) { err = 'Invalid groupid'; } // Check the meshid
|
||||||
|
else if (common.validateInt(command.meshadmin) == false) { err = 'Invalid group rights'; } // Mesh rights must be an integer
|
||||||
// Get the mesh
|
else if (common.validateStrArray(command.usernames, 1, 64) == false) { err = 'Invalid usernames'; } // Username is between 1 and 64 characters
|
||||||
|
else {
|
||||||
|
if (command.meshid.indexOf('/') == -1) { command.meshid = 'mesh/' + domain.id + '/' + command.meshid; }
|
||||||
mesh = parent.meshes[command.meshid];
|
mesh = parent.meshes[command.meshid];
|
||||||
if (mesh) {
|
if (mesh == null) { err = 'Unknown group'; }
|
||||||
// Check if this user has rights to do this
|
else if (mesh.links[user._id] == null || ((mesh.links[user._id].rights & 2) == 0)) { err = 'Permission denied'; }
|
||||||
if (mesh.links[user._id] == null || ((mesh.links[user._id].rights & 2) == 0)) return;
|
else if ((command.meshid.split('/').length != 3) || (command.meshid.split('/')[1] != domain.id)) { err = 'Invalid domain'; } // Invalid domain, operation only valid for current domain
|
||||||
if ((command.meshid.split('/').length != 3) || (command.meshid.split('/')[1] != domain.id)) return; // Invalid domain, operation only valid for current domain
|
}
|
||||||
|
} catch (ex) { err = 'Validation exception: ' + ex; }
|
||||||
|
|
||||||
var unknownUsers = [];
|
// Handle any errors
|
||||||
|
if (err != null) {
|
||||||
|
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: err })); } catch (ex) { } }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var unknownUsers = [], removedCount = 0, failCount = 0;
|
||||||
for (var i in command.usernames) {
|
for (var i in command.usernames) {
|
||||||
// Check if the user exists
|
// Check if the user exists
|
||||||
var newuserid = 'user/' + domain.id + '/' + command.usernames[i].toLowerCase(), newuser = parent.users[newuserid];
|
var newuserid = 'user/' + domain.id + '/' + command.usernames[i].toLowerCase(), newuser = parent.users[newuserid];
|
||||||
@ -1620,8 +1629,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||||||
var event = { etype: 'mesh', username: newuser.name, userid: command.userid, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Added user ' + newuser.name + ' to mesh ' + mesh.name, domain: domain.id };
|
var event = { etype: 'mesh', username: newuser.name, userid: command.userid, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Added user ' + newuser.name + ' to mesh ' + mesh.name, domain: domain.id };
|
||||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
|
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
|
||||||
parent.parent.DispatchEvent(['*', mesh._id, user._id, newuserid], obj, event);
|
parent.parent.DispatchEvent(['*', mesh._id, user._id, newuserid], obj, event);
|
||||||
|
removedCount++;
|
||||||
} else {
|
} else {
|
||||||
unknownUsers.push(command.usernames[i]);
|
unknownUsers.push(command.usernames[i]);
|
||||||
|
failCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1629,20 +1640,32 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||||||
// Send error back, user not found.
|
// Send error back, user not found.
|
||||||
displayNotificationMessage('User' + ((unknownUsers.length > 1)?'s':'') + ' ' + EscapeHtml(unknownUsers.join(', ')) + ' not found.', 'Device Group', 'ServerNotify');
|
displayNotificationMessage('User' + ((unknownUsers.length > 1)?'s':'') + ' ' + EscapeHtml(unknownUsers.join(', ')) + ' not found.', 'Device Group', 'ServerNotify');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: 'ok', removed: removedCount, failed: failCount })); } catch (ex) { } }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'removemeshuser':
|
case 'removemeshuser':
|
||||||
{
|
{
|
||||||
if (common.validateString(command.userid, 1, 1024) == false) break; // Check userid
|
var err = null;
|
||||||
if (common.validateString(command.meshid, 1, 1024) == false) break; // Check meshid
|
try {
|
||||||
if ((command.userid.split('/').length != 3) || (command.userid.split('/')[1] != domain.id)) return; // Invalid domain, operation only valid for current domain
|
if (common.validateString(command.userid, 1, 1024) == false) { err = 'Invalid userid'; } // Check userid
|
||||||
|
if (common.validateString(command.meshid, 1, 1024) == false) { err = 'Invalid groupid'; } // Check meshid
|
||||||
// Get the mesh
|
if (command.userid.indexOf('/') == -1) { command.userid = 'user/' + domain.id + '/' + command.userid; }
|
||||||
|
if ((command.userid.split('/').length != 3) || (command.userid.split('/')[1] != domain.id)) { err = 'Invalid userid'; } // Invalid domain, operation only valid for current domain
|
||||||
|
else {
|
||||||
|
if (command.meshid.indexOf('/') == -1) { command.meshid = 'mesh/' + domain.id + '/' + command.meshid; }
|
||||||
mesh = parent.meshes[command.meshid];
|
mesh = parent.meshes[command.meshid];
|
||||||
if (mesh) {
|
if (mesh == null) { err = 'Unknown device group'; }
|
||||||
// Check if this user has rights to do this
|
else if (mesh.links[user._id] == null || ((mesh.links[user._id].rights & 2) == 0)) { err = 'Permission denied'; }
|
||||||
if (mesh.links[user._id] == null || ((mesh.links[user._id].rights & 2) == 0)) return;
|
else if ((command.meshid.split('/').length != 3) || (command.meshid.split('/')[1] != domain.id)) { err = 'Invalid domain'; } // Invalid domain, operation only valid for current domain
|
||||||
|
}
|
||||||
|
} catch (ex) { err = 'Validation exception: ' + ex; }
|
||||||
|
|
||||||
|
// Handle any errors
|
||||||
|
if (err != null) {
|
||||||
|
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: err })); } catch (ex) { } }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the user exists - Just in case we need to delete a mesh right for a non-existant user, we do it this way. Technically, it's not possible, but just in case.
|
// Check if the user exists - Just in case we need to delete a mesh right for a non-existant user, we do it this way. Technically, it's not possible, but just in case.
|
||||||
var deluserid = command.userid, deluser = parent.users[deluserid];
|
var deluserid = command.userid, deluser = parent.users[deluserid];
|
||||||
@ -1671,7 +1694,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||||||
}
|
}
|
||||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
|
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
|
||||||
parent.parent.DispatchEvent(['*', mesh._id, user._id, command.userid], obj, event);
|
parent.parent.DispatchEvent(['*', mesh._id, user._id, command.userid], obj, event);
|
||||||
}
|
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'removemeshuser', responseid: command.responseid, result: 'ok' })); } catch (ex) { } }
|
||||||
|
} else {
|
||||||
|
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'removemeshuser', responseid: command.responseid, result: 'User not in group' })); } catch (ex) { } }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2621,7 +2646,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||||||
if (common.validateString(command.meshid, 8, 128) == false) break; // Check the meshid
|
if (common.validateString(command.meshid, 8, 128) == false) break; // Check the meshid
|
||||||
if (common.validateInt(command.expire, 0, 99999) == false) break; // Check the expire time in hours
|
if (common.validateInt(command.expire, 0, 99999) == false) break; // Check the expire time in hours
|
||||||
if (common.validateInt(command.flags, 0, 256) == false) break; // Check the flags
|
if (common.validateInt(command.flags, 0, 256) == false) break; // Check the flags
|
||||||
var mesh = parent.meshes[command.meshid];
|
mesh = parent.meshes[command.meshid];
|
||||||
if (mesh == null) break;
|
if (mesh == null) break;
|
||||||
const inviteCookie = parent.parent.encodeCookie({ a: 4, mid: command.meshid, f: command.flags, expire: command.expire * 60 }, parent.parent.invitationLinkEncryptionKey);
|
const inviteCookie = parent.parent.encodeCookie({ a: 4, mid: command.meshid, f: command.flags, expire: command.expire * 60 }, parent.parent.invitationLinkEncryptionKey);
|
||||||
if (inviteCookie == null) break;
|
if (inviteCookie == null) break;
|
||||||
|
Loading…
Reference in New Issue
Block a user