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;