private bool UpgradeKeeFoxTutorialEntriesToRetainSubdomainExclusivityAndResetPriority(PwDatabase db) { // The KeeFox tutorial relies on subdomains being seen as independent // websites but that is no longer the default behaviour in KeeFox 1.5+ // so we have to adjust any existing entries so that the tutorial // continues to work for users with existing databases. List<string> uuids = GetKeeFoxTutorialUUIDsAsStrings(); KeePassLib.Collections.PwObjectList<PwEntry> output = new KeePassLib.Collections.PwObjectList<PwEntry>(); // Scan every entry for matching UUIDs and add them to the list for upgrade KeePassLib.Delegates.EntryHandler eh = delegate(PwEntry pe) { if (uuids.Contains(pe.Uuid.ToHexString())) { output.Add(pe); } return true; }; db.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); if (output.UCount > 0) { foreach (PwEntry pwe in output) { var conf = pwe.GetKPRPCConfig(); if (conf == null) return false; conf.BlockDomainOnlyMatch = true; conf.Priority = 0; pwe.SetKPRPCConfig(conf); } return true; } return true; }
private void OnKPDBOpen(object sender, FileOpenedEventArgs e) { EnsureDBIconIsInKPRPCIconCache(); // If we've not already upgraded the KPRPC data for this database... if (!e.Database.CustomData.Exists("KeePassRPC.KeeFox.configVersion") || e.Database.CustomData.Get("KeePassRPC.KeeFox.configVersion") != "1") { // We know that this upgrade path may contain duplicate KeeFox // sample entries due to an earlier bug so lets get rid of them // for good and replace them with a single instance of each. Not // a perfect solution but should only cause problems for KeeFox // developers and those with OCD and a short fuse. PwUuid pwuuid1 = new PwUuid(new byte[] { 0xe9, 0x9f, 0xf2, 0xed, 0x05, 0x12, 0x47, 0x47, 0xb6, 0x3e, 0xaf, 0xa5, 0x15, 0xa3, 0x04, 0x24}); PwUuid pwuuid2 = new PwUuid(new byte[] { 0xe8, 0x9f, 0xf2, 0xed, 0x05, 0x12, 0x47, 0x47, 0xb6, 0x3e, 0xaf, 0xa5, 0x15, 0xa3, 0x04, 0x25}); PwUuid pwuuid3 = new PwUuid(new byte[] { 0xe7, 0x9f, 0xf2, 0xed, 0x05, 0x12, 0x47, 0x47, 0xb6, 0x3e, 0xaf, 0xa5, 0x15, 0xa3, 0x04, 0x26}); PwUuid pwuuid4 = new PwUuid(new byte[] { 0xe6, 0x9f, 0xf2, 0xed, 0x05, 0x12, 0x47, 0x47, 0xb6, 0x3e, 0xaf, 0xa5, 0x15, 0xa3, 0x04, 0x27}); PwUuid pwuuid5 = new PwUuid(new byte[] { 0xe5, 0x9f, 0xf2, 0xed, 0x05, 0x12, 0x47, 0x47, 0xb6, 0x3e, 0xaf, 0xa5, 0x15, 0xa3, 0x04, 0x28}); List<string> uuids = new List<string>(5); uuids.Add(pwuuid1.ToHexString()); uuids.Add(pwuuid2.ToHexString()); uuids.Add(pwuuid3.ToHexString()); uuids.Add(pwuuid4.ToHexString()); uuids.Add(pwuuid5.ToHexString()); KeePassLib.Collections.PwObjectList<PwEntry> output = new KeePassLib.Collections.PwObjectList<PwEntry>(); // Scan every entry for matching UUIDs and add them to the list for deletion KeePassLib.Delegates.EntryHandler ehdup = delegate(PwEntry pe) { if (uuids.Contains(pe.Uuid.ToHexString())) { output.Add(pe); } return true; }; e.Database.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, ehdup); // Tidy up if (output.UCount > 0) { foreach (PwEntry pwe in output) { pwe.ParentGroup.Entries.Remove(pwe); } InstallKeeFoxSampleEntries(e.Database, true); _host.MainWindow.UpdateUI(false, null, true, null, true, null, true); } bool foundStringsToUpgrade = false; // Scan every string of every entry to find out whether we need to disturb the user KeePassLib.Delegates.EntryHandler eh = delegate(PwEntry pe) { foreach (KeyValuePair<string, ProtectedString> kvp in pe.Strings) { if (StringIsFromKPRPCv1(kvp.Key)) { foundStringsToUpgrade = true; // Cancel our search, we have the answer (unfortunately we can only cancel the search in this group so more organised users will have to wait a little longer) return false; } } return true; }; // If our search is aborted before the end it's becuase we found a string that needs upgrading e.Database.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); if (foundStringsToUpgrade) { DialogResult dr = MessageBox.Show("KeePassRPC (KeeFox) needs to update your database. This process is safe but irreversible so it is strongly recommended that you ensure you have a recent backup of your password database before you continue." + Environment.NewLine + Environment.NewLine + "You can take a backup right now if you want: just find the database file on your system and copy (not move) it to a safe place. The database you are trying to open is located at " + e.Database.IOConnectionInfo.Path + "." + Environment.NewLine + Environment.NewLine + "You will not be able to use this database with older versions of KeeFox once you click OK. Make sure you hold onto your backup copy until you're happy that the upgrade process was successful." + Environment.NewLine + Environment.NewLine + "Press OK to perform the upgrade.", "KeeFox upgrade", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning); if (dr != DialogResult.OK) { // User aborted so we must shut down this database to prevent KeeFox from attempting communication with it e.Database.Close(); _host.MainWindow.DocumentManager.CloseDatabase(e.Database); _host.MainWindow.DocumentManager.ActiveDatabase.UINeedsIconUpdate = true; _host.MainWindow.UpdateUI(true, null, true, null, true, null, false); _host.MainWindow.ResetDefaultFocus(null); DialogResult dr2 = MessageBox.Show("KeePassRPC has NOT upgraded your database. The database has been closed to protect it from damage." + Environment.NewLine + Environment.NewLine + "It is safe to use this database with older versions of KeeFox but you can not use it with this version until you re-open it and perform the upgrade.", "KeeFox upgrade cancelled", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } else { // User has confirmed they have a recent backup so we start the upgrade // Scan every string of every entry to find entries we will update KeePassLib.Delegates.EntryHandler ehupgrade = delegate(PwEntry pe) { foreach (KeyValuePair<string, ProtectedString> kvp in pe.Strings) { if (StringIsFromKPRPCv1(kvp.Key)) { ConvertKPRPCSeperateStringsToJSON(pe, e.Database); return true; } } return true; }; // If our search is successful we know we've upgraded every entry and can save the DB if (e.Database.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, ehupgrade)) { // Store what version of the KPRPC config this is (maybe generously calling // it 1 when I should have included the "1st version" marker 4 years ago!) // Better late than never e.Database.CustomData.Set("KeePassRPC.KeeFox.configVersion", "1"); _host.MainWindow.BeginInvoke(new dlgSaveDB(saveDB), e.Database); DialogResult drfinished = MessageBox.Show("KeePassRPC (KeeFox) information upgraded. Press OK to use your updated database.", "KeeFox upgrade", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } else { // Nothing to upgrade in this DB but we'll bump up the config // version count anyway to ensure that even DBs that contain no // specific KPRPC information are able to be accessed // via KPRPC clients like KeeFox e.Database.CustomData.Set("KeePassRPC.KeeFox.configVersion", "1"); _host.MainWindow.BeginInvoke(new dlgSaveDB(saveDB), e.Database); } } SignalAllManagedRPCClients(KeePassRPC.DataExchangeModel.Signal.DATABASE_OPEN); }
private void RemoveKeeFoxTutorialDuplicateEntries(PwDatabase db) { // We know that this upgrade path may contain duplicate KeeFox // sample entries due to an earlier bug so lets get rid of them // for good and replace them with a single instance of each. Not // a perfect solution but should only cause problems for KeeFox // developers and those with OCD and a short fuse. List<string> uuids = GetKeeFoxTutorialUUIDsAsStrings(); KeePassLib.Collections.PwObjectList<PwEntry> output = new KeePassLib.Collections.PwObjectList<PwEntry>(); // Scan every entry for matching UUIDs and add them to the list for deletion KeePassLib.Delegates.EntryHandler eh = delegate(PwEntry pe) { if (uuids.Contains(pe.Uuid.ToHexString())) { output.Add(pe); } return true; }; db.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); // Tidy up if (output.UCount > 0) { foreach (PwEntry pwe in output) { pwe.ParentGroup.Entries.Remove(pwe); } InstallKeeFoxSampleEntries(db, true); } }
private bool UpgradeKeeFoxTutorialEntriesToRetainSubdomainExclusivityAndResetPriority(PwDatabase db) { // The KeeFox tutorial relies on subdomains being seen as independent // websites but that is no longer the default behaviour in KeeFox 1.5+ // so we have to adjust any existing entries so that the tutorial // continues to work for users with existing databases. List<string> uuids = GetKeeFoxTutorialUUIDsAsStrings(); KeePassLib.Collections.PwObjectList<PwEntry> output = new KeePassLib.Collections.PwObjectList<PwEntry>(); // Scan every entry for matching UUIDs and add them to the list for upgrade KeePassLib.Delegates.EntryHandler eh = delegate(PwEntry pe) { if (uuids.Contains(pe.Uuid.ToHexString())) { output.Add(pe); } return true; }; db.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); if (output.UCount > 0) { foreach (PwEntry pwe in output) { KeePassRPC.DataExchangeModel.EntryConfig conf = null; string json = pwe.Strings.ReadSafe("KPRPC JSON"); if (string.IsNullOrEmpty(json)) conf = new EntryConfig(); else { try { conf = (EntryConfig)Jayrock.Json.Conversion.JsonConvert.Import(typeof(EntryConfig), json); } catch (Exception) { MessageBox.Show("There are configuration errors in this entry. To fix the entry and prevent this warning message appearing, please edit the value of the 'KeePassRPC JSON config' advanced string. Please ask for help on http://keefox.org/help/forum if you're not sure how to fix this.", "Warning: Configuration errors", MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } } conf.BlockDomainOnlyMatch = true; conf.Priority = 0; pwe.Strings.Set("KPRPC JSON", new ProtectedString(true, Jayrock.Json.Conversion.JsonConvert.ExportToString(conf))); } return true; } return true; }