Skip to content

Commit

Permalink
More BitLocker improvements.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ylianst committed Feb 18, 2024
1 parent e5e86fe commit f2bc7d5
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 80 deletions.
71 changes: 34 additions & 37 deletions agents/meshcore.js
Original file line number Diff line number Diff line change
Expand Up @@ -654,22 +654,6 @@ var meshCoreObj = { action: 'coreinfo', value: (require('MeshAgent').coreHash ?
// Get the operating system description string
try { require('os').name().then(function (v) { meshCoreObj.osdesc = v; meshCoreObjChanged(); }); } catch (ex) { }

// Get Volumes and BitLocker if Windows
try {
if (process.platform == 'win32') {
if (require('computer-identifiers').volumes_promise != null) {
var p = require('computer-identifiers').volumes_promise();
p.then(function (res) {
meshCoreObj.volumes = res;
meshCoreObjChanged();
});
} else if (require('computer-identifiers').volumes != null) {
meshCoreObj.volumes = require('computer-identifiers').volumes();
meshCoreObjChanged();
}
}
} catch(e) { }

// Setup logged in user monitoring (THIS IS BROKEN IN WIN7)
try {
var userSession = require('user-sessions');
Expand Down Expand Up @@ -1959,28 +1943,24 @@ function getSystemInformation(func) {
results.hardware.network = { dns: require('os').dns() };
replaceSpacesWithUnderscoresRec(results);
var hasher = require('SHA384Stream').create();
// results.hash = hasher.syncHash(JSON.stringify(results)).toString('hex');
// func(results);


// On Windows platforms, get volume information - Needs more testing.
if (process.platform == 'win32')
{
results.pendingReboot = require('win-info').pendingReboot(); // Pending reboot

if (require('computer-identifiers').volumes_promise != null)
{
var p = require('computer-identifiers').volumes_promise();
p.then(function (res)
{
results.hardware.windows.volumes = res;
results.hardware.windows.volumes = cleanGetBitLockerVolumeInfo(res);
results.hash = hasher.syncHash(JSON.stringify(results)).toString('hex');
func(results);
});
}
else if (require('computer-identifiers').volumes != null)
{
results.hardware.windows.volumes = require('computer-identifiers').volumes();
results.hardware.windows.volumes = cleanGetBitLockerVolumeInfo(require('computer-identifiers').volumes());
results.hash = hasher.syncHash(JSON.stringify(results)).toString('hex');
func(results);
}
Expand Down Expand Up @@ -3801,7 +3781,7 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
if (require('os').dns != null) { availcommands += ',dnsinfo'; }
try { require('linux-dhcp'); availcommands += ',dhcp'; } catch (ex) { }
if (process.platform == 'win32') {
availcommands += ',cs,wpfhwacceleration,uac,volumes,rdpport';
availcommands += ',bitlocker,cs,wpfhwacceleration,uac,volumes,rdpport';
if (bcdOK()) { availcommands += ',safemode'; }
if (require('notifybar-desktop').DefaultPinned != null) { availcommands += ',privacybar'; }
try { require('win-utils'); availcommands += ',taskbar'; } catch (ex) { }
Expand Down Expand Up @@ -3962,6 +3942,17 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
case 'volumes':
response = JSON.stringify(require('win-volumes').getVolumes(), null, 1);
break;
case 'bitlocker':
if (process.platform == 'win32') {
if (require('computer-identifiers').volumes_promise != null) {
var p = require('computer-identifiers').volumes_promise();
p.then(function (res) { sendConsoleText(JSON.stringify(cleanGetBitLockerVolumeInfo(res), null, 1), this.session); });
response = "Please wait...";
} else if (require('computer-identifiers').volumes != null) {
sendConsoleText(JSON.stringify(cleanGetBitLockerVolumeInfo(require('computer-identifiers').volumes()), null, 1), this.session);
}
}
break;
case 'dhcp': // This command is only supported on Linux, this is because Linux does not give us the DNS suffix for each network adapter independently so we have to ask the DHCP server.
{
try { require('linux-dhcp'); } catch (ex) { response = 'Unknown command "dhcp", type "help" for list of available commands.'; break; }
Expand Down Expand Up @@ -5702,27 +5693,15 @@ function sendPeriodicServerUpdate(flags, force) {
});
} catch (ex) { }
}

// Get Defender for Windows Server
try {
var d = require('win-info').defender();
d.then(function(res){
meshCoreObj.defender = res;
meshCoreObjChanged();
});
} catch (ex){ }
// Get Volumes and BitLocker if Windows
try {
if (require('computer-identifiers').volumes_promise != null){
var p = require('computer-identifiers').volumes_promise();
p.then(function (res){
meshCoreObj.volumes = res;
meshCoreObjChanged();
});
}else if (require('computer-identifiers').volumes != null){
meshCoreObj.volumes = require('computer-identifiers').volumes();
meshCoreObjChanged();
}
} catch(e) { }
} catch (ex) { }
}

// Send available data right now
Expand All @@ -5736,6 +5715,24 @@ function sendPeriodicServerUpdate(flags, force) {
}
}

// Sort the names in an object
function sortObject(obj) { return Object.keys(obj).sort().reduce(function(a, v) { a[v] = obj[v]; return a; }, {}); }

// Fix the incoming data and cut down how much data we use
function cleanGetBitLockerVolumeInfo(volumes) {
for (var i in volumes) {
const v = volumes[i];
if (typeof v.size == 'string') { v.size = parseInt(v.size); }
if (v.identifier == '') { delete v.identifier; }
if (v.name == '') { delete v.name; }
if (v.removable != true) { delete v.removable; }
if (v.protectionStatus == 'On') { v.protectionStatus = true; } else { delete v.protectionStatus; }
if (v.volumeStatus == 'FullyDecrypted') { delete v.volumeStatus; }
if (v.recoveryPassword == '') { delete v.recoveryPassword; }
}
return sortObject(volumes);
}

// Once we are done collecting all the data, send to server if needed
var LastPeriodicServerUpdate = null;
var PeriodicServerUpdateNagleTimer = null;
Expand Down
17 changes: 2 additions & 15 deletions meshagent.js
Original file line number Diff line number Diff line change
Expand Up @@ -1940,21 +1940,8 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
// TODO: Check that the agent has an interface that is the same as the one we got this websocket connection on. Only set if we have a match.
}

// Volumes and BitLocker
if (command.volumes != null) {
for (var i in command.volumes) {
// Fix the incoming data and cut down how much data we use
const v = command.volumes[i];
if (typeof v.size == 'string') { v.size = parseInt(v.size); }
if (v.recoveryPassword == '') { delete v.recoveryPassword; }
if (v.identifier == '') { delete v.identifier; }
if (v.name == '') { delete v.name; }
if (v.removable != true) { delete v.removable; }
if (v.protectionStatus == 'On') { v.protectionStatus = true; } else { delete v.protectionStatus; }
if (v.volumeStatus == "FullyDecrypted") { delete v.volumeStatus; }
}
if (JSON.stringify(device.volumes) != JSON.stringify(command.volumes)) { device.volumes = command.volumes; change = 1; }
}
// Remove old volumes and BitLocker data, this is part of sysinfo.
delete device.volumes;

// If there are changes, event the new device
if (change == 1) {
Expand Down
6 changes: 6 additions & 0 deletions meshuser.js
Original file line number Diff line number Diff line change
Expand Up @@ -6273,6 +6273,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
delete doc.type;
delete doc.domain;
delete doc._id;

// If this is not a device group admin users, don't send any BitLocker recovery passwords
if ((rights != MESHRIGHT_ADMIN) && (doc.hardware) && (doc.hardware.windows) && (doc.hardware.windows.volumes)) {
for (var i in doc.hardware.windows.volumes) { delete doc.hardware.windows.volumes[i].recoveryPassword; }
}

if (command.nodeinfo === true) { doc.node = node; doc.rights = rights; }
obj.send(doc);
} else {
Expand Down
44 changes: 16 additions & 28 deletions views/default.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -7451,21 +7451,6 @@
x += addDeviceAttribute("Antivirus", y.join('<br />'));
}

/*
// Volumes and Bitlocker
if (node.volumes){
var bitlocker = [];
for (var i in node.volumes) {
if (typeof node.volumes[i].protectionStatus !== 'undefined' && node.volumes[i].protectionStatus == 'On'){
bitlocker.push('<div style=margin-bottom:2px>' + addKeyLinkConditional(i + ' - <span style=color:green>' + EscapeHtml(node.volumes[i].volumeStatus) + '</span>', 'p10showBitlockerKey(\'' + i + '\')', (userinfo.siteadmin == 0xFFFFFFFF)) + '</div>');
} else if (typeof node.volumes[i].protectionStatus !== 'undefined') {
bitlocker.push('<div style=margin-bottom:2px>' + i + ' - <span style=color:red>' + EscapeHtml(node.volumes[i].volumeStatus) + '</span>' + '</div>');
}
}
if (bitlocker.length > 0) { x += addDeviceAttribute("BitLocker", bitlocker.join(' ')); }
}
*/

// Active Users
if (node.users && node.conn && (node.users.length > 0) && (node.conn & 1)) { x += addDeviceAttribute(((node.users.length > 1)?"Active Users":"Active User"), EscapeHtml(node.users.join(', '))); }

Expand Down Expand Up @@ -7918,13 +7903,6 @@
}
}

function p10showBitlockerKey(drive) {
if (xxdialogMode) return false;
var x = '<div><p>' + "Identifier" + '</p><p style=user-select:text;font-weight:bold>' + EscapeHtml(currentNode.volumes[drive].identifier ? currentNode.volumes[drive].identifier : "Unknown") + '</p>';
x += '<p>' + "Recovery Password" + '</p><p style=user-select:text;font-weight:bold>' + EscapeHtml(currentNode.volumes[drive].recoveryPassword ? currentNode.volumes[drive].recoveryPassword : "Unknown") + '</p></div>';
setDialogMode(2, EscapeHtml(drive) + ': ' + "BitLocker Information", 1, null, x, '');
}

function p20editDeviceNotify() {
if (xxdialogMode) return false;
var devNotify = 0, fx = ((features2 & 0x00004000) && (userinfo.emailVerified))?1:0;
Expand Down Expand Up @@ -12123,24 +12101,27 @@
}

// Volumes and Bitlocker
if (node.volumes) {
if (hardware.windows && hardware.windows.volumes) {
var x = '';
for (var i in node.volumes) {
var m = node.volumes[i];
for (var i in hardware.windows.volumes) {
var m = hardware.windows.volumes[i];
x += '<tr><td><div class=style10 style=border-radius:5px;padding:8px>';
x += '<div style=margin-bottom:3px><b>' + i + ':' + (((m.name == null) || (m.name == '')) ? '' : (' - ' + EscapeHtml(m.name))) + '</b></div>';
if (m.size) {
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
var i = parseInt(Math.floor(Math.log(Math.abs(m.size)) / Math.log(1024)), 10);
var fsize = (i === 0 ? `${m.size} ${sizes[i]}` : `${(m.size / (1024 ** i)).toFixed(2)} ${sizes[i]}`);
var j = parseInt(Math.floor(Math.log(Math.abs(m.size)) / Math.log(1024)), 10);
var fsize = (j === 0 ? `${m.size} ${sizes[j]}` : `${(m.size / (1024 ** j)).toFixed(2)} ${sizes[j]}`);
x += addDetailItem("Capacity", EscapeHtml(fsize), s);
}
if (m.type) { x += addDetailItem("File System", (m.removable == true ? ("Removable" + ' / ') : '') + EscapeHtml(m.type), s); }

if (m.protectionStatus || m.volumeStatus) {
var bitlockerState = [];
if (m.protectionStatus) bitlockerState.push("Enabled");
if (m.volumeStatus) bitlockerState.push(EscapeHtml(m.volumeStatus));
x += addDetailItem("BitLocker", bitlockerState.join(' - '), s);
bitlockerState = bitlockerState.join(' - ');
if (m.recoveryPassword) { bitlockerState += addKeyLink('', 'deviceDetailsShowBitlockerInfo(\"' + encodeURIComponentEx(i) + '\",\"' + encodeURIComponentEx(m.identifier) + '\",\"' + encodeURIComponentEx(m.recoveryPassword) + '\")'); }
x += addDetailItem("BitLocker", bitlockerState, s);
}
x += '</div>';
}
Expand All @@ -12167,6 +12148,13 @@
}
}

function deviceDetailsShowBitlockerInfo(drive, identifier, password) {
if (xxdialogMode) return false;
var x = '<div><p>' + "Identifier" + '</p><p style=user-select:text;font-weight:bold>' + (identifier ? decodeURIComponent(identifier) : "Unknown") + '</p>';
x += '<p>' + "Recovery Password" + '</p><p style=user-select:text;font-weight:bold>' + (password ? decodeURIComponent(password) : "Unknown") + '</p></div>';
setDialogMode(2, decodeURIComponent(drive) + ': ' + "BitLocker Information", 1, null, x, '');
}

//
// CONSOLE
//
Expand Down

0 comments on commit f2bc7d5

Please sign in to comment.