123 lines
3.4 KiB
C#
123 lines
3.4 KiB
C#
/*
|
|
* Copyright (c) 2025 ETH Zürich, IT Services
|
|
*
|
|
* 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.Linq;
|
|
using System.Threading.Tasks;
|
|
using SafeExamBrowser.Configuration.Contracts.Integrity;
|
|
using SafeExamBrowser.I18n.Contracts;
|
|
using SafeExamBrowser.Logging.Contracts;
|
|
using SafeExamBrowser.UserInterface.Contracts.Windows.Data;
|
|
|
|
namespace SafeExamBrowser.Client.Responsibilities
|
|
{
|
|
internal class IntegrityResponsibility : ClientResponsibility
|
|
{
|
|
private readonly IText text;
|
|
|
|
private IIntegrityModule IntegrityModule => Context.IntegrityModule;
|
|
|
|
public IntegrityResponsibility(ClientContext context, ILogger logger, IText text) : base(context, logger)
|
|
{
|
|
this.text = text;
|
|
}
|
|
|
|
public override void Assume(ClientTask task)
|
|
{
|
|
switch (task)
|
|
{
|
|
case ClientTask.ScheduleIntegrityVerification:
|
|
ScheduleIntegrityVerification();
|
|
break;
|
|
case ClientTask.UpdateSessionIntegrity:
|
|
UpdateSessionIntegrity();
|
|
break;
|
|
case ClientTask.VerifySessionIntegrity:
|
|
VerifySessionIntegrity();
|
|
break;
|
|
}
|
|
}
|
|
|
|
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) => VerifyApplicationIntegrity();
|
|
timer.Interval = TEN_MINUTES + (new Random().NextDouble() * FIVE_MINUTES);
|
|
timer.Start();
|
|
}
|
|
|
|
private void UpdateSessionIntegrity()
|
|
{
|
|
var hasQuitPassword = !string.IsNullOrEmpty(Settings?.Security.QuitPasswordHash);
|
|
|
|
if (hasQuitPassword)
|
|
{
|
|
IntegrityModule?.ClearSession(Settings.Browser.ConfigurationKey, Settings.Browser.StartUrl);
|
|
}
|
|
}
|
|
|
|
private void VerifyApplicationIntegrity()
|
|
{
|
|
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_ApplicationIntegrityMessage), text.Get(TextKey.LockScreen_Title), Enumerable.Empty<LockScreenOption>());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Logger.Warn("Failed to verify application integrity!");
|
|
}
|
|
}
|
|
|
|
private void VerifySessionIntegrity()
|
|
{
|
|
var hasQuitPassword = !string.IsNullOrEmpty(Settings.Security.QuitPasswordHash);
|
|
|
|
if (hasQuitPassword && Settings.Security.VerifySessionIntegrity)
|
|
{
|
|
Logger.Info($"Attempting to verify session integrity...");
|
|
|
|
if (IntegrityModule.TryVerifySessionIntegrity(Settings.Browser.ConfigurationKey, Settings.Browser.StartUrl, out var isValid))
|
|
{
|
|
if (isValid)
|
|
{
|
|
Logger.Info("Session integrity successfully verified.");
|
|
IntegrityModule.CacheSession(Settings.Browser.ConfigurationKey, Settings.Browser.StartUrl);
|
|
}
|
|
else
|
|
{
|
|
Logger.Warn("Session integrity is compromised!");
|
|
Task.Delay(1000).ContinueWith(_ =>
|
|
{
|
|
ShowLockScreen(text.Get(TextKey.LockScreen_SessionIntegrityMessage), text.Get(TextKey.LockScreen_Title), Enumerable.Empty<LockScreenOption>());
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Logger.Warn("Failed to verify session integrity!");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|