Updated all agents except macOS and FreeBSD. New agents support compression.

This commit is contained in:
Ylian Saint-Hilaire 2020-07-21 16:20:17 -07:00
parent e020fe8dee
commit 193c85972c
24 changed files with 64 additions and 3501 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1189,20 +1189,22 @@ function createMeshCore(agent) {
var tunnel = tunnels[this.httprequest.index]; var tunnel = tunnels[this.httprequest.index];
if (tunnel == null) return; // Stop duplicate calls. if (tunnel == null) return; // Stop duplicate calls.
// Sent tunnel statistics to the server // Sent tunnel statistics to the server, only send this if compression was used.
if (this.bytesSent_uncompressed.toString() != this.bytesSent_actual.toString()) {
mesh.SendCommand({ mesh.SendCommand({
action: 'tunnelCloseStats', action: 'tunnelCloseStats',
url: tunnel.url, url: tunnel.url,
userid: tunnel.userid, userid: tunnel.userid,
protocol: tunnel.protocol, protocol: tunnel.protocol,
sessionid: tunnel.sessionid, sessionid: tunnel.sessionid,
sent: this.bytesSent_uncompressed + '', sent: this.bytesSent_uncompressed.toString(),
sentActual: this.bytesSent_actual + '', sentActual: this.bytesSent_actual.toString(),
sentRatio: this.bytesSent_ratio, sentRatio: this.bytesSent_ratio,
received: this.bytesReceived_uncompressed + '', received: this.bytesReceived_uncompressed.toString(),
receivedActual: this.bytesReceived_actual + '', receivedActual: this.bytesReceived_actual.toString(),
receivedRatio: this.bytesReceived_ratio receivedRatio: this.bytesReceived_ratio
}); });
}
//sendConsoleText("Tunnel #" + this.httprequest.index + " closed. Sent -> " + this.bytesSent_uncompressed + ' bytes (uncompressed), ' + this.bytesSent_actual + ' bytes (actual), ' + this.bytesSent_ratio + '% compression', this.httprequest.sessionid); //sendConsoleText("Tunnel #" + this.httprequest.index + " closed. Sent -> " + this.bytesSent_uncompressed + ' bytes (uncompressed), ' + this.bytesSent_actual + ' bytes (actual), ' + this.bytesSent_ratio + '% compression', this.httprequest.sessionid);
delete tunnels[this.httprequest.index]; delete tunnels[this.httprequest.index];
@ -1340,7 +1342,7 @@ function createMeshCore(agent) {
var consentMessage = this.httprequest.username + " requesting remote terminal access. Grant access?", consentTitle = 'MeshCentral'; var consentMessage = this.httprequest.username + " requesting remote terminal access. Grant access?", consentTitle = 'MeshCentral';
if (this.httprequest.soptions != null) { if (this.httprequest.soptions != null) {
if (this.httprequest.soptions.consentTitle != null) { consentTitle = this.httprequest.soptions.consentTitle; } if (this.httprequest.soptions.consentTitle != null) { consentTitle = this.httprequest.soptions.consentTitle; }
if (this.httprequest.soptions.consentMsgTerminal != null) { consentMessage = this.httprequest.soptions.consentMsgTerminal.replace('{0}', this.httprequest.username); } if (this.httprequest.soptions.consentMsgTerminal != null) { consentMessage = this.httprequest.soptions.consentMsgTerminal.replace('{0}', this.httprequest.realname).replace('{1}', this.httprequest.username); }
} }
this.httprequest.tpromise._consent = require('message-box').create(consentTitle, consentMessage, 30); this.httprequest.tpromise._consent = require('message-box').create(consentTitle, consentMessage, 30);
this.httprequest.tpromise._consent.retPromise = this.httprequest.tpromise; this.httprequest.tpromise._consent.retPromise = this.httprequest.tpromise;
@ -1547,7 +1549,7 @@ function createMeshCore(agent) {
var notifyMessage = this.ws.httprequest.username + " started a remote terminal session.", notifyTitle = "MeshCentral"; var notifyMessage = this.ws.httprequest.username + " started a remote terminal session.", notifyTitle = "MeshCentral";
if (this.ws.httprequest.soptions != null) { if (this.ws.httprequest.soptions != null) {
if (this.ws.httprequest.soptions.notifyTitle != null) { notifyTitle = this.ws.httprequest.soptions.notifyTitle; } if (this.ws.httprequest.soptions.notifyTitle != null) { notifyTitle = this.ws.httprequest.soptions.notifyTitle; }
if (this.ws.httprequest.soptions.notifyMsgTerminal != null) { notifyMessage = this.ws.httprequest.soptions.notifyMsgTerminal.replace('{0}', this.ws.httprequest.username); } if (this.ws.httprequest.soptions.notifyMsgTerminal != null) { notifyMessage = this.ws.httprequest.soptions.notifyMsgTerminal.replace('{0}', this.ws.httprequest.realname).replace('{1}', this.ws.httprequest.username); }
} }
try { require('toaster').Toast(notifyTitle, notifyMessage); } catch (ex) { } try { require('toaster').Toast(notifyTitle, notifyMessage); } catch (ex) { }
} }

File diff suppressed because it is too large Load Diff

View File

@ -179,7 +179,9 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
var taskLimiterOptions = { hash: meshcorehash, core: parent.parent.defaultMeshCores[corename], name: corename }; var taskLimiterOptions = { hash: meshcorehash, core: parent.parent.defaultMeshCores[corename], name: corename };
// If the agent supports compression, sent the core compressed. // If the agent supports compression, sent the core compressed.
if ((obj.agentInfo.capabilities & 0x80) && (parent.parent.defaultMeshCoresDeflate[corename])) { args.core = parent.parent.defaultMeshCoresDeflate[corename]; } if ((obj.agentInfo.capabilities & 0x80) && (parent.parent.defaultMeshCoresDeflate[corename])) {
args.core = parent.parent.defaultMeshCoresDeflate[corename];
}
// Update new core with task limiting so not to flood the server. This is a high priority task. // Update new core with task limiting so not to flood the server. This is a high priority task.
obj.agentCoreUpdatePending = true; obj.agentCoreUpdatePending = true;
@ -297,12 +299,10 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
// Send compressed data // Send compressed data
obj.agentUpdate.agentUpdateData = obj.agentExeInfo.zdata; obj.agentUpdate.agentUpdateData = obj.agentExeInfo.zdata;
obj.agentUpdate.agentUpdateHash = obj.agentExeInfo.zhash; obj.agentUpdate.agentUpdateHash = obj.agentExeInfo.zhash;
//console.log('Sending compressed update agent', obj.agentExeInfo.zhashhex);
} else { } else {
// Send uncompressed data // Send uncompressed data
obj.agentUpdate.agentUpdateData = obj.agentExeInfo.data; obj.agentUpdate.agentUpdateData = obj.agentExeInfo.data;
obj.agentUpdate.agentUpdateHash = obj.agentExeInfo.hash; obj.agentUpdate.agentUpdateHash = obj.agentExeInfo.hash;
//console.log('Sending uncompressed update agent', obj.agentExeInfo.hashhex);
} }
const len = Math.min(parent.parent.agentUpdateBlockSize, obj.agentUpdate.agentUpdateData.length - obj.agentUpdate.ptr); const len = Math.min(parent.parent.agentUpdateBlockSize, obj.agentUpdate.agentUpdateData.length - obj.agentUpdate.ptr);
@ -1415,6 +1415,10 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
case 'tunnelCloseStats': { case 'tunnelCloseStats': {
// TODO: This this extra stats from the tunnel, you can merge this into the tunnel event in the database. // TODO: This this extra stats from the tunnel, you can merge this into the tunnel event in the database.
//console.log(command); //console.log(command);
// Event the session closed compression data.
var event = { etype: 'node', action: 'sessioncompression', nodeid: obj.dbNodeKey, domain: domain.id, sent: command.sent, sentActual: command.sentActual, msg: 'Agent closed session with ' + command.sentRatio + '% agent to server compression. Sent: ' + command.sent + ', Compressed: ' + command.sentActual + '.' };
parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, event);
break; break;
} }
case 'plugin': { case 'plugin': {

View File

@ -51,6 +51,7 @@
"selfUpdate": { "type": "boolean", "default": false, "description": "When true, this server will attempt to self-update everyday after midnight." }, "selfUpdate": { "type": "boolean", "default": false, "description": "When true, this server will attempt to self-update everyday after midnight." },
"browserPing": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the browser at x seconds interval and expects a response from the browser." }, "browserPing": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the browser at x seconds interval and expects a response from the browser." },
"browserPong": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the browser at x seconds interval." }, "browserPong": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the browser at x seconds interval." },
"agentsInRam": { "type": "boolean", "default": false, "description": "Loads all agent binaries in RAM for faster agent updates." },
"agentPing": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the agent at x seconds interval and expects a response from the agent." }, "agentPing": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the agent at x seconds interval and expects a response from the agent." },
"agentPong": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the agent at x seconds interval." }, "agentPong": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the agent at x seconds interval." },
"agentIdleTimeout": { "type": "integer", "minimum": 1 }, "agentIdleTimeout": { "type": "integer", "minimum": 1 },

View File

@ -649,14 +649,12 @@ function CreateMeshCentralServer(config, args) {
if (typeof obj.args.tlsoffload == 'string') { obj.args.tlsoffload = obj.args.tlsoffload.split(' ').join('').split(','); } if (typeof obj.args.tlsoffload == 'string') { obj.args.tlsoffload = obj.args.tlsoffload.split(' ').join('').split(','); }
// Check if WebSocket compression is supported. It's broken in NodeJS v11.11 to v12.15 // Check if WebSocket compression is supported. It's broken in NodeJS v11.11 to v12.15
if ((obj.args.wscompression == true) || (obj.args.agentwscompression == true)) {
const verSplit = process.version.substring(1).split('.'); const verSplit = process.version.substring(1).split('.');
var ver = parseInt(verSplit[0]) + (parseInt(verSplit[1]) / 100); var ver = parseInt(verSplit[0]) + (parseInt(verSplit[1]) / 100);
if ((ver >= 11.11) && (ver <= 12.15)) { if ((ver >= 11.11) && (ver <= 12.15)) {
if ((obj.args.wscompression === true) || (obj.args.agentwscompression === true)) { addServerWarning('WebSocket compression is disabled, this feature is broken in NodeJS v11.11 to v12.15.'); }
obj.args.wscompression = obj.args.agentwscompression = false; obj.args.wscompression = obj.args.agentwscompression = false;
obj.config.settings.wscompression = obj.config.settings.agentwscompression = false; obj.config.settings.wscompression = obj.config.settings.agentwscompression = false;
addServerWarning('WebSocket compression is disabled, this feature is broken in NodeJS v11.11 to v12.15.');
}
} }
// Local console tracing // Local console tracing
@ -2218,6 +2216,37 @@ function CreateMeshCentralServer(config, args) {
} else { } else {
// Load the agent as-is // Load the agent as-is
obj.meshAgentBinaries[archid].data = obj.fs.readFileSync(agentpath); obj.meshAgentBinaries[archid].data = obj.fs.readFileSync(agentpath);
// Compress the agent using ZIP
var archive = require('archiver')('zip', { level: 9 }); // Sets the compression method.
const onZipData = function onZipData(buffer) { onZipData.x.zacc.push(buffer); }
const onZipEnd = function onZipEnd() {
// Concat all the buffer for create compressed zip agent
var concatData = Buffer.concat(onZipData.x.zacc);
delete onZipData.x.zacc;
// Hash the compressed binary
var hash = obj.crypto.createHash('sha384').update(concatData);
onZipData.x.zhash = hash.digest('binary');
onZipData.x.zhashhex = Buffer.from(onZipData.x.zhash, 'binary').toString('hex');
// Set the agent
onZipData.x.zdata = concatData;
onZipData.x.zsize = concatData.length;
console.log('Packed', onZipData.x.size, onZipData.x.zsize);
}
const onZipError = function onZipError() { delete onZipData.x.zacc; }
obj.meshAgentBinaries[archid].zacc = [];
onZipData.x = obj.meshAgentBinaries[archid];
onZipEnd.x = obj.meshAgentBinaries[archid];
onZipError.x = obj.meshAgentBinaries[archid];
archive.on('data', onZipData);
archive.on('end', onZipEnd);
archive.on('error', onZipError);
archive.append(obj.meshAgentBinaries[archid].data, { name: 'meshagent' });
archive.finalize();
} }
} }

View File

@ -40,6 +40,7 @@
"_compression": true, "_compression": true,
"_wscompression": false, "_wscompression": false,
"_agentwscompression": true, "_agentwscompression": true,
"_agentsInRam": false,
"_webRTC": false, "_webRTC": false,
"_nice404": false, "_nice404": false,
"_clickOnce": false, "_clickOnce": false,