SEBWIN-316: Implemented rudimentary VM detection.
This commit is contained in:
parent
bc0170976c
commit
18fb059ddc
10 changed files with 240 additions and 13 deletions
|
@ -88,6 +88,8 @@ namespace SafeExamBrowser.I18n.Contracts
|
|||
MessageBox_StartupErrorTitle,
|
||||
MessageBox_UnexpectedConfigurationError,
|
||||
MessageBox_UnexpectedConfigurationErrorTitle,
|
||||
MessageBox_VirtualMachineNotAllowed,
|
||||
MessageBox_VirtualMachineNotAllowedTitle,
|
||||
MessageBox_YesButton,
|
||||
Notification_AboutTooltip,
|
||||
Notification_LogTooltip,
|
||||
|
@ -117,6 +119,7 @@ namespace SafeExamBrowser.I18n.Contracts
|
|||
OperationStatus_StopMouseInterception,
|
||||
OperationStatus_TerminateBrowser,
|
||||
OperationStatus_TerminateShell,
|
||||
OperationStatus_ValidateVirtualMachinePolicy,
|
||||
OperationStatus_WaitExplorerStartup,
|
||||
OperationStatus_WaitExplorerTermination,
|
||||
OperationStatus_WaitRuntimeDisconnection,
|
||||
|
|
|
@ -222,6 +222,12 @@
|
|||
<Entry key="MessageBox_UnexpectedConfigurationErrorTitle">
|
||||
Configuration Error
|
||||
</Entry>
|
||||
<Entry key="MessageBox_VirtualMachineNotAllowed">
|
||||
This computer appears to be a virtual machine. The currently active configuration does not allow SEB to be run in a virtual machine.
|
||||
</Entry>
|
||||
<Entry key="MessageBox_VirtualMachineNotAllowedTitle">
|
||||
Virtual Machine Detected
|
||||
</Entry>
|
||||
<Entry key="MessageBox_YesButton">
|
||||
Yes
|
||||
</Entry>
|
||||
|
@ -309,6 +315,9 @@
|
|||
<Entry key="OperationStatus_TerminateShell">
|
||||
Terminating user interface
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_ValidateVirtualMachinePolicy">
|
||||
Validating virtual machine policy
|
||||
</Entry>
|
||||
<Entry key="OperationStatus_WaitExplorerStartup">
|
||||
Waiting for Windows explorer to start up
|
||||
</Entry>
|
||||
|
|
|
@ -7,16 +7,135 @@
|
|||
*/
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations;
|
||||
using SafeExamBrowser.Settings;
|
||||
using SafeExamBrowser.Settings.Security;
|
||||
using SafeExamBrowser.SystemComponents.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
||||
{
|
||||
[TestClass]
|
||||
public class VirtualMachineOperationTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void TODO()
|
||||
private Mock<IVirtualMachineDetector> detector;
|
||||
private Mock<ILogger> logger;
|
||||
private SessionContext context;
|
||||
private VirtualMachineOperation sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
Assert.Fail();
|
||||
detector = new Mock<IVirtualMachineDetector>();
|
||||
logger = new Mock<ILogger>();
|
||||
context = new SessionContext();
|
||||
|
||||
context.Next = new SessionConfiguration();
|
||||
context.Next.Settings = new AppSettings();
|
||||
|
||||
sut = new VirtualMachineOperation(detector.Object, logger.Object, context);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustAbortIfVirtualMachineNotAllowed()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Deny;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(true);
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustSucceedIfVirtualMachineAllowed()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Allow;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(true);
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.AtMostOnce);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Allow;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(false);
|
||||
|
||||
result = sut.Perform();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.AtMost(2));
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Perform_MustSucceedIfNotAVirtualMachine()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Deny;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(false);
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustAbortIfVirtualMachineNotAllowed()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Deny;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(true);
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Aborted, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustSucceedIfVirtualMachineAllowed()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Allow;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(true);
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.AtMostOnce);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Allow;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(false);
|
||||
|
||||
result = sut.Repeat();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.AtMost(2));
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Repeat_MustSucceedIfNotAVirtualMachine()
|
||||
{
|
||||
context.Next.Settings.Security.VirtualMachinePolicy = VirtualMachinePolicy.Deny;
|
||||
detector.Setup(d => d.IsVirtualMachine()).Returns(false);
|
||||
|
||||
var result = sut.Repeat();
|
||||
|
||||
detector.Verify(d => d.IsVirtualMachine(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Revert_MustDoNothing()
|
||||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
detector.VerifyNoOtherCalls();
|
||||
logger.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ namespace SafeExamBrowser.Runtime
|
|||
var sessionContext = new SessionContext();
|
||||
var uiFactory = new UserInterfaceFactory(text);
|
||||
var userInfo = new UserInfo(ModuleLogger(nameof(UserInfo)));
|
||||
var vmDetector = new VirtualMachineDetector(ModuleLogger(nameof(VirtualMachineDetector)), systemInfo);
|
||||
|
||||
var bootstrapOperations = new Queue<IOperation>();
|
||||
var sessionOperations = new Queue<IRepeatableOperation>();
|
||||
|
@ -83,7 +84,7 @@ namespace SafeExamBrowser.Runtime
|
|||
|
||||
sessionOperations.Enqueue(new SessionInitializationOperation(configuration, logger, runtimeHost, sessionContext));
|
||||
sessionOperations.Enqueue(new ConfigurationOperation(args, configuration, new HashAlgorithm(), logger, sessionContext));
|
||||
sessionOperations.Enqueue(new VirtualMachineOperation(sessionContext));
|
||||
sessionOperations.Enqueue(new VirtualMachineOperation(vmDetector, logger, sessionContext));
|
||||
sessionOperations.Enqueue(new ServiceOperation(logger, runtimeHost, serviceProxy, sessionContext, THIRTY_SECONDS, userInfo));
|
||||
sessionOperations.Enqueue(new ClientTerminationOperation(logger, processFactory, proxyFactory, runtimeHost, sessionContext, THIRTY_SECONDS));
|
||||
sessionOperations.Enqueue(new KioskModeOperation(desktopFactory, explorerShell, logger, processFactory, sessionContext));
|
||||
|
|
|
@ -8,34 +8,65 @@
|
|||
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Runtime.Operations.Events;
|
||||
using SafeExamBrowser.Settings.Security;
|
||||
using SafeExamBrowser.SystemComponents.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.Operations
|
||||
{
|
||||
internal class VirtualMachineOperation : SessionOperation
|
||||
{
|
||||
//private IVirtualMachineDetector detector;
|
||||
private IVirtualMachineDetector detector;
|
||||
private ILogger logger;
|
||||
|
||||
public VirtualMachineOperation(/*IVirtualMachineDetector detector, */SessionContext context) : base(context)
|
||||
public VirtualMachineOperation(IVirtualMachineDetector detector, ILogger logger, SessionContext context) : base(context)
|
||||
{
|
||||
//this.detector = detector;
|
||||
this.detector = detector;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event StatusChangedEventHandler StatusChanged { add { } remove { } }
|
||||
public override event ActionRequiredEventHandler ActionRequired;
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
return OperationResult.Success;
|
||||
return ValidatePolicy();
|
||||
}
|
||||
|
||||
public override OperationResult Repeat()
|
||||
{
|
||||
return OperationResult.Success;
|
||||
return ValidatePolicy();
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
private OperationResult ValidatePolicy()
|
||||
{
|
||||
logger.Info($"Validating virtual machine policy...");
|
||||
StatusChanged?.Invoke(TextKey.OperationStatus_ValidateVirtualMachinePolicy);
|
||||
|
||||
if (Context.Next.Settings.Security.VirtualMachinePolicy == VirtualMachinePolicy.Deny && detector.IsVirtualMachine())
|
||||
{
|
||||
var args = new MessageEventArgs
|
||||
{
|
||||
Icon = MessageBoxIcon.Error,
|
||||
Message = TextKey.MessageBox_VirtualMachineNotAllowed,
|
||||
Title = TextKey.MessageBox_VirtualMachineNotAllowedTitle
|
||||
};
|
||||
|
||||
logger.Error("Detected virtual machine while SEB is not allowed to be run in a virtual machine! Aborting startup...");
|
||||
ActionRequired?.Invoke(args);
|
||||
|
||||
return OperationResult.Aborted;
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
namespace SafeExamBrowser.SystemComponents.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides functionality related to virtual machine detection.
|
||||
/// </summary>
|
||||
public interface IVirtualMachineDetector
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether the computer is in fact a virtual machine.
|
||||
/// </summary>
|
||||
bool IsVirtualMachine();
|
||||
}
|
||||
}
|
|
@ -56,6 +56,7 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="Audio\Events\VolumeChangedEventHandler.cs" />
|
||||
<Compile Include="Audio\IAudio.cs" />
|
||||
<Compile Include="IVirtualMachineDetector.cs" />
|
||||
<Compile Include="PowerSupply\Events\StatusChangedEventHandler.cs" />
|
||||
<Compile Include="PowerSupply\IPowerSupply.cs" />
|
||||
<Compile Include="PowerSupply\BatteryChargeStatus.cs" />
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SystemInfo.cs" />
|
||||
<Compile Include="UserInfo.cs" />
|
||||
<Compile Include="VirtualMachineDetector.cs" />
|
||||
<Compile Include="WirelessNetwork\WirelessAdapter.cs" />
|
||||
<Compile Include="WirelessNetwork\WirelessNetwork.cs" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -45,8 +45,8 @@ namespace SafeExamBrowser.SystemComponents
|
|||
|
||||
private void InitializeMachineInfo()
|
||||
{
|
||||
var model = string.Empty;
|
||||
var systemFamily = string.Empty;
|
||||
var model = default(string);
|
||||
var systemFamily = default(string);
|
||||
|
||||
using (var searcher = new ManagementObjectSearcher("Select * from Win32_ComputerSystem"))
|
||||
using (var results = searcher.Get())
|
||||
|
|
41
SafeExamBrowser.SystemComponents/VirtualMachineDetector.cs
Normal file
41
SafeExamBrowser.SystemComponents/VirtualMachineDetector.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.SystemComponents.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.SystemComponents
|
||||
{
|
||||
public class VirtualMachineDetector : IVirtualMachineDetector
|
||||
{
|
||||
private ILogger logger;
|
||||
private ISystemInfo systemInfo;
|
||||
|
||||
public VirtualMachineDetector(ILogger logger, ISystemInfo systemInfo)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.systemInfo = systemInfo;
|
||||
}
|
||||
|
||||
public bool IsVirtualMachine()
|
||||
{
|
||||
var isVirtualMachine = false;
|
||||
var manufacturer = systemInfo.Manufacturer.ToLower();
|
||||
var model = systemInfo.Model.ToLower();
|
||||
|
||||
isVirtualMachine |= manufacturer.Contains("microsoft corporation") && !model.Contains("surface");
|
||||
isVirtualMachine |= manufacturer.Contains("vmware");
|
||||
isVirtualMachine |= manufacturer.Contains("parallels software");
|
||||
isVirtualMachine |= model.Contains("virtualbox");
|
||||
|
||||
logger.Debug($"Computer '{systemInfo.Name}' appears to {(isVirtualMachine ? "" : "not ")}be a virtual machine.");
|
||||
|
||||
return isVirtualMachine;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue