mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-11-29 09:43:56 +03:00
Added polyfill for Array.find() when missing, needed for Windows/Temp self update
This commit is contained in:
parent
13409348c2
commit
ab8b3095dd
@ -6,9 +6,104 @@ var nextTunnelIndex = 1;
|
|||||||
var tunnels = {};
|
var tunnels = {};
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
if (require('MeshAgent').ARCHID == null) {
|
try
|
||||||
|
{
|
||||||
|
Object.defineProperty(Array.prototype, 'find', {
|
||||||
|
value: function (func)
|
||||||
|
{
|
||||||
|
var i = 0;
|
||||||
|
for(i=0;i<this.length;++i)
|
||||||
|
{
|
||||||
|
if(func(this[i]))
|
||||||
|
{
|
||||||
|
return (this[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch(x)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getPotentialServiceNames()
|
||||||
|
{
|
||||||
|
var registry = require('win-registry');
|
||||||
|
var ret = [];
|
||||||
|
var K = registry.QueryKey(registry.HKEY.LocalMachine, 'SYSTEM\\CurrentControlSet\\Services');
|
||||||
|
var service, s;
|
||||||
|
while (K.subkeys.length > 0)
|
||||||
|
{
|
||||||
|
service = K.subkeys.shift();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s = registry.QueryKey(registry.HKEY.LocalMachine, 'SYSTEM\\CurrentControlSet\\Services\\' + service, 'ImagePath');
|
||||||
|
if (s.startsWith(process.execPath) || s.startsWith('"' + process.execPath + '"'))
|
||||||
|
{
|
||||||
|
ret.push(service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (x)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
function _verifyServiceName(names)
|
||||||
|
{
|
||||||
|
var i;
|
||||||
|
var s;
|
||||||
|
var ret = null;
|
||||||
|
for (i = 0; i < names.length; ++i)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s = require('service-manager').manager.getService(names[i]);
|
||||||
|
if (s.isMe())
|
||||||
|
{
|
||||||
|
ret = names[i];
|
||||||
|
s.close();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
catch (z) { }
|
||||||
|
}
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
function windows_getCommandLine()
|
||||||
|
{
|
||||||
|
var parms = [];
|
||||||
|
var GM = require('_GenericMarshal');
|
||||||
|
var k32 = GM.CreateNativeProxy('kernel32.dll');
|
||||||
|
var s32 = GM.CreateNativeProxy('shell32.dll');
|
||||||
|
k32.CreateMethod('GetCommandLineW');
|
||||||
|
k32.CreateMethod('LocalFree');
|
||||||
|
s32.CreateMethod('CommandLineToArgvW');
|
||||||
|
var v = k32.GetCommandLineW();
|
||||||
|
var i;
|
||||||
|
var len = GM.CreateVariable(4);
|
||||||
|
var val = s32.CommandLineToArgvW(v, len);
|
||||||
|
len = len.toBuffer().readInt32LE(0);
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
|
parms.push(val.Deref(i * GM.PointerSize, GM.PointerSize).Deref().Wide2UTF8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k32.LocalFree(val);
|
||||||
|
return (parms);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require('MeshAgent').ARCHID == null)
|
||||||
|
{
|
||||||
var id = null;
|
var id = null;
|
||||||
switch (process.platform) {
|
switch (process.platform)
|
||||||
|
{
|
||||||
case 'win32':
|
case 'win32':
|
||||||
id = require('_GenericMarshal').PointerSize == 4 ? 3 : 4;
|
id = require('_GenericMarshal').PointerSize == 4 ? 3 : 4;
|
||||||
break;
|
break;
|
||||||
@ -16,10 +111,12 @@ if (require('MeshAgent').ARCHID == null) {
|
|||||||
id = require('_GenericMarshal').PointerSize == 4 ? 31 : 30;
|
id = require('_GenericMarshal').PointerSize == 4 ? 31 : 30;
|
||||||
break;
|
break;
|
||||||
case 'darwin':
|
case 'darwin':
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
id = require('os').arch() == 'x64' ? 16 : 29;
|
id = require('os').arch() == 'x64' ? 16 : 29;
|
||||||
}
|
}
|
||||||
catch (xx) {
|
catch (xx)
|
||||||
|
{
|
||||||
id = 16;
|
id = 16;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -29,17 +126,22 @@ if (require('MeshAgent').ARCHID == null) {
|
|||||||
|
|
||||||
//attachDebugger({ webport: 9994, wait: 1 }).then(function (p) { console.log('Debug on port: ' + p); });
|
//attachDebugger({ webport: 9994, wait: 1 }).then(function (p) { console.log('Debug on port: ' + p); });
|
||||||
|
|
||||||
function sendConsoleText(msg, sessionid) {
|
function sendConsoleText(msg, sessionid)
|
||||||
if (sessionid != null) {
|
{
|
||||||
|
if (sessionid != null)
|
||||||
|
{
|
||||||
require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: msg, sessionid: sessionid });
|
require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: msg, sessionid: sessionid });
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: msg });
|
require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: msg });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendAgentMessage(msg, icon) {
|
function sendAgentMessage(msg, icon)
|
||||||
if (sendAgentMessage.messages == null) {
|
{
|
||||||
|
if (sendAgentMessage.messages == null)
|
||||||
|
{
|
||||||
sendAgentMessage.messages = {};
|
sendAgentMessage.messages = {};
|
||||||
sendAgentMessage.nextid = 1;
|
sendAgentMessage.nextid = 1;
|
||||||
}
|
}
|
||||||
@ -48,9 +150,11 @@ function sendAgentMessage(msg, icon) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add to the server event log
|
// Add to the server event log
|
||||||
function MeshServerLog(msg, state) {
|
function MeshServerLog(msg, state)
|
||||||
|
{
|
||||||
if (typeof msg == 'string') { msg = { action: 'log', msg: msg }; } else { msg.action = 'log'; }
|
if (typeof msg == 'string') { msg = { action: 'log', msg: msg }; } else { msg.action = 'log'; }
|
||||||
if (state) {
|
if (state)
|
||||||
|
{
|
||||||
if (state.userid) { msg.userid = state.userid; }
|
if (state.userid) { msg.userid = state.userid; }
|
||||||
if (state.username) { msg.username = state.username; }
|
if (state.username) { msg.username = state.username; }
|
||||||
if (state.sessionid) { msg.sessionid = state.sessionid; }
|
if (state.sessionid) { msg.sessionid = state.sessionid; }
|
||||||
@ -60,9 +164,11 @@ function MeshServerLog(msg, state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add to the server event log, use internationalized events
|
// Add to the server event log, use internationalized events
|
||||||
function MeshServerLogEx(id, args, msg, state) {
|
function MeshServerLogEx(id, args, msg, state)
|
||||||
|
{
|
||||||
var msg = { action: 'log', msgid: id, msgArgs: args, msg: msg };
|
var msg = { action: 'log', msgid: id, msgArgs: args, msg: msg };
|
||||||
if (state) {
|
if (state)
|
||||||
|
{
|
||||||
if (state.userid) { msg.userid = state.userid; }
|
if (state.userid) { msg.userid = state.userid; }
|
||||||
if (state.username) { msg.username = state.username; }
|
if (state.username) { msg.username = state.username; }
|
||||||
if (state.sessionid) { msg.sessionid = state.sessionid; }
|
if (state.sessionid) { msg.sessionid = state.sessionid; }
|
||||||
@ -346,6 +452,34 @@ function windows_execve(name, agentfilename, sessionid) {
|
|||||||
var arg2 = require('_GenericMarshal').CreateVariable('/C wmic service "' + name + '" call stopservice & "' + cwd + agentfilename + '.update.exe" -b64exec ' + 'dHJ5CnsKICAgIHZhciBzZXJ2aWNlTG9jYXRpb24gPSBwcm9jZXNzLmFyZ3YucG9wKCk7CiAgICByZXF1aXJlKCdwcm9jZXNzLW1hbmFnZXInKS5lbnVtZXJhdGVQcm9jZXNzZXMoKS50aGVuKGZ1bmN0aW9uIChwcm9jKQogICAgewogICAgICAgIGZvciAodmFyIHAgaW4gcHJvYykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwcm9jW3BdLnBhdGggPT0gc2VydmljZUxvY2F0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwcm9jZXNzLmtpbGwocHJvY1twXS5waWQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByb2Nlc3MuZXhpdCgpOwogICAgfSk7Cn0KY2F0Y2goZSkKewogICAgcHJvY2Vzcy5leGl0KCk7Cn0=' +
|
var arg2 = require('_GenericMarshal').CreateVariable('/C wmic service "' + name + '" call stopservice & "' + cwd + agentfilename + '.update.exe" -b64exec ' + 'dHJ5CnsKICAgIHZhciBzZXJ2aWNlTG9jYXRpb24gPSBwcm9jZXNzLmFyZ3YucG9wKCk7CiAgICByZXF1aXJlKCdwcm9jZXNzLW1hbmFnZXInKS5lbnVtZXJhdGVQcm9jZXNzZXMoKS50aGVuKGZ1bmN0aW9uIChwcm9jKQogICAgewogICAgICAgIGZvciAodmFyIHAgaW4gcHJvYykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwcm9jW3BdLnBhdGggPT0gc2VydmljZUxvY2F0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwcm9jZXNzLmtpbGwocHJvY1twXS5waWQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByb2Nlc3MuZXhpdCgpOwogICAgfSk7Cn0KY2F0Y2goZSkKewogICAgcHJvY2Vzcy5leGl0KCk7Cn0=' +
|
||||||
' "' + process.execPath + '" & copy "' + cwd + agentfilename + '.update.exe" "' + process.execPath + '" & wmic service "' + name + '" call startservice & erase "' + cwd + agentfilename + '.update.exe"', { wide: true });
|
' "' + process.execPath + '" & copy "' + cwd + agentfilename + '.update.exe" "' + process.execPath + '" & wmic service "' + name + '" call startservice & erase "' + cwd + agentfilename + '.update.exe"', { wide: true });
|
||||||
|
|
||||||
|
if (name == null)
|
||||||
|
{
|
||||||
|
// We can continue with self update for Temp/Console Mode on Windows
|
||||||
|
var db = null;
|
||||||
|
var update = cwd + agentfilename + '.update.exe';
|
||||||
|
var updatedb = cwd + agentfilename + '.update.db';
|
||||||
|
var parms = windows_getCommandLine(); parms.shift();
|
||||||
|
|
||||||
|
var updatesource = parms.find(function (v) { return (v.startsWith('--updateSourcePath=')); });
|
||||||
|
if (updatesource == null)
|
||||||
|
{
|
||||||
|
parms.push('--updateSourcePath="' + cwd + agentfilename + '"');
|
||||||
|
updatesource = (cwd + agentfilename).split('.exe'); updatesource.pop(); updatesource = updatesource.join('.exe');
|
||||||
|
db = updatesource + '.db';
|
||||||
|
updatesource = (' & move "' + updatedb + '" "' + db + '"') + (' & erase "' + updatedb + '"');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
updatesource = updatesource.substring(19).split('.exe');
|
||||||
|
updatesource.pop(); updatesource = updatesource.join('.exe');
|
||||||
|
db = updatesource + '.db';
|
||||||
|
updatesource = (' & move "' + update + '" "' + updatesource + '.exe" & move "' + updatedb + '" "' + db + '" & erase "' + updatedb + '"') + (' & echo move "' + update + '" "' + updatesource + '.exe" & echo move "' + updatedb + '" "' + db + '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = '/C echo copy "' + db + '" "' + updatedb + '" & copy "' + db + '" "' + updatedb + '"' + ' & "' + update + '" ' + parms.join(' ') + updatesource + ' & erase "' + update + '" & echo ERASE "' + update + '"';
|
||||||
|
arg2 = require('_GenericMarshal').CreateVariable(tmp, { wide: true });
|
||||||
|
}
|
||||||
|
|
||||||
arg1.pointerBuffer().copy(args.toBuffer());
|
arg1.pointerBuffer().copy(args.toBuffer());
|
||||||
arg2.pointerBuffer().copy(args.toBuffer(), require('_GenericMarshal').PointerSize);
|
arg2.pointerBuffer().copy(args.toBuffer(), require('_GenericMarshal').PointerSize);
|
||||||
|
|
||||||
@ -363,7 +497,8 @@ function agentUpdate_Start(updateurl, updateoptions) {
|
|||||||
if (updateurl.startsWith("wss://")) { updateurl = "https://" + updateurl.substring(6); }
|
if (updateurl.startsWith("wss://")) { updateurl = "https://" + updateurl.substring(6); }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (agentUpdate_Start._selfupdate != null) {
|
if (agentUpdate_Start._selfupdate != null)
|
||||||
|
{
|
||||||
// We were already called, so we will ignore this duplicate request
|
// We were already called, so we will ignore this duplicate request
|
||||||
if (sessionid != null) { sendConsoleText('Self update already in progress...', sessionid); }
|
if (sessionid != null) { sendConsoleText('Self update already in progress...', sessionid); }
|
||||||
}
|
}
|
||||||
@ -373,25 +508,58 @@ function agentUpdate_Start(updateurl, updateoptions) {
|
|||||||
// This agent doesn't have the ability to tell us which ARCHID it is, so we don't know which agent to pull
|
// This agent doesn't have the ability to tell us which ARCHID it is, so we don't know which agent to pull
|
||||||
sendConsoleText('Unable to initiate update, agent ARCHID is not defined', sessionid);
|
sendConsoleText('Unable to initiate update, agent ARCHID is not defined', sessionid);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
var agentfilename = process.execPath.split(process.platform == 'win32' ? '\\' : '/').pop(); // Local File Name, ie: MeshAgent.exe
|
var agentfilename = process.execPath.split(process.platform == 'win32' ? '\\' : '/').pop(); // Local File Name, ie: MeshAgent.exe
|
||||||
var name = require('MeshAgent').serviceName;
|
var name = require('MeshAgent').serviceName;
|
||||||
if (name == null) { name = (process.platform == 'win32' ? 'Mesh Agent' : 'meshagent'); } // This is an older agent that doesn't expose the service name, so use the default
|
if (name == null) { name = process.platform == 'win32' ? 'Mesh Agent' : 'meshagent'; }
|
||||||
try {
|
if (process.platform == 'win32')
|
||||||
|
{
|
||||||
|
// Special Processing for Temporary/Console Mode Agents on Windows
|
||||||
|
var parms = windows_getCommandLine();
|
||||||
|
if (parms.findIndex(function (val) { return (val.toUpperCase() == 'RUN' || val.toUpperCase() == 'CONNECT');})>=0)
|
||||||
|
{
|
||||||
|
// This is a Temporary/Console Mode Agent
|
||||||
|
sendConsoleText('This is a temporary/console agent, checking for conflicts with background services...');
|
||||||
|
|
||||||
|
// Check to see if our binary conflicts with an installed agent
|
||||||
|
var agents = _getPotentialServiceNames();
|
||||||
|
if(_getPotentialServiceNames().length>0)
|
||||||
|
{
|
||||||
|
sendConsoleText('Self update cannot continue because the installed agent (' + agents[0] + ') conflicts with the currently running Temp/Console agent...', sessionid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sendConsoleText('No conflicts detected...');
|
||||||
|
name = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Not running in Temp/Console Mode... No Op here....
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Non Windows Self Update
|
||||||
|
try
|
||||||
|
{
|
||||||
var s = require('service-manager').manager.getService(name);
|
var s = require('service-manager').manager.getService(name);
|
||||||
if (!s.isMe()) {
|
if (!s.isMe())
|
||||||
|
{
|
||||||
if (process.platform == 'win32') { s.close(); }
|
if (process.platform == 'win32') { s.close(); }
|
||||||
sendConsoleText('Self Update cannot continue, this agent is not an instance of (' + name + ')', sessionid);
|
sendConsoleText('Self Update cannot continue, this agent is not an instance of background service (' + name + ')', sessionid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (process.platform == 'win32') { s.close(); }
|
if (process.platform == 'win32') { s.close(); }
|
||||||
}
|
}
|
||||||
catch (zz) {
|
catch (zz)
|
||||||
|
{
|
||||||
sendConsoleText('Self Update Failed because this agent is not an instance of (' + name + ')', sessionid);
|
sendConsoleText('Self Update Failed because this agent is not an instance of (' + name + ')', sessionid);
|
||||||
sendAgentMessage('Self Update Failed because this agent is not an instance of (' + name + ')', 3);
|
sendAgentMessage('Self Update Failed because this agent is not an instance of (' + name + ')', 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ((sessionid != null) && (updateurl != null)) { sendConsoleText('Downloading update from: ' + updateurl, sessionid); }
|
if ((sessionid != null) && (updateurl != null)) { sendConsoleText('Downloading update from: ' + updateurl, sessionid); }
|
||||||
var options = require('http').parseUri(updateurl != null ? updateurl : require('MeshAgent').ServerUrl);
|
var options = require('http').parseUri(updateurl != null ? updateurl : require('MeshAgent').ServerUrl);
|
||||||
options.protocol = 'https:';
|
options.protocol = 'https:';
|
||||||
@ -1007,7 +1175,25 @@ require('MeshAgent').AddCommandHandler(function (data) {
|
|||||||
function processConsoleCommand(cmd, args, rights, sessionid) {
|
function processConsoleCommand(cmd, args, rights, sessionid) {
|
||||||
try {
|
try {
|
||||||
var response = null;
|
var response = null;
|
||||||
switch (cmd) {
|
switch (cmd)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
{ // This is an unknown command, return an error message
|
||||||
|
response = 'Unknown command \"' + cmd + '\", type \"help\" for list of available commands.';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'commandline':
|
||||||
|
{
|
||||||
|
if (process.platform == 'win32')
|
||||||
|
{
|
||||||
|
response = JSON.stringify(windows_getCommandLine(), null, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response = 'Unknown command \"' + cmd + '\", type \"help\" for list of available commands.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'help':
|
case 'help':
|
||||||
response = "Available commands are: agentupdate, agentupdateex, dbkeys, dbget, dbset, dbcompact, eval, netinfo, osinfo, setdebug, versions.";
|
response = "Available commands are: agentupdate, agentupdateex, dbkeys, dbget, dbset, dbcompact, eval, netinfo, osinfo, setdebug, versions.";
|
||||||
break;
|
break;
|
||||||
@ -1097,10 +1283,11 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
|
|||||||
response = objToString(interfaces, 0, ' ', true);
|
response = objToString(interfaces, 0, ' ', true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: { // This is an unknown command, return an error message
|
case 'name':
|
||||||
response = 'Unknown command \"' + cmd + '\", type \"help\" for list of available commands.';
|
{
|
||||||
break;
|
response = 'Service Name = ' + require('MeshAgent').serviceName;
|
||||||
}
|
}
|
||||||
|
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); }
|
if (response != null) { sendConsoleText(response, sessionid); }
|
||||||
|
Loading…
Reference in New Issue
Block a user