/// <summary> /// Capture keystrokes and filter which key events are permitted to continue. /// </summary> private static IntPtr CaptureMouseButton(int nCode, IntPtr wp, IntPtr lp) { // If the nCode is non-negative, filter the key stroke. if (nCode >= 0) { if ( (bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyTouchOptimized) && (bool) SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyEnableTouchExit)) { TestTouchExitSequence(System.Windows.Forms.Cursor.Position); } //KBDLLHOOKSTRUCT KeyInfo = // (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT)); // Reject any key that's not on our list. if (DisableMouseButton(nCode, wp, lp)) { return((IntPtr)1); } } // Pass the event to the next hook in the chain. return(CallNextHookEx(ptrMouseHook, nCode, wp, lp)); }
private void btnCancel_Click(object sender, EventArgs e) { this.txtQuitPassword.Text = ""; this.Visible = false; if ((bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyTouchOptimized)) { var topWindow = SEBWindowHandler.GetOpenWindows().FirstOrDefault(); if (topWindow.Value != null) { topWindow.Key.AdaptWindowToWorkingArea(); } } }
public static void ShowKeyboard(bool force = false) { try { if (IsPhysicalKeyboardAttached() && !force && (int)SEBSettings.settingsCurrent[SEBSettings.KeyOskBehavior] == 2) { return; } if (!(bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyTouchOptimized)) { return; } if (IsKeyboardVisible()) { return; } if (!SEBWindowHandler.AllowedExecutables.Contains("tabtip.exe")) { SEBWindowHandler.AllowedExecutables.Add("tabtip.exe"); } //TODO: Use Environment Variable here, but with SEB running as 32bit it always takes X86 //string programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); string programFiles = @"C:\Program Files"; string inkDir = @"Common Files\Microsoft Shared\ink"; string onScreenKeyboardPath = Path.Combine(programFiles, inkDir, "TabTip.exe"); Process.Start(onScreenKeyboardPath); if (OnKeyboardStateChanged != null) { var t = new System.Timers.Timer { Interval = 500 }; t.Elapsed += (sender, args) => { if (!IsKeyboardVisible()) { t.Stop(); OnKeyboardStateChanged(false); } }; t.Start(); OnKeyboardStateChanged(true); } } catch { } }
public static bool SetSebClientConfiguration() { SEBClientInfo.IsNewOS = false; SEBClientInfo.ExplorerShellWasKilled = false; SEBClientInfo.UserNameRegistryFlags = new char[100]; SEBClientInfo.RegistryFlags = new char[50]; SEBClientInfo.UserSid = new char[512]; SEBClientInfo.UserName = ""; SEBClientInfo.HostName = "localhost"; SEBClientInfo.HostIpAddress = "127.0.0.1"; SEBClientInfo.PortNumber = 57016; SEBClientInfo.SendInterval = 100; SEBClientInfo.RecvTimeout = 100; SEBClientInfo.NumMessages = 3; SEBClientInfo.SetSebPaths(); byte[] sebSettings = (byte[])null; StringBuilder stringBuilder = new StringBuilder(); try { sebSettings = File.ReadAllBytes(SEBClientInfo.SebClientSettingsProgramDataFile); } catch (Exception ex) { stringBuilder.Append("Could not load SebClientSettigs.seb from the Program Data directory").Append(ex == null ? (string)null : ex.GetType().ToString()).Append(ex.Message); } if (sebSettings == null) { try { sebSettings = File.ReadAllBytes(SEBClientInfo.SebClientSettingsAppDataFile); } catch (Exception ex) { stringBuilder.Append("Could not load SebClientSettigs.seb from the Roaming Application Data directory. ").Append(ex == null ? (string)null : ex.GetType().ToString()).Append(ex.Message); } } if (!SEBSettings.StoreDecryptedSebClientSettings(sebSettings)) { return(false); } SEBClientInfo.InitializeLogger(); Logger.AddError(stringBuilder.ToString(), (object)null, (Exception)null, (string)null); SEBClientInfo.UserName = Environment.UserName; int num = 1; Logger.AddInformation(new StringBuilder("User Name: ").Append(SEBClientInfo.UserName).Append(" Host Name: ").Append(SEBClientInfo.HostName).Append(" Port Number: ").Append(SEBClientInfo.PortNumber).Append(" Send Interval: ").Append(SEBClientInfo.SendInterval).Append(" Recv Timeout: ").Append(SEBClientInfo.RecvTimeout).Append(" Num Messages: ").Append(SEBClientInfo.NumMessages).Append(" SebClientConfigFileDirectory: ").Append(SEBClientInfo.SebClientSettingsAppDataDirectory).Append(" SebClientConfigFile: ").Append(SEBClientInfo.SebClientSettingsAppDataFile).ToString(), (object)null, (Exception)null, (string)null); return(num != 0); }
private static IntPtr CaptureMouseButton(int nCode, IntPtr wp, IntPtr lp) { if (nCode >= 0) { if ((bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "touchOptimized") && (bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "enableTouchExit")) { SebKeyCapture.TestTouchExitSequence(Cursor.Position); } if (SebKeyCapture.DisableMouseButton(nCode, wp, lp)) { return((IntPtr)1); } } return(SebKeyCapture.CallNextHookEx(SebKeyCapture.ptrMouseHook, nCode, wp, lp)); }
private void ResizeTopOpenWindow() { try { if ((bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyTouchOptimized)) { var topWindow = SEBWindowHandler.GetOpenWindows().FirstOrDefault(); if (topWindow.Value != null) { topWindow.Key.AdaptWindowToWorkingArea(); } } } catch { } }
private void btnCancel_Click(object sender, EventArgs e) { this.txtQuitPassword.Text = ""; this.Visible = false; if (!(bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "touchOptimized")) { return; } KeyValuePair <IntPtr, string> keyValuePair = SEBWindowHandler.GetOpenWindows().FirstOrDefault <KeyValuePair <IntPtr, string> >(); if (keyValuePair.Value == null) { return; } keyValuePair.Key.AdaptWindowToWorkingArea(new int?()); }
/// ---------------------------------------------------------------------------------------- /// <summary> /// Helper method: Get preferences dictionary from decrypted data. /// In editing mode, users have to enter the right SEB administrator password /// before they can access the settings contents /// and returns the decrypted bytes /// </summary> /// ---------------------------------------------------------------------------------------- private static DictObj GetPreferencesDictFromConfigData(byte[] sebData, bool forEditing) { DictObj sebPreferencesDict = null; try { // Get preferences dictionary from decrypted data sebPreferencesDict = (DictObj)Plist.readPlist(sebData); } catch (Exception readPlistException) { MessageBox.Show(SEBUIStrings.loadingSettingsFailed, SEBUIStrings.loadingSettingsFailedReason, MessageBoxButtons.OK, MessageBoxIcon.Error); Console.WriteLine(readPlistException.Message); return(null); } // In editing mode, the user has to enter the right SEB administrator password used in those settings before he can access their contents if (forEditing) { // Get the admin password set in these settings string sebFileHashedAdminPassword = (string)SEBSettings.valueForDictionaryKey(sebPreferencesDict, SEBSettings.KeyHashedAdminPassword); // If there was no or empty admin password set in these settings, the user can access them anyways if (!String.IsNullOrEmpty(sebFileHashedAdminPassword)) { // Get the current hashed admin password string hashedAdminPassword = (string)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyHashedAdminPassword); if (hashedAdminPassword == null) { hashedAdminPassword = ""; } // If the current hashed admin password is same as the hashed admin password from the settings file // then the user is allowed to access the settings if (String.Compare(hashedAdminPassword, sebFileHashedAdminPassword, StringComparison.OrdinalIgnoreCase) != 0) { // otherwise we have to ask for the SEB administrator password used in those settings and // allow opening settings only if the user enters the right one if (!askForPasswordAndCompareToHashedPassword(sebFileHashedAdminPassword, forEditing)) { return(null); } } } } // Reading preferences was successful! return(sebPreferencesDict); }
/// ---------------------------------------------------------------------------------------- /// <summary> /// Compute a Browser Exam Key SHA256 hash base16 string. /// </summary> /// ---------------------------------------------------------------------------------------- public static string ComputeBrowserExamKey() { // Serialize preferences dictionary to an XML string string sebXML = Plist.writeXml(SEBSettings.settingsCurrent); //Add the Hash of the Executable and of the XulRunnerFiles to the message sebXML = String.Format("{0}{1}", sebXML, ComputeSEBComponentsHash()); byte[] message = Encoding.UTF8.GetBytes(sebXML); byte[] salt = (byte[])SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyExamKeySalt); var hash = new HMACSHA256(salt); byte[] browserExamKey = hash.ComputeHash(message); string browserExamKeyString = BitConverter.ToString(browserExamKey); return(browserExamKeyString.Replace("-", "").ToLower()); }
public static void InitializeLogger() { if (!(bool)SEBClientInfo.getSebSetting("enableLogging")["enableLogging"]) { return; } string name = (string)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "logDirectoryWin"); if (!string.IsNullOrEmpty(name)) { SEBClientInfo.SebClientLogFileDirectory = Environment.ExpandEnvironmentVariables(name); SEBClientInfo.SebClientLogFile = string.Format("{0}\\{1}", (object)SEBClientInfo.SebClientLogFileDirectory, (object)"SebClient.log"); } else { SEBClientInfo.SetDefaultClientLogFile(); } Logger.InitLogger(SEBClientInfo.SebClientLogFileDirectory, (string)null); }
private void ResizeTopOpenWindow() { try { if (!(bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "touchOptimized")) { return; } KeyValuePair <IntPtr, string> keyValuePair = SEBWindowHandler.GetOpenWindows().FirstOrDefault <KeyValuePair <IntPtr, string> >(); if (keyValuePair.Value == null) { return; } keyValuePair.Key.AdaptWindowToWorkingArea(new int?()); } catch { } }
/// <summary> /// Test app exit keys sequence /// </summary> private static void TestAppExitSequences(IntPtr wp, IntPtr lp) { if (wp == (IntPtr)WM_KEYDOWN) { if (SetAndTestCtrlQExitSequence(wp, lp)) { SEBClientInfo.SebWindowsClientForm.ShowCloseDialogForm(); } if (SetAndTestExitKeySequence(wp, lp) && (bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyIgnoreExitKeys) == false) { SEBClientInfo.SebWindowsClientForm.ExitApplication(); } } else if (wp == (IntPtr)WM_KEYUP) { ResetCtrlQExitSequence(wp, lp); ResetExitKeySequence(wp, lp); } }
/// <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); } }
public static void CheckIfTabletModeIsEnabled() { if ((bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyTouchOptimized)) { bool?tabletMode = null; try { //returns null if the key is not existing (another windows version than 10) tabletMode = (int)Registry.GetValue("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ImmersiveShell", "TabletMode", 1) == 1; } catch (Exception ex) { Logger.AddError("Unable to check for tablet mode, assuming its not a Windows Version with a tablet mode and if so, ignore this error", null, ex, ex.StackTrace); } if (tabletMode != null && tabletMode == false) { SEBMessageBox.Show(SEBUIStrings.tableModeNotEnabledWarningTitle, SEBUIStrings.tableModeNotEnabledWarningText, MessageBoxIcon.Error, MessageBoxButtons.OK); Logger.AddInformation("Windows Tablet mode was not enabled, exiting seb", null, null); throw new SEBNotAllowedToRunEception("SEB not running without Tablet mode..."); } } }
public static void CheckDistributionIntegrity() { string path1 = SEBXulRunnerSettings.ResolveResourcePath((string)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "startURL")); string path2 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "SafeExamBrowser", "SebClientSettings.seb"); if (!File.Exists(path1)) { throw new Exception(string.Format("Distribution is corrupted, file \"{0}\" isn't exists, it's insecure to run app now.", (object)path1)); } if (!File.Exists(path2)) { throw new Exception(string.Format("Distribution is corrupted, file \"{0}\" isn't exists, it's insecure to run app now.", (object)path2)); } byte[] array = ((IEnumerable <byte>)File.ReadAllBytes(path1)).Concat <byte>((IEnumerable <byte>)File.ReadAllBytes(path2)).ToArray <byte>(); string base64String; using (MD5 md5 = MD5.Create()) base64String = Convert.ToBase64String(md5.ComputeHash(array)); if (base64String != IntegrityConstants.IndexCRC) { throw new Exception("Distribution was changed externally, it's insecure to run app now."); } }
private static Dictionary <string, object> GetPreferencesDictFromConfigData(byte[] sebData, bool forEditing) { Dictionary <string, object> dictionary; try { dictionary = (Dictionary <string, object>)Plist.readPlist(sebData); } catch (Exception ex) { int num = (int)SEBMessageBox.Show(SEBUIStrings.loadingSettingsFailed, SEBUIStrings.loadingSettingsFailedReason, MessageBoxIcon.Hand, MessageBoxButtons.OK, forEditing); Console.WriteLine(ex.Message); return((Dictionary <string, object>)null); } if (forEditing) { string str = (string)SEBSettings.valueForDictionaryKey(dictionary, "hashedAdminPassword"); if (!string.IsNullOrEmpty(str) && (string.Compare((string)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "hashedAdminPassword") ?? "", str, StringComparison.OrdinalIgnoreCase) != 0 && !SEBConfigFileManager.askForPasswordAndCompareToHashedPassword(str, forEditing))) { return((Dictionary <string, object>)null); } } return(dictionary); }
private static void TestAppExitSequences(IntPtr wp, IntPtr lp) { if (wp == (IntPtr)256) { if (SebKeyCapture.SetAndTestCtrlQExitSequence(wp, lp)) { SEBClientInfo.SebWindowsClientForm.ShowCloseDialogForm(); } if (!SebKeyCapture.SetAndTestExitKeySequence(wp, lp) || (bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "ignoreExitKeys")) { return; } SEBClientInfo.SebWindowsClientForm.ExitApplication(true); } else { if (!(wp == (IntPtr)257)) { return; } SebKeyCapture.ResetCtrlQExitSequence(wp, lp); SebKeyCapture.ResetExitKeySequence(wp, lp); } }
public static void ShowKeyboard(bool force = false) { try { if (TapTipHandler.IsPhysicalKeyboardAttached() && !force && (int)SEBSettings.settingsCurrent["oskBehavior"] == 2 || (!(bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "touchOptimized") || TapTipHandler.IsKeyboardVisible())) { return; } if (!SEBWindowHandler.AllowedExecutables.Contains("tabtip.exe")) { SEBWindowHandler.AllowedExecutables.Add("tabtip.exe"); } Process.Start(Path.Combine("C:\\Program Files", "Common Files\\Microsoft Shared\\ink", "TabTip.exe")); // ISSUE: reference to a compiler-generated field if (TapTipHandler.OnKeyboardStateChanged == null) { return; } Timer t = new Timer() { Interval = 500.0 }; t.Elapsed += (ElapsedEventHandler)((sender, args) => { if (TapTipHandler.IsKeyboardVisible()) { return; } t.Stop(); // ISSUE: reference to a compiler-generated field TapTipHandler.OnKeyboardStateChanged(false); }); t.Start(); // ISSUE: reference to a compiler-generated field TapTipHandler.OnKeyboardStateChanged(true); } catch { } }
public static bool StoreDecryptedSEBSettings(byte[] sebData) { string sebFilePassword = (string)null; bool passwordIsHash = false; X509Certificate2 sebFileCertificateRef = (X509Certificate2)null; Dictionary <string, object> settingsDict = SEBConfigFileManager.DecryptSEBSettings(sebData, false, ref sebFilePassword, ref passwordIsHash, ref sebFileCertificateRef); if (settingsDict == null) { return(false); } Logger.AddInformation("Reconfiguring", (object)null, (Exception)null, (string)null); SEBClientInfo.SebWindowsClientForm.closeSebClient = false; Logger.AddInformation("Attempting to CloseSEBForm for reconfiguration", (object)null, (Exception)null, (string)null); SEBClientInfo.SebWindowsClientForm.CloseSEBForm(); Logger.AddInformation("Succesfully CloseSEBForm for reconfiguration", (object)null, (Exception)null, (string)null); SEBClientInfo.SebWindowsClientForm.closeSebClient = true; SEBClientInfo.CreateNewDesktopOldValue = (bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "createNewDesktop"); if ((int)settingsDict["sebConfigPurpose"] == 0) { Logger.AddInformation("Reconfiguring to start an exam", (object)null, (Exception)null, (string)null); Logger.AddInformation("Attempting to StoreSebClientSettings", (object)null, (Exception)null, (string)null); SEBSettings.StoreSebClientSettings(settingsDict); Logger.AddInformation("Successfully StoreSebClientSettings", (object)null, (Exception)null, (string)null); SEBClientInfo.examMode = true; SEBClientInfo.InitializeLogger(); if (SEBClientInfo.CreateNewDesktopOldValue != (bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "createNewDesktop")) { if (!SEBClientInfo.CreateNewDesktopOldValue) { int num1 = (int)SEBMessageBox.Show(SEBUIStrings.settingsRequireNewDesktop, SEBUIStrings.settingsRequireNewDesktopReason, MessageBoxIcon.Hand, MessageBoxButtons.OK, false); } else { int num2 = (int)SEBMessageBox.Show(SEBUIStrings.settingsRequireNotNewDesktop, SEBUIStrings.settingsRequireNotNewDesktopReason, MessageBoxIcon.Hand, MessageBoxButtons.OK, false); } SEBClientInfo.SebWindowsClientForm.ExitApplication(true); } Logger.AddInformation("Attemting to InitSEBDesktop for reconfiguration", (object)null, (Exception)null, (string)null); if (!SebWindowsClientMain.InitSEBDesktop()) { return(false); } Logger.AddInformation("Sucessfully InitSEBDesktop for reconfiguration", (object)null, (Exception)null, (string)null); Logger.AddInformation("Attempting to OpenSEBForm for reconfiguration", (object)null, (Exception)null, (string)null); int num = SEBClientInfo.SebWindowsClientForm.OpenSEBForm() ? 1 : 0; Logger.AddInformation("Successfully OpenSEBForm for reconfiguration", (object)null, (Exception)null, (string)null); return(num != 0); } Logger.AddInformation("Reconfiguring to configure a client", (object)null, (Exception)null, (string)null); List <object> objectList = (List <object>)settingsDict["embeddedCertificates"]; for (int index = objectList.Count - 1; index >= 0; --index) { Dictionary <string, object> dictionary = (Dictionary <string, object>)objectList[index]; if ((int)dictionary["type"] == 1) { SEBProtectionController.StoreCertificateIntoStore((byte[])dictionary["certificateData"]); } objectList.RemoveAt(index); } SEBSettings.StoreSebClientSettings(settingsDict); SEBClientInfo.InitializeLogger(); SEBSettings.WriteSebConfigurationFile(SEBClientInfo.SebClientSettingsAppDataFile, "", false, (X509Certificate2)null, SEBSettings.sebConfigPurposes.sebConfigPurposeConfiguringClient, false); if (!SebWindowsClientMain.InitSEBDesktop() || !SEBClientInfo.SebWindowsClientForm.OpenSEBForm()) { return(false); } if (SEBClientInfo.CreateNewDesktopOldValue != (bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "createNewDesktop")) { int num = (int)SEBMessageBox.Show(SEBUIStrings.sebReconfiguredRestartNeeded, SEBUIStrings.sebReconfiguredRestartNeededReason, MessageBoxIcon.Exclamation, MessageBoxButtons.OK, false); SEBClientInfo.SebWindowsClientForm.ExitApplication(true); } if (SEBMessageBox.Show(SEBUIStrings.sebReconfigured, SEBUIStrings.sebReconfiguredQuestion, MessageBoxIcon.Question, MessageBoxButtons.YesNo, false) == DialogResult.No) { SEBClientInfo.SebWindowsClientForm.ExitApplication(true); } return(true); }
///// ---------------------------------------------------------------------------------------- ///// <summary> ///// Show SEB Password Dialog Form. ///// </summary> ///// ---------------------------------------------------------------------------------------- //public static string ShowPasswordDialogForm(string title, string passwordRequestText) //{ // // Set the title of the dialog window // sebPasswordDialogForm.Text = title; // // Set the text of the dialog // sebPasswordDialogForm.LabelText = passwordRequestText; // sebPasswordDialogForm.txtSEBPassword.Focus(); // // If we are running in SebWindowsClient we need to activate it before showing the password dialog // if (SEBClientInfo.SebWindowsClientForm != null) SebWindowsClientForm.SEBToForeground(); //SEBClientInfo.SebWindowsClientForm.Activate(); // // Show password dialog as a modal dialog and determine if DialogResult = OK. // if (sebPasswordDialogForm.ShowDialog() == DialogResult.OK) // { // // Read the contents of testDialog's TextBox. // string password = sebPasswordDialogForm.txtSEBPassword.Text; // sebPasswordDialogForm.txtSEBPassword.Text = ""; // //sebPasswordDialogForm.txtSEBPassword.Focus(); // return password; // } // else // { // return null; // } //} /// Generate Encrypted .seb Settings Data /// ---------------------------------------------------------------------------------------- /// <summary> /// Read SEB settings from UserDefaults and encrypt them using provided security credentials /// </summary> /// ---------------------------------------------------------------------------------------- public static byte[] EncryptSEBSettingsWithCredentials(string settingsPassword, bool passwordIsHash, X509Certificate2 certificateRef, SEBSettings.sebConfigPurposes configPurpose, bool forEditing) { // Get current settings dictionary and clean it from empty arrays and dictionaries //DictObj cleanedCurrentSettings = SEBSettings.CleanSettingsDictionary(); // Serialize preferences dictionary to an XML string string sebXML = Plist.writeXml(SEBSettings.settingsCurrent); string cleanedSebXML = sebXML.Replace("<array />", "<array></array>"); cleanedSebXML = cleanedSebXML.Replace("<dict />", "<dict></dict>"); cleanedSebXML = cleanedSebXML.Replace("<data />", "<data></data>"); byte[] encryptedSebData = Encoding.UTF8.GetBytes(cleanedSebXML); string encryptingPassword = null; // Check for special case: .seb configures client, empty password if (String.IsNullOrEmpty(settingsPassword) && configPurpose == SEBSettings.sebConfigPurposes.sebConfigPurposeConfiguringClient) { encryptingPassword = ""; } else { // in all other cases: // Check if no password entered and no identity selected if (String.IsNullOrEmpty(settingsPassword) && certificateRef == null) { if (SEBMessageBox.Show(SEBUIStrings.noEncryptionChosen, SEBUIStrings.noEncryptionChosenSaveUnencrypted, MessageBoxIcon.Question, MessageBoxButtons.YesNo, neverShowTouchOptimized: forEditing) == DialogResult.Yes) { // OK: save .seb config data unencrypted return encryptedSebData; } else { return null; } } } // gzip the serialized XML data encryptedSebData = GZipByte.Compress(encryptedSebData); // Check if password for encryption is provided and use it then if (!String.IsNullOrEmpty(settingsPassword)) { encryptingPassword = settingsPassword; } // So if password is empty (special case) or provided if (!(encryptingPassword == null)) { // encrypt with password encryptedSebData = EncryptDataUsingPassword(encryptedSebData, encryptingPassword, passwordIsHash, configPurpose); } else { // Create byte array large enough to hold prefix and data byte[] encryptedData = new byte[encryptedSebData.Length + PREFIX_LENGTH]; // if no encryption with password: Add a 4-char prefix identifying plain data string prefixString = PLAIN_DATA_MODE; Buffer.BlockCopy(Encoding.UTF8.GetBytes(prefixString), 0, encryptedData, 0, PREFIX_LENGTH); // append plain data Buffer.BlockCopy(encryptedSebData, 0, encryptedData, PREFIX_LENGTH, encryptedSebData.Length); encryptedSebData = (byte[])encryptedData.Clone(); } // Check if cryptographic identity for encryption is selected if (certificateRef != null) { // Encrypt preferences using a cryptographic identity encryptedSebData = EncryptDataUsingIdentity(encryptedSebData, certificateRef); } // gzip the encrypted data encryptedSebData = GZipByte.Compress(encryptedSebData); return encryptedSebData; }
/// ---------------------------------------------------------------------------------------- /// <summary> /// Encrypt preferences using a password /// </summary> /// ---------------------------------------------------------------------------------------- // Encrypt preferences using a password public static byte[] EncryptDataUsingPassword(byte[] data, string password, bool passwordIsHash, SEBSettings.sebConfigPurposes configPurpose) { string prefixString; // Check if .seb file should start exam or configure client if (configPurpose == SEBSettings.sebConfigPurposes.sebConfigPurposeStartingExam) { // prefix string for starting exam: normal password will be prompted prefixString = PASSWORD_MODE; } else { // prefix string for configuring client: configuring password will either be hashed admin pw on client // or if no admin pw on client set: empty pw prefixString = PASSWORD_CONFIGURING_CLIENT_MODE; if (!String.IsNullOrEmpty(password) && !passwordIsHash) { //empty password means no admin pw on clients and should not be hashed //or we got already a hashed admin pw as settings pw, then we don't hash again password = SEBProtectionController.ComputePasswordHash(password); } } byte[] encryptedData = SEBProtectionController.EncryptDataWithPassword(data, password); // Create byte array large enough to hold prefix and data byte[] encryptedSebData = new byte[encryptedData.Length + PREFIX_LENGTH]; Buffer.BlockCopy(Encoding.UTF8.GetBytes(prefixString), 0, encryptedSebData, 0, PREFIX_LENGTH); Buffer.BlockCopy(encryptedData, 0, encryptedSebData, PREFIX_LENGTH, encryptedData.Length); return encryptedSebData; }
public static void CheckIfRunViaRemoteConnection() { if (System.Windows.Forms.SystemInformation.TerminalServerSession && !(bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyAllowScreenSharing)) { SEBMessageBox.Show(SEBUIStrings.detectedRemoteConnection, SEBUIStrings.detectedRemoteConnectionMessage, MessageBoxIcon.Error, MessageBoxButtons.OK); Logger.AddError("Forbidden to run SEB via Terminal Session!", null, null); Logger.AddInformation("Safe Exam Browser is exiting", null, null); throw new SEBNotAllowedToRunEception("Forbidden to run SEB via Terminal Session!"); } }
private static Dictionary <string, object> DecryptDataWithPasswordForConfiguringClient(byte[] sebData, bool forEditing, ref string sebFilePassword, ref bool passwordIsHash) { passwordIsHash = false; string upper = ((string)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "hashedAdminPassword") ?? "").ToUpper(); byte[] input1 = SEBProtectionController.DecryptDataWithPassword(sebData, upper); string str1; if (input1 == null) { input1 = SEBProtectionController.DecryptDataWithPassword(sebData, ""); if (input1 == null) { int num1 = 5; str1 = (string)null; string passwordRequestText = SEBUIStrings.enterEncryptionPassword; string input2; do { --num1; input2 = ThreadedDialog.ShowPasswordDialogForm(SEBUIStrings.reconfiguringLocalSettings, passwordRequestText); if (input2 == null) { return((Dictionary <string, object>)null); } string passwordHash = SEBProtectionController.ComputePasswordHash(input2); input1 = SEBProtectionController.DecryptDataWithPassword(sebData, passwordHash); passwordRequestText = SEBUIStrings.enterEncryptionPasswordAgain; }while (input1 == null && num1 > 0); if (input1 == null) { int num2 = (int)SEBMessageBox.Show(SEBUIStrings.reconfiguringLocalSettingsFailed, SEBUIStrings.reconfiguringLocalSettingsFailedWrongPassword, MessageBoxIcon.Hand, MessageBoxButtons.OK, forEditing); return((Dictionary <string, object>)null); } if (forEditing) { sebFilePassword = input2; } } } else { sebFilePassword = upper; passwordIsHash = true; } byte[] data = GZipByte.Decompress(input1); Dictionary <string, object> dictionary; try { dictionary = (Dictionary <string, object>)Plist.readPlist(data); } catch (Exception ex) { int num = (int)SEBMessageBox.Show(SEBUIStrings.loadingSettingsFailed, SEBUIStrings.loadingSettingsFailedReason, MessageBoxIcon.Hand, MessageBoxButtons.OK, forEditing); Console.WriteLine(ex.Message); return((Dictionary <string, object>)null); } string str2 = (string)SEBSettings.valueForDictionaryKey(dictionary, "hashedAdminPassword") ?? ""; if (string.Compare(upper, str2, StringComparison.OrdinalIgnoreCase) != 0) { if (forEditing) { if (!SEBConfigFileManager.askForPasswordAndCompareToHashedPassword(str2, forEditing)) { return((Dictionary <string, object>)null); } } else if (!passwordIsHash && upper.Length > 0) { int num1 = 5; str1 = (string)null; string passwordRequestText = SEBUIStrings.enterCurrentAdminPwdForReconfiguring; bool flag; do { --num1; string input2 = ThreadedDialog.ShowPasswordDialogForm(SEBUIStrings.reconfiguringLocalSettings, passwordRequestText); if (input2 == null) { return((Dictionary <string, object>)null); } flag = string.Compare(input2.Length != 0 ? SEBProtectionController.ComputePasswordHash(input2) : "", upper, StringComparison.OrdinalIgnoreCase) == 0; passwordRequestText = SEBUIStrings.enterCurrentAdminPwdForReconfiguringAgain; }while (!flag && num1 > 0); if (!flag) { int num2 = (int)SEBMessageBox.Show(SEBUIStrings.reconfiguringLocalSettingsFailed, SEBUIStrings.reconfiguringLocalSettingsFailedWrongCurrentAdminPwd, MessageBoxIcon.Hand, MessageBoxButtons.OK, forEditing); return((Dictionary <string, object>)null); } } } dictionary["sebConfigPurpose"] = (object)1; return(dictionary); }
/// ---------------------------------------------------------------------------------------- /// <summary> /// Decrypt, parse and use new SEB settings /// </summary> /// ---------------------------------------------------------------------------------------- public static bool StoreDecryptedSEBSettings(byte[] sebData) { DictObj sebPreferencesDict; string sebFilePassword = null; bool passwordIsHash = false; X509Certificate2 sebFileCertificateRef = null; sebPreferencesDict = DecryptSEBSettings(sebData, false, ref sebFilePassword, ref passwordIsHash, ref sebFileCertificateRef); if (sebPreferencesDict == null) { return(false); //Decryption didn't work, we abort } Logger.AddInformation("Reconfiguring"); // Reset SEB, close third party applications SEBClientInfo.SebWindowsClientForm.closeSebClient = false; Logger.AddInformation("Attempting to CloseSEBForm for reconfiguration"); SEBClientInfo.SebWindowsClientForm.CloseSEBForm(); Logger.AddInformation("Succesfully CloseSEBForm for reconfiguration"); SEBClientInfo.SebWindowsClientForm.closeSebClient = true; //SEBClientInfo.SebWindowsClientForm.Close(); //SEBClientInfo.SebWindowsClientForm.Dispose(); // We need to check if setting for createNewDesktop changed SEBClientInfo.CreateNewDesktopOldValue = (bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyCreateNewDesktop); if ((int)sebPreferencesDict[SEBSettings.KeySebConfigPurpose] == (int)SEBSettings.sebConfigPurposes.sebConfigPurposeStartingExam) { /// /// If these SEB settings are ment to start an exam /// Logger.AddInformation("Reconfiguring to start an exam"); /// If these SEB settings are ment to start an exam // Store decrypted settings Logger.AddInformation("Attempting to StoreSebClientSettings"); SEBSettings.StoreSebClientSettings(sebPreferencesDict); Logger.AddInformation("Successfully StoreSebClientSettings"); // Set the flag that SEB is running in exam mode now SEBClientInfo.examMode = true; //Re-initialize logger SEBClientInfo.InitializeLogger(); // Check if SEB is running on the standard desktop and the new settings demand to run in new desktop (createNewDesktop = true) // or the other way around! if (SEBClientInfo.CreateNewDesktopOldValue != (bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyCreateNewDesktop)) { // If it did, SEB needs to quit and be restarted manually for the new setting to take effekt if (SEBClientInfo.CreateNewDesktopOldValue == false) { SEBMessageBox.Show(SEBUIStrings.settingsRequireNewDesktop, SEBUIStrings.settingsRequireNewDesktopReason, MessageBoxIcon.Error, MessageBoxButtons.OK); } else { SEBMessageBox.Show(SEBUIStrings.settingsRequireNotNewDesktop, SEBUIStrings.settingsRequireNotNewDesktopReason, MessageBoxIcon.Error, MessageBoxButtons.OK); } //SEBClientInfo.SebWindowsClientForm.closeSebClient = true; SEBClientInfo.SebWindowsClientForm.ExitApplication(); } // Re-Initialize SEB according to the new settings Logger.AddInformation("Attemting to InitSEBDesktop for reconfiguration"); if (!SebWindowsClientMain.InitSEBDesktop()) { return(false); } Logger.AddInformation("Sucessfully InitSEBDesktop for reconfiguration"); // Re-open the main form //SEBClientInfo.SebWindowsClientForm = new SebWindowsClientForm(); //SebWindowsClientMain.singleInstanceController.SetMainForm(SEBClientInfo.SebWindowsClientForm); //return if initializing SEB with openend preferences was successful Logger.AddInformation("Attempting to OpenSEBForm for reconfiguration"); var ret = SEBClientInfo.SebWindowsClientForm.OpenSEBForm(); Logger.AddInformation("Successfully OpenSEBForm for reconfiguration"); return(ret); } else { /// /// If these SEB settings are ment to configure a client /// Logger.AddInformation("Reconfiguring to configure a client"); /// If these SEB settings are ment to configure a client // Check if we have embedded identities and import them into the Windows Certifcate Store ListObj embeddedCertificates = (ListObj)sebPreferencesDict[SEBSettings.KeyEmbeddedCertificates]; for (int i = embeddedCertificates.Count - 1; i >= 0; i--) { // Get the Embedded Certificate DictObj embeddedCertificate = (DictObj)embeddedCertificates[i]; // Is it an identity? if ((int)embeddedCertificate[SEBSettings.KeyType] == 1) { // Store the identity into the Windows Certificate Store SEBProtectionController.StoreCertificateIntoStore((byte[])embeddedCertificate[SEBSettings.KeyCertificateData]); } // Remove the identity from settings, as it should be only stored in the Certificate Store and not in the locally stored settings file embeddedCertificates.RemoveAt(i); } // Store decrypted settings SEBSettings.StoreSebClientSettings(sebPreferencesDict); //Re-initialize logger SEBClientInfo.InitializeLogger(); // Write new settings to the localapp directory SEBSettings.WriteSebConfigurationFile(SEBClientInfo.SebClientSettingsAppDataFile, "", false, null, SEBSettings.sebConfigPurposes.sebConfigPurposeConfiguringClient); // Re-Initialize SEB desktop according to the new settings if (!SebWindowsClientMain.InitSEBDesktop()) { return(false); } if (SEBClientInfo.SebWindowsClientForm.OpenSEBForm()) { // Activate SebWindowsClient so the message box gets focus //SEBClientInfo.SebWindowsClientForm.Activate(); // Check if setting for createNewDesktop changed if (SEBClientInfo.CreateNewDesktopOldValue != (bool)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyCreateNewDesktop)) { // If it did, SEB needs to quit and be restarted manually for the new setting to take effekt SEBMessageBox.Show(SEBUIStrings.sebReconfiguredRestartNeeded, SEBUIStrings.sebReconfiguredRestartNeededReason, MessageBoxIcon.Warning, MessageBoxButtons.OK); //SEBClientInfo.SebWindowsClientForm.closeSebClient = true; SEBClientInfo.SebWindowsClientForm.ExitApplication(); } if (SEBMessageBox.Show(SEBUIStrings.sebReconfigured, SEBUIStrings.sebReconfiguredQuestion, MessageBoxIcon.Question, MessageBoxButtons.YesNo) == DialogResult.No) { //SEBClientInfo.SebWindowsClientForm.closeSebClient = true; SEBClientInfo.SebWindowsClientForm.ExitApplication(); } return(true); //reading preferences was successful } else { return(false); } } }
/// ---------------------------------------------------------------------------------------- /// <summary> /// Helper method which decrypts the byte array using an empty password, /// or the administrator password currently set in SEB /// or asks for the password used for encrypting this SEB file /// for configuring the client /// </summary> /// ---------------------------------------------------------------------------------------- private static DictObj DecryptDataWithPasswordForConfiguringClient(byte[] sebData, bool forEditing, ref string sebFilePassword, ref bool passwordIsHash) { passwordIsHash = false; string password; // First try to decrypt with the current admin password // get admin password hash string hashedAdminPassword = (string)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyHashedAdminPassword); if (hashedAdminPassword == null) { hashedAdminPassword = ""; } // We use always uppercase letters in the base16 hashed admin password used for encrypting hashedAdminPassword = hashedAdminPassword.ToUpper(); DictObj sebPreferencesDict = null; byte[] decryptedSebData = SEBProtectionController.DecryptDataWithPassword(sebData, hashedAdminPassword); if (decryptedSebData == null) { // If decryption with admin password didn't work, try it with an empty password decryptedSebData = SEBProtectionController.DecryptDataWithPassword(sebData, ""); if (decryptedSebData == null) { // If decryption with empty and admin password didn't work, ask for the password the .seb file was encrypted with // Allow up to 5 attempts for entering decoding password int i = 5; password = null; string enterPasswordString = SEBUIStrings.enterEncryptionPassword; do { i--; // Prompt for password password = SebPasswordDialogForm.ShowPasswordDialogForm(SEBUIStrings.reconfiguringLocalSettings, enterPasswordString); // If cancel was pressed, abort if (password == null) { return(null); } string hashedPassword = SEBProtectionController.ComputePasswordHash(password); // we try to decrypt with the hashed password decryptedSebData = SEBProtectionController.DecryptDataWithPassword(sebData, hashedPassword); // in case we get an error we allow the user to try it again enterPasswordString = SEBUIStrings.enterEncryptionPasswordAgain; } while (decryptedSebData == null && i > 0); if (decryptedSebData == null) { //wrong password entered in 5th try: stop reading .seb file MessageBox.Show(SEBUIStrings.reconfiguringLocalSettingsFailed, SEBUIStrings.reconfiguringLocalSettingsFailedWrongPassword, MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } else { // Decrypting with entered password worked: We save it for returning it later if (forEditing) { sebFilePassword = password; } } } } else { //decrypting with hashedAdminPassword worked: we save it for returning as decryption password sebFilePassword = hashedAdminPassword; // identify that password as hash passwordIsHash = true; } /// Decryption worked // Ungzip the .seb (according to specification >= v14) decrypted serialized XML plist data decryptedSebData = GZipByte.Decompress(decryptedSebData); // Check if the openend reconfiguring seb file has the same admin password inside like the current one try { sebPreferencesDict = (DictObj)Plist.readPlist(decryptedSebData); } catch (Exception readPlistException) { // Error when deserializing the decrypted configuration data // We abort reading the new settings here MessageBox.Show(SEBUIStrings.loadingSettingsFailed, SEBUIStrings.loadingSettingsFailedReason, MessageBoxButtons.OK, MessageBoxIcon.Error); Console.WriteLine(readPlistException.Message); return(null); } // Get the admin password set in these settings string sebFileHashedAdminPassword = (string)SEBSettings.valueForDictionaryKey(sebPreferencesDict, SEBSettings.KeyHashedAdminPassword); if (sebFileHashedAdminPassword == null) { sebFileHashedAdminPassword = ""; } // Has the SEB config file the same admin password inside as the current settings have? if (String.Compare(hashedAdminPassword, sebFileHashedAdminPassword, StringComparison.OrdinalIgnoreCase) != 0) { //No: The admin password inside the .seb file wasn't the same as the current one if (forEditing) { // If the file is openend for editing (and not to reconfigure SEB) // we have to ask the user for the admin password inside the file if (!askForPasswordAndCompareToHashedPassword(sebFileHashedAdminPassword, forEditing)) { // If the user didn't enter the right password we abort return(null); } } else { // The file was actually opened for reconfiguring the SEB client: // we have to ask for the current admin password and // allow reconfiguring only if the user enters the right one // We don't check this for the case the current admin password was used to encrypt the new settings // In this case there can be a new admin pw defined in the new settings and users don't need to enter the old one if (passwordIsHash == false && hashedAdminPassword.Length > 0) { // Allow up to 5 attempts for entering current admin password int i = 5; password = null; string hashedPassword; string enterPasswordString = SEBUIStrings.enterCurrentAdminPwdForReconfiguring; bool passwordsMatch; do { i--; // Prompt for password password = SebPasswordDialogForm.ShowPasswordDialogForm(SEBUIStrings.reconfiguringLocalSettings, enterPasswordString); // If cancel was pressed, abort if (password == null) { return(null); } if (password.Length == 0) { hashedPassword = ""; } else { hashedPassword = SEBProtectionController.ComputePasswordHash(password); } passwordsMatch = (String.Compare(hashedPassword, hashedAdminPassword, StringComparison.OrdinalIgnoreCase) == 0); // in case we get an error we allow the user to try it again enterPasswordString = SEBUIStrings.enterCurrentAdminPwdForReconfiguringAgain; } while (!passwordsMatch && i > 0); if (!passwordsMatch) { //wrong password entered in 5th try: stop reading .seb file MessageBox.Show(SEBUIStrings.reconfiguringLocalSettingsFailed, SEBUIStrings.reconfiguringLocalSettingsFailedWrongCurrentAdminPwd, MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } } } } // We need to set the right value for the key sebConfigPurpose to know later where to store the new settings sebPreferencesDict[SEBSettings.KeySebConfigPurpose] = (int)SEBSettings.sebConfigPurposes.sebConfigPurposeConfiguringClient; // Reading preferences was successful! return(sebPreferencesDict); }
/// <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); }