private void txtNotes_Leave(object sender, EventArgs e) { if (txtNotes.Tag != null) // Textbox has been marked as changed { PwDatabase pwStorage = m_host.Database; PwEntry pe = m_host.MainWindow.GetSelectedEntry(true); PwEntry peInit = (PwEntry)txtNotes.Tag; PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreLastMod | PwCompareOptions.IgnoreLastAccess | PwCompareOptions.IgnoreLastBackup); if (pe.EqualsEntry(peInit, cmpOpt, MemProtCmpMode.None)) { // Text contents has not been changed, undo last backup from history pe.LastModificationTime = peInit.LastModificationTime; pe.History.Remove(pe.History.GetAt(pe.History.UCount - 1)); // Undo backup } else { // Text has been changed - enable save icon Util.UpdateSaveState(); m_host.MainWindow.EnsureVisibleEntry(pe.Uuid); } txtNotes.Tag = null; } txtNotes.TextChanged -= txtNotes_TextChanged; }
private bool SaveEntryStatus(ListViewItem Item, PwIcon icon, string text) { PwListItem pli = (((ListViewItem)Item).Tag as PwListItem); if (pli == null) { Debug.Assert(false); return(false); } PwEntry pe = pli.Entry; pe = m_host.Database.RootGroup.FindEntry(pe.Uuid, true); var protString = pe.Strings.Get(PwDefs.PasswordField); if (protString != null && !protString.IsEmpty) { return(false); } PwEntry peInit = pe.CloneDeep(); pe.CreateBackup(null); pe.Touch(true, false); // Touch *after* backup pe.IconId = icon; Item.ImageIndex = (int)icon; pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(false, text)); Item.SubItems[getSubitemOfField(KeePass.App.Configuration.AceColumnType.UserName)].Text = text; PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreLastMod | PwCompareOptions.IgnoreLastAccess | PwCompareOptions.IgnoreLastBackup); if (pe.EqualsEntry(peInit, cmpOpt, MemProtCmpMode.None)) { pe.LastModificationTime = peInit.LastModificationTime; pe.History.Remove(pe.History.GetAt(pe.History.UCount - 1)); // Undo backup return(false); } else { return(true); } }
/// <summary> /// The function compares two PwEntries in every scope except the Uuid /// </summary> /// <param name="entry">the first entry</param> /// <param name="otherEntry">the second entry</param> /// <param name="bIgnoreKeeShareFields">Should the KeeShare-specific fields be ignored?</param> /// <returns>True if both entries are equal in all field, accordingly to the parametersettings</returns> public static bool IsSimilarTo(this PwEntry entry, PwEntry otherEntry, bool bIgnoreKeeShareFields) { //if both are null they are equal if (entry == null && otherEntry == null) { return(true); } //if only one of them is null we could not clone it => they are not equal if (entry == null || otherEntry == null) { return(false); } // only clone both entries if we need to PwEntry myCopy = entry.CloneDeep(); PwEntry otherCopy = otherEntry; if (bIgnoreKeeShareFields) { myCopy.Strings.Remove(KeeShare.UuidLinkField); otherCopy = otherEntry.CloneDeep(); otherCopy.Strings.Remove(KeeShare.UuidLinkField); } //we have to make the Uuids and creation times equal, because PwEntry.EqualsEntry compares these too //and returns false if they are not equal!! myCopy.SetUuid(otherCopy.Uuid, false); myCopy.CreationTime = otherCopy.CreationTime; PwCompareOptions opts = PwCompareOptions.IgnoreHistory | PwCompareOptions.IgnoreLastAccess | PwCompareOptions.IgnoreLastBackup | PwCompareOptions.IgnoreLastMod | PwCompareOptions.IgnoreParentGroup | PwCompareOptions.IgnoreTimes; return(myCopy.EqualsEntry(otherCopy, opts, MemProtCmpMode.Full)); }
private static void PrepareModDbForMerge(PwDatabase pd, PwDatabase pdOrg) { PwGroup pgRootOrg = pdOrg.RootGroup; PwGroup pgRootNew = pd.RootGroup; if (pgRootNew == null) { Debug.Assert(false); return; } PwCompareOptions pwCmp = (PwCompareOptions.IgnoreParentGroup | PwCompareOptions.NullEmptyEquivStd); DateTime dtNow = DateTime.UtcNow; GroupHandler ghOrg = delegate(PwGroup pg) { PwGroup pgNew = pgRootNew.FindGroup(pg.Uuid, true); if (pgNew == null) { AddDeletedObject(pd, pg.Uuid); return(true); } if (!pgNew.EqualsGroup(pg, (pwCmp | PwCompareOptions.PropertiesOnly), MemProtCmpMode.Full)) { pgNew.Touch(true, false); } PwGroup pgParentA = pg.ParentGroup; PwGroup pgParentB = pgNew.ParentGroup; if ((pgParentA != null) && (pgParentB != null)) { if (!pgParentA.Uuid.Equals(pgParentB.Uuid)) { pgNew.LocationChanged = dtNow; } } else if ((pgParentA == null) && (pgParentB == null)) { } else { pgNew.LocationChanged = dtNow; } return(true); }; EntryHandler ehOrg = delegate(PwEntry pe) { PwEntry peNew = pgRootNew.FindEntry(pe.Uuid, true); if (peNew == null) { AddDeletedObject(pd, pe.Uuid); return(true); } if (!peNew.EqualsEntry(pe, pwCmp, MemProtCmpMode.Full)) { peNew.Touch(true, false); bool bRestoreHistory = false; if (peNew.History.UCount != pe.History.UCount) { bRestoreHistory = true; } else { for (uint u = 0; u < pe.History.UCount; ++u) { if (!peNew.History.GetAt(u).EqualsEntry( pe.History.GetAt(u), pwCmp, MemProtCmpMode.CustomOnly)) { bRestoreHistory = true; break; } } } if (bRestoreHistory) { peNew.History = pe.History.CloneDeep(); foreach (PwEntry peHistNew in peNew.History) { peHistNew.ParentGroup = peNew.ParentGroup; } } } PwGroup pgParentA = pe.ParentGroup; PwGroup pgParentB = peNew.ParentGroup; if ((pgParentA != null) && (pgParentB != null)) { if (!pgParentA.Uuid.Equals(pgParentB.Uuid)) { peNew.LocationChanged = dtNow; } } else if ((pgParentA == null) && (pgParentB == null)) { } else { peNew.LocationChanged = dtNow; } return(true); }; pgRootOrg.TraverseTree(TraversalMethod.PreOrder, ghOrg, ehOrg); }
void SaveEntry() { Database db = App.Kp2a.GetDb(); EntryEditActivity act = this; if (!ValidateBeforeSaving()) { return; } PwEntry initialEntry = State.EntryInDatabase.CloneDeep(); PwEntry newEntry = State.EntryInDatabase; //Clone history and re-assign: newEntry.History = newEntry.History.CloneDeep(); //Based on KeePass Desktop bool bCreateBackup = (!State.IsNew); if (bCreateBackup) { newEntry.CreateBackup(null); } if (State.SelectedIcon) { newEntry.IconId = State.SelectedIconId; newEntry.CustomIconUuid = State.SelectedCustomIconId; } //else the State.EntryInDatabase.Icon /* KPDesktop * if(m_cbCustomForegroundColor.Checked) * newEntry.ForegroundColor = m_clrForeground; * else newEntry.ForegroundColor = Color.Empty; * if(m_cbCustomBackgroundColor.Checked) * newEntry.BackgroundColor = m_clrBackground; * else newEntry.BackgroundColor = Color.Empty; * */ UpdateEntryFromUi(newEntry); newEntry.Binaries = State.Entry.Binaries; newEntry.Expires = State.Entry.Expires; if (newEntry.Expires) { newEntry.ExpiryTime = State.Entry.ExpiryTime; } newEntry.Touch(true, false); // Touch *after* backup StrUtil.NormalizeNewLines(newEntry.Strings, true); bool bUndoBackup = false; PwCompareOptions cmpOpt = (PwCompareOptions.NullEmptyEquivStd | PwCompareOptions.IgnoreTimes); if (bCreateBackup) { cmpOpt |= PwCompareOptions.IgnoreLastBackup; } if (newEntry.EqualsEntry(initialEntry, cmpOpt, MemProtCmpMode.CustomOnly)) { // No modifications at all => restore last mod time and undo backup newEntry.LastModificationTime = initialEntry.LastModificationTime; bUndoBackup = bCreateBackup; } else if (bCreateBackup) { // If only history items have been modified (deleted) => undo // backup, but without restoring the last mod time PwCompareOptions cmpOptNh = (cmpOpt | PwCompareOptions.IgnoreHistory); if (newEntry.EqualsEntry(initialEntry, cmpOptNh, MemProtCmpMode.CustomOnly)) { bUndoBackup = true; } } if (bUndoBackup) { newEntry.History.RemoveAt(newEntry.History.UCount - 1); } newEntry.MaintainBackups(db.KpDatabase); //if ( newEntry.Strings.ReadSafe (PwDefs.TitleField).Equals(State.Entry.Strings.ReadSafe (PwDefs.TitleField)) ) { // SetResult(KeePass.EXIT_REFRESH); //} else { //it's safer to always update the title as we might add further information in the title like expiry etc. SetResult(KeePass.ExitRefreshTitle); //} RunnableOnFinish runnable; ActionOnFinish closeOrShowError = new ActionOnFinish((success, message) => { if (success) { Finish(); } else { OnFinish.DisplayMessage(this, message); } }); ActionOnFinish afterAddEntry = new ActionOnFinish((success, message) => { if (success) { _appTask.AfterAddNewEntry(this, newEntry); } }, closeOrShowError); if (State.IsNew) { runnable = AddEntry.GetInstance(this, App.Kp2a, newEntry, State.ParentGroup, afterAddEntry); } else { runnable = new UpdateEntry(this, App.Kp2a, initialEntry, newEntry, closeOrShowError); } ProgressTask pt = new ProgressTask(App.Kp2a, act, runnable); pt.Run(); }
private bool SaveEntry(PwEntry peTarget, bool bValidate) { if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return true; if(bValidate && !m_icgPassword.ValidateData(true)) return false; if(this.EntrySaving != null) { CancellableOperationEventArgs eaCancel = new CancellableOperationEventArgs(); this.EntrySaving(this, eaCancel); if(eaCancel.Cancel) return false; } peTarget.History = m_vHistory; // Must be called before CreateBackup() bool bCreateBackup = (m_pwEditMode != PwEditMode.AddNewEntry); if(bCreateBackup) peTarget.CreateBackup(null); peTarget.IconId = m_pwEntryIcon; peTarget.CustomIconUuid = m_pwCustomIconID; if(m_cbCustomForegroundColor.Checked) peTarget.ForegroundColor = m_clrForeground; else peTarget.ForegroundColor = Color.Empty; if(m_cbCustomBackgroundColor.Checked) peTarget.BackgroundColor = m_clrBackground; else peTarget.BackgroundColor = Color.Empty; peTarget.OverrideUrl = m_cmbOverrideUrl.Text; List<string> vNewTags = StrUtil.StringToTags(m_tbTags.Text); peTarget.Tags.Clear(); foreach(string strTag in vNewTags) peTarget.AddTag(strTag); peTarget.Expires = m_cgExpiry.Checked; if(peTarget.Expires) peTarget.ExpiryTime = m_cgExpiry.Value; UpdateEntryStrings(true, false, false); peTarget.Strings = m_vStrings; peTarget.Binaries = m_vBinaries; m_atConfig.Enabled = m_cbAutoTypeEnabled.Checked; m_atConfig.ObfuscationOptions = (m_cbAutoTypeObfuscation.Checked ? AutoTypeObfuscationOptions.UseClipboard : AutoTypeObfuscationOptions.None); SaveDefaultSeq(); peTarget.AutoType = m_atConfig; peTarget.Touch(true, false); // Touch *after* backup if(object.ReferenceEquals(peTarget, m_pwEntry)) m_bTouchedOnce = true; StrUtil.NormalizeNewLines(peTarget.Strings, true); bool bUndoBackup = false; PwCompareOptions cmpOpt = m_cmpOpt; if(bCreateBackup) cmpOpt |= PwCompareOptions.IgnoreLastBackup; if(peTarget.EqualsEntry(m_pwInitialEntry, cmpOpt, MemProtCmpMode.CustomOnly)) { // No modifications at all => restore last mod time and undo backup peTarget.LastModificationTime = m_pwInitialEntry.LastModificationTime; bUndoBackup = bCreateBackup; } else if(bCreateBackup) { // If only history items have been modified (deleted) => undo // backup, but without restoring the last mod time PwCompareOptions cmpOptNH = (m_cmpOpt | PwCompareOptions.IgnoreHistory); if(peTarget.EqualsEntry(m_pwInitialEntry, cmpOptNH, MemProtCmpMode.CustomOnly)) bUndoBackup = true; } if(bUndoBackup) peTarget.History.RemoveAt(peTarget.History.UCount - 1); peTarget.MaintainBackups(m_pwDatabase); if(this.EntrySaved != null) this.EntrySaved(this, EventArgs.Empty); return true; }
/* * // Get all user defined strings * internal static Dictionary<string, string> GetDictEntriesUserStrings(PwGroup pwg) * { * Dictionary<string, string> strd = new Dictionary<string, string>(); * //SortedDictionary<string, string> strd = new SortedDictionary<string, string>(); * * // Add all known pwentry strings * foreach (PwEntry pe in pwg.GetEntries(true)) * { * foreach (KeyValuePair<string, ProtectedString> pstr in pe.Strings) * { * if (!strd.ContainsKey(pstr.Key)) * { * if (!PwDefs.IsStandardField(pstr.Key)) * { * strd.Add(pstr.Key, pstr.Value.ReadString()); * } * } * } * } * * return strd; * }*/ // Ported from KeePass Entry Dialog SaveEntry() and UpdateEntryStrings(...) internal static bool SaveEntry(PwDatabase pwStorage, ListViewItem Item, int SubItem, string Text) { PwListItem pli = (((ListViewItem)Item).Tag as PwListItem); if (pli == null) { Debug.Assert(false); return(false); } PwEntry pe = pli.Entry; pe = pwStorage.RootGroup.FindEntry(pe.Uuid, true); PwEntry peInit = pe.CloneDeep(); pe.CreateBackup(null); pe.Touch(true, false); // Touch *after* backup int colID = SubItem; AceColumn col = GetAceColumn(colID); AceColumnType colType = col.Type; switch (colType) { case AceColumnType.Title: //if(PwDefs.IsTanEntry(pe)) //TODO tan list TanTitle ??? pe.Strings.Set(PwDefs.TanTitle, new ProtectedString(false, Text)); //else pe.Strings.Set(PwDefs.TitleField, new ProtectedString(pwStorage.MemoryProtection.ProtectTitle, Text)); break; case AceColumnType.UserName: pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(pwStorage.MemoryProtection.ProtectUserName, Text)); break; case AceColumnType.Password: //byte[] pb = Text.ToUtf8(); //pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(pwStorage.MemoryProtection.ProtectPassword, pb)); //MemUtil.ZeroByteArray(pb); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(pwStorage.MemoryProtection.ProtectPassword, Text)); break; case AceColumnType.Url: pe.Strings.Set(PwDefs.UrlField, new ProtectedString(pwStorage.MemoryProtection.ProtectUrl, Text)); break; case AceColumnType.Notes: pe.Strings.Set(PwDefs.NotesField, new ProtectedString(pwStorage.MemoryProtection.ProtectNotes, Text)); break; case AceColumnType.OverrideUrl: pe.OverrideUrl = Text; break; case AceColumnType.Tags: List <string> vNewTags = StrUtil.StringToTags(Text); pe.Tags.Clear(); foreach (string strTag in vNewTags) { pe.AddTag(strTag); } break; case AceColumnType.CustomString: pe.Strings.Set(col.CustomName, new ProtectedString(pe.Strings.GetSafe(col.CustomName).IsProtected, Text)); break; default: // Nothing todo break; } PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreLastMod | PwCompareOptions.IgnoreLastAccess | PwCompareOptions.IgnoreLastBackup); if (pe.EqualsEntry(peInit, cmpOpt, MemProtCmpMode.None)) { pe.LastModificationTime = peInit.LastModificationTime; pe.History.Remove(pe.History.GetAt(pe.History.UCount - 1)); // Undo backup return(false); } else { return(true); } }
private static void PrepareModDbForMerge(PwDatabase pd, PwDatabase pdOrg) { PwGroup pgRootOrg = pdOrg.RootGroup; PwGroup pgRootNew = pd.RootGroup; if (pgRootNew == null) { Debug.Assert(false); return; } const PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreParentGroup | PwCompareOptions.IgnoreHistory | PwCompareOptions.NullEmptyEquivStd); const MemProtCmpMode cmpMem = MemProtCmpMode.CustomOnly; DateTime dtNow = DateTime.UtcNow; GroupHandler ghOrg = delegate(PwGroup pg) { PwGroup pgNew = pgRootNew.FindGroup(pg.Uuid, true); if (pgNew == null) { AddDeletedObject(pd, pg.Uuid); return(true); } if (!pgNew.EqualsGroup(pg, (cmpOpt | PwCompareOptions.PropertiesOnly), cmpMem)) { pgNew.Touch(true, false); } PwGroup pgParentA = pg.ParentGroup; PwGroup pgParentB = pgNew.ParentGroup; if ((pgParentA != null) && (pgParentB != null)) { if (!pgParentA.Uuid.Equals(pgParentB.Uuid)) { pgNew.LocationChanged = dtNow; } } else if ((pgParentA == null) && (pgParentB == null)) { } else { pgNew.LocationChanged = dtNow; } return(true); }; EntryHandler ehOrg = delegate(PwEntry pe) { PwEntry peNew = pgRootNew.FindEntry(pe.Uuid, true); if (peNew == null) { AddDeletedObject(pd, pe.Uuid); return(true); } // Restore history entries peNew.History = pe.History.CloneDeep(); foreach (PwEntry peHistNew in peNew.History) { peHistNew.ParentGroup = peNew.ParentGroup; } if (!peNew.EqualsEntry(pe, cmpOpt, cmpMem)) { peNew.Touch(true, false); } PwGroup pgParentA = pe.ParentGroup; PwGroup pgParentB = peNew.ParentGroup; if ((pgParentA != null) && (pgParentB != null)) { if (!pgParentA.Uuid.Equals(pgParentB.Uuid)) { peNew.LocationChanged = dtNow; } } else if ((pgParentA == null) && (pgParentB == null)) { } else { peNew.LocationChanged = dtNow; } return(true); }; pgRootOrg.TraverseTree(TraversalMethod.PreOrder, ghOrg, ehOrg); }
public bool SaveEntry(EntryModel edited, PwEntry m_pwInitialEntry /*, bool bValidate*/) { const PwCompareOptions m_cmpOpt = (PwCompareOptions.NullEmptyEquivStd | PwCompareOptions.IgnoreTimes); PwEntry originalEntry = edited.Entry; //peTarget.History = m_vHistory; // Must be called before CreateBackup() bool bCreateBackup = !edited.IsNew; if (bCreateBackup) { originalEntry.CreateBackup(null); } // peTarget.IconId = m_pwEntryIcon; // peTarget.CustomIconUuid = m_pwCustomIconID; // // if(m_cbCustomForegroundColor.Checked) // peTarget.ForegroundColor = m_clrForeground; // else peTarget.ForegroundColor = Color.Empty; // if(m_cbCustomBackgroundColor.Checked) // peTarget.BackgroundColor = m_clrBackground; // else peTarget.BackgroundColor = Color.Empty; //peTarget.OverrideUrl = m_tbOverrideUrl.Text; // List<string> vNewTags = StrUtil.StringToTags(m_tbTags.Text); // peTarget.Tags.Clear(); // foreach(string strTag in vNewTags) peTarget.AddTag(strTag); originalEntry.Expires = edited.Expires; if (originalEntry.Expires) { originalEntry.ExpiryTime = edited.ExpireDate; } UpdateEntryStrings(edited, originalEntry.Strings); // peTarget.Strings = m_vStrings; // peTarget.Binaries = m_vBinaries; // m_atConfig.Enabled = m_cbAutoTypeEnabled.Checked; // m_atConfig.ObfuscationOptions = (m_cbAutoTypeObfuscation.Checked ? // AutoTypeObfuscationOptions.UseClipboard : // AutoTypeObfuscationOptions.None); // // SaveDefaultSeq(); // peTarget.AutoType = m_atConfig; originalEntry.Touch(true, false); // Touch *after* backup // if(object.ReferenceEquals(peTarget, m_pwEntry)) // m_bTouchedOnce = true; StrUtil.NormalizeNewLines(originalEntry.Strings, true); bool bUndoBackup = false; PwCompareOptions cmpOpt = m_cmpOpt; if (bCreateBackup) { cmpOpt |= PwCompareOptions.IgnoreLastBackup; } if (originalEntry.EqualsEntry(m_pwInitialEntry, cmpOpt, MemProtCmpMode.CustomOnly)) { // No modifications at all => restore last mod time and undo backup originalEntry.LastModificationTime = m_pwInitialEntry.LastModificationTime; bUndoBackup = bCreateBackup; } else if (bCreateBackup) { // If only history items have been modified (deleted) => undo // backup, but without restoring the last mod time PwCompareOptions cmpOptNH = (m_cmpOpt | PwCompareOptions.IgnoreHistory); if (originalEntry.EqualsEntry(m_pwInitialEntry, cmpOptNH, MemProtCmpMode.CustomOnly)) { bUndoBackup = true; } } if (bUndoBackup) { originalEntry.History.RemoveAt(originalEntry.History.UCount - 1); } originalEntry.MaintainBackups(db); return(true); }