From 7b71c0488fb8287f13883f9b77747f6778f4416b Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Tue, 29 Sep 2020 15:02:33 -0700 Subject: [PATCH] Added selective session recording. --- meshcentral-config-schema.json | 1 + meshdesktopmultiplex.js | 7 +++++++ meshrelay.js | 13 ++++++++++++- meshuser.js | 1 + sample-config-advanced.json | 1 + views/default.handlebars | 3 +++ 6 files changed, 25 insertions(+), 1 deletion(-) diff --git a/meshcentral-config-schema.json b/meshcentral-config-schema.json index 3e9a4273..02eb837f 100644 --- a/meshcentral-config-schema.json +++ b/meshcentral-config-schema.json @@ -309,6 +309,7 @@ "type": "object", "additionalProperties": false, "properties": { + "onlySelectedDeviceGroups": { "type": "boolean", "default": false, "description": "When enabled, only device groups with the session recording feature turned on will be recorded. When false, all devices are recorded." }, "filepath": { "type": "string" }, "index": { "type": "boolean", "default": false }, "maxRecordings": { "type": "integer" }, diff --git a/meshdesktopmultiplex.js b/meshdesktopmultiplex.js index 35a33b50..0d3a13ba 100644 --- a/meshdesktopmultiplex.js +++ b/meshdesktopmultiplex.js @@ -683,6 +683,13 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) { function recordingSetup(domain, func) { // Setup session recording if ((domain.sessionrecording == true || ((typeof domain.sessionrecording == 'object') && ((domain.sessionrecording.protocols == null) || (domain.sessionrecording.protocols.indexOf(2) >= 0))))) { + + // Check again to make sure we need to start recording + if (domain.sessionrecording.onlyselecteddevicegroups === true) { + var mesh = parent.meshes[obj.meshid]; + if ((mesh.flags == null) || ((mesh.flags & 4) == 0)) { func(false); return; } // Do not record the session + } + var now = new Date(Date.now()); var recFilename = 'desktopSession' + ((domain.id == '') ? '' : '-') + domain.id + '-' + now.getUTCFullYear() + '-' + parent.common.zeroPad(now.getUTCMonth(), 2) + '-' + parent.common.zeroPad(now.getUTCDate(), 2) + '-' + parent.common.zeroPad(now.getUTCHours(), 2) + '-' + parent.common.zeroPad(now.getUTCMinutes(), 2) + '-' + parent.common.zeroPad(now.getUTCSeconds(), 2) + '-' + obj.nodeid.split('/')[2] + '.mcrec' var recFullFilename = null; diff --git a/meshrelay.js b/meshrelay.js index c0d01d2e..c0ad10a9 100644 --- a/meshrelay.js +++ b/meshrelay.js @@ -232,7 +232,18 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie parent.db.Get(obj.req.query.nodeid, function (err, nodes) { var xusername = '', xdevicename = '', xdevicename2 = null, node = null; if ((nodes != null) && (nodes.length == 1)) { node = nodes[0]; xdevicename2 = node.name; xdevicename = '-' + parent.common.makeFilename(node.name); } - + + // Check again if we need to do recording + if (domain.sessionrecording.onlyselecteddevicegroups === true) { + var mesh = parent.meshes[node.meshid]; + if ((mesh.flags == null) || ((mesh.flags & 4) == 0)) { + // Do not record the session, just send session start + try { ws.send('c'); } catch (ex) { } // Send connect to both peers + try { relayinfo.peer1.ws.send('c'); } catch (ex) { } + return; + } + } + // Get the username and make it acceptable as a filename if (sessionUser._id) { xusername = '-' + parent.common.makeFilename(sessionUser._id.split('/')[2]); } diff --git a/meshuser.js b/meshuser.js index 613b094d..ae35dc2e 100644 --- a/meshuser.js +++ b/meshuser.js @@ -421,6 +421,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use serverinfo.maxGuestSessionSharingTime = (typeof domain.maxguestsessionsharingtime == 'number') ? domain.maxguestsessionsharingtime : 60; serverinfo.languages = parent.renderLanguages; serverinfo.tlshash = Buffer.from(parent.webCertificateHashs[domain.id], 'binary').toString('hex').toUpperCase(); // SHA384 of server HTTPS certificate + if ((domain.sessionrecording) && (domain.sessionrecording.onlyselecteddevicegroups === true)) { serverinfo.devGroupSessionRecording = 1; } // Allow enabling of session recording if ((parent.parent.config.domains[domain.id].amtacmactivation != null) && (parent.parent.config.domains[domain.id].amtacmactivation.acmmatch != null)) { var matchingDomains = []; for (var i in parent.parent.config.domains[domain.id].amtacmactivation.acmmatch) { diff --git a/sample-config-advanced.json b/sample-config-advanced.json index 210f3616..91aa4f3b 100644 --- a/sample-config-advanced.json +++ b/sample-config-advanced.json @@ -226,6 +226,7 @@ }, "_agentConfig": [ "webSocketMaskOverride=1", "coreDumpEnabled=1" ], "_sessionRecording": { + "_onlySelectedDeviceGroups": true, "_filepath": "C:\\temp", "_index": true, "_maxRecordings": 10, diff --git a/views/default.handlebars b/views/default.handlebars index 4fc23930..e5706200 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -9321,6 +9321,7 @@ if (currentMesh.flags) { if (currentMesh.flags & 1) { meshFeatures.push("Auto-Remove"); } if (currentMesh.flags & 2) { meshFeatures.push("Hostname Sync"); } + if ((serverinfo.devGroupSessionRecording == 1) && (currentMesh.flags & 4)) { meshFeatures.push("Record Sessions"); } } meshFeatures = meshFeatures.join(', '); if (meshFeatures == '') { meshFeatures = '' + "None" + ''; } @@ -9620,6 +9621,7 @@ var flags = (currentMesh.flags)?currentMesh.flags:0; var x = '

'; x += '

'; + if (serverinfo.devGroupSessionRecording == 1) { x += '

'; } setDialogMode(2, "Edit Device Group Features", 3, p20editmeshfeaturesEx, x); } @@ -9627,6 +9629,7 @@ var flags = 0; if (Q('d20flag1').checked) { flags += 1; } if (Q('d20flag2').checked) { flags += 2; } + if (serverinfo.devGroupSessionRecording == 1) { if (Q('d20flag4').checked) { flags += 4; } } meshserver.send({ action: 'editmesh', meshid: currentMesh._id, flags: flags }); }