SEBWIN-508: Implemented basic JavaScript API.
This commit is contained in:
		
							parent
							
								
									deccb3340c
								
							
						
					
					
						commit
						0da587e521
					
				
					 19 changed files with 311 additions and 100 deletions
				
			
		| 
						 | 
				
			
			@ -13,6 +13,7 @@ using Moq;
 | 
			
		|||
using SafeExamBrowser.Browser.Contracts.Filters;
 | 
			
		||||
using SafeExamBrowser.Browser.Handlers;
 | 
			
		||||
using SafeExamBrowser.Configuration.Contracts;
 | 
			
		||||
using SafeExamBrowser.Configuration.Contracts.Cryptography;
 | 
			
		||||
using SafeExamBrowser.I18n.Contracts;
 | 
			
		||||
using SafeExamBrowser.Logging.Contracts;
 | 
			
		||||
using SafeExamBrowser.Settings.Browser;
 | 
			
		||||
| 
						 | 
				
			
			@ -29,6 +30,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
 | 
			
		|||
	{
 | 
			
		||||
		private AppConfig appConfig;
 | 
			
		||||
		private Mock<IRequestFilter> filter;
 | 
			
		||||
		private Mock<IKeyGenerator> keyGenerator;
 | 
			
		||||
		private Mock<ILogger> logger;
 | 
			
		||||
		private BrowserSettings settings;
 | 
			
		||||
		private WindowSettings windowSettings;
 | 
			
		||||
| 
						 | 
				
			
			@ -41,11 +43,12 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
 | 
			
		|||
		{
 | 
			
		||||
			appConfig = new AppConfig();
 | 
			
		||||
			filter = new Mock<IRequestFilter>();
 | 
			
		||||
			keyGenerator = new Mock<IKeyGenerator>();
 | 
			
		||||
			logger = new Mock<ILogger>();
 | 
			
		||||
			settings = new BrowserSettings();
 | 
			
		||||
			windowSettings = new WindowSettings();
 | 
			
		||||
			text = new Mock<IText>();
 | 
			
		||||
			resourceHandler = new ResourceHandler(appConfig, filter.Object, logger.Object, settings, windowSettings, text.Object);
 | 
			
		||||
			resourceHandler = new ResourceHandler(appConfig, filter.Object, keyGenerator.Object, logger.Object, settings, windowSettings, text.Object);
 | 
			
		||||
 | 
			
		||||
			sut = new TestableRequestHandler(appConfig, filter.Object, logger.Object, resourceHandler, settings, windowSettings, text.Object);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
 | 
			
		|||
using Moq;
 | 
			
		||||
using SafeExamBrowser.Browser.Contracts.Filters;
 | 
			
		||||
using SafeExamBrowser.Configuration.Contracts;
 | 
			
		||||
using SafeExamBrowser.Configuration.Contracts.Cryptography;
 | 
			
		||||
using SafeExamBrowser.I18n.Contracts;
 | 
			
		||||
using SafeExamBrowser.Logging.Contracts;
 | 
			
		||||
using SafeExamBrowser.Settings.Browser;
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +31,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
 | 
			
		|||
	{
 | 
			
		||||
		private AppConfig appConfig;
 | 
			
		||||
		private Mock<IRequestFilter> filter;
 | 
			
		||||
		private Mock<IKeyGenerator> keyGenerator;
 | 
			
		||||
		private Mock<ILogger> logger;
 | 
			
		||||
		private BrowserSettings settings;
 | 
			
		||||
		private WindowSettings windowSettings;
 | 
			
		||||
| 
						 | 
				
			
			@ -41,12 +43,13 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
 | 
			
		|||
		{
 | 
			
		||||
			appConfig = new AppConfig();
 | 
			
		||||
			filter = new Mock<IRequestFilter>();
 | 
			
		||||
			keyGenerator = new Mock<IKeyGenerator>();
 | 
			
		||||
			logger = new Mock<ILogger>();
 | 
			
		||||
			settings = new BrowserSettings();
 | 
			
		||||
			windowSettings = new WindowSettings();
 | 
			
		||||
			text = new Mock<IText>();
 | 
			
		||||
 | 
			
		||||
			sut = new TestableResourceHandler(appConfig, filter.Object, logger.Object, settings, windowSettings, text.Object);
 | 
			
		||||
			sut = new TestableResourceHandler(appConfig, filter.Object, keyGenerator.Object, logger.Object, settings, windowSettings, text.Object);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[TestMethod]
 | 
			
		||||
| 
						 | 
				
			
			@ -57,11 +60,13 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
 | 
			
		|||
			var request = new Mock<IRequest>();
 | 
			
		||||
 | 
			
		||||
			browser.SetupGet(b => b.Address).Returns("http://www.host.org");
 | 
			
		||||
			keyGenerator.Setup(g => g.CalculateBrowserExamKeyHash(It.IsAny<string>())).Returns(new Random().Next().ToString());
 | 
			
		||||
			keyGenerator.Setup(g => g.CalculateConfigurationKeyHash(It.IsAny<string>())).Returns(new Random().Next().ToString());
 | 
			
		||||
			request.SetupGet(r => r.Headers).Returns(new NameValueCollection());
 | 
			
		||||
			request.SetupGet(r => r.Url).Returns("http://www.host.org");
 | 
			
		||||
			request.SetupSet(r => r.Headers = It.IsAny<NameValueCollection>()).Callback<NameValueCollection>((h) => headers = h);
 | 
			
		||||
			settings.SendConfigurationKey = true;
 | 
			
		||||
			settings.SendExamKey = true;
 | 
			
		||||
			settings.SendBrowserExamKey = true;
 | 
			
		||||
 | 
			
		||||
			var result = sut.OnBeforeResourceLoad(browser.Object, Mock.Of<IBrowser>(), Mock.Of<IFrame>(), request.Object, Mock.Of<IRequestCallback>());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +90,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
 | 
			
		|||
			request.SetupGet(r => r.Url).Returns("http://www.host.org");
 | 
			
		||||
			request.SetupSet(r => r.Headers = It.IsAny<NameValueCollection>()).Callback<NameValueCollection>((h) => headers = h);
 | 
			
		||||
			settings.SendConfigurationKey = true;
 | 
			
		||||
			settings.SendExamKey = true;
 | 
			
		||||
			settings.SendBrowserExamKey = true;
 | 
			
		||||
 | 
			
		||||
			var result = sut.OnBeforeResourceLoad(browser.Object, Mock.Of<IBrowser>(), Mock.Of<IFrame>(), request.Object, Mock.Of<IRequestCallback>());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -291,10 +296,11 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
 | 
			
		|||
			internal TestableResourceHandler(
 | 
			
		||||
				AppConfig appConfig,
 | 
			
		||||
				IRequestFilter filter,
 | 
			
		||||
				IKeyGenerator keyGenerator,
 | 
			
		||||
				ILogger logger,
 | 
			
		||||
				BrowserSettings settings,
 | 
			
		||||
				WindowSettings windowSettings,
 | 
			
		||||
				IText text) : base(appConfig, filter, logger, settings, windowSettings, text)
 | 
			
		||||
				IText text) : base(appConfig, filter, keyGenerator, logger, settings, windowSettings, text)
 | 
			
		||||
			{
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,16 +38,17 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
	{
 | 
			
		||||
		private int instanceIdCounter = default(int);
 | 
			
		||||
 | 
			
		||||
		private AppConfig appConfig;
 | 
			
		||||
		private List<BrowserApplicationInstance> instances;
 | 
			
		||||
		private IFileSystemDialog fileSystemDialog;
 | 
			
		||||
		private IHashAlgorithm hashAlgorithm;
 | 
			
		||||
		private INativeMethods nativeMethods;
 | 
			
		||||
		private IMessageBox messageBox;
 | 
			
		||||
		private IModuleLogger logger;
 | 
			
		||||
		private BrowserSettings settings;
 | 
			
		||||
		private IText text;
 | 
			
		||||
		private IUserInterfaceFactory uiFactory;
 | 
			
		||||
		private readonly AppConfig appConfig;
 | 
			
		||||
		private readonly IFileSystemDialog fileSystemDialog;
 | 
			
		||||
		private readonly IHashAlgorithm hashAlgorithm;
 | 
			
		||||
		private readonly List<BrowserApplicationInstance> instances;
 | 
			
		||||
		private readonly IKeyGenerator keyGenerator;
 | 
			
		||||
		private readonly IModuleLogger logger;
 | 
			
		||||
		private readonly IMessageBox messageBox;
 | 
			
		||||
		private readonly INativeMethods nativeMethods;
 | 
			
		||||
		private readonly BrowserSettings settings;
 | 
			
		||||
		private readonly IText text;
 | 
			
		||||
		private readonly IUserInterfaceFactory uiFactory;
 | 
			
		||||
 | 
			
		||||
		public bool AutoStart { get; private set; }
 | 
			
		||||
		public IconResource Icon { get; private set; }
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +66,7 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			BrowserSettings settings,
 | 
			
		||||
			IFileSystemDialog fileSystemDialog,
 | 
			
		||||
			IHashAlgorithm hashAlgorithm,
 | 
			
		||||
			IKeyGenerator keyGenerator,
 | 
			
		||||
			INativeMethods nativeMethods,
 | 
			
		||||
			IMessageBox messageBox,
 | 
			
		||||
			IModuleLogger logger,
 | 
			
		||||
| 
						 | 
				
			
			@ -74,10 +76,11 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			this.appConfig = appConfig;
 | 
			
		||||
			this.fileSystemDialog = fileSystemDialog;
 | 
			
		||||
			this.hashAlgorithm = hashAlgorithm;
 | 
			
		||||
			this.nativeMethods = nativeMethods;
 | 
			
		||||
			this.instances = new List<BrowserApplicationInstance>();
 | 
			
		||||
			this.keyGenerator = keyGenerator;
 | 
			
		||||
			this.logger = logger;
 | 
			
		||||
			this.messageBox = messageBox;
 | 
			
		||||
			this.nativeMethods = nativeMethods;
 | 
			
		||||
			this.settings = settings;
 | 
			
		||||
			this.text = text;
 | 
			
		||||
			this.uiFactory = uiFactory;
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +175,19 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			var isMainInstance = instances.Count == 0;
 | 
			
		||||
			var instanceLogger = logger.CloneFor($"Browser Instance #{id}");
 | 
			
		||||
			var startUrl = url ?? GenerateStartUrl();
 | 
			
		||||
			var instance = new BrowserApplicationInstance(appConfig, settings, id, isMainInstance, fileSystemDialog, hashAlgorithm, messageBox, instanceLogger, text, uiFactory, startUrl);
 | 
			
		||||
			var instance = new BrowserApplicationInstance(
 | 
			
		||||
				appConfig,
 | 
			
		||||
				settings,
 | 
			
		||||
				id,
 | 
			
		||||
				isMainInstance,
 | 
			
		||||
				fileSystemDialog,
 | 
			
		||||
				hashAlgorithm,
 | 
			
		||||
				keyGenerator,
 | 
			
		||||
				messageBox,
 | 
			
		||||
				instanceLogger,
 | 
			
		||||
				text,
 | 
			
		||||
				uiFactory,
 | 
			
		||||
				startUrl);
 | 
			
		||||
 | 
			
		||||
			instance.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args);
 | 
			
		||||
			instance.PopupRequested += Instance_PopupRequested;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,19 +41,21 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
	{
 | 
			
		||||
		private const double ZOOM_FACTOR = 0.2;
 | 
			
		||||
 | 
			
		||||
		private AppConfig appConfig;
 | 
			
		||||
		private readonly AppConfig appConfig;
 | 
			
		||||
		private readonly IFileSystemDialog fileSystemDialog;
 | 
			
		||||
		private readonly IHashAlgorithm hashAlgorithm;
 | 
			
		||||
		private readonly HttpClient httpClient;
 | 
			
		||||
		private readonly IKeyGenerator keyGenerator;
 | 
			
		||||
		private readonly IModuleLogger logger;
 | 
			
		||||
		private readonly IMessageBox messageBox;
 | 
			
		||||
		private readonly IText text;
 | 
			
		||||
		private readonly IUserInterfaceFactory uiFactory;
 | 
			
		||||
 | 
			
		||||
		private IBrowserControl control;
 | 
			
		||||
		private IBrowserWindow window;
 | 
			
		||||
		private HttpClient httpClient;
 | 
			
		||||
		private bool isMainInstance;
 | 
			
		||||
		private IFileSystemDialog fileSystemDialog;
 | 
			
		||||
		private IHashAlgorithm hashAlgorithm;
 | 
			
		||||
		private IMessageBox messageBox;
 | 
			
		||||
		private IModuleLogger logger;
 | 
			
		||||
		private BrowserSettings settings;
 | 
			
		||||
		private string startUrl;
 | 
			
		||||
		private IText text;
 | 
			
		||||
		private IUserInterfaceFactory uiFactory;
 | 
			
		||||
		private double zoomLevel;
 | 
			
		||||
 | 
			
		||||
		private WindowSettings WindowSettings
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +86,7 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			bool isMainInstance,
 | 
			
		||||
			IFileSystemDialog fileSystemDialog,
 | 
			
		||||
			IHashAlgorithm hashAlgorithm,
 | 
			
		||||
			IKeyGenerator keyGenerator,
 | 
			
		||||
			IMessageBox messageBox,
 | 
			
		||||
			IModuleLogger logger,
 | 
			
		||||
			IText text,
 | 
			
		||||
| 
						 | 
				
			
			@ -96,6 +99,7 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			this.isMainInstance = isMainInstance;
 | 
			
		||||
			this.fileSystemDialog = fileSystemDialog;
 | 
			
		||||
			this.hashAlgorithm = hashAlgorithm;
 | 
			
		||||
			this.keyGenerator = keyGenerator;
 | 
			
		||||
			this.messageBox = messageBox;
 | 
			
		||||
			this.logger = logger;
 | 
			
		||||
			this.settings = settings;
 | 
			
		||||
| 
						 | 
				
			
			@ -130,9 +134,11 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			var downloadHandler = new DownloadHandler(appConfig, downloadLogger, settings, WindowSettings);
 | 
			
		||||
			var keyboardHandler = new KeyboardHandler();
 | 
			
		||||
			var lifeSpanHandler = new LifeSpanHandler();
 | 
			
		||||
			var renderProcessMessageLogger = logger.CloneFor($"{nameof(RenderProcessMessageHandler)} #{Id}");
 | 
			
		||||
			var renderProcessMessageHandler = new RenderProcessMessageHandler(appConfig, renderProcessMessageLogger, keyGenerator, text);
 | 
			
		||||
			var requestFilter = new RequestFilter();
 | 
			
		||||
			var requestLogger = logger.CloneFor($"{nameof(RequestHandler)} #{Id}");
 | 
			
		||||
			var resourceHandler = new ResourceHandler(appConfig, requestFilter, logger, settings, WindowSettings, text);
 | 
			
		||||
			var resourceHandler = new ResourceHandler(appConfig, requestFilter, keyGenerator, logger, settings, WindowSettings, text);
 | 
			
		||||
			var requestHandler = new RequestHandler(appConfig, requestFilter, requestLogger, resourceHandler, settings, WindowSettings, text);
 | 
			
		||||
 | 
			
		||||
			Icon = new BrowserIconResource();
 | 
			
		||||
| 
						 | 
				
			
			@ -162,6 +168,7 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
				downloadHandler,
 | 
			
		||||
				keyboardHandler,
 | 
			
		||||
				lifeSpanHandler,
 | 
			
		||||
				renderProcessMessageHandler,
 | 
			
		||||
				requestHandler,
 | 
			
		||||
				startUrl);
 | 
			
		||||
			control.AddressChanged += Control_AddressChanged;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,13 +16,14 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
{
 | 
			
		||||
	internal class BrowserControl : ChromiumWebBrowser, IBrowserControl
 | 
			
		||||
	{
 | 
			
		||||
		private IContextMenuHandler contextMenuHandler;
 | 
			
		||||
		private IDialogHandler dialogHandler;
 | 
			
		||||
		private IDisplayHandler displayHandler;
 | 
			
		||||
		private IDownloadHandler downloadHandler;
 | 
			
		||||
		private IKeyboardHandler keyboardHandler;
 | 
			
		||||
		private ILifeSpanHandler lifeSpanHandler;
 | 
			
		||||
		private IRequestHandler requestHandler;
 | 
			
		||||
		private readonly IContextMenuHandler contextMenuHandler;
 | 
			
		||||
		private readonly IDialogHandler dialogHandler;
 | 
			
		||||
		private readonly IDisplayHandler displayHandler;
 | 
			
		||||
		private readonly IDownloadHandler downloadHandler;
 | 
			
		||||
		private readonly IKeyboardHandler keyboardHandler;
 | 
			
		||||
		private readonly ILifeSpanHandler lifeSpanHandler;
 | 
			
		||||
		private readonly IRenderProcessMessageHandler renderProcessMessageHandler;
 | 
			
		||||
		private readonly IRequestHandler requestHandler;
 | 
			
		||||
 | 
			
		||||
		private AddressChangedEventHandler addressChanged;
 | 
			
		||||
		private LoadFailedEventHandler loadFailed;
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +64,7 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			IDownloadHandler downloadHandler,
 | 
			
		||||
			IKeyboardHandler keyboardHandler,
 | 
			
		||||
			ILifeSpanHandler lifeSpanHandler,
 | 
			
		||||
			IRenderProcessMessageHandler renderProcessMessageHandler,
 | 
			
		||||
			IRequestHandler requestHandler,
 | 
			
		||||
			string url) : base(url)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -72,6 +74,7 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			this.downloadHandler = downloadHandler;
 | 
			
		||||
			this.keyboardHandler = keyboardHandler;
 | 
			
		||||
			this.lifeSpanHandler = lifeSpanHandler;
 | 
			
		||||
			this.renderProcessMessageHandler = renderProcessMessageHandler;
 | 
			
		||||
			this.requestHandler = requestHandler;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +100,7 @@ namespace SafeExamBrowser.Browser
 | 
			
		|||
			KeyboardHandler = keyboardHandler;
 | 
			
		||||
			LifeSpanHandler = lifeSpanHandler;
 | 
			
		||||
			MenuHandler = contextMenuHandler;
 | 
			
		||||
			RenderProcessMessageHandler = renderProcessMessageHandler;
 | 
			
		||||
			RequestHandler = requestHandler;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										8
									
								
								SafeExamBrowser.Browser/Content/Api.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								SafeExamBrowser.Browser/Content/Api.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
SafeExamBrowser = {
 | 
			
		||||
    version: 'SEB_Windows_%%_VERSION_%%',
 | 
			
		||||
    security: {
 | 
			
		||||
        browserExamKey: '%%_BEK_%%',
 | 
			
		||||
        configKey: '%%_CK_%%',
 | 
			
		||||
        updateKeys: (callback) => callback()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -10,21 +10,45 @@ using System.IO;
 | 
			
		|||
using System.Reflection;
 | 
			
		||||
using SafeExamBrowser.I18n.Contracts;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.Browser.Pages
 | 
			
		||||
namespace SafeExamBrowser.Browser.Content
 | 
			
		||||
{
 | 
			
		||||
	internal class HtmlLoader
 | 
			
		||||
	internal class ContentLoader
 | 
			
		||||
	{
 | 
			
		||||
		private string api;
 | 
			
		||||
		private IText text;
 | 
			
		||||
 | 
			
		||||
		internal HtmlLoader(IText text)
 | 
			
		||||
		internal ContentLoader(IText text)
 | 
			
		||||
		{
 | 
			
		||||
			this.text = text;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal string LoadApi(string browserExamKey, string configurationKey, string version)
 | 
			
		||||
		{
 | 
			
		||||
			if (api == default(string))
 | 
			
		||||
			{
 | 
			
		||||
				var assembly = Assembly.GetAssembly(typeof(ContentLoader));
 | 
			
		||||
				var path = $"{typeof(ContentLoader).Namespace}.Api.js";
 | 
			
		||||
 | 
			
		||||
				using (var stream = assembly.GetManifestResourceStream(path))
 | 
			
		||||
				using (var reader = new StreamReader(stream))
 | 
			
		||||
				{
 | 
			
		||||
					api = reader.ReadToEnd();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var js = api;
 | 
			
		||||
 | 
			
		||||
			js = js.Replace("%%_BEK_%%", browserExamKey);
 | 
			
		||||
			js = js.Replace("%%_CK_%%", configurationKey);
 | 
			
		||||
			js = js.Replace("%%_VERSION_%%", version);
 | 
			
		||||
 | 
			
		||||
			return js;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal string LoadBlockedContent()
 | 
			
		||||
		{
 | 
			
		||||
			var assembly = Assembly.GetAssembly(typeof(HtmlLoader));
 | 
			
		||||
			var path = $"{typeof(HtmlLoader).Namespace}.BlockedContent.html";
 | 
			
		||||
			var assembly = Assembly.GetAssembly(typeof(ContentLoader));
 | 
			
		||||
			var path = $"{typeof(ContentLoader).Namespace}.BlockedContent.html";
 | 
			
		||||
 | 
			
		||||
			using (var stream = assembly.GetManifestResourceStream(path))
 | 
			
		||||
			using (var reader = new StreamReader(stream))
 | 
			
		||||
| 
						 | 
				
			
			@ -39,8 +63,8 @@ namespace SafeExamBrowser.Browser.Pages
 | 
			
		|||
 | 
			
		||||
		internal string LoadBlockedPage()
 | 
			
		||||
		{
 | 
			
		||||
			var assembly = Assembly.GetAssembly(typeof(HtmlLoader));
 | 
			
		||||
			var path = $"{typeof(HtmlLoader).Namespace}.BlockedPage.html";
 | 
			
		||||
			var assembly = Assembly.GetAssembly(typeof(ContentLoader));
 | 
			
		||||
			var path = $"{typeof(ContentLoader).Namespace}.BlockedPage.html";
 | 
			
		||||
 | 
			
		||||
			using (var stream = assembly.GetManifestResourceStream(path))
 | 
			
		||||
			using (var reader = new StreamReader(stream))
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2021 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 CefSharp;
 | 
			
		||||
using SafeExamBrowser.Browser.Content;
 | 
			
		||||
using SafeExamBrowser.Configuration.Contracts;
 | 
			
		||||
using SafeExamBrowser.Configuration.Contracts.Cryptography;
 | 
			
		||||
using SafeExamBrowser.I18n.Contracts;
 | 
			
		||||
using SafeExamBrowser.Logging.Contracts;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.Browser.Handlers
 | 
			
		||||
{
 | 
			
		||||
	internal class RenderProcessMessageHandler : IRenderProcessMessageHandler
 | 
			
		||||
	{
 | 
			
		||||
		private readonly AppConfig appConfig;
 | 
			
		||||
		private readonly ContentLoader contentLoader;
 | 
			
		||||
		private readonly ILogger logger;
 | 
			
		||||
		private readonly IKeyGenerator generator;
 | 
			
		||||
 | 
			
		||||
		internal RenderProcessMessageHandler(AppConfig appConfig, ILogger logger, IKeyGenerator generator, IText text)
 | 
			
		||||
		{
 | 
			
		||||
			this.appConfig = appConfig;
 | 
			
		||||
			this.contentLoader = new ContentLoader(text);
 | 
			
		||||
			this.logger = logger;
 | 
			
		||||
			this.generator = generator;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void OnContextCreated(IWebBrowser webBrowser, IBrowser browser, IFrame frame)
 | 
			
		||||
		{
 | 
			
		||||
			var browserExamKey = generator.CalculateBrowserExamKeyHash(webBrowser.Address);
 | 
			
		||||
			var configurationKey = generator.CalculateConfigurationKeyHash(webBrowser.Address);
 | 
			
		||||
			var api = contentLoader.LoadApi(browserExamKey, configurationKey, appConfig.ProgramBuildVersion);
 | 
			
		||||
 | 
			
		||||
			frame.ExecuteJavaScriptAsync(api);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void OnContextReleased(IWebBrowser webBrowser, IBrowser browser, IFrame frame)
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void OnFocusedNodeChanged(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IDomNode node)
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void OnUncaughtException(IWebBrowser webBrowser, IBrowser browser, IFrame frame, JavascriptException exception)
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -12,16 +12,15 @@ using System.Linq;
 | 
			
		|||
using System.Net;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Net.Mime;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using CefSharp;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using Newtonsoft.Json.Linq;
 | 
			
		||||
using SafeExamBrowser.Browser.Content;
 | 
			
		||||
using SafeExamBrowser.Browser.Contracts.Events;
 | 
			
		||||
using SafeExamBrowser.Browser.Contracts.Filters;
 | 
			
		||||
using SafeExamBrowser.Browser.Pages;
 | 
			
		||||
using SafeExamBrowser.Configuration.Contracts;
 | 
			
		||||
using SafeExamBrowser.Configuration.Contracts.Cryptography;
 | 
			
		||||
using SafeExamBrowser.I18n.Contracts;
 | 
			
		||||
using SafeExamBrowser.Logging.Contracts;
 | 
			
		||||
using SafeExamBrowser.Settings.Browser;
 | 
			
		||||
| 
						 | 
				
			
			@ -33,33 +32,34 @@ namespace SafeExamBrowser.Browser.Handlers
 | 
			
		|||
{
 | 
			
		||||
	internal class ResourceHandler : CefSharp.Handler.ResourceRequestHandler
 | 
			
		||||
	{
 | 
			
		||||
		private SHA256Managed algorithm;
 | 
			
		||||
		private AppConfig appConfig;
 | 
			
		||||
		private string browserExamKey;
 | 
			
		||||
		private readonly AppConfig appConfig;
 | 
			
		||||
		private readonly ContentLoader contentLoader;
 | 
			
		||||
		private readonly IRequestFilter filter;
 | 
			
		||||
		private readonly IKeyGenerator keyGenerator;
 | 
			
		||||
		private readonly ILogger logger;
 | 
			
		||||
		private readonly BrowserSettings settings;
 | 
			
		||||
		private readonly IText text;
 | 
			
		||||
		private readonly WindowSettings windowSettings;
 | 
			
		||||
 | 
			
		||||
		private IResourceHandler contentHandler;
 | 
			
		||||
		private IRequestFilter filter;
 | 
			
		||||
		private HtmlLoader htmlLoader;
 | 
			
		||||
		private ILogger logger;
 | 
			
		||||
		private IResourceHandler pageHandler;
 | 
			
		||||
		private string sessionIdentifier;
 | 
			
		||||
		private BrowserSettings settings;
 | 
			
		||||
		private WindowSettings windowSettings;
 | 
			
		||||
		private IText text;
 | 
			
		||||
 | 
			
		||||
		internal event SessionIdentifierDetectedEventHandler SessionIdentifierDetected;
 | 
			
		||||
 | 
			
		||||
		internal ResourceHandler(
 | 
			
		||||
			AppConfig appConfig,
 | 
			
		||||
			IRequestFilter filter,
 | 
			
		||||
			IKeyGenerator keyGenerator,
 | 
			
		||||
			ILogger logger,
 | 
			
		||||
			BrowserSettings settings,
 | 
			
		||||
			WindowSettings windowSettings,
 | 
			
		||||
			IText text)
 | 
			
		||||
		{
 | 
			
		||||
			this.appConfig = appConfig;
 | 
			
		||||
			this.algorithm = new SHA256Managed();
 | 
			
		||||
			this.filter = filter;
 | 
			
		||||
			this.htmlLoader = new HtmlLoader(text);
 | 
			
		||||
			this.contentLoader = new ContentLoader(text);
 | 
			
		||||
			this.keyGenerator = keyGenerator;
 | 
			
		||||
			this.logger = logger;
 | 
			
		||||
			this.settings = settings;
 | 
			
		||||
			this.windowSettings = windowSettings;
 | 
			
		||||
| 
						 | 
				
			
			@ -123,22 +123,15 @@ namespace SafeExamBrowser.Browser.Handlers
 | 
			
		|||
			if (pageUrl?.Host?.Equals(requestUrl?.Host) == true)
 | 
			
		||||
			{
 | 
			
		||||
				var headers = new NameValueCollection(request.Headers);
 | 
			
		||||
				var urlWithoutFragment = request.Url.Split('#')[0];
 | 
			
		||||
 | 
			
		||||
				if (settings.SendConfigurationKey)
 | 
			
		||||
				{
 | 
			
		||||
					var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlWithoutFragment + settings.ConfigurationKey));
 | 
			
		||||
					var key = BitConverter.ToString(hash).ToLower().Replace("-", string.Empty);
 | 
			
		||||
 | 
			
		||||
					headers["X-SafeExamBrowser-ConfigKeyHash"] = key;
 | 
			
		||||
					headers["X-SafeExamBrowser-ConfigKeyHash"] = keyGenerator.CalculateConfigurationKeyHash(request.Url);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (settings.SendExamKey)
 | 
			
		||||
				if (settings.SendBrowserExamKey)
 | 
			
		||||
				{
 | 
			
		||||
					var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlWithoutFragment + (browserExamKey ?? ComputeBrowserExamKey())));
 | 
			
		||||
					var key = BitConverter.ToString(hash).ToLower().Replace("-", string.Empty);
 | 
			
		||||
 | 
			
		||||
					headers["X-SafeExamBrowser-RequestHash"] = key;
 | 
			
		||||
					headers["X-SafeExamBrowser-RequestHash"] = keyGenerator.CalculateBrowserExamKeyHash(request.Url);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				request.Headers = headers;
 | 
			
		||||
| 
						 | 
				
			
			@ -169,27 +162,6 @@ namespace SafeExamBrowser.Browser.Handlers
 | 
			
		|||
			return block;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string ComputeBrowserExamKey()
 | 
			
		||||
		{
 | 
			
		||||
			var salt = settings.ExamKeySalt;
 | 
			
		||||
 | 
			
		||||
			if (salt == default(byte[]))
 | 
			
		||||
			{
 | 
			
		||||
				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))
 | 
			
		||||
			{
 | 
			
		||||
				var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(appConfig.CodeSignatureHash + appConfig.ProgramBuildVersion + settings.ConfigurationKey));
 | 
			
		||||
				var key = BitConverter.ToString(hash).ToLower().Replace("-", string.Empty);
 | 
			
		||||
 | 
			
		||||
				browserExamKey = key;
 | 
			
		||||
 | 
			
		||||
				return browserExamKey;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool IsMailtoUrl(string url)
 | 
			
		||||
		{
 | 
			
		||||
			return url.StartsWith(Uri.UriSchemeMailto);
 | 
			
		||||
| 
						 | 
				
			
			@ -234,12 +206,12 @@ namespace SafeExamBrowser.Browser.Handlers
 | 
			
		|||
		{
 | 
			
		||||
			if (contentHandler == default(IResourceHandler))
 | 
			
		||||
			{
 | 
			
		||||
				contentHandler = CefSharp.ResourceHandler.FromString(htmlLoader.LoadBlockedContent());
 | 
			
		||||
				contentHandler = CefSharp.ResourceHandler.FromString(contentLoader.LoadBlockedContent());
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (pageHandler == default(IResourceHandler))
 | 
			
		||||
			{
 | 
			
		||||
				pageHandler = CefSharp.ResourceHandler.FromString(htmlLoader.LoadBlockedPage());
 | 
			
		||||
				pageHandler = CefSharp.ResourceHandler.FromString(contentLoader.LoadBlockedPage());
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			switch (resourceType)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,9 +104,10 @@
 | 
			
		|||
    <Compile Include="Handlers\DownloadHandler.cs" />
 | 
			
		||||
    <Compile Include="Handlers\KeyboardHandler.cs" />
 | 
			
		||||
    <Compile Include="Handlers\LifeSpanHandler.cs" />
 | 
			
		||||
    <Compile Include="Handlers\RenderProcessMessageHandler.cs" />
 | 
			
		||||
    <Compile Include="Handlers\RequestHandler.cs" />
 | 
			
		||||
    <Compile Include="Handlers\ResourceHandler.cs" />
 | 
			
		||||
    <Compile Include="Pages\HtmlLoader.cs" />
 | 
			
		||||
    <Compile Include="Content\ContentLoader.cs" />
 | 
			
		||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
| 
						 | 
				
			
			@ -148,8 +149,8 @@
 | 
			
		|||
    </ProjectReference>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <EmbeddedResource Include="Pages\BlockedContent.html" />
 | 
			
		||||
    <EmbeddedResource Include="Pages\BlockedPage.html" />
 | 
			
		||||
    <EmbeddedResource Include="Content\BlockedContent.html" />
 | 
			
		||||
    <EmbeddedResource Include="Content\BlockedPage.html" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Include="app.config" />
 | 
			
		||||
| 
						 | 
				
			
			@ -157,6 +158,9 @@
 | 
			
		|||
      <SubType>Designer</SubType>
 | 
			
		||||
    </None>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <EmbeddedResource Include="Content\Api.js" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <PostBuildEvent>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -209,8 +209,19 @@ namespace SafeExamBrowser.Client
 | 
			
		|||
		private IOperation BuildBrowserOperation()
 | 
			
		||||
		{
 | 
			
		||||
			var fileSystemDialog = BuildFileSystemDialog();
 | 
			
		||||
			var keyGenerator = new KeyGenerator(context.AppConfig, ModuleLogger(nameof(KeyGenerator)), context.Settings);
 | 
			
		||||
			var moduleLogger = ModuleLogger(nameof(BrowserApplication));
 | 
			
		||||
			var browser = new BrowserApplication(context.AppConfig, context.Settings.Browser, fileSystemDialog, new HashAlgorithm(), nativeMethods, messageBox, moduleLogger, text, uiFactory);
 | 
			
		||||
			var browser = new BrowserApplication(
 | 
			
		||||
				context.AppConfig,
 | 
			
		||||
				context.Settings.Browser,
 | 
			
		||||
				fileSystemDialog,
 | 
			
		||||
				new HashAlgorithm(),
 | 
			
		||||
				keyGenerator,
 | 
			
		||||
				nativeMethods,
 | 
			
		||||
				messageBox,
 | 
			
		||||
				moduleLogger,
 | 
			
		||||
				text,
 | 
			
		||||
				uiFactory);
 | 
			
		||||
			var operation = new BrowserOperation(actionCenter, context, logger, taskbar, taskview, uiFactory);
 | 
			
		||||
 | 
			
		||||
			context.Browser = browser;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2021 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.Cryptography
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Provides funcionality to calculate keys for integrity checks.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public interface IKeyGenerator
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Calculates the hash value of the browser exam key (BEK) for the given URL.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		string CalculateBrowserExamKeyHash(string url);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Calculates the hash value of the configuration key (CK) for the given URL.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		string CalculateConfigurationKeyHash(string url);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -59,6 +59,7 @@
 | 
			
		|||
    <Compile Include="Cryptography\EncryptionParameters.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\ICertificateStore.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\IHashAlgorithm.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\IKeyGenerator.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\IPasswordEncryption.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\IPublicKeyEncryption.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\PasswordParameters.cs" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -346,7 +346,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData.DataMapping
 | 
			
		|||
		{
 | 
			
		||||
			if (value is byte[] salt)
 | 
			
		||||
			{
 | 
			
		||||
				settings.Browser.ExamKeySalt = salt;
 | 
			
		||||
				settings.Browser.BrowserExamKeySalt = salt;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -487,7 +487,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData.DataMapping
 | 
			
		|||
			if (value is bool send)
 | 
			
		||||
			{
 | 
			
		||||
				settings.Browser.SendConfigurationKey = send;
 | 
			
		||||
				settings.Browser.SendExamKey = send;
 | 
			
		||||
				settings.Browser.SendBrowserExamKey = send;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										75
									
								
								SafeExamBrowser.Configuration/Cryptography/KeyGenerator.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								SafeExamBrowser.Configuration/Cryptography/KeyGenerator.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2021 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.Security.Cryptography;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using SafeExamBrowser.Configuration.Contracts;
 | 
			
		||||
using SafeExamBrowser.Configuration.Contracts.Cryptography;
 | 
			
		||||
using SafeExamBrowser.Logging.Contracts;
 | 
			
		||||
using SafeExamBrowser.Settings;
 | 
			
		||||
 | 
			
		||||
namespace SafeExamBrowser.Configuration.Cryptography
 | 
			
		||||
{
 | 
			
		||||
	public class KeyGenerator : IKeyGenerator
 | 
			
		||||
	{
 | 
			
		||||
		private readonly SHA256Managed algorithm;
 | 
			
		||||
		private readonly AppConfig appConfig;
 | 
			
		||||
		private readonly ILogger logger;
 | 
			
		||||
		private readonly AppSettings settings;
 | 
			
		||||
 | 
			
		||||
		private string browserExamKey;
 | 
			
		||||
 | 
			
		||||
		public KeyGenerator(AppConfig appConfig, ILogger logger, AppSettings settings)
 | 
			
		||||
		{
 | 
			
		||||
			this.algorithm = new SHA256Managed();
 | 
			
		||||
			this.appConfig = appConfig;
 | 
			
		||||
			this.logger = logger;
 | 
			
		||||
			this.settings = settings;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string CalculateBrowserExamKeyHash(string url)
 | 
			
		||||
		{
 | 
			
		||||
			var urlWithoutFragment = url.Split('#')[0];
 | 
			
		||||
			var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlWithoutFragment + (browserExamKey ?? ComputeBrowserExamKey())));
 | 
			
		||||
			var key = BitConverter.ToString(hash).ToLower().Replace("-", string.Empty);
 | 
			
		||||
 | 
			
		||||
			return key;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string CalculateConfigurationKeyHash(string url)
 | 
			
		||||
		{
 | 
			
		||||
			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);
 | 
			
		||||
 | 
			
		||||
			return key;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string ComputeBrowserExamKey()
 | 
			
		||||
		{
 | 
			
		||||
			var salt = settings.Browser.BrowserExamKeySalt;
 | 
			
		||||
 | 
			
		||||
			if (salt == default(byte[]))
 | 
			
		||||
			{
 | 
			
		||||
				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))
 | 
			
		||||
			{
 | 
			
		||||
				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;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +74,7 @@
 | 
			
		|||
    <Compile Include="ConfigurationData\Keys.cs" />
 | 
			
		||||
    <Compile Include="ConfigurationData\DataValues.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\CertificateStore.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\KeyGenerator.cs" />
 | 
			
		||||
    <Compile Include="DataCompression\GZipCompressor.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\PasswordEncryption.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\PublicKeyEncryption.cs" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,6 +66,11 @@ namespace SafeExamBrowser.Settings.Browser
 | 
			
		|||
		/// </summary>
 | 
			
		||||
		public bool AllowUploads { get; set; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The salt value for the calculation of the browser exam key which is used for integrity checks with server applications (see also <see cref="SendBrowserExamKey"/>).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public byte[] BrowserExamKeySalt { get; set; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The configuration key used for integrity checks with server applications (see also <see cref="SendConfigurationKey"/>).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -108,11 +113,6 @@ namespace SafeExamBrowser.Settings.Browser
 | 
			
		|||
		/// </summary>
 | 
			
		||||
		public bool EnableBrowser { get; set; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The salt value for the calculation of the exam key which is used for integrity checks with server applications (see also <see cref="SendExamKey"/>).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public byte[] ExamKeySalt { get; set; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The settings to be used for the browser request filter.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -169,9 +169,9 @@ namespace SafeExamBrowser.Settings.Browser
 | 
			
		|||
		public bool SendConfigurationKey { get; set; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Determines whether the exam key header is sent with every HTTP request (see also <see cref="ExamKeySalt"/>).
 | 
			
		||||
		/// Determines whether the browser exam key header is sent with every HTTP request (see also <see cref="BrowserExamKeySalt"/>).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public bool SendExamKey { get; set; }
 | 
			
		||||
		public bool SendBrowserExamKey { get; set; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The URL with which the main browser window will be loaded.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue