Skip to content

Commit

Permalink
Migrate OTP placeholder
Browse files Browse the repository at this point in the history
Changing the OTP placeholder will now replace the placeholder in all string fields - previously this was done in Auto-Type sequences only
Backup entries before migrating OTP placeholder
  • Loading branch information
Rookiestyle committed Dec 12, 2020
1 parent b9f5404 commit dc1b294
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/KeePassOTPExt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ private void MigratePlacholderInOpenDatabases(string sOldPlaceholder, string pla
if (!doc.Database.IsOpen) m_host.MainWindow.OpenDatabase(doc.LockedIoc, null, doc.LockedIoc.IsLocalFile());
if (!doc.Database.IsOpen) continue;
m.SetDB(doc.Database);
if (m.MigratePlaceholder(sOldPlaceholder, Config.Placeholder, false))
if (m.MigratePlaceholder(sOldPlaceholder, Config.Placeholder))
{
doc.Database.Modified = true;
bChanged = true;
Expand Down
36 changes: 30 additions & 6 deletions src/Migration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public virtual void MigrateFromKeePassOTP(bool bRemove, out int EntriesOverall,
EntriesOverall = EntriesMigrated = -1;
}

public bool MigratePlaceholder(string from, string to, bool bTouchEntries)
public bool MigratePlaceholder(string from, string to)
{
bool bChanged = false;
if (!m_bInitialized) return bChanged;
Expand All @@ -64,20 +64,44 @@ public bool MigratePlaceholder(string from, string to, bool bTouchEntries)
EntryHandler eh = delegate (PwEntry pe)
{
if (pe == null) { return true; }
bool bBackupRequired = true;
foreach (var a in pe.AutoType.Associations)
{
if (a.Sequence.Contains(from))
{
if (bBackupRequired)
{
bBackupRequired = false;
pe.CreateBackup(m_db);
}
a.Sequence = a.Sequence.Replace(from, to);
bChanged = true;
}
}
if (pe.AutoType.DefaultSequence.Contains(from))
{
if (bBackupRequired)
{
bBackupRequired = false;
pe.CreateBackup(m_db);
}
pe.AutoType.DefaultSequence = pe.AutoType.DefaultSequence.Replace(from, to);
bChanged = true;
}
if (bTouchEntries) pe.Touch(true);
foreach (var s in pe.Strings.GetKeys())
{
ProtectedString ps = pe.Strings.Get(s);
if (!ps.Contains(from)) continue;
if (bBackupRequired)
{
bBackupRequired = false;
pe.CreateBackup(m_db);
}
ps = ps.Replace(from, to);
pe.Strings.Set(s, ps);
bChanged = true;
}
pe.Touch(true, false);
return true;
};

Expand Down Expand Up @@ -212,7 +236,7 @@ public override void MigrateToKeePassOTP(bool bRemove, out int EntriesOverall, o
}
}
finally { EndLogger(); }
MigratePlaceholder(OtherPluginPlaceholder, Config.Placeholder, false);
MigratePlaceholder(OtherPluginPlaceholder, Config.Placeholder);
}

public override void MigrateFromKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated)
Expand Down Expand Up @@ -289,7 +313,7 @@ public override void MigrateFromKeePassOTP(bool bRemove, out int EntriesOverall,
{
EndLogger();
}
MigratePlaceholder(Config.Placeholder, OtherPluginPlaceholder, false);
MigratePlaceholder(Config.Placeholder, OtherPluginPlaceholder);
}
}

Expand Down Expand Up @@ -395,7 +419,7 @@ public override void MigrateToKeePassOTP(bool bRemove, out int EntriesOverall, o
{
EndLogger();
}
MigratePlaceholder(m_OtherPluginPlaceholder, Config.Placeholder, false);
MigratePlaceholder(m_OtherPluginPlaceholder, Config.Placeholder);
}

public override void MigrateFromKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated)
Expand Down Expand Up @@ -462,7 +486,7 @@ public override void MigrateFromKeePassOTP(bool bRemove, out int EntriesOverall,
}
}
finally { EndLogger(); }
MigratePlaceholder(Config.Placeholder, m_OtherPluginPlaceholder, false);
MigratePlaceholder(Config.Placeholder, m_OtherPluginPlaceholder);
}
}
}
4 changes: 2 additions & 2 deletions src/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.21")]
[assembly: AssemblyFileVersion("0.21")]
[assembly: AssemblyVersion("0.22")]
[assembly: AssemblyFileVersion("0.22")]
71 changes: 71 additions & 0 deletions src/Util.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

Expand Down Expand Up @@ -618,4 +619,74 @@ public static List<Delegate> GetEventHandlers(this object obj, string EventName)
return result;
}
}

internal static class PSExtensions
{
internal static bool Contains(this ProtectedString ps, string search)
{
return Contains(ps, new ProtectedString(false, search));
}

internal static bool Contains(this ProtectedString ps, ProtectedString search)
{
return IndexOfSubString(ps, search) > 0;
}

internal static ProtectedString Replace(this ProtectedString ps, string search, string replace)
{
return Replace(ps, new ProtectedString(true, StrUtil.Utf8.GetBytes(search)), new ProtectedString(true, StrUtil.Utf8.GetBytes(replace)));
}

internal static ProtectedString Replace(this ProtectedString ps, ProtectedString search, ProtectedString replace)
{
ProtectedString result = ps;
int i = IndexOfSubString(result, search);
while (i >= 0)
{
var psAfter = result.Remove(0, i + search.Length);
var psBefore = result.Remove(i, result.Length - i);
result = psBefore + replace + psAfter;
i = IndexOfSubString(result, search);
}
return result;
}

private static int IndexOfSubString(ProtectedString ps, ProtectedString search)
{
if (ps == null || ps.IsEmpty || search == null || search.IsEmpty) return -1;
int i = 0;
int max = ps.Length - search.Length;
if (max < 0) return -1;
var haystack = ps.ReadChars();
var needle = search.ReadChars();
char[] slice = null;
try
{
while (i <= max)
{
slice = haystack.Slice(i, search.Length);
if (needle.SequenceEqual(slice)) return i;
i++;
}
return -1;
}
catch
{
return -1;
}
finally
{
MemUtil.ZeroArray(haystack);
MemUtil.ZeroArray(needle);
if (slice != null) MemUtil.ZeroArray(slice);
}
}

internal static T[] Slice<T>(this T[] data, int index, int length)
{
T[] result = new T[length];
Array.Copy(data, index, result, 0, length);
return result;
}
}
}
4 changes: 2 additions & 2 deletions src/Utilities/Tools_UI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ public static bool PreserveEntriesShown

public static void RefreshEntriesList(bool bSetModified)
{
UpdateUIAndRefreshEntriesList(false, null, false, null, false, null, bSetModified);
UpdateUI(false, null, false, null, false, null, bSetModified);
}

public static void UpdateUIAndRefreshEntriesList(bool bRecreateTabBar, KeePass.UI.PwDocument dsSelect,
public static void UpdateUI(bool bRecreateTabBar, KeePass.UI.PwDocument dsSelect,
bool bUpdateGroupList, KeePassLib.PwGroup pgSelect, bool bUpdateEntryList,
KeePassLib.PwGroup pgEntrySource, bool bSetModified)
{
Expand Down
2 changes: 1 addition & 1 deletion version.info
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
:
KeePassOTP:0.21
KeePassOTP:0.22
KeePassOTP!de:11
KeePassOTP!fr:3
:

0 comments on commit dc1b294

Please sign in to comment.