Skip to content

Commit 73c9763

Browse files
committed
SEBWIN-1054: Integrated improved verification.
1 parent c7468d4 commit 73c9763

8 files changed

Lines changed: 73 additions & 40 deletions

File tree

SafeExamBrowser.Configuration.Contracts/Integrity/IIntegrityModule.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ public interface IIntegrityModule
2323
/// </summary>
2424
void ClearSession(string configurationKey, string startUrl);
2525

26+
/// <summary>
27+
/// Indicates whether the computer system is a virtual machine and if so, provides its manufacturer and probability.
28+
/// </summary>
29+
bool IsVirtualMachine(out string manufacturer, out int probability);
30+
2631
/// <summary>
2732
/// Attempts to calculate the app signature key.
2833
/// </summary>

SafeExamBrowser.Configuration.Contracts/SafeExamBrowser.Configuration.Contracts.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
<Compile Include="Cryptography\EncryptionParameters.cs" />
6161
<Compile Include="Cryptography\ICertificateStore.cs" />
6262
<Compile Include="Cryptography\IHashAlgorithm.cs" />
63-
<Compile Include="Integrity\IIntegrityModule.cs" />
6463
<Compile Include="Cryptography\IKeyGenerator.cs" />
6564
<Compile Include="Cryptography\IPasswordEncryption.cs" />
6665
<Compile Include="Cryptography\IPublicKeyEncryption.cs" />
@@ -75,6 +74,7 @@
7574
<Compile Include="DataResources\IResourceLoader.cs" />
7675
<Compile Include="DataResources\IResourceSaver.cs" />
7776
<Compile Include="IConfigurationRepository.cs" />
77+
<Compile Include="Integrity\IIntegrityModule.cs" />
7878
<Compile Include="LoadStatus.cs" />
7979
<Compile Include="Properties\AssemblyInfo.cs" />
8080
<Compile Include="SaveStatus.cs" />

SafeExamBrowser.Configuration/Integrity/IntegrityModule.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,35 @@ public void ClearSession(string configurationKey, string startUrl)
7474
}
7575
}
7676

77+
public bool IsVirtualMachine(out string manufacturer, out int probability)
78+
{
79+
var isVm = false;
80+
81+
manufacturer = default;
82+
probability = default;
83+
84+
try
85+
{
86+
isVm = IsVirtualMachine(out IntPtr bstr, out probability);
87+
88+
if (bstr != IntPtr.Zero)
89+
{
90+
manufacturer = Marshal.PtrToStringBSTR(bstr);
91+
Marshal.FreeBSTR(bstr);
92+
}
93+
}
94+
catch (DllNotFoundException)
95+
{
96+
logger.Warn("Integrity module is not available!");
97+
}
98+
catch (Exception e)
99+
{
100+
logger.Error("Unexpected error while attempting to query virtual machine information!", e);
101+
}
102+
103+
return isVm;
104+
}
105+
77106
public bool TryCalculateAppSignatureKey(string connectionToken, string salt, out string appSignatureKey)
78107
{
79108
appSignatureKey = default;
@@ -242,6 +271,9 @@ private bool TryWriteSessionCache(IEnumerable<(string configurationKey, string s
242271
[return: MarshalAs(UnmanagedType.BStr)]
243272
private static extern string CalculateBrowserExamKey(string configurationKey, string salt);
244273

274+
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
275+
private static extern bool IsVirtualMachine(out IntPtr manufacturer, out int probability);
276+
245277
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
246278
private static extern bool VerifyCodeSignature();
247279
}

SafeExamBrowser.Configuration/SafeExamBrowser.Configuration.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
<Compile Include="ConfigurationData\Keys.cs" />
7676
<Compile Include="ConfigurationData\DataValues.cs" />
7777
<Compile Include="Cryptography\CertificateStore.cs" />
78-
<Compile Include="Integrity\IntegrityModule.cs" />
7978
<Compile Include="Cryptography\KeyGenerator.cs" />
8079
<Compile Include="DataCompression\GZipCompressor.cs" />
8180
<Compile Include="Cryptography\PasswordEncryption.cs" />
@@ -90,6 +89,7 @@
9089
<Compile Include="DataFormats\XmlParser.cs" />
9190
<Compile Include="DataFormats\XmlSerializer.cs" />
9291
<Compile Include="DataResources\FileResourceSaver.cs" />
92+
<Compile Include="Integrity\IntegrityModule.cs" />
9393
<Compile Include="Properties\AssemblyInfo.cs" />
9494
<Compile Include="ConfigurationRepository.cs" />
9595
<Compile Include="DataResources\FileResourceLoader.cs" />

SafeExamBrowser.Monitoring.Contracts/IVirtualMachineDetector.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace SafeExamBrowser.Monitoring.Contracts
1414
public interface IVirtualMachineDetector
1515
{
1616
/// <summary>
17-
/// Indicates whether the computer is in fact a virtual machine.
17+
/// Indicates whether the computer system is in fact a virtual machine.
1818
/// </summary>
1919
bool IsVirtualMachine();
2020
}

SafeExamBrowser.Monitoring/SafeExamBrowser.Monitoring.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@
7676
<Compile Include="VirtualMachineDetector.cs" />
7777
</ItemGroup>
7878
<ItemGroup>
79+
<ProjectReference Include="..\SafeExamBrowser.Configuration.Contracts\SafeExamBrowser.Configuration.Contracts.csproj">
80+
<Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project>
81+
<Name>SafeExamBrowser.Configuration.Contracts</Name>
82+
</ProjectReference>
7983
<ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
8084
<Project>{64ea30fb-11d4-436a-9c2b-88566285363e}</Project>
8185
<Name>SafeExamBrowser.Logging.Contracts</Name>

SafeExamBrowser.Monitoring/VirtualMachineDetector.cs

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System;
1010
using System.Linq;
1111
using System.Management;
12+
using SafeExamBrowser.Configuration.Contracts.Integrity;
1213
using SafeExamBrowser.Logging.Contracts;
1314
using SafeExamBrowser.Monitoring.Contracts;
1415
using SafeExamBrowser.SystemComponents.Contracts;
@@ -42,79 +43,70 @@ public class VirtualMachineDetector : IVirtualMachineDetector
4243
"PROD_VIRTUAL_DVD"
4344
};
4445

45-
private static readonly (string hardware, bool required)[] SystemHardware =
46+
private static readonly string[] SystemHardware =
4647
{
47-
("CIM_Memory", false),
48-
("CIM_NumericSensor", false),
49-
("CIM_Sensor", false),
50-
("CIM_TemperatureSensor", false),
51-
("CIM_VoltageSensor", false),
52-
("Win32_CacheMemory", false),
53-
("Win32_Fan", false),
54-
("Win32_PerfRawData_Counters_ThermalZoneInformation", true),
55-
("Win32_VoltageProbe", false)
48+
"CIM_Memory",
49+
"CIM_NumericSensor",
50+
"CIM_Sensor",
51+
"CIM_TemperatureSensor",
52+
"CIM_VoltageSensor",
53+
"Win32_CacheMemory",
54+
"Win32_Fan",
55+
"Win32_VoltageProbe"
5656
};
5757

58+
private readonly IIntegrityModule integrityModule;
5859
private readonly ILogger logger;
5960
private readonly IRegistry registry;
6061
private readonly ISystemInfo systemInfo;
6162

62-
public VirtualMachineDetector(ILogger logger, IRegistry registry, ISystemInfo systemInfo)
63+
public VirtualMachineDetector(IIntegrityModule integrityModule, ILogger logger, IRegistry registry, ISystemInfo systemInfo)
6364
{
65+
this.integrityModule = integrityModule;
6466
this.logger = logger;
6567
this.registry = registry;
6668
this.systemInfo = systemInfo;
6769
}
6870

6971
public bool IsVirtualMachine()
7072
{
71-
var isVirtualMachine = false;
73+
var isVm = false;
7274

73-
isVirtualMachine |= HasNoSystemHardware();
74-
isVirtualMachine |= HasVirtualDevice();
75-
isVirtualMachine |= HasVirtualMacAddress();
76-
isVirtualMachine |= IsVirtualCpu();
77-
isVirtualMachine |= IsVirtualRegistry();
78-
isVirtualMachine |= IsVirtualSystem(systemInfo.BiosInfo, systemInfo.Manufacturer, systemInfo.Model);
75+
isVm |= HasNoSystemHardware();
76+
isVm |= HasVirtualDevice();
77+
isVm |= HasVirtualMacAddress();
78+
isVm |= IsVirtualCpu();
79+
isVm |= IsVirtualRegistry();
80+
isVm |= IsVirtualSystem(systemInfo.BiosInfo, systemInfo.Manufacturer, systemInfo.Model);
81+
isVm |= integrityModule.IsVirtualMachine(out var manufacturer, out var probability);
7982

80-
logger.Debug($"Computer '{systemInfo.Name}' appears {(isVirtualMachine ? "" : "not ")}to be a virtual machine.");
83+
logger.Debug($"Computer '{systemInfo.Name}' appears {(isVm ? "" : "not ")}to be a virtual machine{(isVm ? $" ({manufacturer}, {probability}%)" : "")}.");
8184

82-
return isVirtualMachine;
85+
return isVm;
8386
}
8487

8588
private bool HasNoSystemHardware()
8689
{
87-
var hasOther = false;
88-
var hasRequired = true;
90+
var hasHardware = false;
8991

9092
try
9193
{
92-
foreach (var (hardware, required) in SystemHardware)
94+
foreach (var hardware in SystemHardware)
9395
{
9496
using (var searcher = new ManagementObjectSearcher($"SELECT * FROM {hardware}"))
9597
using (var results = searcher.Get())
9698
{
97-
var hasResults = results.Count > 0;
98-
99-
if (required)
100-
{
101-
hasRequired &= hasResults;
102-
}
103-
else
104-
{
105-
hasOther |= hasResults;
106-
}
99+
hasHardware |= results.Count > 0;
107100
}
108101
}
109102
}
110103
catch (Exception e)
111104
{
112-
hasOther = false;
113-
hasRequired = false;
105+
hasHardware = false;
114106
logger.Error("Failed to query system hardware!", e);
115107
}
116108

117-
return !(hasRequired && hasOther);
109+
return !hasHardware;
118110
}
119111

120112
private bool HasVirtualDevice()

SafeExamBrowser.Runtime/CompositionRoot.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ private SessionOperationSequence BuildSessionOperations(
154154
var remoteSessionDetector = new RemoteSessionDetector(ModuleLogger(nameof(RemoteSessionDetector)));
155155
var sentinel = new SystemSentinel(ModuleLogger(nameof(SystemSentinel)), nativeMethods, registry);
156156
var server = new ServerProxy(appConfig, keyGenerator, ModuleLogger(nameof(ServerProxy)), systemInfo, userInfo);
157-
var virtualMachineDetector = new VirtualMachineDetector(ModuleLogger(nameof(VirtualMachineDetector)), registry, systemInfo);
157+
var virtualMachineDetector = new VirtualMachineDetector(integrityModule, ModuleLogger(nameof(VirtualMachineDetector)), registry, systemInfo);
158158

159159
operations.Enqueue(new SessionInitializationOperation(dependencies, fileSystem, repository));
160160
operations.Enqueue(new ConfigurationOperation(args, dependencies, new FileSystem(), new HashAlgorithm(), repository, uiFactory));

0 commit comments

Comments
 (0)