SEBWIN-510: Implemented functionality.

This commit is contained in:
Damian Büchel 2022-07-18 21:37:04 +02:00
parent bd5f7d4293
commit 2fdacfc1b0
17 changed files with 309 additions and 38 deletions

View file

@ -21,6 +21,7 @@ using SafeExamBrowser.Communication.Contracts.Hosts;
using SafeExamBrowser.Communication.Contracts.Proxies;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Configuration.Contracts.Cryptography;
using SafeExamBrowser.Configuration.Contracts.Integrity;
using SafeExamBrowser.Core.Contracts.OperationModel;
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
using SafeExamBrowser.I18n.Contracts;
@ -55,6 +56,7 @@ namespace SafeExamBrowser.Client.UnitTests
private Mock<IExplorerShell> explorerShell;
private Mock<IFileSystemDialog> fileSystemDialog;
private Mock<IHashAlgorithm> hashAlgorithm;
private Mock<IIntegrityModule> integrityModule;
private Mock<ILogger> logger;
private Mock<IMessageBox> messageBox;
private Mock<IOperationSequence> operationSequence;
@ -84,6 +86,7 @@ namespace SafeExamBrowser.Client.UnitTests
explorerShell = new Mock<IExplorerShell>();
fileSystemDialog = new Mock<IFileSystemDialog>();
hashAlgorithm = new Mock<IHashAlgorithm>();
integrityModule = new Mock<IIntegrityModule>();
logger = new Mock<ILogger>();
messageBox = new Mock<IMessageBox>();
operationSequence = new Mock<IOperationSequence>();
@ -110,6 +113,7 @@ namespace SafeExamBrowser.Client.UnitTests
explorerShell.Object,
fileSystemDialog.Object,
hashAlgorithm.Object,
integrityModule.Object,
logger.Object,
messageBox.Object,
operationSequence.Object,
@ -371,7 +375,7 @@ namespace SafeExamBrowser.Client.UnitTests
};
messageBox.Setup(m => m.Show(
It.Is<string>(s => s == args.Message),
It.Is<string>(s => s == args.Message),
It.Is<string>(s => s == args.Title),
It.Is<MessageBoxAction>(a => a == (MessageBoxAction) args.Action),
It.Is<MessageBoxIcon>(i => i == (MessageBoxIcon) args.Icon),

View file

@ -21,6 +21,7 @@ using SafeExamBrowser.Communication.Contracts.Events;
using SafeExamBrowser.Communication.Contracts.Hosts;
using SafeExamBrowser.Communication.Contracts.Proxies;
using SafeExamBrowser.Configuration.Contracts.Cryptography;
using SafeExamBrowser.Configuration.Contracts.Integrity;
using SafeExamBrowser.Core.Contracts.OperationModel;
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
using SafeExamBrowser.I18n.Contracts;
@ -43,30 +44,32 @@ namespace SafeExamBrowser.Client
{
internal class ClientController
{
private IActionCenter actionCenter;
private IApplicationMonitor applicationMonitor;
private ClientContext context;
private IDisplayMonitor displayMonitor;
private IExplorerShell explorerShell;
private IFileSystemDialog fileSystemDialog;
private IHashAlgorithm hashAlgorithm;
private ILogger logger;
private IMessageBox messageBox;
private IOperationSequence operations;
private IRuntimeProxy runtime;
private bool sessionLocked;
private Action shutdown;
private ISplashScreen splashScreen;
private ISystemMonitor systemMonitor;
private ITaskbar taskbar;
private IText text;
private IUserInterfaceFactory uiFactory;
private readonly IActionCenter actionCenter;
private readonly IApplicationMonitor applicationMonitor;
private readonly ClientContext context;
private readonly IDisplayMonitor displayMonitor;
private readonly IExplorerShell explorerShell;
private readonly IFileSystemDialog fileSystemDialog;
private readonly IHashAlgorithm hashAlgorithm;
private readonly IIntegrityModule integrityModule;
private readonly ILogger logger;
private readonly IMessageBox messageBox;
private readonly IOperationSequence operations;
private readonly IRuntimeProxy runtime;
private readonly Action shutdown;
private readonly ISplashScreen splashScreen;
private readonly ISystemMonitor systemMonitor;
private readonly ITaskbar taskbar;
private readonly IText text;
private readonly IUserInterfaceFactory uiFactory;
private IBrowserApplication Browser => context.Browser;
private IClientHost ClientHost => context.ClientHost;
private IServerProxy Server => context.Server;
private AppSettings Settings => context.Settings;
private bool sessionLocked;
internal ClientController(
IActionCenter actionCenter,
IApplicationMonitor applicationMonitor,
@ -75,6 +78,7 @@ namespace SafeExamBrowser.Client
IExplorerShell explorerShell,
IFileSystemDialog fileSystemDialog,
IHashAlgorithm hashAlgorithm,
IIntegrityModule integrityModule,
ILogger logger,
IMessageBox messageBox,
IOperationSequence operations,
@ -93,6 +97,7 @@ namespace SafeExamBrowser.Client
this.explorerShell = explorerShell;
this.fileSystemDialog = fileSystemDialog;
this.hashAlgorithm = hashAlgorithm;
this.integrityModule = integrityModule;
this.logger = logger;
this.messageBox = messageBox;
this.operations = operations;
@ -123,6 +128,7 @@ namespace SafeExamBrowser.Client
RegisterEvents();
ShowShell();
AutoStartApplications();
ScheduleIntegrityVerification();
var communication = runtime.InformClientReady();
@ -215,12 +221,12 @@ namespace SafeExamBrowser.Client
private void Taskbar_LoseFocusRequested(bool forward)
{
this.Browser.Focus(forward);
Browser.Focus(forward);
}
private void Browser_LoseFocusRequested(bool forward)
{
this.taskbar.Focus(forward);
taskbar.Focus(forward);
}
private void DeregisterEvents()
@ -307,6 +313,39 @@ namespace SafeExamBrowser.Client
}
}
private void ScheduleIntegrityVerification()
{
const int FIVE_MINUTES = 300000;
const int TEN_MINUTES = 600000;
var timer = new System.Timers.Timer();
timer.AutoReset = false;
timer.Elapsed += (o, args) =>
{
logger.Info($"Attempting to verify application integrity...");
if (integrityModule.TryVerifyCodeSignature(out var isValid))
{
if (isValid)
{
logger.Info("Application integrity successfully verified.");
}
else
{
logger.Warn("Application integrity is compromised!");
ShowLockScreen(text.Get(TextKey.LockScreen_IntegrityMessage), text.Get(TextKey.LockScreen_Title), Enumerable.Empty<LockScreenOption>());
}
}
else
{
logger.Warn("Failed to verify application integrity!");
}
};
timer.Interval = TEN_MINUTES + (new Random().NextDouble() * FIVE_MINUTES);
timer.Start();
}
private void ApplicationMonitor_ExplorerStarted()
{
logger.Info("Trying to terminate Windows explorer...");
@ -798,7 +837,7 @@ namespace SafeExamBrowser.Client
{
var result = messageBox.Show(TextKey.MessageBox_Quit, TextKey.MessageBox_QuitTitle, MessageBoxAction.YesNo, MessageBoxIcon.Question);
var quit = result == MessageBoxResult.Yes;
if (quit)
{
logger.Info("The user chose to terminate the application.");

View file

@ -18,7 +18,9 @@ using SafeExamBrowser.Communication.Contracts;
using SafeExamBrowser.Communication.Contracts.Proxies;
using SafeExamBrowser.Communication.Hosts;
using SafeExamBrowser.Communication.Proxies;
using SafeExamBrowser.Configuration.Contracts.Integrity;
using SafeExamBrowser.Configuration.Cryptography;
using SafeExamBrowser.Configuration.Integrity;
using SafeExamBrowser.Core.Contracts.OperationModel;
using SafeExamBrowser.Core.OperationModel;
using SafeExamBrowser.Core.Operations;
@ -68,6 +70,7 @@ namespace SafeExamBrowser.Client
private UserInterfaceMode uiMode;
private IActionCenter actionCenter;
private IIntegrityModule integrityModule;
private ILogger logger;
private IMessageBox messageBox;
private INativeMethods nativeMethods;
@ -94,6 +97,7 @@ namespace SafeExamBrowser.Client
actionCenter = uiFactory.CreateActionCenter();
context = new ClientContext();
integrityModule = new IntegrityModule(ModuleLogger(nameof(IntegrityModule)));
messageBox = BuildMessageBox();
nativeMethods = new NativeMethods();
networkAdapter = new NetworkAdapter(ModuleLogger(nameof(NetworkAdapter)), nativeMethods);
@ -143,6 +147,7 @@ namespace SafeExamBrowser.Client
explorerShell,
fileSystemDialog,
hashAlgorithm,
integrityModule,
logger,
messageBox,
sequence,
@ -212,7 +217,7 @@ namespace SafeExamBrowser.Client
private IOperation BuildBrowserOperation()
{
var fileSystemDialog = BuildFileSystemDialog();
var keyGenerator = new KeyGenerator(context.AppConfig, ModuleLogger(nameof(KeyGenerator)), context.Settings);
var keyGenerator = new KeyGenerator(context.AppConfig, integrityModule, ModuleLogger(nameof(KeyGenerator)), context.Settings);
var moduleLogger = ModuleLogger(nameof(BrowserApplication));
var browser = new BrowserApplication(
context.AppConfig,

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2022 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.Configuration.Contracts.Integrity
{
/// <summary>
/// Provides functionality related to application integrity.
/// </summary>
public interface IIntegrityModule
{
/// <summary>
/// Attempts to calculate the browser exam key.
/// </summary>
bool TryCalculateBrowserExamKey(string configurationKey, string salt, out string browserExamKey);
/// <summary>
/// Attempts to verify the code signature.
/// </summary>
bool TryVerifyCodeSignature(out bool isValid);
}
}

View file

@ -59,6 +59,7 @@
<Compile Include="Cryptography\EncryptionParameters.cs" />
<Compile Include="Cryptography\ICertificateStore.cs" />
<Compile Include="Cryptography\IHashAlgorithm.cs" />
<Compile Include="Integrity\IIntegrityModule.cs" />
<Compile Include="Cryptography\IKeyGenerator.cs" />
<Compile Include="Cryptography\IPasswordEncryption.cs" />
<Compile Include="Cryptography\IPublicKeyEncryption.cs" />

View file

@ -11,6 +11,7 @@ using System.Security.Cryptography;
using System.Text;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Configuration.Contracts.Cryptography;
using SafeExamBrowser.Configuration.Contracts.Integrity;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.Settings;
@ -20,15 +21,17 @@ namespace SafeExamBrowser.Configuration.Cryptography
{
private readonly SHA256Managed algorithm;
private readonly AppConfig appConfig;
private readonly IIntegrityModule integrityModule;
private readonly ILogger logger;
private readonly AppSettings settings;
private string browserExamKey;
public KeyGenerator(AppConfig appConfig, ILogger logger, AppSettings settings)
public KeyGenerator(AppConfig appConfig, IIntegrityModule integrityModule, ILogger logger, AppSettings settings)
{
this.algorithm = new SHA256Managed();
this.appConfig = appConfig;
this.integrityModule = integrityModule;
this.logger = logger;
this.settings = settings;
}
@ -37,7 +40,7 @@ namespace SafeExamBrowser.Configuration.Cryptography
{
var urlWithoutFragment = url.Split('#')[0];
var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlWithoutFragment + (browserExamKey ?? ComputeBrowserExamKey())));
var key = BitConverter.ToString(hash).ToLower().Replace("-", string.Empty);
var key = ToString(hash);
return key;
}
@ -46,7 +49,7 @@ namespace SafeExamBrowser.Configuration.Cryptography
{
var urlWithoutFragment = url.Split('#')[0];
var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlWithoutFragment + settings.Browser.ConfigurationKey));
var key = BitConverter.ToString(hash).ToLower().Replace("-", string.Empty);
var key = ToString(hash);
return key;
}
@ -55,21 +58,35 @@ namespace SafeExamBrowser.Configuration.Cryptography
{
var salt = settings.Browser.BrowserExamKeySalt;
if (salt == default(byte[]))
if (salt == default || salt.Length == 0)
{
salt = new byte[0];
logger.Warn("The current configuration does not contain a salt value for the browser exam key!");
}
using (var algorithm = new HMACSHA256(salt))
if (integrityModule.TryCalculateBrowserExamKey(settings.Browser.ConfigurationKey, ToString(salt), out browserExamKey))
{
var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(appConfig.CodeSignatureHash + appConfig.ProgramBuildVersion + settings.Browser.ConfigurationKey));
var key = BitConverter.ToString(hash).ToLower().Replace("-", string.Empty);
browserExamKey = key;
return browserExamKey;
logger.Debug("Successfully calculated BEK using integrity module.");
}
else
{
logger.Warn("Failed to calculate BEK using integrity module! Falling back to simplified calculation...");
using (var algorithm = new HMACSHA256(salt))
{
var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(appConfig.CodeSignatureHash + appConfig.ProgramBuildVersion + settings.Browser.ConfigurationKey));
var key = ToString(hash);
browserExamKey = key;
}
}
return browserExamKey;
}
private string ToString(byte[] bytes)
{
return BitConverter.ToString(bytes).ToLower().Replace("-", string.Empty);
}
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2022 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 System;
using System.Runtime.InteropServices;
using SafeExamBrowser.Configuration.Contracts.Integrity;
using SafeExamBrowser.Logging.Contracts;
namespace SafeExamBrowser.Configuration.Integrity
{
public class IntegrityModule : IIntegrityModule
{
const string DLL_NAME =
#if X86
"seb_x86.dll";
#else
"seb_x64.dll";
#endif
private readonly ILogger logger;
public IntegrityModule(ILogger logger)
{
this.logger = logger;
}
public bool TryCalculateBrowserExamKey(string configurationKey, string salt, out string browserExamKey)
{
browserExamKey = default;
try
{
browserExamKey = CalculateBrowserExamKey(configurationKey, salt);
}
catch (DllNotFoundException)
{
logger.Warn("Integrity module is not present!");
}
catch (Exception e)
{
logger.Error("Unexpected error while attempting to calculate browser exam key!", e);
}
return browserExamKey != default;
}
public bool TryVerifyCodeSignature(out bool isValid)
{
var success = false;
isValid = default;
try
{
isValid = VerifyCodeSignature();
success = true;
}
catch (DllNotFoundException)
{
logger.Warn("Integrity module is not present!");
}
catch (Exception e)
{
logger.Error("Unexpected error while attempting to verify code signature!", e);
}
return success;
}
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string CalculateBrowserExamKey(string configurationKey, string salt);
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern bool VerifyCodeSignature();
}
}

View file

@ -16,7 +16,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DefineConstants>TRACE;DEBUG;X86</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
@ -24,7 +24,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<DefineConstants>TRACE;X86</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
@ -74,6 +74,7 @@
<Compile Include="ConfigurationData\Keys.cs" />
<Compile Include="ConfigurationData\DataValues.cs" />
<Compile Include="Cryptography\CertificateStore.cs" />
<Compile Include="Integrity\IntegrityModule.cs" />
<Compile Include="Cryptography\KeyGenerator.cs" />
<Compile Include="DataCompression\GZipCompressor.cs" />
<Compile Include="Cryptography\PasswordEncryption.cs" />

View file

@ -65,11 +65,12 @@ namespace SafeExamBrowser.I18n.Contracts
LockScreen_DisplayConfigurationContinueOption,
LockScreen_DisplayConfigurationTerminateOption,
LockScreen_DisplayConfigurationMessage,
LockScreen_IntegrityMessage,
LockScreen_Title,
LockScreen_UnlockButton,
LockScreen_UserSessionContinueOption,
LockScreen_UserSessionMessage,
LockScreen_UserSessionTerminateOption,
LockScreen_Title,
LockScreen_UnlockButton,
LogWindow_AlwaysOnTop,
LogWindow_AutoScroll,
LogWindow_Title,
@ -193,6 +194,7 @@ namespace SafeExamBrowser.I18n.Contracts
OperationStatus_ValidateDisplayConfiguration,
OperationStatus_ValidateRemoteSessionPolicy,
OperationStatus_ValidateVirtualMachinePolicy,
OperationStatus_VerifyApplicationIntegrity,
OperationStatus_WaitDisclaimerConfirmation,
OperationStatus_WaitExplorerStartup,
OperationStatus_WaitExplorerTermination,

View file

@ -153,6 +153,9 @@
<Entry key="LockScreen_DisplayConfigurationMessage">
Eine verbotene Bildschirm-Konfiguration wurde detektiert. Bitte wählen Sie eine der verfügbaren Optionen aus und geben Sie das korrekte Passwort ein, um SEB zu entsperren.
</Entry>
<Entry key="LockScreen_IntegrityMessage">
Sie verwenden eine inoffizielle SEB-Version! Bitte stellen Sie sicher, dass Sie einen offiziellen Safe Exam Browser verwenden. Geben Sie bitte das korrekte Passwort ein, um SEB zu entsperren.
</Entry>
<Entry key="LockScreen_Title">
SEB GESPERRT
</Entry>
@ -537,6 +540,9 @@
<Entry key="OperationStatus_ValidateVirtualMachinePolicy">
Validiere Richtlinie für virtuelle Maschinen
</Entry>
<Entry key="OperationStatus_VerifyApplicationIntegrity">
Überprüfe Integrität
</Entry>
<Entry key="OperationStatus_WaitDisclaimerConfirmation">
Warte auf die Bestätigung des Hinweises zur Fernüberwachung
</Entry>

View file

@ -153,6 +153,9 @@
<Entry key="LockScreen_DisplayConfigurationMessage">
A prohibited display configuration has been detected. In order to unlock SEB, please select one of the available options and enter the correct unlock password.
</Entry>
<Entry key="LockScreen_IntegrityMessage">
You are using an unofficial SEB version! Please make sure to use an official Safe Exam Browser. In order to unlock SEB, please enter the correct unlock password.
</Entry>
<Entry key="LockScreen_Title">
SEB LOCKED
</Entry>
@ -537,6 +540,9 @@
<Entry key="OperationStatus_ValidateVirtualMachinePolicy">
Validating virtual machine policy
</Entry>
<Entry key="OperationStatus_VerifyApplicationIntegrity">
Verifying integrity
</Entry>
<Entry key="OperationStatus_WaitDisclaimerConfirmation">
Waiting for confirmation of the disclaimer
</Entry>

View file

@ -153,6 +153,9 @@
<Entry key="LockScreen_DisplayConfigurationMessage">
Une configuration d'affichage interdite a été détectée. Pour déverrouiller SEB, veuillez sélectionner l'une des options disponibles et saisir le mot de passe de déverrouillage correct.
</Entry>
<Entry key="LockScreen_IntegrityMessage">
Vous utilisez une version non officielle de SEB! Assurez-vous d'utiliser un Safe Exam Browser officiel. Afin de déverrouiller SEB, veuillez entrer le mot de passe de déverrouillage correct.
</Entry>
<Entry key="LockScreen_Title">
SEB VEROUILLE
</Entry>
@ -537,6 +540,9 @@
<Entry key="OperationStatus_ValidateVirtualMachinePolicy">
Validation de la directive sur les machines virtuelles
</Entry>
<Entry key="OperationStatus_VerifyApplicationIntegrity">
Vérification de l'intégrité
</Entry>
<Entry key="OperationStatus_WaitDisclaimerConfirmation">
En attente de confirmation de la clause de non-responsabilité
</Entry>

View file

@ -153,6 +153,9 @@
<Entry key="LockScreen_DisplayConfigurationMessage">
È stata rilevata una configurazione di visualizzazione vietata. Per sbloccare SEB, seleziona una delle opzioni disponibili e inserisci la password di sblocco corretta.
</Entry>
<Entry key="LockScreen_IntegrityMessage">
Stai usando una versione SEB non ufficiale! Assicurati di utilizzare un Safe Exam Browser ufficiale. Per sbloccare SEB, inserisci la password di sblocco corretta.
</Entry>
<Entry key="LockScreen_Title">
SEB BLOCCATO
</Entry>
@ -537,6 +540,9 @@
<Entry key="OperationStatus_ValidateVirtualMachinePolicy">
Convalida dei criteri della macchina virtuale
</Entry>
<Entry key="OperationStatus_VerifyApplicationIntegrity">
Verifica dell'integrità
</Entry>
<Entry key="OperationStatus_WaitDisclaimerConfirmation">
In attesa di conferma del disclaimer
</Entry>

View file

@ -138,6 +138,9 @@
<Entry key="LockScreen_DisplayConfigurationMessage">
检测到禁止的显示配置。 要解锁 SEB请选择可用选项之一并输入正确的解锁密码。
</Entry>
<Entry key="LockScreen_IntegrityMessage">
您使用的是非官方 SEB 版本! 请确保使用官方的安全考试浏览器。 要解锁 SEB请输入正确的解锁密码。
</Entry>
<Entry key="LockScreen_Title">
防作弊考试专用浏览器已锁定
</Entry>
@ -492,6 +495,9 @@
<Entry key="OperationStatus_ValidateVirtualMachinePolicy">
验证虚拟机策略
</Entry>
<Entry key="OperationStatus_VerifyApplicationIntegrity">
验证完整性
</Entry>
<Entry key="OperationStatus_WaitDisclaimerConfirmation">
等待确认免责声明
</Entry>

View file

@ -17,6 +17,7 @@ using SafeExamBrowser.Configuration.Cryptography;
using SafeExamBrowser.Configuration.DataCompression;
using SafeExamBrowser.Configuration.DataFormats;
using SafeExamBrowser.Configuration.DataResources;
using SafeExamBrowser.Configuration.Integrity;
using SafeExamBrowser.Core.Contracts.OperationModel;
using SafeExamBrowser.Core.OperationModel;
using SafeExamBrowser.Core.Operations;
@ -63,6 +64,7 @@ namespace SafeExamBrowser.Runtime
var userInfo = new UserInfo(ModuleLogger(nameof(UserInfo)));
var args = Environment.GetCommandLineArgs();
var integrityModule = new IntegrityModule(ModuleLogger(nameof(IntegrityModule)));
var desktopFactory = new DesktopFactory(ModuleLogger(nameof(DesktopFactory)));
var desktopMonitor = new DesktopMonitor(ModuleLogger(nameof(DesktopMonitor)));
var displayMonitor = new DisplayMonitor(ModuleLogger(nameof(DisplayMonitor)), nativeMethods, systemInfo);
@ -85,6 +87,7 @@ namespace SafeExamBrowser.Runtime
bootstrapOperations.Enqueue(new I18nOperation(logger, text));
bootstrapOperations.Enqueue(new CommunicationHostOperation(runtimeHost, logger));
bootstrapOperations.Enqueue(new IntegrityOperation(integrityModule, logger));
sessionOperations.Enqueue(new SessionInitializationOperation(configuration, fileSystem, logger, runtimeHost, sessionContext));
sessionOperations.Enqueue(new ConfigurationOperation(args, configuration, new FileSystem(), new HashAlgorithm(), logger, sessionContext));

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2022 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.Configuration.Contracts.Integrity;
using SafeExamBrowser.Core.Contracts.OperationModel;
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
namespace SafeExamBrowser.Runtime.Operations
{
internal class IntegrityOperation : IOperation
{
private readonly IIntegrityModule module;
private readonly ILogger logger;
public event ActionRequiredEventHandler ActionRequired { add { } remove { } }
public event StatusChangedEventHandler StatusChanged;
public IntegrityOperation(IIntegrityModule module, ILogger logger)
{
this.module = module;
this.logger = logger;
}
public OperationResult Perform()
{
logger.Info($"Attempting to verify application integrity...");
StatusChanged?.Invoke(TextKey.OperationStatus_VerifyApplicationIntegrity);
if (module.TryVerifyCodeSignature(out var isValid))
{
if (isValid)
{
logger.Info("Application integrity successfully verified.");
}
else
{
logger.Warn("Application integrity is compromised!");
}
}
else
{
logger.Warn("Failed to verify application integrity!");
}
return OperationResult.Success;
}
public OperationResult Revert()
{
return OperationResult.Success;
}
}
}

View file

@ -106,6 +106,7 @@
<Compile Include="Operations\Events\PasswordRequiredEventArgs.cs" />
<Compile Include="Operations\Events\ServerFailureEventArgs.cs" />
<Compile Include="Operations\Events\UnexpectedErrorMessageArgs.cs" />
<Compile Include="Operations\IntegrityOperation.cs" />
<Compile Include="Operations\KioskModeOperation.cs" />
<Compile Include="Operations\ProctoringWorkaroundOperation.cs" />
<Compile Include="Operations\RemoteSessionOperation.cs" />