diff --git a/SafeExamBrowser.SystemComponents.Contracts/ISystemInfo.cs b/SafeExamBrowser.SystemComponents.Contracts/ISystemInfo.cs index 18eeb45c..e83e32e1 100644 --- a/SafeExamBrowser.SystemComponents.Contracts/ISystemInfo.cs +++ b/SafeExamBrowser.SystemComponents.Contracts/ISystemInfo.cs @@ -42,5 +42,15 @@ namespace SafeExamBrowser.SystemComponents.Contracts /// Provides detailed version information about the currently running operating system. /// string OperatingSystemInfo { get; } + + /// + /// The MAC address of the network adapter + /// + string MacAddress { get; } + + /// + /// Provides the DeviceID information of the user's Plug and Play devices + /// + string[] PlugAndPlayDeviceIds { get; } } } diff --git a/SafeExamBrowser.SystemComponents/SystemInfo.cs b/SafeExamBrowser.SystemComponents/SystemInfo.cs index e0655682..3eb62c72 100644 --- a/SafeExamBrowser.SystemComponents/SystemInfo.cs +++ b/SafeExamBrowser.SystemComponents/SystemInfo.cs @@ -7,6 +7,7 @@ */ using System; +using System.Collections.Generic; using System.Linq; using System.Management; using System.Windows.Forms; @@ -23,6 +24,8 @@ namespace SafeExamBrowser.SystemComponents public string Model { get; private set; } public string Name { get; private set; } public OperatingSystem OperatingSystem { get; private set; } + public string MacAddress { get; private set; } + public string[] PlugAndPlayDeviceIds { get; private set; } public string OperatingSystemInfo { @@ -34,6 +37,8 @@ namespace SafeExamBrowser.SystemComponents InitializeBattery(); InitializeMachineInfo(); InitializeOperatingSystem(); + InitializeMacAddress(); + InitializePnPDevices(); } private void InitializeBattery() @@ -128,5 +133,56 @@ namespace SafeExamBrowser.SystemComponents { return Environment.Is64BitOperatingSystem ? "x64" : "x86"; } + + private void InitializeMacAddress() + { + using (var searcher = new ManagementObjectSearcher("Select MACAddress from Win32_NetworkAdapterConfiguration WHERE DNSDomain IS NOT NULL")) + using (var results = searcher.Get()) + { + + if (results != null && results.Count > 0) + { + using (var networkAdapter = results.Cast().First()) + { + foreach (var property in networkAdapter.Properties) + { + + if (property.Name.Equals("MACAddress")) + { + MacAddress = Convert.ToString(property.Value).Replace(":", "").ToUpper(); + } + } + } + } + else + { + MacAddress = "000000000000"; + } + } + } + + private void InitializePnPDevices() + { + var deviceList = new List(); + using (var searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT DeviceID FROM Win32_PnPEntity")) + using (var results = searcher.Get()) + { + foreach (ManagementObject queryObj in results) + { + using (queryObj) + { + foreach (var property in queryObj.Properties) + { + if (property.Name.Equals("DeviceID")) + { + deviceList.Add(Convert.ToString(property.Value).ToLower()); + } + } + } + } + PlugAndPlayDeviceIds = deviceList.ToArray(); + + } + } } } diff --git a/SafeExamBrowser.SystemComponents/VirtualMachineDetector.cs b/SafeExamBrowser.SystemComponents/VirtualMachineDetector.cs index 26d4f964..35c1319a 100644 --- a/SafeExamBrowser.SystemComponents/VirtualMachineDetector.cs +++ b/SafeExamBrowser.SystemComponents/VirtualMachineDetector.cs @@ -8,14 +8,18 @@ using SafeExamBrowser.Logging.Contracts; using SafeExamBrowser.SystemComponents.Contracts; +using System.Globalization; +using System.Linq; namespace SafeExamBrowser.SystemComponents { public class VirtualMachineDetector : IVirtualMachineDetector { + private static readonly string[] PCI_VENDOR_BLACKLIST = { "vbox", "80ee", "qemu", "1af4", "1b36" }; //Virtualbox: VBOX, 80EE RedHat: QUEMU, 1AF4, 1B36 + private ILogger logger; private ISystemInfo systemInfo; - + public VirtualMachineDetector(ILogger logger, ISystemInfo systemInfo) { this.logger = logger; @@ -27,6 +31,8 @@ namespace SafeExamBrowser.SystemComponents var isVirtualMachine = false; var manufacturer = systemInfo.Manufacturer.ToLower(); var model = systemInfo.Model.ToLower(); + var macAddress = systemInfo.MacAddress; + var plugAndPlayDeviceIds = systemInfo.PlugAndPlayDeviceIds; isVirtualMachine |= manufacturer.Contains("microsoft corporation") && !model.Contains("surface"); isVirtualMachine |= manufacturer.Contains("vmware"); @@ -34,6 +40,17 @@ namespace SafeExamBrowser.SystemComponents isVirtualMachine |= model.Contains("virtualbox"); isVirtualMachine |= manufacturer.Contains("qemu"); + if (macAddress != null && macAddress.Count() > 2) + { + isVirtualMachine |= ((byte.Parse(macAddress[1].ToString(), NumberStyles.HexNumber) & 2) == 2 || macAddress.StartsWith("080027")); + } + + foreach (var device in plugAndPlayDeviceIds) + { + isVirtualMachine |= PCI_VENDOR_BLACKLIST.Any(device.ToLower().Contains); + + } + logger.Debug($"Computer '{systemInfo.Name}' appears to {(isVirtualMachine ? "" : "not ")}be a virtual machine."); return isVirtualMachine;