/// <summary> /// The main routine, called when import is selected /// </summary> /// <param name="pwStorage"></param> /// <param name="sInput"></param> /// <param name="slLogger"></param> public override void Import(PwDatabase pwStorage, System.IO.Stream sInput, KeePassLib.Interfaces.IStatusLogger slLogger) { try { Form1 form = new Form1(); form.Initialise(pwStorage); if (form.ShowDialog() == DialogResult.OK) { // return; bool overwritePassword = form.Overwrite; bool searchWeb = form.GetTitles; bool checkMatches = form.Merge; string masterPassword = form.Password; bool addAutoType = form.AddAutoType; PwIcon iconId = (PwIcon)Enum.Parse(typeof(PwIcon), form.IconName); string profilePath = form.ProfilePath; if (String.IsNullOrEmpty(profilePath)) { MessageBox.Show("No Profile Selected. Use Load More Profiles", "Profile Required", MessageBoxButtons.OK, MessageBoxIcon.Error); Import(pwStorage, sInput, slLogger); // bit of a hack! return; } PwGroup group = form.Group; if (group == null) group = pwStorage.RootGroup; // return; try { InternetAccessor internetAccessor = new InternetAccessor(); slLogger.StartLogging("Importing Firefox Passwords", false); slLogger.SetText("Logging In", LogStatusType.Info); FirefoxProfile profile = new FirefoxProfile(profilePath); profile.Login(masterPassword); slLogger.SetText("Reading Signon file", LogStatusType.Info); FirefoxSignonsFile signonsFile = profile.GetSignonsFile(masterPassword); slLogger.SetText("Processing Passwords", LogStatusType.Info); int count = signonsFile.SignonSites.Count; int pos = 0; // return; // Loop each entry and add it to KeePass foreach (FirefoxSignonSite signonSite in signonsFile.SignonSites) { // keep the user informed of progress pos++; foreach (FirefoxSignon signon in signonSite.Signons) { if (!slLogger.ContinueWork()) // Check if process has been cancelled by the user break; slLogger.SetProgress((uint)(100 * ((double)pos) / ((double)count))); string notes = String.Empty; if (form.IncludeImportNotes) { notes += "Imported from FireFox by the Web Site Advantage FireFox to KeePass Importer" + Environment.NewLine; } // gather the data to import string title = signonSite.Site; string url = signonSite.Site; if (!String.IsNullOrEmpty(signon.LoginFormDomain)) { title = signon.LoginFormDomain; url = signon.LoginFormDomain; } string host = url; try { Uri uri = new Uri(url); host = uri.Host; } catch { } slLogger.SetText(title, LogStatusType.Info); string username = signon.UserName; bool newEntry = true; PwEntry pe = null; if (checkMatches) pe = KeePassHelper.FindMatchingEntry(pwStorage.RootGroup, url, username); if (pe == null) { // create a new entry pe = new PwEntry(true, true); group.AddEntry(pe, true); slLogger.SetText("Created new entry", LogStatusType.AdditionalInfo); } else { newEntry = false; slLogger.SetText("Found matching entry", LogStatusType.AdditionalInfo); } if (newEntry || overwritePassword) { // set the password pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(pwStorage.MemoryProtection.ProtectPassword, signon.Password)); } if (newEntry) { // set all fields pe.Strings.Set(PwDefs.TitleField, new ProtectedString(pwStorage.MemoryProtection.ProtectTitle, title)); pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(pwStorage.MemoryProtection.ProtectUserName, username)); pe.Strings.Set(PwDefs.UrlField, new ProtectedString(pwStorage.MemoryProtection.ProtectUrl, url)); if (!String.IsNullOrEmpty(notes)) pe.Strings.Set(PwDefs.NotesField, new ProtectedString(pwStorage.MemoryProtection.ProtectNotes, notes)); pe.Expires = false; pe.IconId = iconId; // Gatter any extra information... if (!String.IsNullOrEmpty(signon.UserNameField)) pe.Strings.Set("UserNameField", new ProtectedString(false, signon.UserNameField)); if (!String.IsNullOrEmpty(signon.PasswordField)) pe.Strings.Set("PasswordField", new ProtectedString(false, signon.PasswordField)); if (!String.IsNullOrEmpty(signon.LoginFormDomain)) pe.Strings.Set("LoginFormDomain", new ProtectedString(false, signon.LoginFormDomain)); } string webTitle = null; // if new or the title is the same as the url then we should try and get the title if (searchWeb) { // test if new or entry has url as title if ((newEntry || pe.Strings.Get(PwDefs.TitleField).ReadString() == pe.Strings.Get(PwDefs.UrlField).ReadString())) { // get the pages title slLogger.SetText("Accessing website for title", LogStatusType.AdditionalInfo); webTitle = internetAccessor.ScrapeTitle(url); if (!String.IsNullOrEmpty(webTitle)) { slLogger.SetText("Title set from internet to " + webTitle, LogStatusType.AdditionalInfo); pe.Strings.Set(PwDefs.TitleField, new ProtectedString(pwStorage.MemoryProtection.ProtectTitle, webTitle)); } } //else //{ // // Entry has a good title, keep it incase there are other ones for this site // title = pe.Strings.Get(PwDefs.TitleField).ReadString(); //} } // return; if (addAutoType) KeePassHelper.InsertAutoType(pe, "*" + host + "*", KeePassUtilities.AutoTypeSequence()); // return; if (webTitle != null && addAutoType) KeePassHelper.InsertAutoType(pe, KeePassUtilities.AutoTypeWindow(webTitle), KeePassUtilities.AutoTypeSequence()); } } } finally { slLogger.EndLogging(); } } } catch (Exception ex) { ErrorMessage.ShowErrorMessage("Importer", "Import Failed", ex); } }
/// <summary> /// generates a keepass xml file by directly accessing firefoxes passwords /// designed to be used in a thread /// uses the thread /// </summary> private void GenerateUsingFirefox() { try { InternetAccessor internetAccessor = new InternetAccessor(); FirefoxProfile profile = new FirefoxProfile(this.ProfilePath); profile.Login(this.FirefoxMasterPassword); FirefoxSignonsFile signonsFile = profile.GetSignonsFile(this.FirefoxMasterPassword); // the group to store the passwords // the output xml document XmlDocument keePassDocument = new XmlDocument(); XmlElement keePassRootElement = keePassDocument.CreateElement("pwlist"); keePassDocument.AppendChild(keePassRootElement); int current = 0; int max = signonsFile.SignonSites.Count; // loop each input password and generate the output password foreach (FirefoxSignonSite signonSite in signonsFile.SignonSites) { current++; string siteTitle = null; if (GetTitles) siteTitle = internetAccessor.ScrapeTitle(signonSite.Site); foreach (FirefoxSignon signon in signonSite.Signons) { string title = siteTitle == null ? signonSite.Site : siteTitle; if (!String.IsNullOrEmpty(signon.LoginFormDomain)) title = signon.LoginFormDomain; string host = null; try { Uri uri = new Uri(signonSite.Site); host = uri.Host; } catch { } if (GetTitles) { // get the pages title string internetTitle = null; if (String.IsNullOrEmpty(signon.LoginFormDomain) || signon.LoginFormDomain == signonSite.Site) internetTitle = siteTitle; else internetTitle = internetAccessor.ScrapeTitle(signon.LoginFormDomain); if (!String.IsNullOrEmpty(internetTitle)) { title = internetTitle; } } string notes = String.Empty; if (checkBoxIncludeImportNotes.Checked) { notes += "Imported from FireFox by the Web Site Advantage Firefox To KeePass" + Environment.NewLine; } if (GenerateAutoType) { if (this.GetTitles) { notes += Environment.NewLine + "Auto-Type: " + KeePassUtilities.AutoTypeSequence() + Environment.NewLine + (String.IsNullOrEmpty(host) ? String.Empty : "Auto-Type-Window: *" + host + "*" + Environment.NewLine) + "Auto-Type-Window: " + KeePassUtilities.AutoTypeWindow(title) + Environment.NewLine; } else { if (!String.IsNullOrEmpty(host)) { notes += Environment.NewLine + "Auto-Type: " + KeePassUtilities.AutoTypeSequence() + Environment.NewLine + "Auto-Type-Window: *" + host + "*" + Environment.NewLine; } } } string now = XmlConvert.ToString(DateTime.Now, "yyyy-MM-ddTHH:mm:ss"); // create xml XmlElement keePassEntryElement = keePassDocument.CreateElement("pwentry"); keePassRootElement.AppendChild(keePassEntryElement); XmlElement keePassGroupElement = keePassDocument.CreateElement("group"); keePassEntryElement.AppendChild(keePassGroupElement); keePassGroupElement.InnerText = GroupName; // set the group the password gets stored in if (!String.IsNullOrEmpty(GroupName)) keePassGroupElement.SetAttribute("tree", GroupName); XmlElement keePassTitleElement = keePassDocument.CreateElement("title"); keePassEntryElement.AppendChild(keePassTitleElement); keePassTitleElement.InnerText = title; XmlElement keePassUserNameElement = keePassDocument.CreateElement("username"); keePassEntryElement.AppendChild(keePassUserNameElement); keePassUserNameElement.InnerText = signon.UserName; XmlElement keePassURLElement = keePassDocument.CreateElement("url"); keePassEntryElement.AppendChild(keePassURLElement); keePassURLElement.InnerText = signonSite.Site; XmlElement keePassPasswordElement = keePassDocument.CreateElement("password"); keePassEntryElement.AppendChild(keePassPasswordElement); keePassPasswordElement.InnerText = signon.Password; if (!String.IsNullOrEmpty(notes)) { // put other stuff in the notes XmlElement keePassNotesElement = keePassDocument.CreateElement("notes"); keePassEntryElement.AppendChild(keePassNotesElement); // keePassNotesElement.InnerText = XmlCDataSection cd = keePassDocument.CreateCDataSection(notes); keePassNotesElement.AppendChild(cd); } XmlElement keePassUuidElement = keePassDocument.CreateElement("uuid"); keePassEntryElement.AppendChild(keePassUuidElement); keePassUuidElement.InnerText = Guid.NewGuid().ToString().Replace("-", "").ToLower(); // condensed guid XmlElement keePassImageElement = keePassDocument.CreateElement("image"); keePassEntryElement.AppendChild(keePassImageElement); keePassImageElement.InnerText = IconId.ToString(); XmlElement keePassCreatedElement = keePassDocument.CreateElement("creationtime"); keePassEntryElement.AppendChild(keePassCreatedElement); keePassCreatedElement.InnerText = now; XmlElement keePassModifiedElement = keePassDocument.CreateElement("lastmodtime"); keePassEntryElement.AppendChild(keePassModifiedElement); keePassModifiedElement.InnerText = now; XmlElement keePassAccessedElement = keePassDocument.CreateElement("lastaccesstime"); keePassEntryElement.AppendChild(keePassAccessedElement); keePassAccessedElement.InnerText = now; // so it does not expire XmlElement keePassExpiresElement = keePassDocument.CreateElement("expiretime"); keePassEntryElement.AppendChild(keePassExpiresElement); keePassExpiresElement.SetAttribute("expires", "false"); keePassExpiresElement.InnerText = "2999-12-28T23:59:59"; LogProgress((int)((double)(current) * 100 / (double)max)); } } // save the xml. this way the encoding header is included... XmlTextWriter writer = new XmlTextWriter(KeePassFile, Encoding.UTF8); try { writer.Formatting = Formatting.Indented; keePassDocument.Save(writer); } finally { writer.Close(); } this.ThreadFinished(null); } catch (Exception ex) { this.ThreadFinished(ex); } }