SEBWIN-633: Fixed ease of access exploit.

This commit is contained in:
Damian Büchel 2022-12-21 05:37:03 +01:00
parent 3bd786543d
commit f0aecb06d9
19 changed files with 417 additions and 22 deletions

View file

@ -33,6 +33,7 @@ using SafeExamBrowser.Server.Contracts;
using SafeExamBrowser.Server.Contracts.Data;
using SafeExamBrowser.Settings;
using SafeExamBrowser.Settings.Monitoring;
using SafeExamBrowser.SystemComponents.Contracts.Registry;
using SafeExamBrowser.UserInterface.Contracts;
using SafeExamBrowser.UserInterface.Contracts.FileSystemDialog;
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
@ -60,6 +61,7 @@ namespace SafeExamBrowser.Client.UnitTests
private Mock<ILogger> logger;
private Mock<IMessageBox> messageBox;
private Mock<IOperationSequence> operationSequence;
private Mock<IRegistry> registry;
private Mock<IRuntimeProxy> runtimeProxy;
private Mock<IServerProxy> server;
private Guid sessionId;
@ -92,6 +94,7 @@ namespace SafeExamBrowser.Client.UnitTests
logger = new Mock<ILogger>();
messageBox = new Mock<IMessageBox>();
operationSequence = new Mock<IOperationSequence>();
registry = new Mock<IRegistry>();
runtimeProxy = new Mock<IRuntimeProxy>();
server = new Mock<IServerProxy>();
sessionId = Guid.NewGuid();
@ -119,6 +122,7 @@ namespace SafeExamBrowser.Client.UnitTests
logger.Object,
messageBox.Object,
operationSequence.Object,
registry.Object,
runtimeProxy.Object,
shutdown.Object,
splashScreen.Object,

View file

@ -33,6 +33,7 @@ using SafeExamBrowser.Monitoring.Contracts.System;
using SafeExamBrowser.Server.Contracts;
using SafeExamBrowser.Server.Contracts.Data;
using SafeExamBrowser.Settings;
using SafeExamBrowser.SystemComponents.Contracts.Registry;
using SafeExamBrowser.UserInterface.Contracts;
using SafeExamBrowser.UserInterface.Contracts.FileSystemDialog;
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
@ -55,6 +56,7 @@ namespace SafeExamBrowser.Client
private readonly ILogger logger;
private readonly IMessageBox messageBox;
private readonly IOperationSequence operations;
private readonly IRegistry registry;
private readonly IRuntimeProxy runtime;
private readonly Action shutdown;
private readonly ISplashScreen splashScreen;
@ -83,6 +85,7 @@ namespace SafeExamBrowser.Client
ILogger logger,
IMessageBox messageBox,
IOperationSequence operations,
IRegistry registry,
IRuntimeProxy runtime,
Action shutdown,
ISplashScreen splashScreen,
@ -101,6 +104,7 @@ namespace SafeExamBrowser.Client
this.logger = logger;
this.messageBox = messageBox;
this.operations = operations;
this.registry = registry;
this.runtime = runtime;
this.shutdown = shutdown;
this.splashScreen = splashScreen;
@ -167,6 +171,7 @@ namespace SafeExamBrowser.Client
CloseShell();
DeregisterEvents();
UpdateSessionIntegrity();
TerminateIntegrityVerification();
var success = operations.TryRevert() == OperationResult.Success;
@ -206,6 +211,7 @@ namespace SafeExamBrowser.Client
ClientHost.ServerFailureActionRequested += ClientHost_ServerFailureActionRequested;
ClientHost.Shutdown += ClientHost_Shutdown;
displayMonitor.DisplayChanged += DisplayMonitor_DisplaySettingsChanged;
registry.ValueChanged += Registry_ValueChanged;
runtime.ConnectionLost += Runtime_ConnectionLost;
systemMonitor.SessionSwitched += SystemMonitor_SessionSwitched;
taskbar.LoseFocusRequested += Taskbar_LoseFocusRequested;
@ -240,6 +246,7 @@ namespace SafeExamBrowser.Client
applicationMonitor.ExplorerStarted -= ApplicationMonitor_ExplorerStarted;
applicationMonitor.TerminationFailed -= ApplicationMonitor_TerminationFailed;
displayMonitor.DisplayChanged -= DisplayMonitor_DisplaySettingsChanged;
registry.ValueChanged -= Registry_ValueChanged;
runtime.ConnectionLost -= Runtime_ConnectionLost;
systemMonitor.SessionSwitched -= SystemMonitor_SessionSwitched;
taskbar.QuitButtonClicked -= Shell_QuitButtonClicked;
@ -351,6 +358,8 @@ namespace SafeExamBrowser.Client
};
timer.Interval = TEN_MINUTES + (new Random().NextDouble() * FIVE_MINUTES);
timer.Start();
registry.StartMonitoring(RegistryKey.MachineHive.EaseOfAccess_Key, RegistryKey.MachineHive.EaseOfAccess_Name);
}
private void VerifySessionIntegrity()
@ -394,6 +403,11 @@ namespace SafeExamBrowser.Client
}
}
private void TerminateIntegrityVerification()
{
registry.StopMonitoring();
}
private void ApplicationMonitor_ExplorerStarted()
{
logger.Info("Trying to terminate Windows explorer...");
@ -681,6 +695,40 @@ namespace SafeExamBrowser.Client
splashScreen.UpdateStatus(status, true);
}
private void Registry_ValueChanged(object oldValue, object newValue)
{
logger.Warn($"The ease of access registry value has changed from '{oldValue}' to '{newValue}'! Attempting to show lock screen...");
if (!sessionLocked)
{
var message = text.Get(TextKey.LockScreen_EaseOfAccessMessage);
var title = text.Get(TextKey.LockScreen_Title);
var continueOption = new LockScreenOption { Text = text.Get(TextKey.LockScreen_EaseOfAccessContinueOption) };
var terminateOption = new LockScreenOption { Text = text.Get(TextKey.LockScreen_EaseOfAccessTerminateOption) };
sessionLocked = true;
registry.StopMonitoring();
var result = ShowLockScreen(message, title, new[] { continueOption, terminateOption });
if (result.OptionId == continueOption.Id)
{
logger.Info("The session will be allowed to resume as requested by the user...");
}
else if (result.OptionId == terminateOption.Id)
{
logger.Info("Attempting to shutdown as requested by the user...");
TryRequestShutdown();
}
sessionLocked = false;
}
else
{
logger.Info("Lock screen is already active.");
}
}
private void Runtime_ConnectionLost()
{
logger.Error("Lost connection to the runtime!");

View file

@ -45,6 +45,7 @@ using SafeExamBrowser.SystemComponents.Contracts.PowerSupply;
using SafeExamBrowser.SystemComponents.Keyboard;
using SafeExamBrowser.SystemComponents.Network;
using SafeExamBrowser.SystemComponents.PowerSupply;
using SafeExamBrowser.SystemComponents.Registry;
using SafeExamBrowser.UserInterface.Contracts;
using SafeExamBrowser.UserInterface.Contracts.FileSystemDialog;
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
@ -113,6 +114,7 @@ namespace SafeExamBrowser.Client
var explorerShell = new ExplorerShell(ModuleLogger(nameof(ExplorerShell)), nativeMethods);
var fileSystemDialog = BuildFileSystemDialog();
var hashAlgorithm = new HashAlgorithm();
var registry = new Registry(ModuleLogger(nameof(Registry)));
var splashScreen = uiFactory.CreateSplashScreen();
var systemMonitor = new SystemMonitor(ModuleLogger(nameof(SystemMonitor)));
@ -149,6 +151,7 @@ namespace SafeExamBrowser.Client
logger,
messageBox,
sequence,
registry,
runtimeProxy,
shutdown,
splashScreen,

View file

@ -65,8 +65,11 @@ namespace SafeExamBrowser.I18n.Contracts
LockScreen_ApplicationsMessage,
LockScreen_ApplicationsTerminateOption,
LockScreen_DisplayConfigurationContinueOption,
LockScreen_DisplayConfigurationTerminateOption,
LockScreen_DisplayConfigurationMessage,
LockScreen_DisplayConfigurationTerminateOption,
LockScreen_EaseOfAccessContinueOption,
LockScreen_EaseOfAccessMessage,
LockScreen_EaseOfAccessTerminateOption,
LockScreen_SessionIntegrityMessage,
LockScreen_Title,
LockScreen_UnlockButton,
@ -197,6 +200,7 @@ namespace SafeExamBrowser.I18n.Contracts
OperationStatus_ValidateRemoteSessionPolicy,
OperationStatus_ValidateVirtualMachinePolicy,
OperationStatus_VerifyApplicationIntegrity,
OperationStatus_VerifySessionIntegrity,
OperationStatus_WaitDisclaimerConfirmation,
OperationStatus_WaitExplorerStartup,
OperationStatus_WaitExplorerTermination,

View file

@ -153,11 +153,20 @@
<Entry key="LockScreen_DisplayConfigurationContinueOption">
Bildschirm-Konfiguration temporär erlauben. Dies gilt nur für die momentan laufende Sitzung!
</Entry>
<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_DisplayConfigurationTerminateOption">
Safe Exam Browser beenden. WARNUNG: Sie werden keine Möglichkeit haben, Daten zu speichern oder weitere Aktionen auszuführen, SEB wird sofort beendet!
</Entry>
<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 key="LockScreen_EaseOfAccessContinueOption">
Barrierefreiheit-Konfiguration temporär erlauben. Dies gilt nur für die momentan laufende Sitzung!
</Entry>
<Entry key="LockScreen_EaseOfAccessMessage">
Eine verbotene Barrierefreiheit-Konfiguration für den Windows Security Screen 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_EaseOfAccessTerminateOption">
Safe Exam Browser beenden. WARNUNG: Sie werden keine Möglichkeit haben, Daten zu speichern oder weitere Aktionen auszuführen, SEB wird sofort beendet!
</Entry>
<Entry key="LockScreen_SessionIntegrityMessage">
Die letzte Sitzung mit der momentan aktiven Konfiguration oder Start-URL wurde nicht ordnungsgemäss beendet! Geben Sie bitte das korrekte Passwort ein, um SEB zu entsperren.
@ -549,6 +558,9 @@
<Entry key="OperationStatus_VerifyApplicationIntegrity">
Überprüfe Integrität
</Entry>
<Entry key="OperationStatus_VerifySessionIntegrity">
Überprüfe Integrität der Sitzung
</Entry>
<Entry key="OperationStatus_WaitDisclaimerConfirmation">
Warte auf die Bestätigung des Hinweises zur Fernüberwachung
</Entry>

View file

@ -153,11 +153,20 @@
<Entry key="LockScreen_DisplayConfigurationContinueOption">
Temporarily allow the display configuration. This applies only to the currently running session!
</Entry>
<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_DisplayConfigurationTerminateOption">
Terminate Safe Exam Browser. WARNING: There will be no possibility to save data or perform any further actions, the shutdown will be initiated immediately!
</Entry>
<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 key="LockScreen_EaseOfAccessContinueOption">
Temporarily allow the ease of access configuration. This applies only to the currently running session!
</Entry>
<Entry key="LockScreen_EaseOfAccessMessage">
A prohibited ease of access configuration for the Windows Security Screen 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_EaseOfAccessTerminateOption">
Terminate Safe Exam Browser. WARNING: There will be no possibility to save data or perform any further actions, the shutdown will be initiated immediately!
</Entry>
<Entry key="LockScreen_SessionIntegrityMessage">
The last session with the currently active configuration or start URL was not terminated properly! Please enter the correct password to unlock SEB.
@ -549,6 +558,9 @@
<Entry key="OperationStatus_VerifyApplicationIntegrity">
Verifying integrity
</Entry>
<Entry key="OperationStatus_VerifySessionIntegrity">
Verifying session integrity
</Entry>
<Entry key="OperationStatus_WaitDisclaimerConfirmation">
Waiting for confirmation of the disclaimer
</Entry>

View file

@ -148,17 +148,26 @@
Les applications sur liste noire énumérées ci-dessous ont été lancées et nont pas pu être automatiquement supprimées! Afin de débloquer SEB, veuillez sélectionner l'une des options disponibles et entrer le mot de passe de déblocage.
</Entry>
<Entry key="LockScreen_ApplicationsTerminateOption">
Terminer Safe Exam Browser. AVERTISSEMENT: Il n'y aura pas de possibilité de sauvegarder les données ou d'effectuer d'autres actions, l'arrêt sera déclenché immédiatement!
Terminer Safe Exam Browser. AVERTISSEMENT: Il n'y aura aucune possibilité de sauvegarder les données ou d'effectuer d'autres actions, la fermeture sera initiée immédiatement!
</Entry>
<Entry key="LockScreen_DisplayConfigurationContinueOption">
Autoriser temporairement la configuration de l'affichage. Ceci s'applique uniquement à la session en cours!
</Entry>
<Entry key="LockScreen_DisplayConfigurationTerminateOption">
Terminez le navigateur Safe Exam. AVERTISSEMENT: Il n'y aura aucune possibilité de sauvegarder des données ou d'effectuer d'autres actions, l'arrêt sera déclenché immédiatement!
</Entry>
<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_DisplayConfigurationTerminateOption">
Terminer Safe Exam Browser. AVERTISSEMENT: Il n'y aura aucune possibilité de sauvegarder les données ou d'effectuer d'autres actions, la fermeture sera initiée immédiatement!
</Entry>
<Entry key="LockScreen_EaseOfAccessContinueOption">
Autoriser temporairement la configuration de la facilité d'accès. Ceci s'applique uniquement à la session en cours!
</Entry>
<Entry key="LockScreen_EaseOfAccessMessage">
Une configuration de facilité d'accès interdite pour l'écran de sécurité de Windows a été détectée. Afin de déverrouiller le SEB, veuillez sélectionner l'une des options disponibles et saisir le mot de passe de déverrouillage correct.
</Entry>
<Entry key="LockScreen_EaseOfAccessTerminateOption">
Terminer Safe Exam Browser. AVERTISSEMENT: Il n'y aura aucune possibilité de sauvegarder les données ou d'effectuer d'autres actions, la fermeture sera initiée immédiatement!
</Entry>
<Entry key="LockScreen_SessionIntegrityMessage">
La dernière session avec la configuration ou l'URL de démarrage actuellement active n'a pas été terminée correctement! Afin de déverrouiller SEB, veuillez entrer le mot de passe de déverrouillage correct.
</Entry>
@ -175,7 +184,7 @@
L'utilisateur actif a changé ou l'ordinateur a été verrouillé! Afin de déverrouiller SEB, veuillez sélectionner une des options disponibles et entrer le mot de passe de déverrouillage.
</Entry>
<Entry key="LockScreen_UserSessionTerminateOption">
Terminer Safe Exam Browser. AVERTISSEMENT: Il n'y aura pas de possibilité de sauvegarder les données ou d'effectuer d'autres actions, l'arrêt sera déclenché immédiatement!
Terminer Safe Exam Browser. AVERTISSEMENT: Il n'y aura aucune possibilité de sauvegarder les données ou d'effectuer d'autres actions, la fermeture sera initiée immédiatement!
</Entry>
<Entry key="LogWindow_AlwaysOnTop">
Toujours au premier plan
@ -549,6 +558,9 @@
<Entry key="OperationStatus_VerifyApplicationIntegrity">
Vérification de l'intégrité
</Entry>
<Entry key="OperationStatus_VerifySessionIntegrity">
Vérification de l'intégrité de la session
</Entry>
<Entry key="OperationStatus_WaitDisclaimerConfirmation">
En attente de confirmation de la clause de non-responsabilité
</Entry>

View file

@ -148,17 +148,26 @@
Le applicazioni nella lista nera elencate di seguito sono state avviate e non è stato possibile terminare automaticamente! Per sbloccare SEB, seleziona una delle opzioni disponibili e inserisci la password di sblocco corretta.
</Entry>
<Entry key="LockScreen_ApplicationsTerminateOption">
Chiudi Safe Exam Browser. ATTENZIONE: non ci sarà la possibilità di salvare dati o eseguire ulteriori azioni, lo spegnimento verrà avviato immediatamente!
Terminare Safe Exam Browser. ATTENZIONE: Non sarà possibile salvare i dati o eseguire ulteriori azioni, la chiusura verrà avviata immediatamente!
</Entry>
<Entry key="LockScreen_DisplayConfigurationContinueOption">
Consenti temporaneamente la configurazione del display. Questo vale solo per la sessione attualmente in esecuzione!
</Entry>
<Entry key="LockScreen_DisplayConfigurationTerminateOption">
Termina Browser esame sicuro. ATTENZIONE: non sarà possibile salvare i dati o eseguire ulteriori azioni, lo spegnimento verrà avviato immediatamente!
</Entry>
<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_DisplayConfigurationTerminateOption">
Terminare Safe Exam Browser. ATTENZIONE: Non sarà possibile salvare i dati o eseguire ulteriori azioni, la chiusura verrà avviata immediatamente!
</Entry>
<Entry key="LockScreen_EaseOfAccessContinueOption">
Consente temporaneamente la configurazione della facilità di accesso. Questo vale solo per la sessione in corso!
</Entry>
<Entry key="LockScreen_EaseOfAccessMessage">
È stata rilevata una configurazione di facilità di accesso non consentita per la schermata di sicurezza di Windows. Per sbloccare SEB, seleziona una delle opzioni disponibili e inserisci la password di sblocco corretta.
</Entry>
<Entry key="LockScreen_EaseOfAccessTerminateOption">
Terminare Safe Exam Browser. ATTENZIONE: Non sarà possibile salvare i dati o eseguire ulteriori azioni, la chiusura verrà avviata immediatamente!
</Entry>
<Entry key="LockScreen_SessionIntegrityMessage">
L'ultima sessione con la configurazione o l'URL di avvio attualmente attiva non è stata terminata correttamente! Per sbloccare SEB, inserisci la password di sblocco corretta.
</Entry>
@ -175,7 +184,7 @@
L'utente attivo è cambiato o il computer è stato bloccato! Per sbloccare SEB, seleziona una delle opzioni disponibili e inserisci la password di sblocco corretta.
</Entry>
<Entry key="LockScreen_UserSessionTerminateOption">
Chiudi Safe Exam Browser. ATTENZIONE: non ci sarà la possibilità di salvare dati o eseguire ulteriori azioni, lo spegnimento verrà avviato immediatamente!
Terminare Safe Exam Browser. ATTENZIONE: Non sarà possibile salvare i dati o eseguire ulteriori azioni, la chiusura verrà avviata immediatamente!
</Entry>
<Entry key="LogWindow_AlwaysOnTop">
Sempre in cima
@ -549,6 +558,9 @@
<Entry key="OperationStatus_VerifyApplicationIntegrity">
Verifica dell'integrità
</Entry>
<Entry key="OperationStatus_VerifySessionIntegrity">
Verifica dell'integrità della sessione
</Entry>
<Entry key="OperationStatus_WaitDisclaimerConfirmation">
In attesa di conferma del disclaimer
</Entry>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Text>
<Entry key="AboutWindow_LicenseInfo">
此应用程序受Mozilla Public License, 版本 2.0 的条款约束。汉化人272881521@qq.com。防作弊考试专用浏览器使用以下框架和第三方知识库:
此应用程序受Mozilla Public License, 版本 2.0 的条款约束。防作弊考试专用浏览器使用以下框架和第三方知识库:
</Entry>
<Entry key="AboutWindow_Title">
版本 &amp; 许可证信息
@ -138,11 +138,20 @@
<Entry key="LockScreen_DisplayConfigurationContinueOption">
暂时允许显示配置。 这仅适用于当前正在运行的会话!
</Entry>
<Entry key="LockScreen_DisplayConfigurationMessage">
检测到禁止的显示配置。 要解锁 SEB请选择可用选项之一并输入正确的解锁密码。
</Entry>
<Entry key="LockScreen_DisplayConfigurationTerminateOption">
终止安全考试浏览器。 警告:将无法保存数据或执行任何进一步操作,将立即启动关机!
</Entry>
<Entry key="LockScreen_DisplayConfigurationMessage">
检测到禁止的显示配置。 要解锁 SEB请选择可用选项之一并输入正确的解锁密码。
<Entry key="LockScreen_EaseOfAccessContinueOption">
暂时允许轻松访问的配置。这只适用于当前运行的会话!
</Entry>
<Entry key="LockScreen_EaseOfAccessMessage">
检测到一个被禁止的Windows安全屏幕的访问方便配置。为了解锁SEB请选择一个可用的选项并输入正确的解锁密码。
</Entry>
<Entry key="LockScreen_EaseOfAccessTerminateOption">
终止安全考试浏览器。警告:将没有可能保存数据或执行任何进一步的行动,关闭将立即启动!
</Entry>
<Entry key="LockScreen_SessionIntegrityMessage">
当前激活的配置或启动URL的最后一个会话没有被正确终止! 请输入正确的密码以解锁SEB。
@ -504,6 +513,9 @@
<Entry key="OperationStatus_VerifyApplicationIntegrity">
验证完整性
</Entry>
<Entry key="OperationStatus_VerifySessionIntegrity">
验证会话的完整性
</Entry>
<Entry key="OperationStatus_WaitDisclaimerConfirmation">
等待确认免责声明
</Entry>

View file

@ -32,6 +32,7 @@ using SafeExamBrowser.Server;
using SafeExamBrowser.Settings.Logging;
using SafeExamBrowser.SystemComponents;
using SafeExamBrowser.SystemComponents.Contracts;
using SafeExamBrowser.SystemComponents.Registry;
using SafeExamBrowser.UserInterface.Desktop;
using SafeExamBrowser.WindowsApi;
@ -73,6 +74,7 @@ namespace SafeExamBrowser.Runtime
var messageBox = new MessageBoxFactory(text);
var processFactory = new ProcessFactory(ModuleLogger(nameof(ProcessFactory)));
var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), ModuleLogger(nameof(ProxyFactory)));
var registry = new Registry(ModuleLogger(nameof(Registry)));
var remoteSessionDetector = new RemoteSessionDetector(ModuleLogger(nameof(RemoteSessionDetector)));
var runtimeHost = new RuntimeHost(appConfig.RuntimeAddress, new HostObjectFactory(), ModuleLogger(nameof(RuntimeHost)), FIVE_SECONDS);
var runtimeWindow = uiFactory.CreateRuntimeWindow(appConfig);
@ -87,13 +89,14 @@ namespace SafeExamBrowser.Runtime
bootstrapOperations.Enqueue(new I18nOperation(logger, text));
bootstrapOperations.Enqueue(new CommunicationHostOperation(runtimeHost, logger));
bootstrapOperations.Enqueue(new IntegrityOperation(integrityModule, logger));
bootstrapOperations.Enqueue(new ApplicationIntegrityOperation(integrityModule, logger));
sessionOperations.Enqueue(new SessionInitializationOperation(configuration, fileSystem, logger, runtimeHost, sessionContext));
sessionOperations.Enqueue(new ConfigurationOperation(args, configuration, new FileSystem(), new HashAlgorithm(), logger, sessionContext));
sessionOperations.Enqueue(new ServerOperation(args, configuration, fileSystem, logger, sessionContext, server));
sessionOperations.Enqueue(new DisclaimerOperation(logger, sessionContext));
sessionOperations.Enqueue(new RemoteSessionOperation(remoteSessionDetector, logger, sessionContext));
sessionOperations.Enqueue(new SessionIntegrityOperation(logger, registry, sessionContext));
sessionOperations.Enqueue(new VirtualMachineOperation(vmDetector, logger, sessionContext));
sessionOperations.Enqueue(new DisplayMonitorOperation(displayMonitor, logger, sessionContext, text));
sessionOperations.Enqueue(new ServiceOperation(logger, runtimeHost, serviceProxy, sessionContext, THIRTY_SECONDS, userInfo));

View file

@ -14,7 +14,7 @@ using SafeExamBrowser.Logging.Contracts;
namespace SafeExamBrowser.Runtime.Operations
{
internal class IntegrityOperation : IOperation
internal class ApplicationIntegrityOperation : IOperation
{
private readonly IIntegrityModule module;
private readonly ILogger logger;
@ -22,7 +22,7 @@ namespace SafeExamBrowser.Runtime.Operations
public event ActionRequiredEventHandler ActionRequired { add { } remove { } }
public event StatusChangedEventHandler StatusChanged;
public IntegrityOperation(IIntegrityModule module, ILogger logger)
public ApplicationIntegrityOperation(IIntegrityModule module, ILogger logger)
{
this.module = module;
this.logger = logger;

View file

@ -0,0 +1,81 @@
/*
* 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.Core.Contracts.OperationModel;
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
using SafeExamBrowser.I18n.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Registry;
namespace SafeExamBrowser.Runtime.Operations
{
internal class SessionIntegrityOperation : SessionOperation
{
private readonly ILogger logger;
private readonly IRegistry registry;
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
public override event StatusChangedEventHandler StatusChanged;
public SessionIntegrityOperation(ILogger logger, IRegistry registry, SessionContext context) : base(context)
{
this.logger = logger;
this.registry = registry;
}
public override OperationResult Perform()
{
StatusChanged?.Invoke(TextKey.OperationStatus_VerifySessionIntegrity);
return VerifyEaseOfAccessConfiguration();
}
public override OperationResult Repeat()
{
StatusChanged?.Invoke(TextKey.OperationStatus_VerifySessionIntegrity);
return VerifyEaseOfAccessConfiguration();
}
public override OperationResult Revert()
{
return OperationResult.Success;
}
private OperationResult VerifyEaseOfAccessConfiguration()
{
var result = OperationResult.Failed;
logger.Info($"Attempting to verify ease of access configuration...");
if (registry.TryRead(RegistryKey.MachineHive.EaseOfAccess_Key, RegistryKey.MachineHive.EaseOfAccess_Name, out var value))
{
if (value == default || (value is string s && string.IsNullOrWhiteSpace(s)))
{
result = OperationResult.Success;
logger.Info("Ease of access configuration successfully verified.");
}
else if (!Context.Next.Settings.Service.IgnoreService)
{
result = OperationResult.Success;
logger.Info($"Ease of access configuration is compromised ('{value}'), but service will be active in the next session.");
}
else
{
logger.Warn($"Ease of access configuration is compromised: '{value}'! Aborting session initialization...");
}
}
else
{
logger.Error("Failed to verify ease of access configuration!");
}
return result;
}
}
}

View file

@ -106,13 +106,14 @@
<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\ApplicationIntegrityOperation.cs" />
<Compile Include="Operations\KioskModeOperation.cs" />
<Compile Include="Operations\ProctoringWorkaroundOperation.cs" />
<Compile Include="Operations\RemoteSessionOperation.cs" />
<Compile Include="Operations\ServerOperation.cs" />
<Compile Include="Operations\ServiceOperation.cs" />
<Compile Include="Operations\SessionActivationOperation.cs" />
<Compile Include="Operations\SessionIntegrityOperation.cs" />
<Compile Include="Operations\SessionOperation.cs" />
<Compile Include="Operations\SessionInitializationOperation.cs" />
<Compile Include="Communication\RuntimeHost.cs" />

View file

@ -0,0 +1,15 @@
/*
* 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.SystemComponents.Contracts.Registry.Events
{
/// <summary>
/// Indicates that a registry value has changed.
/// </summary>
public delegate void RegistryValueChangedEventHandler(object oldValue, object newValue);
}

View file

@ -0,0 +1,38 @@
/*
* 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.SystemComponents.Contracts.Registry.Events;
namespace SafeExamBrowser.SystemComponents.Contracts.Registry
{
/// <summary>
/// Provides functionality related to the Windows registry.
/// </summary>
public interface IRegistry
{
/// <summary>
/// Fired when a registry value previously registred via <see cref="StartMonitoring(string, string)"/> has changed.
/// </summary>
event RegistryValueChangedEventHandler ValueChanged;
/// <summary>
/// Starts monitoring the specified registry value.
/// </summary>
void StartMonitoring(string key, string name);
/// <summary>
/// Stops the monitoring of all previously registered registry values.
/// </summary>
void StopMonitoring();
/// <summary>
/// Attempts to read the value of the given name under the specified registry key.
/// </summary>
bool TryRead(string key, string name, out object value);
}
}

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.SystemComponents.Contracts.Registry
{
/// <summary>
/// Defines registry keys and names used in conjunction with <see cref="IRegistry"/>. Use the pattern "LogicalGroup_Key" resp. "LogicalGroup_Name"
/// to allow for a better overview over all keys, names and their usage (where applicable).
/// </summary>
public static class RegistryKey
{
/// <summary>
/// All registry keys and names located in the machine hive.
/// </summary>
public static class MachineHive
{
public const string EaseOfAccess_Key = @"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\Utilman.exe";
public const string EaseOfAccess_Name = "Debugger";
}
}
}

View file

@ -57,6 +57,8 @@
<Compile Include="Audio\Events\VolumeChangedEventHandler.cs" />
<Compile Include="Audio\IAudio.cs" />
<Compile Include="IFileSystem.cs" />
<Compile Include="Registry\Events\RegistryValueChangedEventHandler.cs" />
<Compile Include="Registry\IRegistry.cs" />
<Compile Include="IRemoteSessionDetector.cs" />
<Compile Include="IVirtualMachineDetector.cs" />
<Compile Include="Network\ConnectionType.cs" />
@ -76,6 +78,7 @@
<Compile Include="PowerSupply\IPowerSupplyStatus.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Network\ConnectionStatus.cs" />
<Compile Include="Registry\RegistryKey.cs" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View file

@ -0,0 +1,108 @@
/*
* 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.Collections.Concurrent;
using System.Timers;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.SystemComponents.Contracts.Registry;
using SafeExamBrowser.SystemComponents.Contracts.Registry.Events;
namespace SafeExamBrowser.SystemComponents.Registry
{
public class Registry : IRegistry
{
private readonly ILogger logger;
private readonly ConcurrentBag<(string key, string name, object value)> values;
private Timer timer;
public event RegistryValueChangedEventHandler ValueChanged;
public Registry(ILogger logger)
{
this.logger = logger;
this.values = new ConcurrentBag<(string key, string name, object value)>();
}
public void StartMonitoring(string key, string name)
{
const int ONE_SECOND = 1000;
if (timer?.Enabled != true)
{
timer = new Timer(ONE_SECOND);
timer.AutoReset = true;
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
if (TryRead(key, name, out var value))
{
values.Add((key, name, value));
logger.Debug($"Started monitoring value '{name}' from registry key '{key}'. Initial value: '{value}'.");
}
else
{
logger.Error($"Failed to start monitoring value '{name}' from registry key '{key}'!");
}
}
public void StopMonitoring()
{
while (!values.IsEmpty)
{
values.TryTake(out _);
}
if (timer != null)
{
timer.Stop();
logger.Debug("Stopped monitoring the registry.");
}
}
public bool TryRead(string key, string name, out object value)
{
var success = true;
value = default;
try
{
value = Microsoft.Win32.Registry.GetValue(key, name, default);
}
catch (Exception e)
{
success = false;
logger.Error($"Failed to read value '{name}' from registry key '{key}'!", e);
}
return success;
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
foreach (var item in values)
{
if (TryRead(item.key, item.name, out var value))
{
if (item.value != value)
{
logger.Debug($"Value '{item.name}' from registry key '{item.key}' has changed from '{item.value}' to '{value}'!");
ValueChanged?.Invoke(item.value, value);
}
}
else
{
logger.Error($"Failed to monitor value '{item.name}' from registry key '{item.key}'!");
}
}
}
}
}

View file

@ -97,6 +97,7 @@
<Compile Include="PowerSupply\PowerSupply.cs" />
<Compile Include="PowerSupply\PowerSupplyStatus.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Registry\Registry.cs" />
<Compile Include="RemoteSessionDetector.cs" />
<Compile Include="SystemInfo.cs" />
<Compile Include="UserInfo.cs" />