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); } }
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> /// 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; } }