/// <inheritdoc /> public override void Import(PwDatabase db, System.IO.Stream input, IStatusLogger logger) { try { ImportDialog form; while (true) { form = new ImportDialog(db); if (form.ShowDialog() != DialogResult.OK) { return; } if (string.IsNullOrEmpty(form.ProfilePath)) { MessageBox.Show( "No Profile Selected. Use Load More Profiles", "Profile Required", MessageBoxButtons.OK, MessageBoxIcon.Error ); } else { break; } } try { logger.StartLogging("Importing Firefox Passwords", false); logger.SetText("Logging in", LogStatusType.Info); using (var profile = new Profile(form.ProfilePath, form.Password)) { logger.SetText("Reading the signon file", LogStatusType.Info); IEnumerable <Signon> signons = profile.GetSignons(); ProcessSignonsAsync(signons, form, db, logger).GetAwaiter().GetResult(); } } finally { logger.EndLogging(); } } catch (Exception ex) { if (ex.Message.Contains("Failed to Validate Password")) { MessageBox.Show(ex.Message, "Import Failed", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { ErrorDialog.Show("Import Failed", ex); } } }
public static async Task ProcessSignonsAsync( IEnumerable <Signon> signons, ImportDialog form, PwDatabase db, IStatusLogger logger) { logger.SetText("Processing signons", LogStatusType.Info); List <Task> tasks = signons.Select(signon => AddEntryAsync(signon, form, db, logger)).ToList(); int total = tasks.Count; var progress = 0; while (tasks.Count > 0) { Task completedTask = Task.Factory.ContinueWhenAny(tasks.ToArray(), task => tasks.Remove(task)); await completedTask.ConfigureAwait(false); ++progress; logger.SetProgress((uint)(100 * (double)progress / total)); } }
public static async Task AddEntryAsync(Signon signon, ImportDialog form, PwDatabase db, IStatusLogger logger) { logger.SetText("Processing signon " + signon.Username + " @ " + signon.Hostname, LogStatusType.Info); PwGroup group = form.Group ?? db.RootGroup; PwEntry entry = null; var newEntry = true; if (form.CheckExisting) // TODO: Search using both the Hostname and FormSubmitUrl. { entry = KeePassHelper.FindMatchingEntry(db.RootGroup, signon.Hostname, signon.Username); } if (entry == null) { // Create a new entry. entry = new PwEntry(true, true); group.AddEntry(entry, true); logger.SetText("Created new entry", LogStatusType.AdditionalInfo); } else { newEntry = false; logger.SetText("Found matching entry", LogStatusType.AdditionalInfo); } if (newEntry || form.Overwrite) { // Set the password. entry.Strings.Set( PwDefs.PasswordField, new ProtectedString(db.MemoryProtection.ProtectPassword, signon.Password) ); } if (!newEntry) { return; } string title = signon.Hostname; try { var uri = new Uri(signon.Hostname); title = uri.Host; } catch (UriFormatException ex) // TODO: May need to also catch ArgumentException { logger.SetText("The URL of the signon could not be parsed", LogStatusType.Warning); } if (form.GetTitles || form.GetIcons) { logger.SetText("Scraping " + signon.Hostname + " for the title and/or icon", LogStatusType.AdditionalInfo); ValueTuple <string, byte[]> results = await WebScraper.ScrapeAsync( signon.Hostname, form.GetTitles, form.GetIcons ).ConfigureAwait(false); string titleWeb = results.Item1; byte[] iconData = results.Item2; if (!string.IsNullOrWhiteSpace(titleWeb)) { title = titleWeb.Trim(); } if (iconData != null) { var icon = new PwCustomIcon(new PwUuid(true), iconData); db.CustomIcons.Add(icon); entry.CustomIconUuid = icon.Uuid; } } // Set all fields. entry.Strings.Set( PwDefs.TitleField, new ProtectedString(db.MemoryProtection.ProtectTitle, title) ); entry.Strings.Set( PwDefs.UserNameField, new ProtectedString(db.MemoryProtection.ProtectUserName, signon.Username) ); entry.Strings.Set (PwDefs.UrlField, new ProtectedString(db.MemoryProtection.ProtectUrl, signon.Hostname) ); if (form.IncludeNotes) { entry.Strings.Set( PwDefs.NotesField, new ProtectedString(db.MemoryProtection.ProtectNotes, Note)); } entry.Expires = false; entry.IconId = form.EntryIcon; entry.CreationTime = signon.TimeCreated ?? entry.CreationTime; entry.LastAccessTime = signon.TimeLastUsed ?? entry.LastAccessTime; entry.LastModificationTime = signon.TimePasswordChanged ?? entry.LastModificationTime; entry.UsageCount = signon.TimesUsed; }