From f6c38837358d86602e9e5ac3eda1b4eb1c49835c Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Fri, 19 Aug 2022 20:15:06 -0700 Subject: [PATCH] Added support for pre-defined scripts. --- meshcentral-config-schema.json | 33 +++++++++++++++++++++ meshuser.js | 52 ++++++++++++++++++++++++++++++++-- sample-config-advanced.json | 25 ++++++++++++++++ views/default.handlebars | 32 +++++++++++++++++++-- 4 files changed, 136 insertions(+), 6 deletions(-) diff --git a/meshcentral-config-schema.json b/meshcentral-config-schema.json index 01d02fdd..a5078e91 100644 --- a/meshcentral-config-schema.json +++ b/meshcentral-config-schema.json @@ -383,6 +383,39 @@ "expire": { "type": "number", "description": "When set, limits the self-created guest sharing link to this number of minutes." } } }, + "PreconfiguredScripts": { + "type": "array", + "default": null, + "description": "When set, your can try click the run button to run on of these scripts on the remote device.", + "items": { + "type": "object", + "required": [ "name", "type" ], + "properties": { + "name": { + "description": "Name of the script.", + "type": "string" + }, + "type": { + "description": "The type of script.", + "type": "string", + "enum": [ "bat", "ps1", "sh", "agent" ] + }, + "runas": { + "description": "How to run this script, does not appy to agent scripts.", + "type": "string", + "enum": ["agent", "userfirst", "user"] + }, + "cmd": { + "description": "The command or \\r\\n seperated commands to run, if set do not use the file key.", + "type": "string" + }, + "file": { + "description": "The script file path and name, if set do not use the cmd key. This file path starts in meshcentral-data.", + "type": "string" + } + } + } + }, "preConfiguredRemoteInput": { "type": "array", "default": null, diff --git a/meshuser.js b/meshuser.js index 9373582a..e9f29eb4 100644 --- a/meshuser.js +++ b/meshuser.js @@ -593,6 +593,18 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if ((typeof domain.terminal.linuxshell == 'string') && (domain.terminal.linuxshell != 'any')) { serverinfo.linuxshell = domain.terminal.linuxshell; } } if (Array.isArray(domain.preconfiguredremoteinput)) { serverinfo.preConfiguredRemoteInput = domain.preconfiguredremoteinput; } + if (Array.isArray(domain.preconfiguredscripts)) { + const r = []; + for (var i in domain.preconfiguredscripts) { + const types = ['', 'bat', 'ps1', 'sh', 'agent']; // 1 = Windows Command, 2 = Windows PowerShell, 3 = Linux, 4 = Agent + const script = domain.preconfiguredscripts[i]; + if ((typeof script.name == 'string') && (script.name.length <= 32) && (typeof script.type == 'string') && ((typeof script.file == 'string') || (typeof script.cmd == 'string'))) { + const s = { name: script.name, type: types.indexOf(script.type.toLowerCase()) }; + if (s.type > 0) { r.push(s); } + } + } + serverinfo.preConfiguredScripts = r; + } // Send server information try { ws.send(JSON.stringify({ action: 'serverinfo', serverinfo: serverinfo })); } catch (ex) { } @@ -2783,8 +2795,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use case 'runcommands': { if (common.validateArray(command.nodeids, 1) == false) break; // Check nodeid's - if (typeof command.type != 'number') break; // Check command type - if (typeof command.runAsUser != 'number') { command.runAsUser = 0; } // Check runAsUser + if (typeof command.presetcmd != 'number') { + if (typeof command.type != 'number') break; // Check command type + if (typeof command.runAsUser != 'number') { command.runAsUser = 0; } // Check runAsUser + } const processRunCommand = function (command) { for (i in command.nodeids) { @@ -2873,7 +2887,39 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } } - if (typeof command.cmdpath == 'string') { + if (typeof command.presetcmd == 'number') { + // If a pre-set command is used, load the command + if (Array.isArray(domain.preconfiguredscripts) == false) return; + const script = domain.preconfiguredscripts[command.presetcmd]; + if (script == null) return; + delete command.presetcmd; + + // Decode script type + const types = ['', 'bat', 'ps1', 'sh', 'agent']; // 1 = Windows Command, 2 = Windows PowerShell, 3 = Linux, 4 = Agent + if (typeof script.type == 'string') { const stype = types.indexOf(script.type.toLowerCase()); if (stype > 0) { command.type = stype; } } + if (command.type == null) return; + + // Decode script runas + if (command.type != 4) { + const runAsModes = ['agent', 'userfirst', 'user']; // 0 = AsAgent, 1 = UserFirst, 2 = UserOnly + if (typeof script.runas == 'string') { const srunas = runAsModes.indexOf(script.runas.toLowerCase()); if (srunas >= 0) { command.runAsUser = srunas; } } + } + + if (typeof script.file == 'string') { + // The pre-defined script commands are in a file, load it + const scriptPath = parent.common.joinPath(parent.parent.datapath, script.file); + fs.readFile(scriptPath, function (err, data) { + // If loaded correctly, run loaded commands + if ((err != null) || (data == null) || (data.length == 0) || (data.length > 65535)) return; + command.cmds = data.toString(); + processRunCommand(command); + }); + } else if (typeof script.cmd == 'string') { + // The pre-defined script commands are right in the config.json, use that + command.cmds = script.cmd; + processRunCommand(command); + } + } else if (typeof command.cmdpath == 'string') { // If a server command path is used, load the script from the path var file = parent.getServerFilePath(user, domain, command.cmdpath); if (file != null) { diff --git a/sample-config-advanced.json b/sample-config-advanced.json index 53eac102..79d05fa7 100644 --- a/sample-config-advanced.json +++ b/sample-config-advanced.json @@ -243,6 +243,31 @@ } ] }, + "PreconfiguredScripts": [ + { + "name": "Run NotePad as user", + "file": "scripts/notepad.bat", + "type": "bat", + "runas": "user" + }, + { + "name": "Run NotePad as agent", + "cmd": "notepad.exe", + "type": "bat", + "runas": "agent" + }, + { + "name": "Run echo", + "cmd": "echo \"hello world\"", + "type": "sh", + "runas": "agent" + }, + { + "name": "Agent Update", + "cmd": "agentupdate", + "type": "agent" + } + ], "PreconfiguredRemoteInput": [ { "name": "CompanyUrl", diff --git a/views/default.handlebars b/views/default.handlebars index 69c87754..fd89505e 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -138,7 +138,10 @@
Customize...
- +