seb-win-refactoring/SebWindowsConfig/Utilities/SEBClientInfo.cs

461 lines
22 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
//
// SEBClientInfo.cs
// SafeExamBrowser
//
// Copyright (c) 2010-2020 Viktor Tomas, Dirk Bauer, Daniel R. Schneider, Pascal Wyss,
// ETH Zurich, Educational Development and Technology (LET),
// based on the original idea of Safe Exam Browser
// by Stefan Schneider, University of Giessen
// Project concept: Thomas Piendl, Daniel R. Schneider,
// Dirk Bauer, Kai Reuter, Tobias Halbherr, Karsten Burger, Marco Lehre,
// Brigitte Schmucki, Oliver Rahs. French localization: Nicolas Dunand
//
// ``The contents of this file are subject to the Mozilla Public License
// Version 1.1 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations
// under the License.
//
// The Original Code is Safe Exam Browser for Windows.
//
// The Initial Developers of the Original Code are Viktor Tomas,
// Dirk Bauer, Daniel R. Schneider, Pascal Wyss.
// Portions created by Viktor Tomas, Dirk Bauer, Daniel R. Schneider, Pascal Wyss
// are Copyright (c) 2010-2020 Viktor Tomas, Dirk Bauer, Daniel R. Schneider,
// Pascal Wyss, ETH Zurich, Educational Development and Technology (LET),
// based on the original idea of Safe Exam Browser
// by Stefan Schneider, University of Giessen. All Rights Reserved.
//
// Contributor(s): ______________________________________.
//
namespace SebWindowsConfig.Utilities
{
public enum chooseFileToUploadPolicies
{
manuallyWithFileRequester = 0,
attemptUploadSameFileDownloadedBefore = 1,
onlyAllowUploadSameFileDownloadedBefore = 2
};
public enum newBrowserWindowPolicies
{
getGenerallyBlocked = 0,
openInSameWindow = 1,
openInNewWindow = 2
};
public enum sebServicePolicies
{
ignoreService = 0,
indicateMissingService = 1,
forceSebService = 2
};
public enum browserViewModes
{
browserViewModeWindow = 0,
browserViewModeFullscreen = 1
};
// MAC
public enum sebPurposePolicies
{
sebPurposePolicyStartingExam = 0,
sebPurposePolicyConfiguringClient = 1
};
public enum URLFilterRuleActions
{
block = 0,
allow = 1,
ignore = 2,
unknown = 3
};
public enum SEBMinMacOSVersion
{
SEBMinOSX10_7 = 0,
SEBMinOSX10_8 = 1,
SEBMinOSX10_9 = 2,
SEBMinOSX10_10 = 3,
SEBMinOSX10_11 = 4,
SEBMinMacOS10_12 = 5,
SEBMinMacOS10_13 = 6,
SEBMinMacOS10_14 = 7
};
public class SEBClientInfo
{
#region Imports
[DllImport("kernel32.Dll")]
public static extern short GetVersionEx(ref OSVERSIONINFO o);
#endregion
// Socket protocol
//static int ai_family = AF_INET;
//static int ai_socktype = SOCK_STREAM;
//static int ai_protocol = IPPROTO_TCP;
#region Constants
// Name and location of SEB configuration files and logfiles
public const string SEB_CLIENT_CONFIG = "SebClientSettings.seb";
public const string SEB_CLIENT_LOG = "SebClient.log";
private const string XUL_RUNNER_CONFIG = "config.json";
public const string SEB_SHORTNAME = "SEB";
public const string XUL_RUNNER = "firefox.exe";
private const string XUL_RUNNER_INI = "seb.ini";
// Application path contains [MANUFACTURER]\[PRODUCT_NAME]
// (see also "SebWindowsPackageSetup" Project in MS Visual Studio 10)
public const string MANUFACTURER_LOCAL = "SafeExamBrowser";
//private const string MANUFACTURER = "ETH Zuerich";
public const string PRODUCT_NAME = "SafeExamBrowser";
public const string SEB_SERVICE_DIRECTORY = "SebWindowsServiceWCF";
public const string SEB_BROWSER_DIRECTORY = "SebWindowsBrowser";
private const string XUL_RUNNER_DIRECTORY = "xulrunner";
private const string XUL_SEB_DIRECTORY = "xul_seb";
public const string FILENAME_SEB = "SafeExamBrowser.exe";
public const string FILENAME_SEBCONFIGTOOL = "SEBConfigTool.exe";
public const string FILENAME_SEBSERVICE = "SebWindowsServiceWCF.exe";
public const string FILENAME_DLL_FLECK = "Fleck.dll";
public const string FILENAME_DLL_ICONLIB = "IconLib.dll";
public const string FILENAME_DLL_IONICZIP = "Ionic.Zip.dll";
public const string FILENAME_DLL_METRO = "MetroFramework.dll";
public const string FILENAME_DLL_NAUDIO = "NAudio.dll";
public const string FILENAME_DLL_NEWTONSOFTJSON = "Newtonsoft.Json.dll";
public const string FILENAME_DLL_SERVICECONTRACTS = "SEBWindowsServiceContracts.dll";
public const string BROWSER_USERAGENT_DESKTOP = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0";
public const string BROWSER_USERAGENT_TOUCH = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0; Touch) Gecko/20100101 Firefox/52.0";
public const string BROWSER_USERAGENT_TOUCH_IPAD = "Mozilla/5.0 (iPad; CPU OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.3 Mobile/15E216 Safari/605.1.15";
public const string BROWSER_USERAGENT_SEB = "SEB";
public const string END_OF_STRING_KEYWORD = "---SEB---";
private const string DEFAULT_USERNAME = "";
private const string DEFAULT_HOSTNAME = "localhost";
private const string DEFAULT_HOST_IP_ADDRESS = "127.0.0.1";
private const int DEFAULT_PORTNUMBER = 57016;
public const string DEFAULT_KEY = "Di𝈭l𝈖Ch𝈒ah𝉇t𝈁a𝉈Hai1972";
private const int DEFAULT_SEND_INTERVAL = 100;
private const int DEFAULT_RECV_TIMEOUT = 100;
private const int DEFAULT_NUM_MESSAGES = 3;
public const string SEB_NEW_DESKTOP_NAME = "SEBDesktop";
public const string SEB_WINDOWS_SERVICE_NAME = "SebWindowsService";
#endregion
#region Public Properties
public static bool ExplorerShellWasKilled { get; set; }
public static bool IsNewOS { get; set; }
public static bool examMode = false;
// SEB Client Socket properties
public static char[] UserNameRegistryFlags { get; set; }
public static char[] RegistryFlags { get; set; }
public static string HostName { get; set; }
public static string HostIpAddress { get; set; }
public static string UserName { get; set; }
public static char[] UserSid { get; set; }
public static int PortNumber { get; set; }
public static int SendInterval { get; set; }
public static int RecvTimeout { get; set; }
public static int NumMessages { get; set; }
public static int MessageNr { get; set; }
public static string DesktopName { get; set; }
// SEB Client Directories properties
public static string ApplicationExecutableDirectory { get; set; }
public static string ProgramFilesX86Directory { get; set; }
public static bool LogFileDesiredMsgHook { get; set; }
public static bool LogFileDesiredSebClient { get; set; }
public static string SebClientLogFileDirectory { get; set; }
public static string SebClientDirectory { get; set; }
public static string SebClientLogFile { get; set; }
public static string SebClientSettingsProgramDataDirectory { get; set; }
public static string SebClientSettingsAppDataDirectory { get; set; }
public static string XulRunnerAdditionalDictionariesDirectory { get; set; }
public static string XulRunnerDirectory { get; set; }
public static string XulSebDirectory { get; set; }
public static string SebClientSettingsProgramDataFile;
public static string SebClientSettingsAppDataFile;
public static string XulRunnerConfigFileDirectory { get; set; }
public static string XulRunnerConfigFile;
public static string XulRunnerExePath;
public static string XulRunnerSebIniPath;
public static string XulRunnerParameter;
//public static string XulRunnerFlashContainerState { get; set; }
public static string ExamUrl { get; set; }
public static string QuitPassword { get; set; }
public static string QuitHashcode { get; set; }
//public static Dictionary<string, object> sebSettings = new Dictionary<string, object>();
public static string LoadingSettingsFileName = "";
public static float scaleFactor = 1;
public static int appChooserHeight = 132;
#endregion
#region Structures
/// <summary>
/// Stores windows version info.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct OSVERSIONINFO
{
public int dwOSVersionInfoSize;
public int dwMajorVersion;
public int dwMinorVersion;
public int dwBuildNumber;
public int dwPlatformId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szCSDVersion;
}
#endregion
//public static SEBClientConfig sebClientConfig;
public static Dictionary<string, object> getSebSetting(string key)
{
object sebSetting = null;
try
{
sebSetting = SEBSettings.settingsCurrent[key];
}
catch
{
sebSetting = null;
}
if (sebSetting != null)
return SEBSettings.settingsCurrent;
else
return SEBSettings.settingsDefault;
}
/// <summary>
/// Sets user, host info, send-recv interval, recv timeout, Logger and read SebClient configuration.
/// </summary>
/// <returns></returns>
public static bool SetSebClientConfiguration()
{
bool setSebClientConfiguration = false;
// Initialise socket properties
IsNewOS = false;
ExplorerShellWasKilled = false;
UserNameRegistryFlags = new char[100];
RegistryFlags = new char[50];
UserSid = new char[512];
UserName = DEFAULT_USERNAME;
HostName = DEFAULT_HOSTNAME;
HostIpAddress = DEFAULT_HOST_IP_ADDRESS;
PortNumber = DEFAULT_PORTNUMBER;
SendInterval = DEFAULT_SEND_INTERVAL;
RecvTimeout = DEFAULT_RECV_TIMEOUT;
NumMessages = DEFAULT_NUM_MESSAGES;
//Sets paths to files SEB has to save or read from the file system
SetSebPaths();
byte[] sebClientSettings = null;
// Create a string builder for a temporary log (until we can write it with the Logger)
StringBuilder tempLogStringBuilder = new StringBuilder();
// Try to read the SebClientSettigs.seb file from the program data directory
try
{
sebClientSettings = File.ReadAllBytes(SebClientSettingsProgramDataFile);
}
catch (Exception streamReadException)
{
// Write error into string with temporary log string builder
tempLogStringBuilder.Append("Could not load SebClientSettigs.seb from the Program Data directory").Append(streamReadException == null ? null : streamReadException.GetType().ToString()).Append(streamReadException.Message);
}
if (sebClientSettings == null)
{
// Try to read the SebClientSettigs.seb file from the local application data directory
try
{
sebClientSettings = File.ReadAllBytes(SebClientSettingsAppDataFile);
}
catch (Exception streamReadException)
{
// Write error into string with temporary log string builder
tempLogStringBuilder.Append("Could not load SebClientSettigs.seb from the Roaming Application Data directory. ").Append(streamReadException == null ? null : streamReadException.GetType().ToString()).Append(streamReadException.Message);
}
}
// Store the decrypted configuration settings.
if (!SEBSettings.StoreDecryptedSebClientSettings(sebClientSettings))
return false;
// Initialise Logger, if enabled
InitializeLogger();
// Save the temporary log string into the log
Logger.AddError(tempLogStringBuilder.ToString(), null, null);
// Set username
UserName = Environment.UserName;
setSebClientConfiguration = true;
// Write settings into log
StringBuilder userInfo =
new StringBuilder ("User Name: " ).Append(UserName)
.Append(" Host Name: " ).Append(HostName)
.Append(" Port Number: " ).Append(PortNumber)
.Append(" Send Interval: " ).Append(SendInterval)
.Append(" Recv Timeout: " ).Append(RecvTimeout)
.Append(" Num Messages: " ).Append(NumMessages)
.Append(" SebClientConfigFileDirectory: ").Append(SebClientSettingsAppDataDirectory)
.Append(" SebClientConfigFile: " ).Append(SebClientSettingsAppDataFile);
Logger.AddInformation(userInfo.ToString(), null, null);
return setSebClientConfiguration;
}
/// <summary>
/// Initialise Logger if it's enabled.
/// </summary>
public static void InitializeLogger()
{
if ((Boolean)getSebSetting(SEBSettings.KeyEnableLogging)[SEBSettings.KeyEnableLogging])
{
string logDirectory = (string)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyLogDirectoryWin);
if (!String.IsNullOrEmpty(logDirectory))
{
// Expand environment variables in log file path
SebClientLogFileDirectory = Environment.ExpandEnvironmentVariables(logDirectory);
SebClientLogFile = String.Format(@"{0}\{1}", SebClientLogFileDirectory, SEB_CLIENT_LOG);
}
else
{
SEBClientInfo.SetDefaultClientLogFile();
}
Logger.InitLogger(SEBClientInfo.SebClientLogFileDirectory, null);
}
}
/// <summary>
/// Sets paths to files SEB has to save or read from the file system.
/// </summary>
public static void SetSebPaths()
{
// Get the path of the directory the application executable lies in
ApplicationExecutableDirectory = Path.GetDirectoryName(Application.ExecutablePath);
// Get the path of the "Program Files X86" directory.
ProgramFilesX86Directory = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
// Get the path of the "Program Data" and "Local Application Data" directory.
string programDataDirectory = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); //GetEnvironmentVariable("PROGRAMMDATA");
string appDataDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
/// Get paths for the two possible locations of the SebClientSettings.seb file
///
// In the program data directory (for managed systems, only an administrator can write in this directory):
// If there is a SebClientSettigs.seb file, then this has priority and is used by the SEB client, another
// SebClientSettigs.seb file in the local app data folder is ignored then and the SEB client cannot be
// reconfigured by opening a .seb file saved for configuring a client
StringBuilder sebClientSettingsProgramDataDirectoryBuilder = new StringBuilder(programDataDirectory).Append("\\").Append(MANUFACTURER_LOCAL).Append("\\"); //.Append(PRODUCT_NAME).Append("\\");
SebClientSettingsProgramDataDirectory = sebClientSettingsProgramDataDirectoryBuilder.ToString();
// In the local application data directory (for unmanaged systems like student computers, user can write in this directory):
// A SebClientSettigs.seb file in this directory can be created or replaced by opening a .seb file saved for configuring a client
StringBuilder sebClientSettingsAppDataDirectoryBuilder = new StringBuilder(appDataDirectory).Append("\\").Append(MANUFACTURER_LOCAL).Append("\\"); //.Append(PRODUCT_NAME).Append("\\");
SebClientSettingsAppDataDirectory = sebClientSettingsAppDataDirectoryBuilder.ToString();
// Set the location of the SebWindowsClientDirectory
StringBuilder sebClientDirectoryBuilder = new StringBuilder(ProgramFilesX86Directory).Append("\\").Append(PRODUCT_NAME).Append("\\");
SebClientDirectory = sebClientDirectoryBuilder.ToString();
// The directory into which additional dictionaries are extracted.
XulRunnerAdditionalDictionariesDirectory = Path.Combine(SebClientSettingsAppDataDirectory, "Dictionaries");
// Set the location of the XulRunnerDirectory
//StringBuilder xulRunnerDirectoryBuilder = new StringBuilder(SebClientDirectory).Append(XUL_RUNNER_DIRECTORY).Append("\\");
//XulRunnerDirectory = xulRunnerDirectoryBuilder.ToString();
StringBuilder xulRunnerDirectoryBuilder = new StringBuilder(SEB_BROWSER_DIRECTORY).Append("\\").Append(XUL_RUNNER_DIRECTORY).Append("\\");
XulRunnerDirectory = xulRunnerDirectoryBuilder.ToString();
// Set the location of the XulSebDirectory
//StringBuilder xulSebDirectoryBuilder = new StringBuilder(SebClientDirectory).Append(XUL_SEB_DIRECTORY).Append("\\");
//XulSebDirectory = xulSebDirectoryBuilder.ToString();
StringBuilder xulSebDirectoryBuilder = new StringBuilder(SEB_BROWSER_DIRECTORY).Append("\\").Append(XUL_SEB_DIRECTORY).Append("\\");
XulSebDirectory = xulSebDirectoryBuilder.ToString();
// Set the location of the XulRunnerExePath
//StringBuilder xulRunnerExePathBuilder = new StringBuilder("\"").Append(XulRunnerDirectory).Append(XUL_RUNNER).Append("\"");
//XulRunnerExePath = xulRunnerExePathBuilder.ToString();
StringBuilder xulRunnerExePathBuilder = new StringBuilder(XulRunnerDirectory).Append(XUL_RUNNER); //.Append("\"");
XulRunnerExePath = xulRunnerExePathBuilder.ToString();
// Set the location of the seb.ini
StringBuilder xulRunnerSebIniPathBuilder = new StringBuilder(XulSebDirectory).Append(XUL_RUNNER_INI); //.Append("\"");
XulRunnerSebIniPath = xulRunnerSebIniPathBuilder.ToString();
// Get the two possible paths of the SebClientSettings.seb file
StringBuilder sebClientSettingsProgramDataBuilder = new StringBuilder(SebClientSettingsProgramDataDirectory).Append(SEB_CLIENT_CONFIG);
SebClientSettingsProgramDataFile = sebClientSettingsProgramDataBuilder.ToString();
StringBuilder sebClientSettingsAppDataBuilder = new StringBuilder(SebClientSettingsAppDataDirectory).Append(SEB_CLIENT_CONFIG);
SebClientSettingsAppDataFile = sebClientSettingsAppDataBuilder.ToString();
// Set the default location of the SebClientLogFileDirectory
SetDefaultClientLogFile();
}
/// <summary>
/// Set the default location of the SebClientLogFileDirectory.
/// </summary>
public static void SetDefaultClientLogFile()
{
StringBuilder SebClientLogFileDirectoryBuilder = new StringBuilder(SebClientSettingsAppDataDirectory); //.Append("\\").Append(MANUFACTURER_LOCAL).Append("\\");
SebClientLogFileDirectory = SebClientLogFileDirectoryBuilder.ToString();
// Set the path of the SebClient.log file
StringBuilder sebClientLogFileBuilder = new StringBuilder(SebClientLogFileDirectory).Append(SEB_CLIENT_LOG);
SebClientLogFile = sebClientLogFileBuilder.ToString();
}
public static bool CreateNewDesktopOldValue { get; set; }
public static string ContractEnvironmentVariables(string path)
{
path = Path.GetFullPath(path);
DictionaryEntry currentEntry = new DictionaryEntry("", "");
foreach (object key in Environment.GetEnvironmentVariables().Keys)
{
string value = (string)Environment.GetEnvironmentVariables()[key];
if (path.ToUpperInvariant().Contains(value.ToUpperInvariant()) && value.Length > ((string)currentEntry.Value).Length)
{
currentEntry.Key = (string)key;
currentEntry.Value = value;
}
}
return path.Replace((string)currentEntry.Value, "%" + (string)currentEntry.Key + "%");
}
}
}