SEBWIN-309: Implemented draft of browser exam key.

This commit is contained in:
dbuechel 2020-02-10 12:19:25 +01:00
parent 92d22a8437
commit 5ce5c78641
6 changed files with 28 additions and 54 deletions

View file

@ -106,12 +106,16 @@ namespace SafeExamBrowser.Browser.Handlers
{ {
var headers = new NameValueCollection(request.Headers); var headers = new NameValueCollection(request.Headers);
var urlWithoutFragment = request.Url.Split('#')[0]; var urlWithoutFragment = request.Url.Split('#')[0];
var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlWithoutFragment + settings.HashValue)); var configurationBytes = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlWithoutFragment + settings.HashValue));
var configurationKey = BitConverter.ToString(hash).ToLower().Replace("-", string.Empty); var configurationKey = BitConverter.ToString(configurationBytes).ToLower().Replace("-", string.Empty);
var browserExamBytes = algorithm.ComputeHash(Encoding.UTF8.GetBytes(appConfig.CodeSignatureHash + appConfig.ProgramBuildVersion + configurationKey));
var browserExamKey = BitConverter.ToString(browserExamBytes).ToLower().Replace("-", string.Empty);
var requestHashBytes = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlWithoutFragment + browserExamKey));
var requestHashKey = BitConverter.ToString(requestHashBytes).ToLower().Replace("-", string.Empty);
// TODO: Implement Browser Exam Key calculation.
// headers["X-SafeExamBrowser-RequestHash"] = ...;
headers["X-SafeExamBrowser-ConfigKeyHash"] = configurationKey; headers["X-SafeExamBrowser-ConfigKeyHash"] = configurationKey;
headers["X-SafeExamBrowser-RequestHash"] = requestHashKey;
request.Headers = headers; request.Headers = headers;
} }

View file

@ -86,6 +86,11 @@ namespace SafeExamBrowser.Configuration.Contracts
/// </summary> /// </summary>
public string ClientLogFilePath { get; set; } public string ClientLogFilePath { get; set; }
/// <summary>
/// The hash value of the certificate used to sign the application binaries, or <c>null</c> if the binaries are unsigned.
/// </summary>
public string CodeSignatureHash { get; set; }
/// <summary> /// <summary>
/// The file extension of configuration files for the application (including the period). /// The file extension of configuration files for the application (including the period).
/// </summary> /// </summary>

View file

@ -39,8 +39,6 @@ namespace SafeExamBrowser.Configuration.UnitTests
[TestInitialize] [TestInitialize]
public void Initialize() public void Initialize()
{ {
var executablePath = Assembly.GetExecutingAssembly().Location;
binaryParser = new Mock<IDataParser>(); binaryParser = new Mock<IDataParser>();
binarySerializer = new Mock<IDataSerializer>(); binarySerializer = new Mock<IDataSerializer>();
certificateStore = new Mock<ICertificateStore>(); certificateStore = new Mock<ICertificateStore>();
@ -56,7 +54,7 @@ namespace SafeExamBrowser.Configuration.UnitTests
fileSaver.Setup(f => f.CanSave(It.IsAny<Uri>())).Returns<Uri>(u => u.IsFile); fileSaver.Setup(f => f.CanSave(It.IsAny<Uri>())).Returns<Uri>(u => u.IsFile);
networkLoader.Setup(n => n.CanLoad(It.IsAny<Uri>())).Returns<Uri>(u => u.Scheme.Equals("http") || u.Scheme.Equals("seb")); networkLoader.Setup(n => n.CanLoad(It.IsAny<Uri>())).Returns<Uri>(u => u.Scheme.Equals("http") || u.Scheme.Equals("seb"));
sut = new ConfigurationRepository(certificateStore.Object, hashAlgorithm.Object, logger.Object, executablePath, string.Empty, string.Empty, string.Empty, string.Empty); sut = new ConfigurationRepository(certificateStore.Object, hashAlgorithm.Object, logger.Object);
sut.InitializeAppConfig(); sut.InitializeAppConfig();
} }

View file

@ -7,7 +7,10 @@
*/ */
using System; using System;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection;
using SafeExamBrowser.Configuration.Contracts; using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Settings; using SafeExamBrowser.Settings;
using SafeExamBrowser.Settings.Browser; using SafeExamBrowser.Settings.Browser;
@ -22,27 +25,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
internal class DataValues internal class DataValues
{ {
private const string DEFAULT_CONFIGURATION_NAME = "SebClientSettings.seb"; private const string DEFAULT_CONFIGURATION_NAME = "SebClientSettings.seb";
private AppConfig appConfig; private AppConfig appConfig;
private string executablePath;
private string programBuild;
private string programCopyright;
private string programTitle;
private string programVersion;
internal DataValues(
string executablePath,
string programBuild,
string programCopyright,
string programTitle,
string programVersion)
{
this.executablePath = executablePath ?? string.Empty;
this.programBuild = programBuild ?? string.Empty;
this.programCopyright = programCopyright ?? string.Empty;
this.programTitle = programTitle ?? string.Empty;
this.programVersion = programVersion ?? string.Empty;
}
internal string GetAppDataFilePath() internal string GetAppDataFilePath()
{ {
@ -51,6 +34,12 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
internal AppConfig InitializeAppConfig() internal AppConfig InitializeAppConfig()
{ {
var executable = Assembly.GetExecutingAssembly();
var certificate = executable.Modules.First().GetSignerCertificate();
var programBuild = FileVersionInfo.GetVersionInfo(executable.Location).FileVersion;
var programCopyright = executable.GetCustomAttribute<AssemblyCopyrightAttribute>().Copyright;
var programTitle = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title;
var programVersion = executable.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
var appDataLocalFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), nameof(SafeExamBrowser)); var appDataLocalFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), nameof(SafeExamBrowser));
var appDataRoamingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(SafeExamBrowser)); var appDataRoamingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(SafeExamBrowser));
var programDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), nameof(SafeExamBrowser)); var programDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), nameof(SafeExamBrowser));
@ -65,8 +54,9 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
appConfig.BrowserLogFilePath = Path.Combine(logFolder, $"{logFilePrefix}_Browser.log"); appConfig.BrowserLogFilePath = Path.Combine(logFolder, $"{logFilePrefix}_Browser.log");
appConfig.ClientId = Guid.NewGuid(); appConfig.ClientId = Guid.NewGuid();
appConfig.ClientAddress = $"{AppConfig.BASE_ADDRESS}/client/{Guid.NewGuid()}"; appConfig.ClientAddress = $"{AppConfig.BASE_ADDRESS}/client/{Guid.NewGuid()}";
appConfig.ClientExecutablePath = Path.Combine(Path.GetDirectoryName(executablePath), $"{nameof(SafeExamBrowser)}.Client.exe"); appConfig.ClientExecutablePath = Path.Combine(Path.GetDirectoryName(executable.Location), $"{nameof(SafeExamBrowser)}.Client.exe");
appConfig.ClientLogFilePath = Path.Combine(logFolder, $"{logFilePrefix}_Client.log"); appConfig.ClientLogFilePath = Path.Combine(logFolder, $"{logFilePrefix}_Client.log");
appConfig.CodeSignatureHash = certificate?.GetCertHashString();
appConfig.ConfigurationFileExtension = ".seb"; appConfig.ConfigurationFileExtension = ".seb";
appConfig.ConfigurationFileMimeType = "application/seb"; appConfig.ConfigurationFileMimeType = "application/seb";
appConfig.ProgramBuildVersion = programBuild; appConfig.ProgramBuildVersion = programBuild;

View file

@ -33,15 +33,7 @@ namespace SafeExamBrowser.Configuration
private IList<IResourceLoader> resourceLoaders; private IList<IResourceLoader> resourceLoaders;
private IList<IResourceSaver> resourceSavers; private IList<IResourceSaver> resourceSavers;
public ConfigurationRepository( public ConfigurationRepository(ICertificateStore certificateStore, IHashAlgorithm hashAlgorithm, IModuleLogger logger)
ICertificateStore certificateStore,
IHashAlgorithm hashAlgorithm,
IModuleLogger logger,
string executablePath,
string programBuild,
string programCopyright,
string programTitle,
string programVersion)
{ {
this.certificateStore = certificateStore; this.certificateStore = certificateStore;
this.hashAlgorithm = hashAlgorithm; this.hashAlgorithm = hashAlgorithm;
@ -51,7 +43,7 @@ namespace SafeExamBrowser.Configuration
dataSerializers = new List<IDataSerializer>(); dataSerializers = new List<IDataSerializer>();
dataMapper = new DataMapper(); dataMapper = new DataMapper();
dataProcessor = new DataProcessor(); dataProcessor = new DataProcessor();
dataValues = new DataValues(executablePath, programBuild, programCopyright, programTitle, programVersion); dataValues = new DataValues();
resourceLoaders = new List<IResourceLoader>(); resourceLoaders = new List<IResourceLoader>();
resourceSavers = new List<IResourceSaver>(); resourceSavers = new List<IResourceSaver>();
} }

View file

@ -8,7 +8,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using SafeExamBrowser.Communication.Contracts; using SafeExamBrowser.Communication.Contracts;
@ -129,12 +128,6 @@ namespace SafeExamBrowser.Runtime
private void InitializeConfiguration() private void InitializeConfiguration()
{ {
var executable = Assembly.GetExecutingAssembly();
var programBuild = FileVersionInfo.GetVersionInfo(executable.Location).FileVersion;
var programCopyright = executable.GetCustomAttribute<AssemblyCopyrightAttribute>().Copyright;
var programTitle = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title;
var programVersion = executable.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
var certificateStore = new CertificateStore(ModuleLogger(nameof(CertificateStore))); var certificateStore = new CertificateStore(ModuleLogger(nameof(CertificateStore)));
var compressor = new GZipCompressor(ModuleLogger(nameof(GZipCompressor))); var compressor = new GZipCompressor(ModuleLogger(nameof(GZipCompressor)));
var passwordEncryption = new PasswordEncryption(ModuleLogger(nameof(PasswordEncryption))); var passwordEncryption = new PasswordEncryption(ModuleLogger(nameof(PasswordEncryption)));
@ -144,15 +137,7 @@ namespace SafeExamBrowser.Runtime
var xmlParser = new XmlParser(compressor, ModuleLogger(nameof(XmlParser))); var xmlParser = new XmlParser(compressor, ModuleLogger(nameof(XmlParser)));
var xmlSerializer = new XmlSerializer(ModuleLogger(nameof(XmlSerializer))); var xmlSerializer = new XmlSerializer(ModuleLogger(nameof(XmlSerializer)));
configuration = new ConfigurationRepository( configuration = new ConfigurationRepository(certificateStore, new HashAlgorithm(), repositoryLogger);
certificateStore,
new HashAlgorithm(),
repositoryLogger,
executable.Location,
programBuild,
programCopyright,
programTitle,
programVersion);
appConfig = configuration.InitializeAppConfig(); appConfig = configuration.InitializeAppConfig();
configuration.Register(new BinaryParser( configuration.Register(new BinaryParser(