More support for agent update using meshcore.
Ylian Saint-Hilaire committed
Jan 14, 2021 at 20:27 UTC
82f3a40ba6d5265bf22539f918f4dcfedd9a44fe
22 files changed
+39
-13
agents/agents-0.7.45/meshagent_arm
renamed
agents/agents-0.7.45/meshagent_arm-linaro
renamed
agents/agents-0.7.45/meshagent_arm64
renamed
agents/agents-0.7.45/meshagent_armhf
renamed
agents/agents-0.7.45/meshagent_armhf2
renamed
agents/agents-0.7.45/meshagent_freebsd_x86-64
renamed
agents/agents-0.7.45/meshagent_mips
renamed
agents/agents-0.7.45/meshagent_mips24kc
renamed
agents/agents-0.7.45/meshagent_mipsel24kc
renamed
agents/agents-0.7.45/meshagent_osx-arm-64
renamed
agents/agents-0.7.45/meshagent_osx-universal-64
renamed
agents/agents-0.7.45/meshagent_osx-x86-64
renamed
agents/agents-0.7.45/meshagent_pogo
renamed
agents/agents-0.7.45/meshagent_poky
renamed
agents/agents-0.7.45/meshagent_poky64
renamed
agents/agents-0.7.45/meshagent_x86
renamed
agents/agents-0.7.45/meshagent_x86-64
renamed
agents/agents-0.7.45/meshagent_x86-64_nokvm
renamed
agents/agents-0.7.45/meshagent_x86_nokvm
renamed
agents/recoverycore.js
+7
-2
@@ -287,7 +287,7 @@ function getServerTargetUrlEx(url) {
287
288
require('MeshAgent').on('Connected', function () {
289
require('os').name().then(function (v) {
290
- //sendConsoleText("Mesh Agent Receovery Console, OS: " + v);
290
+ //sendConsoleText("Mesh Agent Recovery Console, OS: " + v);
291
require('MeshAgent').SendCommand(meshCoreObj);
292
});
293
});
@@ -643,12 +643,17 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
643
var response = null;
644
switch (cmd) {
645
case 'help':
646
- response = "Available commands are: osinfo, dbkeys, dbget, dbset, dbcompact, netinfo, versions.";
646
+ response = "Available commands are: osinfo, dbkeys, dbget, dbset, dbcompact, netinfo, versions, agentupdate.";
647
break;
648
case 'versions':
649
response = JSON.stringify(process.versions, null, ' ');
650
break;
651
case 'agentupdate':
652
+ // Request that the server send a agent update command
653
+ require('MeshAgent').SendCommand({ action: 'agentupdate' });
654
+ break;
655
+ case 'agentupdateex':
656
+ // Perform an direct agent update without requesting any information from the server, this should not typically be used.
657
agentUpdate_Start(null, { session: sessionid });
658
break;
659
case 'osinfo': { // Return the operating system information
meshagent.js
+27
-10
@@ -152,7 +152,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
152
// We need to check if the core is current. Figure out what core we need.
153
var corename = null;
154
if (parent.parent.meshAgentsArchitectureNumbers[obj.agentInfo.agentId] != null) {
155
- if (obj.agentCoreCheck == 1001) {
155
+ if ((obj.agentCoreCheck == 1001) || (obj.agentCoreUpdate == true)) {
156
// If the user asked, use the recovery core.
157
corename = parent.parent.meshAgentsArchitectureNumbers[obj.agentInfo.agentId].rcore;
158
} else if (obj.agentInfo.capabilities & 0x40) {
@@ -167,8 +167,8 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
167
// If we have a core, use it.
168
if (corename != null) {
169
const meshcorehash = parent.parent.defaultMeshCoresHash[corename];
170
- if ((agentMeshCoreHash != meshcorehash) || (obj.agentCoreUpdate === true)) {
171
- if ((obj.agentCoreCheck < 5) || (obj.agentCoreCheck == 1001)) {
170
+ if (agentMeshCoreHash != meshcorehash) {
171
+ if ((obj.agentCoreCheck < 5) || (obj.agentCoreCheck == 1001) || (obj.agentCoreUpdate == true)) {
172
if (meshcorehash == null) {
173
// Clear the core
174
obj.sendBinary(common.ShortToStr(10) + common.ShortToStr(0)); // MeshCommand_CoreModule, ask mesh agent to clear the core
@@ -238,9 +238,9 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
238
if (agentUpdateMethod === 2) { // Use meshcore agent update system
239
// Send the recovery core to the agent, if the agent is capable of running one
240
if (((obj.agentInfo.capabilities & 16) != 0) && (parent.parent.meshAgentsArchitectureNumbers[obj.agentInfo.agentId].core != null)) {
241
- obj.agentCoreCheck = 1001;
241
+ //obj.agentCoreCheck = 1001;
242
obj.agentCoreUpdate = true;
243
- obj.sendBinary(common.ShortToStr(11) + common.ShortToStr(0)); // Command 11, ask for mesh core hash.
243
+ obj.sendBinary(common.ShortToStr(11) + common.ShortToStr(0));
244
}
245
} else if (agentUpdateMethod === 1) { // Use native agent update system
246
// Mesh agent update required, do it using task limiter so not to flood the network. Medium priority task.
@@ -526,6 +526,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
526
if ((msg.substring(2, 34) == parent.swarmCertificateHash256) || (msg.substring(2, 50) == parent.swarmCertificateHash384)) { obj.useSwarmCert = true; }
527
} else if (cmd == 30) {
528
// Agent Commit Date. This is future proofing. Can be used to change server behavior depending on the date range of the agent.
529
+ try { obj.AgentCommitDate = Date.parse(msg.substring(2)) } catch (ex) { }
530
//console.log('Connected Agent Commit Date: ' + msg.substring(2) + ", " + Date.parse(msg.substring(2)));
531
}
532
}
@@ -543,7 +544,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
544
parent.parent.debug('agent', 'Agent disconnect ' + obj.nodeid + ' (' + obj.remoteaddrport + ') id=' + agentId);
545
546
// Log the agent disconnection if we are not testing agent update
546
- if (args.agentupdatetest !== true) {
547
+ if (args.agentupdatetest == null) {
548
if (parent.wsagentsDisconnections[obj.nodeid] == null) {
549
parent.wsagentsDisconnections[obj.nodeid] = 1;
550
} else {
@@ -1150,7 +1151,9 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1151
{
1152
if ((obj.agentCoreUpdate === true) && (obj.agentExeInfo != null)) {
1153
// Agent update. The recovery core was loaded in the agent, send a command to update the agent
1153
- var cmd = { action: 'agentUpdate', url: obj.agentExeInfo.url, hash: obj.agentExeInfo.hashhex };
1154
+ var cmd = { action: 'agentupdate', url: obj.agentExeInfo.url, hash: obj.agentExeInfo.hashhex };
1155
+ // Add the hash
1156
+ if (obj.agentExeInfo.fileHash != null) { cmd.hash = obj.agentExeInfo.fileHashHex; } else { cmd.hash = obj.agentExeInfo.hashhex; }
1157
// Add server TLS cert hash
1158
if (parent.parent.args.ignoreagenthashcheck !== true) {
1159
const tlsCertHash = parent.webCertificateFullHashs[domain.id];
@@ -1158,7 +1161,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1161
}
1162
// Send the agent update command
1163
obj.send(JSON.stringify(cmd));
1161
- delete obj.agentCoreUpdate;
1164
+ //delete obj.agentCoreUpdate;
1165
} else {
1166
// Sent by the agent to update agent information
1167
ChangeAgentCoreInfo(command);
@@ -1451,6 +1454,20 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1454
try { ws.send(JSON.stringify(responseCmd)); } catch (ex) { }
1455
break;
1456
}
1457
+ case 'agentupdate': {
1458
+ // Agent is requesting an agent update
1459
+ var cmd = { action: 'agentupdate', url: obj.agentExeInfo.url, hash: obj.agentExeInfo.hashhex };
1460
+ // Add the hash
1461
+ if (obj.agentExeInfo.fileHash != null) { cmd.hash = obj.agentExeInfo.fileHashHex; } else { cmd.hash = obj.agentExeInfo.hashhex; }
1462
+ // Add server TLS cert hash
1463
+ if (parent.parent.args.ignoreagenthashcheck !== true) {
1464
+ const tlsCertHash = parent.webCertificateFullHashs[domain.id];
1465
+ if (tlsCertHash != null) { cmd.servertlshash = Buffer.from(tlsCertHash, 'binary').toString('hex'); }
1466
+ }
1467
+ // Send the agent update command
1468
+ obj.send(JSON.stringify(cmd));
1469
+ break;
1470
+ }
1471
default: {
1472
parent.agentStats.unknownAgentActionCount++;
1473
parent.parent.debug('agent', 'Unknown agent action (' + obj.remoteaddrport + '): ' + JSON.stringify(command) + '.');
@@ -1701,8 +1718,8 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1718
if (((agentExeInfo.id == 16) || (agentExeInfo.id == 29)) && (parent.parent.meshAgentBinaries[10005].hash == agentHash)) return 0;
1719
1720
// No match, update the agent.
1704
- if ((agentExeInfo.id == 3) && (agentExeInfo.id == 4)) return 2; // For Windows agents, use the meshcore update technique.
1705
- return 1; // For all other agents, use the native update technique.
1721
+ if ((obj.AgentCommitDate == null) && ((agentExeInfo.id == 3) || (agentExeInfo.id == 4))) return 2; // For older Windows agents, use the meshcore update technique.
1722
+ return 1; // By default, use the native update technique.
1723
}
1724
1725
// Request that the core dump file on this agent be uploaded to the server
meshcentral.js
+5
-1
@@ -2445,9 +2445,13 @@ function CreateMeshCentralServer(config, args) {
2445
this.meshAgentBinary.size = this.meshAgentBinary.data.length;
2446
delete this.bufferList;
2447
2448
+ // Hash the uncompressed binary
2449
+ var hash = obj.crypto.createHash('sha384').update(this.meshAgentBinary.data);
2450
+ this.meshAgentBinary.fileHash = hash.digest('binary');
2451
+ this.meshAgentBinary.fileHashHex = Buffer.from(this.meshAgentBinary.fileHash, 'binary').toString('hex');
2452
+
2453
// Compress the agent using ZIP
2454
var archive = require('archiver')('zip', { level: 9 }); // Sets the compression method.
2450
-
2455
const onZipData = function onZipData(buffer) { onZipData.x.zacc.push(buffer); }
2456
const onZipEnd = function onZipEnd() {
2457
// Concat all the buffer for create compressed zip agent