public static async Task Init() { Instance = new Bookmarks(); #if APPX IStorageFile bookmarksFile = (IStorageFile)await ApplicationData.Current.LocalFolder.TryGetItemAsync("Bookmarks.xml"); string bookmarksFileText = null; // If there isn't a file in the Windows Store app data directory, try the desktop app directory if (bookmarksFile == null) { try { if (File.Exists(BookmarksFileName)) { bookmarksFileText = File.ReadAllText(BookmarksFileName); } } catch (Exception) { } } else { bookmarksFileText = await FileIO.ReadTextAsync(bookmarksFile); } if (String.IsNullOrEmpty(bookmarksFileText)) { return; } using (StringReader bookmarksFileTextReader = new StringReader(bookmarksFileText)) using (XmlReader bookmarksXmlReader = new XmlTextReader(bookmarksFileTextReader)) { // Deserialize the bookmarks folder structure from BookmarksFileName; BookmarksFolder.ReadXml() will call itself recursively to deserialize // child folders, so all we have to do is start the deserialization process from the root folder XmlSerializer bookmarksSerializer = new XmlSerializer(typeof(BookmarksFolder)); Instance.RootFolder = (BookmarksFolder)bookmarksSerializer.Deserialize(bookmarksXmlReader); } #else if (File.Exists(BookmarksFileName)) { // Deserialize the bookmarks folder structure from BookmarksFileName; BookmarksFolder.ReadXml() will call itself recursively to deserialize // child folders, so all we have to do is start the deserialization process from the root folder XmlSerializer bookmarksSerializer = new XmlSerializer(typeof(BookmarksFolder)); using (XmlReader bookmarksReader = new XmlTextReader(BookmarksFileName)) Instance.RootFolder = (BookmarksFolder)bookmarksSerializer.Deserialize(bookmarksReader); } #endif }
/// <summary> /// Constructor; initializes the UI. /// </summary> /// <param name="openToBookmarks">Bookmarks, if any, that we should open when initially creating the UI.</param> public MainForm(IEnumerable <Guid> openToBookmarks) : this() { if (openToBookmarks != null) { IEnumerable <Guid> toBookmarks = openToBookmarks.ToList(); if (toBookmarks.Any()) { OpenToBookmarks = (from Guid bookmarkGuid in toBookmarks select Bookmarks.FindBookmark(bookmarkGuid)).ToList(); } } // Show the bookmarks manager window initially if we're not opening bookmarks or history entries if (OpenToBookmarks == null && OpenToHistory == Guid.Empty) { OpenBookmarkManager(); } }
private static async Task<bool> SetupEncryption() { bool convertingToRsa = false; // If the user hasn't formally selected an encryption type (either they're starting the application for the first time or are running a legacy // version that explicitly used Rijndael), ask them if they want to use RSA if (Options.Instance.EncryptionType == null) { string messageBoxText = @"Do you want to use an RSA key container to encrypt your passwords? The RSA encryption mode uses cryptographic keys associated with your Windows user account to encrypt sensitive data without having to enter an encryption password every time you start this application. However, your bookmarks file will be tied uniquely to this user account and you will be unable to share them between multiple users."; if (Options.Instance.FirstLaunch) messageBoxText += @" The alternative is to derive an encryption key from a password that you will need to enter every time that this application starts."; else messageBoxText += @" Since you've already encrypted your data with a password once, you would need to enter it one more time to decrypt it before RSA can be used."; Options.Instance.EncryptionType = MessageBox.Show(messageBoxText, "Use RSA?", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes ? EncryptionType.Rsa : EncryptionType.Rijndael; // Since they want to use RSA but already have connection data encrypted with Rijndael, we'll have to capture that password so that we can // decrypt it using Rijndael and then re-encrypt it using the RSA keypair convertingToRsa = Options.Instance.EncryptionType == EncryptionType.Rsa && !Options.Instance.FirstLaunch; } // If this is the first time that the user is running the application, pop up and information box informing them that they're going to enter a // password used to encrypt sensitive connection details if (Options.Instance.FirstLaunch) { if (Options.Instance.EncryptionType == EncryptionType.Rijndael) MessageBox.Show(Resources.FirstRunPasswordText, Resources.FirstRunPasswordTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); #if !APPX Directory.CreateDirectory(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "EasyConnect")); #endif } if (Options.Instance.EncryptionType != null) await Options.Instance.Save(); bool encryptionTypeSet = false; while (true) { // Get the user's encryption password via the password dialog if (!encryptionTypeSet && (Options.Instance.EncryptionType == EncryptionType.Rijndael || convertingToRsa)) { PasswordWindow passwordWindow = new PasswordWindow(); passwordWindow.ShowDialog(); ConnectionFactory.SetEncryptionType(EncryptionType.Rijndael, passwordWindow.Password); } else ConnectionFactory.SetEncryptionType(Options.Instance.EncryptionType.Value); // Create the bookmark and history windows which will try to use the password to decrypt sensitive connection details; if it's unable to, an // exception will be thrown that wraps a CryptographicException instance try { await Bookmarks.Init(); await History.Init(); await ConnectionFactory.GetDefaultProtocol(); encryptionTypeSet = true; break; } catch (Exception e) { if ((Options.Instance.EncryptionType == EncryptionType.Rijndael || convertingToRsa) && !ContainsCryptographicException(e)) throw; // Tell the user that their password is incorrect and, if they click OK, repeat the process DialogResult result = MessageBox.Show(Resources.IncorrectPasswordText, Resources.ErrorTitle, MessageBoxButtons.OKCancel, MessageBoxIcon.Error); if (result != DialogResult.OK) { return false; } } } // If we're converting over to RSA, we've already loaded and decrypted the sensitive data using if (convertingToRsa) { ConnectionFactory.SetEncryptionType(Options.Instance.EncryptionType.Value, null); await Bookmarks.Instance.Save(); await History.Instance.Save(); await ConnectionFactory.SetDefaults(await ConnectionFactory.GetDefaults(await ConnectionFactory.GetDefaultProtocol())); } return true; }