mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-22 21:31:35 +03:00
Fixed agent 'msg' dispatching.
This commit is contained in:
parent
9453ee9ba3
commit
bcf5cfbb5e
@ -1,35 +1,30 @@
|
||||
|
||||
var http = require('http');
|
||||
var childProcess = require('child_process');
|
||||
var meshCoreObj = { "action": "coreinfo", "value": "MeshCore Recovery", "caps": 14 }; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript
|
||||
var meshCoreObj = { action: 'coreinfo', value: "MeshCore Recovery", caps: 14 }; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript
|
||||
var nextTunnelIndex = 1;
|
||||
var tunnels = {};
|
||||
var fs = require('fs');
|
||||
|
||||
//attachDebugger({ webport: 9994, wait: 1 }).then(function (p) { console.log('Debug on port: ' + p); });
|
||||
|
||||
function sendConsoleText(msg)
|
||||
{
|
||||
require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": msg });
|
||||
function sendConsoleText(msg) {
|
||||
require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: msg });
|
||||
}
|
||||
// Return p number of spaces
|
||||
function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ret; } return r; }
|
||||
|
||||
setInterval(function () { sendConsoleText('Timer!'); }, 2000);
|
||||
|
||||
var path =
|
||||
{
|
||||
join: function ()
|
||||
{
|
||||
join: function () {
|
||||
var x = [];
|
||||
for (var i in arguments)
|
||||
{
|
||||
for (var i in arguments) {
|
||||
var w = arguments[i];
|
||||
if (w != null)
|
||||
{
|
||||
if (w != null) {
|
||||
while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
|
||||
if (i != 0)
|
||||
{
|
||||
while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); }
|
||||
}
|
||||
if (i != 0) { while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } }
|
||||
x.push(w);
|
||||
}
|
||||
}
|
||||
@ -53,16 +48,14 @@ function objToString(x, p, pad, ret) {
|
||||
}
|
||||
|
||||
// Split a string taking into account the quoats. Used for command line parsing
|
||||
function splitArgs(str)
|
||||
{
|
||||
function splitArgs(str) {
|
||||
var myArray = [], myRegexp = /[^\s"]+|"([^"]*)"/gi;
|
||||
do { var match = myRegexp.exec(str); if (match != null) { myArray.push(match[1] ? match[1] : match[0]); } } while (match != null);
|
||||
return myArray;
|
||||
}
|
||||
|
||||
// Parse arguments string array into an object
|
||||
function parseArgs(argv)
|
||||
{
|
||||
function parseArgs(argv) {
|
||||
var results = { '_': [] }, current = null;
|
||||
for (var i = 1, len = argv.length; i < len; i++) {
|
||||
var x = argv[i];
|
||||
@ -77,8 +70,7 @@ function parseArgs(argv)
|
||||
return results;
|
||||
}
|
||||
// Get server target url with a custom path
|
||||
function getServerTargetUrl(path)
|
||||
{
|
||||
function getServerTargetUrl(path) {
|
||||
var x = require('MeshAgent').ServerUrl;
|
||||
//sendConsoleText("mesh.ServerUrl: " + mesh.ServerUrl);
|
||||
if (x == null) { return null; }
|
||||
@ -89,16 +81,13 @@ function getServerTargetUrl(path)
|
||||
}
|
||||
|
||||
// Get server url. If the url starts with "*/..." change it, it not use the url as is.
|
||||
function getServerTargetUrlEx(url)
|
||||
{
|
||||
function getServerTargetUrlEx(url) {
|
||||
if (url.substring(0, 2) == '*/') { return getServerTargetUrl(url.substring(2)); }
|
||||
return url;
|
||||
}
|
||||
|
||||
require('MeshAgent').on('Connected', function ()
|
||||
{
|
||||
require('os').name().then(function (v)
|
||||
{
|
||||
require('MeshAgent').on('Connected', function () {
|
||||
require('os').name().then(function (v) {
|
||||
sendConsoleText("Mesh Agent Receovery Console, OS: " + v);
|
||||
require('MeshAgent').SendCommand(meshCoreObj);
|
||||
});
|
||||
@ -127,20 +116,15 @@ function onTunnelUpgrade(response, s, head) {
|
||||
}
|
||||
}
|
||||
|
||||
require('MeshAgent').AddCommandHandler(function (data)
|
||||
{
|
||||
if (typeof data == 'object')
|
||||
{
|
||||
require('MeshAgent').AddCommandHandler(function (data) {
|
||||
if (typeof data == 'object') {
|
||||
// If this is a console command, parse it and call the console handler
|
||||
switch (data.action)
|
||||
{
|
||||
switch (data.action) {
|
||||
case 'msg':
|
||||
{
|
||||
switch (data.type)
|
||||
{
|
||||
switch (data.type) {
|
||||
case 'console': { // Process a console command
|
||||
if (data.value && data.sessionid)
|
||||
{
|
||||
if (data.value && data.sessionid) {
|
||||
var args = splitArgs(data.value);
|
||||
processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid);
|
||||
}
|
||||
@ -156,13 +140,11 @@ require('MeshAgent').AddCommandHandler(function (data)
|
||||
woptions.rejectUnauthorized = 0;
|
||||
//sendConsoleText(JSON.stringify(woptions));
|
||||
var tunnel = http.request(woptions);
|
||||
tunnel.on('upgrade', function (response, s, head)
|
||||
{
|
||||
tunnel.on('upgrade', function (response, s, head) {
|
||||
this.s = s;
|
||||
s.httprequest = this;
|
||||
s.tunnel = this;
|
||||
s.on('end', function ()
|
||||
{
|
||||
s.on('end', function () {
|
||||
if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls.
|
||||
|
||||
// If there is a upload or download active on this connection, close the file
|
||||
@ -176,11 +158,9 @@ require('MeshAgent').AddCommandHandler(function (data)
|
||||
// Clean up WebSocket
|
||||
this.removeAllListeners('data');
|
||||
});
|
||||
s.on('data', function (data)
|
||||
{
|
||||
s.on('data', function (data) {
|
||||
// If this is upload data, save it to file
|
||||
if (this.httprequest.uploadFile)
|
||||
{
|
||||
if (this.httprequest.uploadFile) {
|
||||
try { fs.writeSync(this.httprequest.uploadFile, data); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror' }))); return; } // Write to the file, if there is a problem, error out.
|
||||
this.write(new Buffer(JSON.stringify({ action: 'uploadack', reqid: this.httprequest.uploadFileid }))); // Ask for more data
|
||||
return;
|
||||
@ -191,23 +171,19 @@ require('MeshAgent').AddCommandHandler(function (data)
|
||||
if ((data == 'c') || (data == 'cr')) { this.httprequest.state = 1; sendConsoleText("Tunnel #" + this.httprequest.index + " now active", this.httprequest.sessionid); }
|
||||
} else {
|
||||
// Handle tunnel data
|
||||
if (this.httprequest.protocol == 0)
|
||||
{
|
||||
if (this.httprequest.protocol == 0) {
|
||||
// Take a look at the protocol
|
||||
this.httprequest.protocol = parseInt(data);
|
||||
if (typeof this.httprequest.protocol != 'number') { this.httprequest.protocol = 0; }
|
||||
if (this.httprequest.protocol == 1)
|
||||
{
|
||||
if (this.httprequest.protocol == 1) {
|
||||
// Remote terminal using native pipes
|
||||
if (process.platform == "win32")
|
||||
{
|
||||
if (process.platform == "win32") {
|
||||
this.httprequest._term = require('win-terminal').Start(80, 25);
|
||||
this.httprequest._term.pipe(this, { dataTypeSkip: 1 });
|
||||
this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false });
|
||||
this.prependListener('end', function () { this.httprequest._term.end(function () { sendConsoleText('Terminal was closed'); }); });
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
this.httprequest.process = childProcess.execFile("/bin/sh", ["sh"], { type: childProcess.SpawnTypes.TERM });
|
||||
this.httprequest.process.tunnel = this;
|
||||
this.httprequest.process.on('exit', function (ecode, sig) { this.tunnel.end(); });
|
||||
@ -218,8 +194,7 @@ require('MeshAgent').AddCommandHandler(function (data)
|
||||
}
|
||||
|
||||
this.on('end', function () {
|
||||
if (process.platform == "win32")
|
||||
{
|
||||
if (process.platform == "win32") {
|
||||
// Unpipe the web socket
|
||||
this.unpipe(this.httprequest._term);
|
||||
this.httprequest._term.unpipe(this);
|
||||
@ -231,8 +206,7 @@ require('MeshAgent').AddCommandHandler(function (data)
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (this.httprequest.protocol == 5)
|
||||
{
|
||||
else if (this.httprequest.protocol == 5) {
|
||||
// Process files commands
|
||||
var cmd = null;
|
||||
try { cmd = JSON.parse(data); } catch (e) { };
|
||||
@ -245,8 +219,7 @@ require('MeshAgent').AddCommandHandler(function (data)
|
||||
|
||||
if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
|
||||
//console.log(objToString(cmd, 0, ' '));
|
||||
switch (cmd.action)
|
||||
{
|
||||
switch (cmd.action) {
|
||||
case 'ls':
|
||||
// Send the folder content to the browser
|
||||
var response = getDirectoryInfo(cmd.path);
|
||||
@ -260,8 +233,7 @@ require('MeshAgent').AddCommandHandler(function (data)
|
||||
}
|
||||
case 'rm': {
|
||||
// Delete, possibly recursive delete
|
||||
for (var i in cmd.delfiles)
|
||||
{
|
||||
for (var i in cmd.delfiles) {
|
||||
try { deleteFolderRecursive(path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (e) { }
|
||||
}
|
||||
break;
|
||||
@ -304,7 +276,7 @@ require('MeshAgent').AddCommandHandler(function (data)
|
||||
}
|
||||
});
|
||||
});
|
||||
tunnel.onerror = function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); }
|
||||
tunnel.onerror = function (e) { sendConsoleText("ERROR: " + JSON.stringify(e)); }
|
||||
tunnel.sessionid = data.sessionid;
|
||||
tunnel.rights = data.rights;
|
||||
tunnel.state = 0;
|
||||
@ -337,20 +309,16 @@ require('MeshAgent').AddCommandHandler(function (data)
|
||||
}
|
||||
});
|
||||
|
||||
function processConsoleCommand(cmd, args, rights, sessionid)
|
||||
{
|
||||
try
|
||||
{
|
||||
function processConsoleCommand(cmd, args, rights, sessionid) {
|
||||
try {
|
||||
var response = null;
|
||||
switch (cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
case 'help':
|
||||
response = 'Available commands are: osinfo, dbkeys, dbget, dbset, dbcompact, netinfo.';
|
||||
response = "Available commands are: osinfo, dbkeys, dbget, dbset, dbcompact, netinfo.";
|
||||
break;
|
||||
|
||||
case 'osinfo': { // Return the operating system information
|
||||
var i = 1;
|
||||
if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; }
|
||||
if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = "Calling " + i + " times."; }
|
||||
for (var j = 0; j < i; j++) {
|
||||
var pr = require('os').name();
|
||||
pr.sessionid = sessionid;
|
||||
@ -363,34 +331,34 @@ function processConsoleCommand(cmd, args, rights, sessionid)
|
||||
break;
|
||||
}
|
||||
case 'dbget': { // Return the data store value for a given key
|
||||
if (db == null) { response = 'Database not accessible.'; break; }
|
||||
if (db == null) { response = "Database not accessible."; break; }
|
||||
if (args['_'].length != 1) {
|
||||
response = 'Proper usage: dbget (key)'; // Display the value for a given database key
|
||||
response = "Proper usage: dbget (key)"; // Display the value for a given database key
|
||||
} else {
|
||||
response = db.Get(args['_'][0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'dbset': { // Set a data store key and value pair
|
||||
if (db == null) { response = 'Database not accessible.'; break; }
|
||||
if (db == null) { response = "Database not accessible."; break; }
|
||||
if (args['_'].length != 2) {
|
||||
response = 'Proper usage: dbset (key) (value)'; // Set a database key
|
||||
response = "Proper usage: dbset (key) (value)"; // Set a database key
|
||||
} else {
|
||||
var r = db.Put(args['_'][0], args['_'][1]);
|
||||
response = 'Key set: ' + r;
|
||||
response = "Key set: " + r;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'dbcompact': { // Compact the data store
|
||||
if (db == null) { response = 'Database not accessible.'; break; }
|
||||
if (db == null) { response = "Database not accessible."; break; }
|
||||
var r = db.Compact();
|
||||
response = 'Database compacted: ' + r;
|
||||
response = "Database compacted: " + r;
|
||||
break;
|
||||
}
|
||||
case 'tunnels': { // Show the list of current tunnels
|
||||
response = '';
|
||||
for (var i in tunnels) { response += 'Tunnel #' + i + ', ' + tunnels[i].url + '\r\n'; }
|
||||
if (response == '') { response = 'No websocket sessions.'; }
|
||||
for (var i in tunnels) { response += "Tunnel #" + i + ", " + tunnels[i].url + '\r\n'; }
|
||||
if (response == '') { response = "No websocket sessions."; }
|
||||
break;
|
||||
}
|
||||
case 'netinfo': { // Show network interface information
|
||||
@ -404,13 +372,12 @@ function processConsoleCommand(cmd, args, rights, sessionid)
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e) { response = 'Command returned an exception error: ' + e; console.log(e); }
|
||||
} catch (e) { response = "Command returned an exception error: " + e; console.log(e); }
|
||||
if (response != null) { sendConsoleText(response, sessionid); }
|
||||
}
|
||||
|
||||
// Get a formated response for a given directory path
|
||||
function getDirectoryInfo(reqpath)
|
||||
{
|
||||
function getDirectoryInfo(reqpath) {
|
||||
var response = { path: reqpath, dir: [] };
|
||||
if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) {
|
||||
// List all the drives in the root, or the root itself
|
||||
|
@ -645,7 +645,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
}
|
||||
else if ((command.fileop == 'rename') && (common.IsFilenameValid(command.oldname) == true) && (common.IsFilenameValid(command.newname) == true)) {
|
||||
// Rename
|
||||
try { fs.renameSync(path + "/" + command.oldname, path + "/" + command.newname); } catch (e) { }
|
||||
try { fs.renameSync(path + '/' + command.oldname, path + '/' + command.newname); } catch (e) { }
|
||||
}
|
||||
else if ((command.fileop == 'copy') || (command.fileop == 'move')) {
|
||||
if (common.validateArray(command.names, 1) == false) return;
|
||||
|
@ -4262,17 +4262,18 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
// TODO: Add multi-server support
|
||||
}
|
||||
}
|
||||
} else { // Route this command to the mesh
|
||||
} else { // Route this command to all users with MESHRIGHT_AGENTCONSOLE rights to this device group
|
||||
command.nodeid = nodeid;
|
||||
var cmdstr = JSON.stringify(command);
|
||||
if (obj.GetMeshRights(userid, meshid) == 0) return; // TODO: Check if this is ok
|
||||
|
||||
// Find all connected users for this mesh and send the message
|
||||
// Find all connected user sessions with access to this device
|
||||
for (var userid in obj.wssessions) {
|
||||
var xsessions = obj.wssessions[userid];
|
||||
// Send the message to all users on this server
|
||||
if (obj.GetMeshRights(userid, meshid) != 0) {
|
||||
// Send the message to all sessions for this user on this server
|
||||
for (i in xsessions) { try { xsessions[i].send(cmdstr); } catch (e) { } }
|
||||
}
|
||||
}
|
||||
|
||||
// Send the message to all users of other servers
|
||||
if (parent.multiServer != null) {
|
||||
|
Loading…
Reference in New Issue
Block a user