From ed45f7b4a72ec0260712657a924bbeda7c6c2938 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Tue, 27 Oct 2020 16:40:12 -0700 Subject: [PATCH] Improved agent coredump processing. --- agents/meshcore.js | 34 ++++++++++++++++++++++++++++------ meshagent.js | 4 ++-- webserver.js | 22 ++++++++++++++++++---- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/agents/meshcore.js b/agents/meshcore.js index e40d7ab0..cde06193 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -1140,8 +1140,12 @@ function createMeshCore(agent) { case 'coredump': // Set the current agent coredump situation. if (data.value === true) { - // TODO: This replace() below is not ideal, would be better to remove the .exe at the end instead of replace. - process.coreDumpLocation = (process.platform == 'win32') ? (process.execPath.replace('.exe', '.dmp')) : (process.execPath + '.dmp'); + if (process.platform == 'win32') { + // TODO: This replace() below is not ideal, would be better to remove the .exe at the end instead of replace. + process.coreDumpLocation = process.execPath.replace('.exe', '.dmp'); + } else { + process.coreDumpLocation = (process.cwd() != '//') ? (process.cwd() + 'core') : null; + } } else if (data.value === false) { process.coreDumpLocation = null; } @@ -1151,8 +1155,18 @@ function createMeshCore(agent) { var r = { action: 'getcoredump', value: (process.coreDumpLocation != null) }; var coreDumpPath = null; if (process.platform == 'win32') { coreDumpPath = process.coreDumpLocation; } else { coreDumpPath = (process.cwd() != '//') ? fs.existsSync(process.cwd() + 'core') : null; } - if ((coreDumpPath != null) && (fs.existsSync(coreDumpPath))) { r.exists = (db.Get('CoreDumpTime') != require('fs').statSync(coreDumpPath).mtime); } - if (r.exists == true) { r.agenthashhex = getSHA384FileHash(process.execPath).toString('hex'); } + if ((coreDumpPath != null) && (fs.existsSync(coreDumpPath))) { + try { + var coredate = fs.statSync(coreDumpPath).mtime; + var coretime = new Date(coredate).getTime(); + var agenttime = new Date(fs.statSync(process.execPath).mtime).getTime(); + if (coretime > agenttime) { r.exists = (db.Get('CoreDumpTime') != coredate); } + } catch (ex) { } + } + if (r.exists == true) { + r.agenthashhex = getSHA384FileHash(process.execPath).toString('hex'); // Hash of current agent + r.corehashhex = getSHA384FileHash(coreDumpPath).toString('hex'); // Hash of core dump file + } mesh.SendCommand(JSON.stringify(r)); default: // Unknown action, ignore it. @@ -2662,9 +2676,17 @@ function createMeshCore(agent) { response = 'coredump is: ' + ((process.coreDumpLocation == null) ? 'off' : 'on'); if (process.coreDumpLocation != null) { if (process.platform == 'win32') { - if (fs.existsSync(process.coreDumpLocation)) { response += '\r\n CoreDump present at: ' + process.coreDumpLocation; } + if (fs.existsSync(process.coreDumpLocation)) { + response += '\r\n CoreDump present at: ' + process.coreDumpLocation; + response += '\r\n CoreDump Time: ' + new Date(fs.statSync(process.coreDumpLocation).mtime).getTime(); + response += '\r\n Agent Time : ' + new Date(fs.statSync(process.execPath).mtime).getTime(); + } } else { - if ((process.cwd() != '//') && fs.existsSync(process.cwd() + 'core')) { response += '\r\n CoreDump present at: ' + process.cwd() + 'core'; } + if ((process.cwd() != '//') && fs.existsSync(process.cwd() + 'core')) { + response += '\r\n CoreDump present at: ' + process.cwd() + 'core'; + response += '\r\n CoreDump Time: ' + new Date(fs.statSync(process.cwd() + 'core').mtime).getTime(); + response += '\r\n Agent Time : ' + new Date(fs.statSync(process.execPath).mtime).getTime(); + } } } break; diff --git a/meshagent.js b/meshagent.js index 4c951a9b..a820d64b 100644 --- a/meshagent.js +++ b/meshagent.js @@ -1395,7 +1395,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Get the core dump uploaded to the server. parent.lastCoreDumpRequest = Date.now(); - obj.RequestCoreDump(command.agenthashhex); + obj.RequestCoreDump(command.agenthashhex, command.corehashhex); }); }); } @@ -1668,7 +1668,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { } // Request that the core dump file on this agent be uploaded to the server - obj.RequestCoreDump = function (agenthashhex) { + obj.RequestCoreDump = function (agenthashhex, corehashhex) { if (agenthashhex.length > 16) { agenthashhex = agenthashhex.substring(0, 16); } const cookie = parent.parent.encodeCookie({ a: 'aft', b: 'coredump', c: obj.agentInfo.agentId + '-' + agenthashhex + '-' + obj.nodeid + '.dmp' }, parent.parent.loginCookieEncryptionKey); obj.send('{"action":"msg","type":"tunnel","value":"*/' + (((domain.dns == null) && (domain.id != '')) ? (domain.id + '/') : '') + 'agenttransfer.ashx?c=' + cookie + '","rights":"4294967295"}'); diff --git a/webserver.js b/webserver.js index 5f3fd3c3..a2c62167 100644 --- a/webserver.js +++ b/webserver.js @@ -3753,7 +3753,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { onFileOpen.xws.send(JSON.stringify({ action: 'download', sub: 'startack', id: onFileOpen.xws.xid, ack: 1 })); // Ask for a directory (test) }; callback.xws = this; - obj.fs.open(this.xfilepath, 'w', callback) + obj.fs.open(this.xfilepath + '.part', 'w', callback); break; } } @@ -3769,7 +3769,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { if (onFileDataWritten.xflags & 1) { // End of file parent.debug('web', "Completed downloads of agent dumpfile, " + onFileDataWritten.xws.xfilelen + " bytes."); - if (onFileDataWritten.xws.xfile) { try { obj.fs.close(onFileDataWritten.xws.xfile, function (err) { }); } catch (ex) { } } + if (onFileDataWritten.xws.xfile) { + obj.fs.close(onFileDataWritten.xws.xfile, function (err) { }); + obj.fs.rename(onFileDataWritten.xws.xfilepath + '.part', onFileDataWritten.xws.xfilepath, function (err) { }); + onFileDataWritten.xws.xfile = null; + } onFileDataWritten.xws.send(JSON.stringify({ action: 'markcoredump' })); // Ask to delete the core dump file try { onFileDataWritten.xws.close(); } catch (ex) { } } else { @@ -3785,7 +3789,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { if (flags & 1) { // End of file parent.debug('web', "Completed downloads of agent dumpfile, " + this.xfilelen + " bytes."); - if (this.xfile) { try { obj.fs.close(this.xfile, function (err) { }); } catch (ex) { } } + if (this.xfile) { + obj.fs.close(this.xfile, function (err) { }); + obj.fs.rename(this.xfilepath + '.part', this.xfilepath, function (err) { }); + this.xfile = null; + } this.send(JSON.stringify({ action: 'markcoredump' })); // Ask to delete the core dump file try { this.close(); } catch (ex) { } } else { @@ -3800,7 +3808,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { ws.on('error', function (err) { console.log('Agent file transfer server error from ' + req.clientIp + ', ' + err.toString().split('\r')[0] + '.'); }); // If closed, do nothing - ws.on('close', function (req) { }); + ws.on('close', function (req) { + if (this.xfile) { + obj.fs.close(this.xfile, function (err) { }); + obj.fs.unlink(this.xfilepath + '.part', function (err) { }); // Remove a partial file + } + }); } // Handle the web socket echo request, just echo back the data sent @@ -5853,6 +5866,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { obj.GetNodeRights = function (user, mesh, nodeid) { if ((user == null) || (mesh == null) || (nodeid == null)) { return 0; } if (typeof user == 'string') { user = obj.users[user]; } + if (user == null) { return 0; } var r = obj.GetMeshRights(user, mesh); if (r == 0xFFFFFFFF) return r;