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