private void SetAlternateLocation(string workingFolder, string projectRootFolder) { // Check whether the schema is in the current directory. if (Directory.GetFiles(workingFolder, this.SchemaName).Length > 0) { AlternateLocation = this.SchemaName; } else if ( !String.IsNullOrEmpty(projectRootFolder) && this.SchemaLocation.ToLower().StartsWith(projectRootFolder.ToLower()) ) { string schemaDirectory = this.SchemaLocation.Substring( 0, this.SchemaLocation.LastIndexOf('\\')); string currentDirectory = workingFolder; // Remove the project root before passing them to the relative path finder. schemaDirectory = schemaDirectory.Substring(projectRootFolder.Length); currentDirectory = currentDirectory.Substring(projectRootFolder.Length); AlternateLocation = IOPathHelper.GetRelativePath(schemaDirectory, currentDirectory); if (AlternateLocation.EndsWith("/")) { AlternateLocation = AlternateLocation + this.SchemaName; } else { AlternateLocation = AlternateLocation + "/" + this.SchemaName; } } else { AlternateLocation = this.SchemaLocation; } }
/// <summary> /// Delinks an externally added fortress from the list. /// </summary> /// <param name="deletableVm"></param> public void DelinkExternalFortress(FortressViewModel deletableVm) { try { if (!File.Exists(IOPathHelper.GetLinkedFortressListFile())) { return; } var linkedFortessFile = File.ReadAllLines(IOPathHelper.GetLinkedFortressListFile()).ToList(); if (linkedFortessFile.Contains(deletableVm.FullName)) { linkedFortessFile.Remove(deletableVm.FullName); } File.WriteAllLines(IOPathHelper.GetLinkedFortressListFile(), linkedFortessFile); Fortresses.Remove(deletableVm); } catch (Exception ex) { Logger.log.Error($"Error while de-linking a fortress: {ex}"); ex.SetUserMessage($"Couldn't de-link fortress - An error occured while trying to de-link it. The problem could be solved by restarting the program."); Communication.InformUserAboutError(ex); } }
void Start() { try { Logger.log.Info("Building the gates..."); InitializeComponent(); // For some reason, VS is firing an exceptionn when trying to do this in XAML... this.WindowStartupLocation = WindowStartupLocation.CenterScreen; // Give the NavigationHelper access to the views. Navigation.MainFrame = MainFrame; Navigation.MainWindowInstance = this; // Load the Password_Blacklist into appdata. IOPathHelper.CreateDirectory(IOPathHelper.GetListsDirectory()); if (!File.Exists(IOPathHelper.GetPasswordBlackListFile())) { File.Copy(IOPathHelper.GetAppLocation() + $"\\{TermHelper.GetPasswordBlackListName()}", IOPathHelper.GetPasswordBlackListFile()); Logger.log.Info("Default-Settings have been written!"); } Logger.log.Info("Gates have been built but remain closed."); Testing(); } catch (Exception ex) { ex.SetUserMessage($"A problem occured while trying to build Sen's Fortress. Make sure the program has access to write and read files on and from your harddrive."); Logger.log.Error($"Error while trying to load MainWindow :{ex}"); Communication.InformUserAboutError(ex); } }
public static string[] GetBlackList() { if (_blacklist == null) { _blacklist = File.ReadAllLines(IOPathHelper.GetPasswordBlackListFile()); } return(_blacklist); }
private async void Save_Button_Click(object sender, RoutedEventArgs e) { try { await Task.Run(() => { Application.Current.Dispatcher.Invoke(() => InformationPanel_Textblock.Text = "Validating your rights..."); // Validate the key first. if (DataAccessService.Instance.ValidateMasterkey(masterPasswordBox.Password)) { var aesHelper = new AesHelper(); var hashedKey = aesHelper.CreateKey(masterPasswordBox.Password, 256, CurrentFortressData.Salt); var secureMasterkey = new Masterkey(hashedKey); hashedKey = null; Application.Current.Dispatcher.Invoke(() => InformationPanel_Textblock.Text = "You have the correct keys my friend."); IOPathHelper.CreateDirectory(IOPathHelper.GetBackedUpFortressDirectory()); // Make sure the directory exists. // Backup fortress Application.Current.Dispatcher.Invoke(() => InformationPanel_Textblock.Text = "Backup-ing your fortress..."); DataAccessService.Instance.BackupFortress( System.IO.Path.Combine(IOPathHelper.GetBackedUpFortressDirectory(), $"(Backup){CurrentFortressData.FortressName}{TermHelper.GetZippedFileEnding()}")); Application.Current.Dispatcher.Invoke(() => InformationPanel_Textblock.Text = "Fortress backed up. Proceeding to save the fortress..."); // Now save the fortress. DataAccessService.Instance.SaveFortress(secureMasterkey); Application.Current.Dispatcher.Invoke(() => InformationPanel_Textblock.Text = "Fortress saved successfully."); // Backup the fortress again with the newly saved changes. DataAccessService.Instance.BackupFortress( System.IO.Path.Combine(IOPathHelper.GetBackedUpFortressDirectory(), $"(Backup){CurrentFortressData.FortressName}{TermHelper.GetZippedFileEnding()}")); Thread.Sleep(1000); // Make the user see the result for a second. Application.Current.Dispatcher.Invoke(() => DialogResult = true); } else { Application.Current.Dispatcher.Invoke(() => InformationPanel_Textblock.Text = "The mission could not be executed."); return; } }); } catch (Exception ex) { Logger.log.Error(ex); InformationPanel_Textblock.Text = "The mission could not be executed."; return; } finally { masterPasswordBox.Password = string.Empty; // Delete the password } }
/// <summary> /// Get the logConfig and sets the custom settings /// </summary> /// <param name="logConfig"></param> private static XmlDocument GetLogConfigAndSetCustomSettings() { // Open the logConfig using (FileStream fs = new FileStream(IOPathHelper.Getlog4netConfigFile(), FileMode.Open, FileAccess.ReadWrite, FileShare.Read)) { XmlDocument log4netconfig = new XmlDocument(); log4netconfig.Load(fs); var logPathNode = log4netconfig.SelectSingleNode("log4net/appender/file"); logPathNode.InnerXml = IOPathHelper.GetLogFileDirectory(); fs.SetLength(0); log4netconfig.Save(fs); return(log4netconfig); } }
/// <summary> /// Adds an external fortress to the FotressListConfig file. /// </summary> private void LinkExternalFortress() { try { // Open a file dialog var openFileDialog = new OpenFileDialog(); openFileDialog.Filter = $"Fortress (*{TermHelper.GetZippedFileEnding()}) | *{TermHelper.GetZippedFileEnding()}"; openFileDialog.ShowDialog(); if (openFileDialog.FileNames.Count() == 0) { return; } if (File.Exists(IOPathHelper.GetLinkedFortressListFile())) { var linkedFortressesFile = File.ReadAllLines(IOPathHelper.GetLinkedFortressListFile()).ToList(); foreach (var path in openFileDialog.FileNames) { if (linkedFortressesFile.Contains(path)) { Communication.InformUser("You already added this fortress."); return; } linkedFortressesFile.Add(path); } File.WriteAllLines(IOPathHelper.GetLinkedFortressListFile(), linkedFortressesFile); } // If the linkedFortressesFile doesn't exist - write it. else { IOPathHelper.CreateDirectory(IOPathHelper.GetConfigsDirectory()); File.WriteAllLines(IOPathHelper.GetLinkedFortressListFile(), openFileDialog.FileNames); } Logger.log.Info($"Linked external fortress: {openFileDialog.FileName}."); LoadFortresses(); } catch (Exception ex) { Logger.log.Error($"Error while linking a fortress: {ex}"); ex.SetUserMessage($"Couldn't add fortress - An error occured while trying to link it. Make sure the selected file ends with {TermHelper.GetZippedFileEnding()} or try to restart the program."); Communication.InformUserAboutError(ex); } }
/// <summary> /// Stores a serializible model into the datacache /// </summary> /// <typeparam name="T"></typeparam> /// <param name="model"></param> internal void StoreOne(ModelBase model, bool isByteModel = false, ByteModel byteModel = null) { CheckDatacache(); // If its a normal ModelBase storing. if (!isByteModel) { var ds = new DataContractSerializer(model.GetType()); var settings = new XmlWriterSettings { Indent = true }; var currentSaveLocation = Path.Combine(_databasePath, TermHelper.GetDatabaseTerm(), model.GetType().Name); // Always check if a directory exists. If not, create it. IOPathHelper.CreateDirectory(currentSaveLocation); using (var sww = new StringWriter()) { using (var w = XmlWriter.Create(Path.Combine(currentSaveLocation, $"{model.Id}.xml"), settings)) { ds.WriteObject(w, model); } } } else if (isByteModel) // If it's a byteModel { var currentSaveLocation = Path.Combine(_databasePath, TermHelper.GetDatabaseTerm(), byteModel.GetType().Name); // It's important to write the bytes decrypted since MemProtection works with the localUser. So the data would be bound to this pc and user. var decryptedValue = CryptMemoryProtection.DecryptInMemoryData(byteModel.EncryptedValue); // Always check if a directory exists. If not, create it. IOPathHelper.CreateDirectory(currentSaveLocation); // Write the Value of byteModels into a file with the foreignKey as the name. File.WriteAllBytes($"{currentSaveLocation}\\{byteModel.ForeignKey}", decryptedValue); decryptedValue = null; } }
/// <summary> /// Creates a new <see cref="Fortress"/> with a <see cref="MasterKey"/> and saves it encrypted. /// </summary> internal void WriteFortress(Fortress fortress, bool overwrite = false) { try { Logger.log.Info("Starting to write a fortress..."); var databasePath = Path.Combine(fortress.FullPath, TermHelper.GetDatabaseTerm()); // =========================================================== Create the root directory IOPathHelper.CreateDirectory(fortress.FullPath); Logger.log.Debug($"Created outer walls {fortress.FullPath}."); // =========================================================== Create the sub directories for the database IOPathHelper.CreateDirectory(databasePath); Logger.log.Debug($"Created the {TermHelper.GetDatabaseTerm()}"); // =========================================================== Create the file which holds the salt to unlock the database StoreSalt(fortress.FullPath, fortress.Salt); Logger.log.Debug("Stored salt"); // =========================================================== Store the user Input and initial data in the database foreach (var modelList in _unsecureDatacache.Values) // UnsecureDatacache { foreach (var model in modelList) { StoreOne(model); } } foreach (var pair in _secureDatacache) { // We filter: Only if the sensible data has a parent we want to save it. Otherwise the parent has been deleted, // which makes the sensible counterpart useless. if (_unsecureDatacache.Values.Any(l => l.Any(m => m.Id == pair.Key))) { var byteModel = new ByteModel(pair.Key, pair.Value); StoreOne(null, true, byteModel); } } Logger.log.Debug("Stored fortress information."); // =========================================================== Zip only the database ZipHelper.ZipSavedArchives(databasePath, $"{databasePath}{TermHelper.GetZippedFileEnding()}"); Directory.Delete(databasePath, true); Logger.log.Debug($"{TermHelper.GetDatabaseTerm()} has been zipped."); // =========================================================== Encrypt the database var aesAlg = new AesAlgorithm(); // Read all bytes from the database directory var data = File.ReadAllBytes($"{databasePath}{TermHelper.GetZippedFileEnding()}"); // Encrypt it var encryptedData = aesAlg.Encrypt(data, fortress.MasterKey.Value, fortress.Salt); // Write the encrypted file File.WriteAllBytes($"{databasePath}{TermHelper.GetDatabaseEnding()}", encryptedData); // Delete the zip File.Delete($"{databasePath}{TermHelper.GetZippedFileEnding()}"); Logger.log.Debug($"Encrypted {TermHelper.GetDatabaseTerm()}"); // =========================================================== Zip the whole fortress if (overwrite) { File.Delete($"{fortress.FullPath}{TermHelper.GetZippedFileEnding()}"); } ZipHelper.ZipSavedArchives(fortress.FullPath, $"{fortress.FullPath}{TermHelper.GetZippedFileEnding()}"); Directory.Delete(fortress.FullPath, true); Logger.log.Debug("Fortress has been zipped."); Logger.log.Info("Fortress has been sucessfully written!"); } catch (Exception ex) { // Delete all changes that have been made to this point. We do not want half-built fortresses. if (Directory.Exists(fortress.FullPath)) { Directory.Delete(fortress.FullPath, true); } if (File.Exists(Path.Combine(fortress.FullPath, TermHelper.GetZippedFileEnding()))) { File.Delete(fortress.FullPath + TermHelper.GetZippedFileEnding()); } ex.SetUserMessage(WellKnownExceptionMessages.DataExceptionMessage()); throw ex; } }
private void Register_Button_Click(object sender, RoutedEventArgs e) { try { Reset(); var currentPw = string.Empty; var currentReenteredPw = string.Empty; if (_pwIsVisible) { currentPw = Master_VisibleTextbox.Text; currentReenteredPw = MasterReentered_Textbox.Text; } else { currentPw = Master_PasswordBox.Password; currentReenteredPw = MasterReentered_PasswordBox.Password; } // Check if all criteria are correct if (Info_Checkbox.IsChecked == false) { Output_Textblock.Text = "You need to varify first that you have read the text on the left."; Info_Checkbox.Foreground = Brushes.Red; return; } if (FortressName_Textbox.Text == string.Empty) { Output_Textblock.Text = "You need to name your fortress."; FortressName_Textbox.BorderBrush = Brushes.Red; return; } if (WellKnownSpecialCharacters.ContainsSpecialCharacters(FortressName_Textbox.Text)) { Output_Textblock.Text = "Special characters in the name are not allowed."; FortressName_Textbox.BorderBrush = Brushes.Red; return; } if (currentPw.Length < 8 || !(currentPw.Any(char.IsUpper)) || !(currentPw.Any(char.IsDigit))) { Output_Textblock.Text = "The masterkey has to match the following criteria: Minumum 8 characters long; Contain at least one upper case character and one digit."; Master_PasswordBox.Foreground = Brushes.Red; Master_VisibleTextbox.Foreground = Brushes.Red; return; } if (currentReenteredPw != currentPw) { Output_Textblock.Text = "Masterkey doesn't match the reentered one."; MasterReentered_PasswordBox.Foreground = Brushes.Red; MasterReentered_Textbox.Foreground = Brushes.Red; return; } // If they are - continue to make the fortress. var aesHelper = new AesHelper(); var salt = aesHelper.GenerateSalt(); var hashedKey = aesHelper.CreateKey(Master_PasswordBox.Password, 256, salt); var fullPath = string.Empty; // If the user has entered a custom path -> Disabled for now if (_fullPath != string.Empty) { fullPath = $"{_fullPath}\\{FortressName_Textbox.Text}"; } else // else use the default. { fullPath = $"{IOPathHelper.GetDefaultFortressDirectory()}\\{FortressName_Textbox.Text}"; } var name = "NOT GIVEN"; var lastName = "NOT GIVEN"; var userName = "******"; var eMail = "*****@*****.**"; var fortress = new Fortress(salt, hashedKey, fullPath, name, lastName, userName, eMail); DataAccessService.Instance.CreateNewFortress(fortress); // Create the new fortress. ClearPasswords(); Navigation.LoginManagementInstance.LoadFortresses(); // Refresh the list. Communication.InformUser($"{FortressName_Textbox.Text} has been successfully built."); } catch (Exception ex) { ClearPasswords(); Logger.log.Error($"Error while trying to register a new fortress: {ex}"); ex.SetUserMessage("There was a problem creating the fortress. The given passwords have been flushed out of memory."); Communication.InformUserAboutError(ex); } }
/// <summary> /// Loads all fortresses: Default and linked. /// </summary> public void LoadFortresses() { try { // If the fortress folder doesn't exist, a fortress hasn't been created into the default location if (!Directory.Exists(IOPathHelper.GetDefaultFortressDirectory()) && !File.Exists(IOPathHelper.GetLinkedFortressListFile())) { return; } var allFortresses = new List <string>(); // First get all fortresses in the default location var defaultFortresses = Directory.GetFiles(IOPathHelper.GetDefaultFortressDirectory()).Where(f => f.EndsWith(TermHelper.GetZippedFileEnding())).ToList(); allFortresses.AddRange(defaultFortresses); // Now look for externally added fortress in the fortress config if (File.Exists(IOPathHelper.GetLinkedFortressListFile())) { var linkedFortresses = File.ReadAllLines(IOPathHelper.GetLinkedFortressListFile()).ToList(); var emptyPaths = new List <string>(); foreach (var path in linkedFortresses) { // If the file exists, we add it to the UI. if (File.Exists(path)) { allFortresses.Add(path); } // If the given path does not exist anymore, because the fortress got moved, delete it. else { emptyPaths.Add(path); } } // When empty paths have been found, delete them and tell the User. if (emptyPaths.Count > 0) { foreach (var path in emptyPaths) { linkedFortresses.Remove(path); } File.WriteAllLines(IOPathHelper.GetLinkedFortressListFile(), linkedFortresses); Communication.InformUser($"Old or corrupted paths have been found - they were de-linked from the fortress list."); } } Fortresses.Clear(); foreach (var fortress in allFortresses) { // If the files does not have the default database ending, skip it. if (!fortress.EndsWith(TermHelper.GetZippedFileEnding())) { break; } var created = File.GetCreationTime(fortress); var modified = File.GetLastWriteTime(fortress); var fortressVm = new FortressViewModel(fortress, created, modified, this); if (!fortress.Contains(IOPathHelper.GetDefaultFortressDirectory())) { fortressVm.IsDefaultLocated = false; } Fortresses.Add(fortressVm); } } catch (Exception ex) { Logger.log.Error($"Error while loading the fortress list: {ex}"); ex.SetUserMessage("An error occured while trying to load all known fortresses. If the fortress has been moved, try to select it again or restart the program."); Communication.InformUserAboutError(ex); } }
/// <summary> /// Returns false if any changes were made to the settings from outside. /// </summary> /// <returns></returns> public bool ScanSettings() => SecurityParameterProvider.Instance.GetCurrentHashOf(nameof(Settings)) == ByteHelper.ReadHash(IOPathHelper.GetSettingsFile()) ? true : false;