/// <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; // PATCH: supplied by Sarel Botha // remove protocol from site so that it works with new KeepassHTTP if (title.StartsWith("http://")) { title = title.Substring(7); } if (title.StartsWith("https://")) { title = title.Substring(8); } // remove port number if the title contains it so that it will work with new KeepassHTTP if (title.Contains(":")) { title = title.Substring(0, title.IndexOf(':')); } // PATCH END 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) { if (ex.Message.Contains("Failed to Validate Password")) { MessageBox.Show(ex.Message, "Import Failed", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { 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); } }
/// <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 { FormXml form = new FormXml(); form.Initialise(pwStorage); // form.GroupName = pwStorage.RootGroup.Name; //if (pwStorage.LastSelectedGroup != null) //{ // form.GroupName = pwStorage.RootGroup.FindGroup(pwStorage.LastSelectedGroup, true).Name; //} if (form.ShowDialog() == DialogResult.OK) { bool overwritePassword = form.Overwrite; bool searchWeb = form.GetTitles; bool checkMatches = form.Merge; bool addAutoType = form.AddAutoType; PwIcon iconId = (PwIcon)Enum.Parse(typeof(PwIcon), form.IconName); PwGroup group = form.Group; if (group == null) { group = pwStorage.RootGroup; } try { InternetAccessor internetAccessor = new InternetAccessor(); slLogger.StartLogging("Importing Firefox File", false); slLogger.SetText("Reading File", LogStatusType.Info); // Load in the supplied xml document XmlDocument fireFoxDocument = new XmlDocument(); XmlReaderSettings settings = new XmlReaderSettings(); settings.CheckCharacters = false; settings.ValidationType = ValidationType.None; XmlReader reader = XmlTextReader.Create(sInput, settings); try { fireFoxDocument.Load(reader); } catch (Exception ex) { throw new Exception("Failed to load the password file. " + Environment.NewLine + "This may be due to the presence of foreign characters in the data. " + Environment.NewLine + "Please check the website for help" + Environment.NewLine + Environment.NewLine + ex.Message, ex); } finally { reader.Close(); } // Get a collection of nodes that represent each password XmlNodeList fireFoxEntryNodes = fireFoxDocument.SelectNodes("xml/entries/entry"); int count = fireFoxEntryNodes.Count; int pos = 0; // Loop each entry and add it to KeePass foreach (XmlElement fireFoxEntryElement in fireFoxEntryNodes) { if (!slLogger.ContinueWork()) // Check if process has been cancelled by the user { break; } // keep the user informed of progress pos++; slLogger.SetProgress((uint)(100 * ((double)pos) / ((double)count))); // gather the data to import string title = "HOST"; XmlNode hostNode = fireFoxEntryElement.SelectSingleNode("@host"); XmlNode formSubmitURLNode = fireFoxEntryElement.SelectSingleNode("@formSubmitURL"); XmlNode userNode = fireFoxEntryElement.SelectSingleNode("@user"); XmlNode passwordNode = fireFoxEntryElement.SelectSingleNode("@password"); if (hostNode != null) { title = hostNode.InnerText; } slLogger.SetText(title, LogStatusType.Info); string notes = String.Empty; if (form.IncludeImportNotes) { notes += "Imported from FireFox by the Web Site Advantage FireFox to KeePass Importer" + Environment.NewLine; } string url = String.Empty; if (hostNode != null) { url = hostNode.InnerText; } string formSubmitURL = String.Empty; if (formSubmitURLNode != null) { formSubmitURL = formSubmitURLNode.InnerText; } if (!String.IsNullOrEmpty(formSubmitURL)) { url = formSubmitURL; } string host = url; try { Uri uri = new Uri(url); host = uri.Host; } catch { } string username = String.Empty; if (userNode != null) { username = userNode.InnerText; } 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 if (passwordNode != null) { pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(pwStorage.MemoryProtection.ProtectPassword, passwordNode.InnerText)); } } 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 (fireFoxEntryElement.HasAttribute("userFieldName") && fireFoxEntryElement.GetAttribute("userFieldName").Length > 0) { pe.Strings.Set("UserNameField", new ProtectedString(false, fireFoxEntryElement.GetAttribute("userFieldName"))); } if (fireFoxEntryElement.HasAttribute("usernameField") && fireFoxEntryElement.GetAttribute("usernameField").Length > 0) { pe.Strings.Set("UserNameField", new ProtectedString(false, fireFoxEntryElement.GetAttribute("usernameField"))); } if (fireFoxEntryElement.HasAttribute("passFieldName") && fireFoxEntryElement.GetAttribute("passFieldName").Length > 0) { pe.Strings.Set("PasswordField", new ProtectedString(false, fireFoxEntryElement.GetAttribute("passFieldName"))); } if (fireFoxEntryElement.HasAttribute("passwordField") && fireFoxEntryElement.GetAttribute("passwordField").Length > 0) { pe.Strings.Set("PasswordField", new ProtectedString(false, fireFoxEntryElement.GetAttribute("passwordField"))); } if (fireFoxEntryElement.HasAttribute("httpRealm") && fireFoxEntryElement.GetAttribute("httpRealm").Length > 0) { pe.Strings.Set("HttpRealm", new ProtectedString(false, fireFoxEntryElement.GetAttribute("httpRealm"))); } if (fireFoxEntryElement.HasAttribute("formSubmitURL") && fireFoxEntryElement.GetAttribute("formSubmitURL").Length > 0) { pe.Strings.Set("LoginFormDomain", new ProtectedString(false, fireFoxEntryElement.GetAttribute("formSubmitURL"))); } } 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)) { // PATCH: supplied by Sarel Botha // remove protocol from site so that it works with new KeepassHTTP if (webTitle.StartsWith("http://")) { webTitle = webTitle.Substring(7); } if (webTitle.StartsWith("https://")) { webTitle = webTitle.Substring(8); } // remove port number if the title contains it so that it will work with new KeepassHTTP if (webTitle.Contains(":")) { webTitle = webTitle.Substring(0, webTitle.IndexOf(':')); } // PATCH END slLogger.SetText("Title set from internet to " + webTitle, LogStatusType.AdditionalInfo); pe.Strings.Set(PwDefs.TitleField, new ProtectedString(pwStorage.MemoryProtection.ProtectTitle, webTitle)); } } } if (addAutoType) { KeePassHelper.InsertAutoType(pe, "*" + host + "*", KeePassUtilities.AutoTypeSequence()); } if (webTitle != null && addAutoType) { KeePassHelper.InsertAutoType(pe, KeePassUtilities.AutoTypeWindow(webTitle), KeePassUtilities.AutoTypeSequence()); } } } finally { slLogger.EndLogging(); } } } catch (Exception ex) { if (ex.Message.Contains("Failed to Validate Password")) { MessageBox.Show(ex.Message, "Import Failed", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { ErrorMessage.ShowErrorMessage("Importer Xml", "Import Failed", ex); } } }
/// <summary> /// Create the keepass file using an exported firefox file /// </summary> private void GenerateUsingExport() { try { InternetAccessor internetAccessor = new InternetAccessor(); // load in the firefox xml document XmlDocument fireFoxDocument = new XmlDocument(); FileStream fileStream = File.Open(FirefoxFile, FileMode.Open, FileAccess.Read); try { XmlReaderSettings settings = new XmlReaderSettings(); settings.CheckCharacters = false; settings.ValidationType = ValidationType.None; XmlReader reader = XmlTextReader.Create(fileStream, settings); try { fireFoxDocument.Load(reader); } finally { reader.Close(); } } catch (Exception ex) { throw new Exception("Failed to load the password file. " + Environment.NewLine + "This may be due to the presence of foreign characters in the data. " + Environment.NewLine + "Please check the website for help" + Environment.NewLine + Environment.NewLine + ex.Message, ex); } finally { fileStream.Close(); } // get a list of each password node XmlNodeList fireFoxEntryNodes = fireFoxDocument.SelectNodes("xml/entries/entry"); // the output xml document XmlDocument keePassDocument = new XmlDocument(); XmlElement keePassRootElement = keePassDocument.CreateElement("pwlist"); keePassDocument.AppendChild(keePassRootElement); int current = 0; int max = fireFoxEntryNodes.Count; // loop each input password and generate the output password foreach (XmlElement fireFoxEntryElement in fireFoxEntryNodes) { current++; string title = fireFoxEntryElement.SelectSingleNode("@host").InnerText; string url = title; string formSubmitURL = fireFoxEntryElement.SelectSingleNode("@formSubmitURL").InnerText; if (!String.IsNullOrEmpty(formSubmitURL)) { url = formSubmitURL; } string host = url; try { Uri uri = new Uri(url); host = uri.Host; } catch { } string internetTitle = null; if (GetTitles) { // get the pages title try { internetTitle = internetAccessor.ScrapeTitle(url); if (!String.IsNullOrEmpty(internetTitle)) { title = internetTitle; } } catch (Exception ex) { // some issue! KeePassUtilities.LogException(ex); } } string notes = String.Empty; if (checkBoxIncludeImportNotes.Checked) { notes += "Imported from FireFox by the Web Site Advantage Firefox To KeePass Importer" + Environment.NewLine + Environment.NewLine + "UserNameField=" + fireFoxEntryElement.SelectSingleNode("@userFieldName").InnerText + System.Environment.NewLine + "PasswordField=" + fireFoxEntryElement.SelectSingleNode("@passFieldName").InnerText + System.Environment.NewLine + "LoginFormDomain=" + fireFoxEntryElement.SelectSingleNode("@formSubmitURL").InnerText + System.Environment.NewLine; } if (GenerateAutoType) { if (!String.IsNullOrEmpty(internetTitle)) { notes += Environment.NewLine + "Auto-Type: " + KeePassUtilities.AutoTypeSequence() + Environment.NewLine + "Auto-Type-Window: *" + host + "*" + Environment.NewLine + "Auto-Type-Window: " + KeePassUtilities.AutoTypeWindow(internetTitle) + Environment.NewLine; } else { 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 the 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 = fireFoxEntryElement.SelectSingleNode("@user").InnerText; XmlElement keePassURLElement = keePassDocument.CreateElement("url"); keePassEntryElement.AppendChild(keePassURLElement); keePassURLElement.InnerText = fireFoxEntryElement.SelectSingleNode("@host").InnerText; XmlElement keePassPasswordElement = keePassDocument.CreateElement("password"); keePassEntryElement.AppendChild(keePassPasswordElement); keePassPasswordElement.InnerText = fireFoxEntryElement.SelectSingleNode("@password").InnerText; // put other stuff in the notes if (!String.IsNullOrEmpty(notes)) { XmlElement keePassNotesElement = keePassDocument.CreateElement("notes"); keePassEntryElement.AppendChild(keePassNotesElement); 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)); } 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); } }