mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-04-23 03:45:45 -04:00
Added tasklimiter and improvements to agent meshcore update system.
This commit is contained in:
parent
0a44d8c873
commit
cd84af5cb9
@ -905,7 +905,7 @@ function createMeshCore(agent)
|
|||||||
switch (data.action)
|
switch (data.action)
|
||||||
{
|
{
|
||||||
case 'agentupdate':
|
case 'agentupdate':
|
||||||
agentUpdate_Start(data.url, { hash: data.hash, tlshash: data.servertlshash });
|
agentUpdate_Start(data.url, { hash: data.hash, tlshash: data.servertlshash, sessionid: data.sessionid });
|
||||||
break;
|
break;
|
||||||
case 'msg': {
|
case 'msg': {
|
||||||
switch (data.type)
|
switch (data.type)
|
||||||
@ -3053,11 +3053,11 @@ function createMeshCore(agent)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'agentupdate':
|
case 'agentupdate':
|
||||||
require('MeshAgent').SendCommand({ action: 'agentupdate' });
|
require('MeshAgent').SendCommand({ action: 'agentupdate', sessionid: sessionid });
|
||||||
break;
|
break;
|
||||||
case 'agentupdateex':
|
case 'agentupdateex':
|
||||||
// Perform an direct agent update without requesting any information from the server, this should not typically be used.
|
// Perform an direct agent update without requesting any information from the server, this should not typically be used.
|
||||||
agentUpdate_Start(null, { session: sessionid });
|
agentUpdate_Start(null, { sessionid: sessionid });
|
||||||
break;
|
break;
|
||||||
case 'msh':
|
case 'msh':
|
||||||
response = JSON.stringify(_MSH(), null, 2);
|
response = JSON.stringify(_MSH(), null, 2);
|
||||||
@ -4343,7 +4343,7 @@ function createMeshCore(agent)
|
|||||||
function agentUpdate_Start(updateurl, updateoptions)
|
function agentUpdate_Start(updateurl, updateoptions)
|
||||||
{
|
{
|
||||||
// If this value is null
|
// If this value is null
|
||||||
var sessionid = updateoptions != null ? updateoptions.session : null; // If this is null, messages will be broadcast. Otherwise they will be unicasted
|
var sessionid = (updateoptions != null) ? updateoptions.sessionid : null; // If this is null, messages will be broadcast. Otherwise they will be unicasted
|
||||||
|
|
||||||
if (this._selfupdate != null)
|
if (this._selfupdate != null)
|
||||||
{
|
{
|
||||||
@ -4380,7 +4380,7 @@ function createMeshCore(agent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendConsoleText('Downloading update...', sessionid);
|
if (sessionid != null) { sendConsoleText('Downloading update...', 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:';
|
||||||
if (updateurl == null) { options.path = ('/meshagents?id=' + require('MeshAgent').ARCHID); }
|
if (updateurl == null) { options.path = ('/meshagents?id=' + require('MeshAgent').ARCHID); }
|
||||||
@ -4422,7 +4422,7 @@ function createMeshCore(agent)
|
|||||||
{
|
{
|
||||||
if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase())
|
if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase())
|
||||||
{
|
{
|
||||||
sendConsoleText('Download complete. HASH verified.', sessionid);
|
if (sessionid != null) { sendConsoleText('Download complete. HASH verified.', sessionid); }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4433,10 +4433,13 @@ function createMeshCore(agent)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sendConsoleText('Download complete. HASH=' + h.toString('hex'), sessionid);
|
if (sessionid != null) { sendConsoleText('Download complete. HASH=' + h.toString('hex'), sessionid); }
|
||||||
}
|
}
|
||||||
|
|
||||||
sendConsoleText('Updating and restarting agent...', sessionid);
|
// Send an indication to the server that we got the update download correctly.
|
||||||
|
try { mesh.SendCommand({ action: 'agentupdatedownloaded' }); } catch (e) { }
|
||||||
|
|
||||||
|
if (sessionid != null) { sendConsoleText('Updating and restarting agent...', sessionid); }
|
||||||
if (process.platform == 'win32')
|
if (process.platform == 'win32')
|
||||||
{
|
{
|
||||||
// Use _wexecve() equivalent to perform the update
|
// Use _wexecve() equivalent to perform the update
|
||||||
@ -4458,7 +4461,7 @@ function createMeshCore(agent)
|
|||||||
m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP | require('fs').CHMOD_MODES.S_IXOTH);
|
m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP | require('fs').CHMOD_MODES.S_IXOTH);
|
||||||
require('fs').chmodSync(process.execPath, m);
|
require('fs').chmodSync(process.execPath, m);
|
||||||
|
|
||||||
sendConsoleText('Restarting service...', sessionid);
|
if (sessionid != null) { sendConsoleText('Restarting service...', sessionid); }
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// restart service
|
// restart service
|
||||||
|
@ -86,7 +86,7 @@ function windows_execve(name, agentfilename, sessionid)
|
|||||||
function agentUpdate_Start(updateurl, updateoptions)
|
function agentUpdate_Start(updateurl, updateoptions)
|
||||||
{
|
{
|
||||||
// If this value is null
|
// If this value is null
|
||||||
var sessionid = updateoptions != null ? updateoptions.session : null; // If this is null, messages will be broadcast. Otherwise they will be unicasted
|
var sessionid = (updateoptions != null) ? updateoptions.sessionid : null; // If this is null, messages will be broadcast. Otherwise they will be unicasted
|
||||||
|
|
||||||
if (this._selfupdate != null)
|
if (this._selfupdate != null)
|
||||||
{
|
{
|
||||||
@ -123,7 +123,7 @@ function agentUpdate_Start(updateurl, updateoptions)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendConsoleText('Downloading update...', sessionid);
|
if (sessionid != null) { sendConsoleText('Downloading update...', 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:';
|
||||||
if (updateurl == null) { options.path = ('/meshagents?id=' + require('MeshAgent').ARCHID); }
|
if (updateurl == null) { options.path = ('/meshagents?id=' + require('MeshAgent').ARCHID); }
|
||||||
@ -165,7 +165,7 @@ function agentUpdate_Start(updateurl, updateoptions)
|
|||||||
{
|
{
|
||||||
if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase())
|
if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase())
|
||||||
{
|
{
|
||||||
sendConsoleText('Download complete. HASH verified.', sessionid);
|
if (sessionid != null) { sendConsoleText('Download complete. HASH verified.', sessionid); }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -179,7 +179,10 @@ function agentUpdate_Start(updateurl, updateoptions)
|
|||||||
sendConsoleText('Download complete. HASH=' + h.toString('hex'), sessionid);
|
sendConsoleText('Download complete. HASH=' + h.toString('hex'), sessionid);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendConsoleText('Updating and restarting agent...', sessionid);
|
// Send an indication to the server that we got the update download correctly.
|
||||||
|
try { mesh.SendCommand({ action: 'agentupdatedownloaded' }); } catch (e) { }
|
||||||
|
|
||||||
|
if (sessionid != null) { sendConsoleText('Updating and restarting agent...', sessionid); }
|
||||||
if (process.platform == 'win32')
|
if (process.platform == 'win32')
|
||||||
{
|
{
|
||||||
// Use _wexecve() equivalent to perform the update
|
// Use _wexecve() equivalent to perform the update
|
||||||
@ -201,7 +204,7 @@ function agentUpdate_Start(updateurl, updateoptions)
|
|||||||
m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP | require('fs').CHMOD_MODES.S_IXOTH);
|
m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP | require('fs').CHMOD_MODES.S_IXOTH);
|
||||||
require('fs').chmodSync(process.execPath, m);
|
require('fs').chmodSync(process.execPath, m);
|
||||||
|
|
||||||
sendConsoleText('Restarting service...', sessionid);
|
if (sessionid != null) { sendConsoleText('Restarting service...', sessionid); }
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// restart service
|
// restart service
|
||||||
@ -406,7 +409,7 @@ require('MeshAgent').AddCommandHandler(function (data)
|
|||||||
switch (data.action)
|
switch (data.action)
|
||||||
{
|
{
|
||||||
case 'agentupdate':
|
case 'agentupdate':
|
||||||
agentUpdate_Start(data.url, { hash: data.hash, tlshash: data.servertlshash });
|
agentUpdate_Start(data.url, { hash: data.hash, tlshash: data.servertlshash, sessionid: data.sessionid });
|
||||||
break;
|
break;
|
||||||
case 'msg':
|
case 'msg':
|
||||||
{
|
{
|
||||||
@ -662,11 +665,11 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
|
|||||||
break;
|
break;
|
||||||
case 'agentupdate':
|
case 'agentupdate':
|
||||||
// Request that the server send a agent update command
|
// Request that the server send a agent update command
|
||||||
require('MeshAgent').SendCommand({ action: 'agentupdate' });
|
require('MeshAgent').SendCommand({ action: 'agentupdate', sessionid: sessionid });
|
||||||
break;
|
break;
|
||||||
case 'agentupdateex':
|
case 'agentupdateex':
|
||||||
// Perform an direct agent update without requesting any information from the server, this should not typically be used.
|
// Perform an direct agent update without requesting any information from the server, this should not typically be used.
|
||||||
agentUpdate_Start(null, { session: sessionid });
|
agentUpdate_Start(null, { sessionid: sessionid });
|
||||||
break;
|
break;
|
||||||
case 'osinfo': { // Return the operating system information
|
case 'osinfo': { // Return the operating system information
|
||||||
var i = 1;
|
var i = 1;
|
||||||
|
81
meshagent.js
81
meshagent.js
@ -89,7 +89,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
// Set this agent as no longer authenticated
|
// Set this agent as no longer authenticated
|
||||||
obj.authenticated = -1;
|
obj.authenticated = -1;
|
||||||
|
|
||||||
// If we where updating the agent, clean that up.
|
// If we where updating the agent using native method, clean that up.
|
||||||
if (obj.agentUpdate != null) {
|
if (obj.agentUpdate != null) {
|
||||||
if (obj.agentUpdate.fd) { try { parent.fs.close(obj.agentUpdate.fd); } catch (ex) { } }
|
if (obj.agentUpdate.fd) { try { parent.fs.close(obj.agentUpdate.fd); } catch (ex) { } }
|
||||||
parent.parent.taskLimiter.completed(obj.agentUpdate.taskid); // Indicate this task complete
|
parent.parent.taskLimiter.completed(obj.agentUpdate.taskid); // Indicate this task complete
|
||||||
@ -97,6 +97,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
delete obj.agentUpdate;
|
delete obj.agentUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we where updating the agent meshcore method, clean that up.
|
||||||
|
if (obj.agentCoreUpdateTaskId != null) {
|
||||||
|
parent.parent.taskLimiter.completed(obj.agentCoreUpdateTaskId);
|
||||||
|
delete obj.agentCoreUpdateTaskId;
|
||||||
|
}
|
||||||
|
|
||||||
// Perform timer cleanup
|
// Perform timer cleanup
|
||||||
if (obj.pingtimer) { clearInterval(obj.pingtimer); delete obj.pingtimer; }
|
if (obj.pingtimer) { clearInterval(obj.pingtimer); delete obj.pingtimer; }
|
||||||
if (obj.pongtimer) { clearInterval(obj.pongtimer); delete obj.pongtimer; }
|
if (obj.pongtimer) { clearInterval(obj.pongtimer); delete obj.pongtimer; }
|
||||||
@ -238,7 +244,6 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
if (agentUpdateMethod === 2) { // Use meshcore agent update system
|
if (agentUpdateMethod === 2) { // Use meshcore agent update system
|
||||||
// Send the recovery core to the agent, if the agent is capable of running one
|
// Send the recovery core to the agent, if the agent is capable of running one
|
||||||
if (((obj.agentInfo.capabilities & 16) != 0) && (parent.parent.meshAgentsArchitectureNumbers[obj.agentInfo.agentId].core != null)) {
|
if (((obj.agentInfo.capabilities & 16) != 0) && (parent.parent.meshAgentsArchitectureNumbers[obj.agentInfo.agentId].core != null)) {
|
||||||
//obj.agentCoreCheck = 1001;
|
|
||||||
obj.agentCoreUpdate = true;
|
obj.agentCoreUpdate = true;
|
||||||
obj.sendBinary(common.ShortToStr(11) + common.ShortToStr(0));
|
obj.sendBinary(common.ShortToStr(11) + common.ShortToStr(0));
|
||||||
}
|
}
|
||||||
@ -1152,17 +1157,26 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
{
|
{
|
||||||
if ((obj.agentCoreUpdate === true) && (obj.agentExeInfo != null)) {
|
if ((obj.agentCoreUpdate === true) && (obj.agentExeInfo != null)) {
|
||||||
// Agent update. The recovery core was loaded in the agent, send a command to update the agent
|
// Agent update. The recovery core was loaded in the agent, send a command to update the agent
|
||||||
var cmd = { action: 'agentupdate', url: obj.agentExeInfo.url, hash: obj.agentExeInfo.hashhex };
|
parent.parent.taskLimiter.launch(function (argument, taskid, taskLimiterQueue) { // Medium priority task
|
||||||
// Add the hash
|
// If agent disconnection, complete and exit now.
|
||||||
if (obj.agentExeInfo.fileHash != null) { cmd.hash = obj.agentExeInfo.fileHashHex; } else { cmd.hash = obj.agentExeInfo.hashhex; }
|
if (obj.authenticated != 2) { parent.parent.taskLimiter.completed(taskid); return; }
|
||||||
// Add server TLS cert hash
|
|
||||||
if (parent.parent.args.ignoreagenthashcheck !== true) {
|
// Agent update. The recovery core was loaded in the agent, send a command to update the agent
|
||||||
const tlsCertHash = parent.webCertificateFullHashs[domain.id];
|
obj.agentCoreUpdateTaskId = taskid;
|
||||||
if (tlsCertHash != null) { cmd.servertlshash = Buffer.from(tlsCertHash, 'binary').toString('hex'); }
|
var cmd = { action: 'agentupdate', url: obj.agentExeInfo.url, hash: obj.agentExeInfo.hashhex };
|
||||||
}
|
|
||||||
// Send the agent update command
|
// Add the hash
|
||||||
obj.send(JSON.stringify(cmd));
|
if (obj.agentExeInfo.fileHash != null) { cmd.hash = obj.agentExeInfo.fileHashHex; } else { cmd.hash = obj.agentExeInfo.hashhex; }
|
||||||
//delete obj.agentCoreUpdate;
|
|
||||||
|
// Add server TLS cert hash
|
||||||
|
if (parent.parent.args.ignoreagenthashcheck !== true) {
|
||||||
|
const tlsCertHash = parent.webCertificateFullHashs[domain.id];
|
||||||
|
if (tlsCertHash != null) { cmd.servertlshash = Buffer.from(tlsCertHash, 'binary').toString('hex'); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the agent update command
|
||||||
|
obj.send(JSON.stringify(cmd));
|
||||||
|
}, null, 1);
|
||||||
} else {
|
} else {
|
||||||
// Sent by the agent to update agent information
|
// Sent by the agent to update agent information
|
||||||
ChangeAgentCoreInfo(command);
|
ChangeAgentCoreInfo(command);
|
||||||
@ -1456,17 +1470,38 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'agentupdate': {
|
case 'agentupdate': {
|
||||||
// Agent is requesting an agent update
|
var func = function agentUpdateFunc(argument, taskid, taskLimiterQueue) { // Medium priority task
|
||||||
var cmd = { action: 'agentupdate', url: obj.agentExeInfo.url, hash: obj.agentExeInfo.hashhex };
|
// If agent disconnection, complete and exit now.
|
||||||
// Add the hash
|
if (obj.authenticated != 2) { parent.parent.taskLimiter.completed(taskid); return; }
|
||||||
if (obj.agentExeInfo.fileHash != null) { cmd.hash = obj.agentExeInfo.fileHashHex; } else { cmd.hash = obj.agentExeInfo.hashhex; }
|
|
||||||
// Add server TLS cert hash
|
// Agent is requesting an agent update
|
||||||
if (parent.parent.args.ignoreagenthashcheck !== true) {
|
obj.agentCoreUpdateTaskId = taskid;
|
||||||
const tlsCertHash = parent.webCertificateFullHashs[domain.id];
|
var cmd = { action: 'agentupdate', url: obj.agentExeInfo.url, hash: obj.agentExeInfo.hashhex, sessionid: agentUpdateFunc.sessionid };
|
||||||
if (tlsCertHash != null) { cmd.servertlshash = Buffer.from(tlsCertHash, 'binary').toString('hex'); }
|
|
||||||
|
// Add the hash
|
||||||
|
if (obj.agentExeInfo.fileHash != null) { cmd.hash = obj.agentExeInfo.fileHashHex; } else { cmd.hash = obj.agentExeInfo.hashhex; }
|
||||||
|
|
||||||
|
// Add server TLS cert hash
|
||||||
|
if (parent.parent.args.ignoreagenthashcheck !== true) {
|
||||||
|
const tlsCertHash = parent.webCertificateFullHashs[domain.id];
|
||||||
|
if (tlsCertHash != null) { cmd.servertlshash = Buffer.from(tlsCertHash, 'binary').toString('hex'); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the agent update command
|
||||||
|
obj.send(JSON.stringify(cmd));
|
||||||
|
}
|
||||||
|
func.sessionid = command.sessionid;
|
||||||
|
|
||||||
|
// Agent update. The recovery core was loaded in the agent, send a command to update the agent
|
||||||
|
parent.parent.taskLimiter.launch(func, null, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'agentupdatedownloaded': {
|
||||||
|
if (obj.agentCoreUpdateTaskId != null) {
|
||||||
|
// Indicate this udpate task is complete
|
||||||
|
parent.parent.taskLimiter.completed(obj.agentCoreUpdateTaskId);
|
||||||
|
delete obj.agentCoreUpdateTaskId;
|
||||||
}
|
}
|
||||||
// Send the agent update command
|
|
||||||
obj.send(JSON.stringify(cmd));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user