Restore SEBPatch
This commit is contained in:
166
SafeExamBrowser.Service/Operations/LockdownOperation.cs
Normal file
166
SafeExamBrowser.Service/Operations/LockdownOperation.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.Collections.Generic;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Lockdown.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Service.Operations
|
||||
{
|
||||
internal class LockdownOperation : SessionOperation
|
||||
{
|
||||
private readonly IFeatureConfigurationBackup backup;
|
||||
private readonly IFeatureConfigurationFactory factory;
|
||||
private readonly IFeatureConfigurationMonitor monitor;
|
||||
private readonly ILogger logger;
|
||||
|
||||
private Guid groupId;
|
||||
|
||||
public LockdownOperation(
|
||||
IFeatureConfigurationBackup backup,
|
||||
IFeatureConfigurationFactory factory,
|
||||
IFeatureConfigurationMonitor monitor,
|
||||
ILogger logger,
|
||||
SessionContext sessionContext) : base(sessionContext)
|
||||
{
|
||||
this.backup = backup;
|
||||
this.factory = factory;
|
||||
this.monitor = monitor;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
groupId = Guid.NewGuid();
|
||||
|
||||
var success = true;
|
||||
var sid = Context.Configuration.UserSid;
|
||||
var userName = Context.Configuration.UserName;
|
||||
var configurations = new List<(IFeatureConfiguration, bool)>
|
||||
{
|
||||
(factory.CreateChangePasswordConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisablePasswordChange),
|
||||
(factory.CreateChromeNotificationConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableChromeNotifications),
|
||||
(factory.CreateEaseOfAccessConfiguration(groupId), Context.Configuration.Settings.Service.DisableEaseOfAccessOptions),
|
||||
(factory.CreateFindPrinterConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableFindPrinter),
|
||||
(factory.CreateLockWorkstationConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableUserLock),
|
||||
(factory.CreateMachinePowerOptionsConfiguration(groupId), Context.Configuration.Settings.Service.DisablePowerOptions),
|
||||
(factory.CreateNetworkOptionsConfiguration(groupId), Context.Configuration.Settings.Service.DisableNetworkOptions),
|
||||
(factory.CreateRemoteConnectionConfiguration(groupId), Context.Configuration.Settings.Service.DisableRemoteConnections),
|
||||
(factory.CreateSignoutConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableSignout),
|
||||
(factory.CreateSwitchUserConfiguration(groupId), Context.Configuration.Settings.Service.DisableUserSwitch),
|
||||
(factory.CreateTaskManagerConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableTaskManager),
|
||||
(factory.CreateUserPowerOptionsConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisablePowerOptions),
|
||||
(factory.CreateWindowsUpdateConfiguration(groupId), Context.Configuration.Settings.Service.DisableWindowsUpdate)
|
||||
};
|
||||
|
||||
if (Context.Configuration.Settings.Service.SetVmwareConfiguration)
|
||||
{
|
||||
configurations.Add((factory.CreateVmwareOverlayConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableVmwareOverlay));
|
||||
}
|
||||
|
||||
logger.Info($"Attempting to perform lockdown (feature configuration group: {groupId})...");
|
||||
|
||||
foreach (var (configuration, disable) in configurations)
|
||||
{
|
||||
success &= TrySet(configuration, disable);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
monitor.Start();
|
||||
logger.Info("Lockdown successful.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Lockdown was not successful!");
|
||||
}
|
||||
|
||||
return success ? OperationResult.Success : OperationResult.Failed;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
logger.Info($"Attempting to revert lockdown (feature configuration group: {groupId})...");
|
||||
|
||||
var configurations = backup.GetBy(groupId);
|
||||
var success = true;
|
||||
|
||||
monitor.Reset();
|
||||
|
||||
foreach (var configuration in configurations)
|
||||
{
|
||||
success &= TryRestore(configuration);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
logger.Info("Lockdown reversion successful.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn("Lockdown reversion was not successful!");
|
||||
}
|
||||
|
||||
return success ? OperationResult.Success : OperationResult.Failed;
|
||||
}
|
||||
|
||||
private bool TryRestore(IFeatureConfiguration configuration)
|
||||
{
|
||||
var success = configuration.Restore();
|
||||
|
||||
if (success)
|
||||
{
|
||||
backup.Delete(configuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error($"Failed to restore {configuration}!");
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private bool TrySet(IFeatureConfiguration configuration, bool disable)
|
||||
{
|
||||
var success = false;
|
||||
var status = FeatureConfigurationStatus.Undefined;
|
||||
|
||||
configuration.Initialize();
|
||||
backup.Save(configuration);
|
||||
|
||||
if (disable)
|
||||
{
|
||||
success = configuration.DisableFeature();
|
||||
status = FeatureConfigurationStatus.Disabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
success = configuration.EnableFeature();
|
||||
status = FeatureConfigurationStatus.Enabled;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
monitor.Observe(configuration, status);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error($"Failed to configure {configuration}!");
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
48
SafeExamBrowser.Service/Operations/RestoreOperation.cs
Normal file
48
SafeExamBrowser.Service/Operations/RestoreOperation.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.Lockdown.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Service.Operations
|
||||
{
|
||||
internal class RestoreOperation : IOperation
|
||||
{
|
||||
private readonly IFeatureConfigurationBackup backup;
|
||||
private ILogger logger;
|
||||
private readonly SessionContext sessionContext;
|
||||
|
||||
public event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public event StatusChangedEventHandler StatusChanged { add { } remove { } }
|
||||
|
||||
public RestoreOperation(IFeatureConfigurationBackup backup, ILogger logger, SessionContext sessionContext)
|
||||
{
|
||||
this.backup = backup;
|
||||
this.logger = logger;
|
||||
this.sessionContext = sessionContext;
|
||||
}
|
||||
|
||||
public OperationResult Perform()
|
||||
{
|
||||
logger.Info("Starting auto-restore mechanism...");
|
||||
sessionContext.AutoRestoreMechanism.Start();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public OperationResult Revert()
|
||||
{
|
||||
logger.Info("Stopping auto-restore mechanism...");
|
||||
sessionContext.AutoRestoreMechanism.Stop();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Service.Operations
|
||||
{
|
||||
internal class ServiceEventCleanupOperation : IOperation
|
||||
{
|
||||
private ILogger logger;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
public event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public event StatusChangedEventHandler StatusChanged { add { } remove { } }
|
||||
|
||||
public ServiceEventCleanupOperation(ILogger logger, SessionContext sessionContext)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.sessionContext = sessionContext;
|
||||
}
|
||||
|
||||
public OperationResult Perform()
|
||||
{
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public OperationResult Revert()
|
||||
{
|
||||
if (sessionContext.ServiceEvent != null)
|
||||
{
|
||||
logger.Info("Closing service event...");
|
||||
sessionContext.ServiceEvent.Close();
|
||||
logger.Info("Service event successfully closed.");
|
||||
}
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Service.Operations
|
||||
{
|
||||
internal class SessionActivationOperation : SessionOperation
|
||||
{
|
||||
private ILogger logger;
|
||||
|
||||
public SessionActivationOperation(ILogger logger, SessionContext sessionContext) : base(sessionContext)
|
||||
{
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
var success = Context.ServiceEvent.Set();
|
||||
|
||||
if (success)
|
||||
{
|
||||
logger.Info("Successfully informed runtime about new session activation.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Failed to inform runtime about new session activation!");
|
||||
}
|
||||
|
||||
Context.IsRunning = success;
|
||||
|
||||
return success ? OperationResult.Success : OperationResult.Failed;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
return OperationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.Threading;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
|
||||
namespace SafeExamBrowser.Service.Operations
|
||||
{
|
||||
internal class SessionInitializationOperation : SessionOperation
|
||||
{
|
||||
private ILogger logger;
|
||||
private Func<string, EventWaitHandle> serviceEventFactory;
|
||||
|
||||
public SessionInitializationOperation(ILogger logger, Func<string, EventWaitHandle> serviceEventFactory, SessionContext sessionContext) : base(sessionContext)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.serviceEventFactory = serviceEventFactory;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
logger.Info("Initializing new session...");
|
||||
logger.Info($" -> Client-ID: {Context.Configuration.AppConfig.ClientId}");
|
||||
logger.Info($" -> Runtime-ID: {Context.Configuration.AppConfig.RuntimeId}");
|
||||
logger.Info($" -> Session-ID: {Context.Configuration.SessionId}");
|
||||
|
||||
logger.Info("Stopping auto-restore mechanism...");
|
||||
Context.AutoRestoreMechanism.Stop();
|
||||
|
||||
InitializeServiceEvent();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
var success = true;
|
||||
var wasRunning = Context.IsRunning;
|
||||
|
||||
logger.Info("Starting auto-restore mechanism...");
|
||||
Context.AutoRestoreMechanism.Start();
|
||||
|
||||
logger.Info("Clearing session data...");
|
||||
Context.Configuration = null;
|
||||
Context.IsRunning = false;
|
||||
|
||||
if (Context.ServiceEvent != null && wasRunning)
|
||||
{
|
||||
success = Context.ServiceEvent.Set();
|
||||
|
||||
if (success)
|
||||
{
|
||||
logger.Info("Successfully informed runtime about session termination.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Failed to inform runtime about session termination!");
|
||||
}
|
||||
}
|
||||
|
||||
return success ? OperationResult.Success : OperationResult.Failed;
|
||||
}
|
||||
|
||||
private void InitializeServiceEvent()
|
||||
{
|
||||
if (Context.ServiceEvent != null)
|
||||
{
|
||||
logger.Info("Closing service event from previous session...");
|
||||
Context.ServiceEvent.Close();
|
||||
logger.Info("Service event successfully closed.");
|
||||
}
|
||||
|
||||
logger.Info("Attempting to create new service event...");
|
||||
Context.ServiceEvent = serviceEventFactory.Invoke(Context.Configuration.AppConfig.ServiceEventName);
|
||||
logger.Info("Service event successfully created.");
|
||||
}
|
||||
}
|
||||
}
|
32
SafeExamBrowser.Service/Operations/SessionOperation.cs
Normal file
32
SafeExamBrowser.Service/Operations/SessionOperation.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 SafeExamBrowser.Core.Contracts.OperationModel;
|
||||
using SafeExamBrowser.Core.Contracts.OperationModel.Events;
|
||||
|
||||
namespace SafeExamBrowser.Service.Operations
|
||||
{
|
||||
/// <summary>
|
||||
/// The base implementation to be used for all operations in the session operation sequence.
|
||||
/// </summary>
|
||||
internal abstract class SessionOperation : IOperation
|
||||
{
|
||||
protected SessionContext Context { get; private set; }
|
||||
|
||||
public event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public event StatusChangedEventHandler StatusChanged { add { } remove { } }
|
||||
|
||||
public SessionOperation(SessionContext sessionContext)
|
||||
{
|
||||
Context = sessionContext;
|
||||
}
|
||||
|
||||
public abstract OperationResult Perform();
|
||||
public abstract OperationResult Revert();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user