private void SprEngine_FilterCompile(object sender, SprEventArgs e) { if ((e.Context.Flags & SprCompileFlags.ExtActive) != SprCompileFlags.ExtActive) { return; } if (e.Text.IndexOf(Config.Placeholder, StringComparison.InvariantCultureIgnoreCase) >= 0) { OTPDAO.EnsureOTPUsagePossible(e.Context.Entry); KPOTP myOTP = OTPDAO.GetOTP(e.Context.Entry); if (!myOTP.Valid) { PluginDebug.AddError("Auto-Type OTP failed", 0, "Uuid: " + e.Context.Entry.Uuid.ToHexString()); } else { PluginDebug.AddInfo("Auto-Type OTP success", 0, "Uuid: " + e.Context.Entry.Uuid.ToHexString()); } e.Text = StrUtil.ReplaceCaseInsensitive(e.Text, Config.Placeholder, myOTP.GetOTP(false, true)); if (myOTP.Valid && (myOTP.Type == KPOTPType.HOTP)) { var newOTP = myOTP.Clone(); newOTP.HOTPCounter++; OTPDAO.SaveOTP(newOTP, e.Context.Entry); } } }
internal static bool CopyOTP(PwEntry pe) { if (!OTPDAO.EnsureOTPUsagePossible(pe)) { PluginDebug.AddError("Copy OTP failed", 0, "Uuid: " + pe.Uuid.ToHexString(), "OTP db not unlocked"); return(false); } KPOTP myOTP = OTPDAO.GetOTP(pe); if (!myOTP.Valid) { PluginDebug.AddError("Copy OTP failed", 0, "Uuid: " + pe.Uuid.ToHexString()); return(false); } ClipboardUtil.CopyAndMinimize(myOTP.GetOTP(false, true), true, Program.MainForm, pe, Program.MainForm.DocumentManager.SafeFindContainerOf(pe)); Program.MainForm.StartClipboardCountdown(); PluginDebug.AddInfo("Copy OTP success", 0, "Uuid: " + pe.Uuid.ToString()); if (myOTP.Type == KPOTPType.HOTP) { myOTP.HOTPCounter++; OTPDAO.SaveOTP(myOTP, pe); } return(true); }
private void OnOTPSetup(object sender, EventArgs e) { if (m_host.MainWindow.GetSelectedEntriesCount() != 1) { return; } PwEntry pe = m_host.MainWindow.GetSelectedEntry(true); if (!OTPDAO.EnsureOTPSetupPossible(pe)) { return; } var otpSetup = new KeePassOTPSetup(); Tools.GlobalWindowManager(otpSetup); otpSetup.OTP = OTPDAO.GetOTP(pe); otpSetup.EntryUrl = pe.Strings.GetSafe(PwDefs.UrlField).ReadString(); otpSetup.InitEx(); if (otpSetup.ShowDialog(m_host.MainWindow) == DialogResult.OK) { OTPDAO.SaveOTP(otpSetup.OTP, pe); } otpSetup.Dispose(); }
public override void MigrateFromKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated) { EntriesOverall = EntriesMigrated = -1; if (!m_bInitialized) { return; } EntriesOverall = EntriesMigrated = 0; OTPDAO.OTPHandler_DB h = OTPDAO.GetOTPHandler(m_db); if ((h != null) && !h.EnsureOTPUsagePossible(null)) { return; } PwObjectList <PwEntry> lEntries = m_db.RootGroup.GetEntries(true); if (lEntries.Count() == 0) { return; } OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries.GetAt(0)); InitLogger("KeePassOTP -> KeeTrayTOTP", lEntries.Count()); try { foreach (PwEntry pe in lEntries) { IncreaseLogger(); KPOTP otp = OTPDAO.GetOTP(pe); if (!otp.Valid) { continue; } EntriesOverall++; if (otp.Encoding != KPOTPEncoding.BASE32) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "Encoding not supported: " + otp.Encoding.ToString()); continue; } if (otp.Hash != KPOTPHash.SHA1) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "Hash not supported: " + otp.Hash.ToString()); continue; } if (otp.Type != KPOTPType.TOTP) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "Type not supported: " + otp.Type.ToString()); continue; } string settings = otp.TOTPTimestep.ToString() + ";" + otp.Length.ToString(); if (otp.TimeCorrectionUrlOwn) { settings += ";" + pe.Strings.ReadSafe(PwDefs.UrlField); } else if (!string.IsNullOrEmpty(otp.TimeCorrectionUrl)) { settings += ";" + otp.TimeCorrectionUrl; } pe.Strings.Set("TOTP Seed", otp.OTPSeed); pe.Strings.Set("TOTP Settings", new ProtectedString(false, settings)); EntriesMigrated++; if (bRemove) { otp.OTPSeed = ProtectedString.EmptyEx; try { handler.IgnoreBuffer = true; OTPDAO.SaveOTP(otp, pe); } finally { handler.IgnoreBuffer = false; } } } } finally { EndLogger(); } MigratePlaceholder(Config.Placeholder, OtherPluginPlaceholder, false); }
public override void MigrateToKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated) { EntriesOverall = EntriesMigrated = -1; if (!m_bInitialized) { return; } EntriesOverall = EntriesMigrated = 0; List <PwEntry> lEntries = m_db.RootGroup.GetEntries(true).Where(x => x.Strings.Exists("TOTP Seed")).ToList(); EntriesOverall = lEntries.Count; if (lEntries.Count == 0) { return; } if (!OTPDAO.EnsureOTPSetupPossible(lEntries[0])) { return; } OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries[0]); InitLogger("KeeTrayTOTP -> KeePassOTP", lEntries.Count); try { foreach (PwEntry pe in lEntries) { IncreaseLogger(); string seed = pe.Strings.ReadSafe("TOTP Seed"); string settings = pe.Strings.ReadSafe("TOTP Settings"); if (string.IsNullOrEmpty(settings)) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "OTP data: not defined"); continue; } var parameters = settings.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); if (parameters.Count() < 2) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "OTP data: " + settings); continue; } var otp = OTPDAO.GetOTP(pe); otp.OTPSeed = new ProtectedString(true, MigrateString(seed)); otp.TOTPTimestep = MigrateInt(parameters[0], 30); int l = MigrateInt(parameters[1], -1); if (l == -1) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "OTP data: " + settings); continue; } otp.Length = l; if ((parameters.Count() > 2) && !string.IsNullOrEmpty(parameters[2])) { otp.TimeCorrectionUrl = parameters[2]; } if (otp.Valid) { EntriesMigrated++; try { handler.IgnoreBuffer = true; OTPDAO.SaveOTP(otp, pe); } finally { handler.IgnoreBuffer = false; } if (bRemove) { pe.Strings.Remove("TOTP Seed"); pe.Strings.Remove("TOTP Settings"); } } else { string s = string.Empty; for (int i = 0; i < parameters.Count(); i++) { if (parameters[i].ToLowerInvariant().StartsWith("key=")) { s += "key=<secret>"; } else { s += parameters[i]; } if (i < parameters.Count() - 1) { s += "&"; } } PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "OTP data: " + s); } } } finally { EndLogger(); } MigratePlaceholder(OtherPluginPlaceholder, Config.Placeholder, false); }
public override void MigrateFromKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated) { EntriesOverall = EntriesMigrated = -1; if (!m_bInitialized) { return; } EntriesOverall = EntriesMigrated = 0; OTPDAO.OTPHandler_DB h = OTPDAO.GetOTPHandler(m_db); if ((h != null) && !h.EnsureOTPUsagePossible(null)) { return; } PwObjectList <PwEntry> lEntries = m_db.RootGroup.GetEntries(true); if (lEntries.Count() == 0) { return; } OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries.GetAt(0)); InitLogger("KeePassOTP -> KeeOTP", lEntries.Count()); try { foreach (PwEntry pe in lEntries) { IncreaseLogger(); KPOTP otp = OTPDAO.GetOTP(pe); if (!otp.Valid) { continue; } EntriesOverall++; if (otp.Encoding != KPOTPEncoding.BASE32) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "Encoding not supported: " + otp.Encoding.ToString()); continue; } if (otp.Hash != KPOTPHash.SHA1) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "Hash not supported: " + otp.Hash.ToString()); continue; } if (otp.Type != KPOTPType.TOTP) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "Type not supported: " + otp.Type.ToString()); continue; } string s = "key=" + otp.OTPSeed.ReadString(); if (otp.Length != 6) { s += "&size=" + otp.Length.ToString(); } if (otp.Type == KPOTPType.HOTP) { s += "&type=hotp"; if (otp.HOTPCounter > 0) { s += "&counter=" + otp.HOTPCounter.ToString(); } } if ((otp.Type == KPOTPType.TOTP) && (otp.TOTPTimestep != 30)) { s += "&step=" + otp.TOTPTimestep.ToString(); } pe.Strings.Set("otp", new ProtectedString(true, s)); if (pe.Strings.Exists("otp")) { EntriesMigrated++; } if (bRemove) { otp.OTPSeed = ProtectedString.EmptyEx; try { handler.IgnoreBuffer = true; OTPDAO.SaveOTP(otp, pe); } finally { handler.IgnoreBuffer = false; } } } } finally { EndLogger(); } MigratePlaceholder(Config.Placeholder, OtherPluginPlaceholder, false); }
public override void MigrateToKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated) { EntriesOverall = EntriesMigrated = -1; if (!m_bInitialized) { return; } EntriesOverall = EntriesMigrated = 0; List <PwEntry> lEntries = m_db.RootGroup.GetEntries(true).Where(x => x.Strings.Exists("otp")).ToList(); EntriesOverall = lEntries.Count; if (lEntries.Count == 0) { return; } if (!OTPDAO.EnsureOTPSetupPossible(lEntries[0])) { return; } OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries[0]); InitLogger("KeeOTP -> KeePassOTP", lEntries.Count); try { foreach (PwEntry pe in lEntries) { IncreaseLogger(); string old = pe.Strings.ReadSafe("otp"); if (string.IsNullOrEmpty(old)) { continue; } var parameters = old.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries); var otp = OTPDAO.GetOTP(pe); foreach (var parameter in parameters) { var kvp = parameter.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries); if (kvp.Length != 2) { continue; } switch (kvp[0].ToLowerInvariant()) { case "key": otp.OTPSeed = new ProtectedString(true, MigrateString(kvp[1])); break; case "type": otp.Type = kvp[1].ToLower() != "hotp" ? KPOTPType.TOTP : KPOTPType.HOTP; break; case "step": otp.TOTPTimestep = MigrateInt(kvp[1], 30); break; case "counter": otp.HOTPCounter = MigrateInt(kvp[1], 0); break; case "size": otp.Length = MigrateInt(kvp[1], 6); break; default: break; } } if (otp.Valid) { EntriesMigrated++; try { handler.IgnoreBuffer = true; OTPDAO.SaveOTP(otp, pe); } finally { handler.IgnoreBuffer = false; } pe.Touch(true); //Only remove setting if we migrated to OTP-DB //Do not remove if KeePassOTP stores OTP data within the entry if (bRemove && Config.UseDBForOTPSeeds(pe.GetDB())) { pe.Strings.Remove("otp"); } } else { string s = string.Empty; for (int i = 0; i < parameters.Count(); i++) { if (parameters[i].ToLowerInvariant().StartsWith("key=")) { s += "key=<secret>"; } else { s += parameters[i]; } if (i < parameters.Count() - 1) { s += "&"; } } PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "OTP data: " + s); } } } finally { EndLogger(); } MigratePlaceholder(OtherPluginPlaceholder, Config.Placeholder, false); }
public override void MigrateFromKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated) { EntriesOverall = EntriesMigrated = -1; if (!m_bInitialized) { return; } EntriesOverall = EntriesMigrated = 0; OTPDAO.OTPHandler_DB h = OTPDAO.GetOTPHandler(m_db); if ((h != null) && !h.EnsureOTPUsagePossible(null)) { return; } PwObjectList <PwEntry> lEntries = m_db.RootGroup.GetEntries(true); if (lEntries.Count() == 0) { return; } OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries.GetAt(0)); InitLogger("KeePassOTP -> KeeTrayTOTP", lEntries.Count()); try { foreach (PwEntry pe in lEntries) { IncreaseLogger(); KPOTP otp = OTPDAO.GetOTP(pe); if (!otp.Valid) { continue; } EntriesOverall++; if (otp.Type != KPOTPType.HOTP && otp.Type != KPOTPType.TOTP) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "Type not supported: " + otp.Type.ToString()); continue; } if (otp.Type == KPOTPType.TOTP) { if (Tools.KeePassVersion < m_vKeePass247) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "Type not supported: " + otp.Type.ToString(), "Minimum required KeePass version: " + m_vKeePass247.ToString()); } foreach (var line in m_dTotpStrings) { if (line.Key == otp.Encoding) { pe.Strings.Set(line.Value, otp.OTPSeed); } else { pe.Strings.Remove(line.Value); } } if (otp.TOTPTimestep == 30) { pe.Strings.Remove(TOTPPERIOD); } else { pe.Strings.Set(TOTPPERIOD, new ProtectedString(false, otp.TOTPTimestep.ToString())); } if (otp.Length == 6) { pe.Strings.Remove(TOTPLENGTH); } else { pe.Strings.Set(TOTPLENGTH, new ProtectedString(false, otp.Length.ToString())); } if (otp.Hash == KPOTPHash.SHA1) { pe.Strings.Remove(TOTPHASH); } else if (otp.Hash == KPOTPHash.SHA256) { pe.Strings.Set(TOTPHASH, new ProtectedString(false, "HMAC-SHA-256")); } else if (otp.Hash == KPOTPHash.SHA512) { pe.Strings.Set(TOTPHASH, new ProtectedString(false, "HMAC-SHA-512")); } bool bDummy; MigratePlaceholder(Config.Placeholder, PLACEHOLDER_TOTP, pe, out bDummy); } else if (otp.Type == KPOTPType.HOTP) { if (otp.Length != 6) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "Length not supported: " + otp.Length.ToString()); continue; } if (otp.Hash != KPOTPHash.SHA1) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "Hash not supported: " + otp.Hash.ToString()); continue; } foreach (var line in m_dHotpStrings) { if (line.Key == otp.Encoding) { pe.Strings.Set(line.Value, otp.OTPSeed); } else { pe.Strings.Remove(line.Value); } } pe.Strings.Set(HOTP_COUNTER, new ProtectedString(false, otp.HOTPCounter.ToString())); bool bDummy; MigratePlaceholder(Config.Placeholder, PLACEHOLDER_HOTP, pe, out bDummy); } EntriesMigrated++; if (bRemove) { otp.OTPSeed = ProtectedString.EmptyEx; try { handler.IgnoreBuffer = true; OTPDAO.SaveOTP(otp, pe); } finally { handler.IgnoreBuffer = false; } } } } finally { EndLogger(); } MigratePlaceholder(Config.Placeholder, PLACEHOLDER_TOTP); //In case something is defined on group level (could be right, could be wrong, ...) }
private void MigrateToKeePassOTP_Totp(bool bRemove, out int EntriesOverall, out int EntriesMigrated) { EntriesOverall = EntriesMigrated = 0; Dictionary <PwEntry, KPOTPEncoding> dEntries = new Dictionary <PwEntry, KPOTPEncoding>(); foreach (KeyValuePair <KPOTPEncoding, string> kvp in m_dTotpStrings) { List <PwEntry> lHelp = m_db.RootGroup.GetEntries(true).Where(x => x.Strings.Exists(kvp.Value)).ToList(); foreach (PwEntry pe in lHelp) { if (!dEntries.ContainsKey(pe)) { dEntries[pe] = kvp.Key; } } } EntriesOverall = dEntries.Count; if (dEntries.Count == 0) { return; } if (!OTPDAO.EnsureOTPSetupPossible(dEntries.Keys.First())) { return; } OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(dEntries.Keys.First()); InitLogger("KeePass -> KeePassOTP (TOTP)", dEntries.Count); try { foreach (KeyValuePair <PwEntry, KPOTPEncoding> kvp in dEntries) { IncreaseLogger(); KPOTPEncoding enc = kvp.Value; PwEntry pe = kvp.Key; var otp = OTPDAO.GetOTP(pe); otp.Encoding = enc; otp.OTPSeed = new ProtectedString(true, MigrateString(pe.Strings.ReadSafe(m_dTotpStrings[enc]))); string hash = pe.Strings.ReadSafe(TOTPHASH).ToLowerInvariant(); if (hash.Contains("sha-512")) { otp.Hash = KPOTPHash.SHA512; } else if (hash.Contains("sha-256")) { otp.Hash = KPOTPHash.SHA256; } else { otp.Hash = KPOTPHash.SHA1; } otp.Length = MigrateInt(pe.Strings.ReadSafe(TOTPLENGTH), 6); otp.TOTPTimestep = MigrateInt(pe.Strings.ReadSafe(TOTPPERIOD), 30); otp.HOTPCounter = MigrateInt(pe.Strings.ReadSafe(HOTP_COUNTER), 0); if (otp.Valid) { EntriesMigrated++; try { handler.IgnoreBuffer = true; OTPDAO.SaveOTP(otp, pe); } finally { handler.IgnoreBuffer = false; } if (bRemove) { pe.Strings.Remove(m_dTotpStrings[enc]); pe.Strings.Remove(TOTPHASH); pe.Strings.Remove(TOTPLENGTH); pe.Strings.Remove(TOTPPERIOD); } } else { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "OTP data: " + m_dHotpStrings[enc]); } } } finally { EndLogger(); } MigratePlaceholder(PLACEHOLDER_TOTP, Config.Placeholder); }
private void MigrateToKeePassOTP_Hotp(bool bRemove, out int EntriesOverall, out int EntriesMigrated) { EntriesOverall = EntriesMigrated = 0; List <PwEntry> lEntries = m_db.RootGroup.GetEntries(true).Where(x => x.Strings.Exists(HOTP_COUNTER)).ToList(); EntriesOverall = lEntries.Count; if (lEntries.Count == 0) { return; } if (!OTPDAO.EnsureOTPSetupPossible(lEntries[0])) { return; } OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries[0]); InitLogger("KeePass -> KeePassOTP (HOTP)", lEntries.Count); try { foreach (PwEntry pe in lEntries) { IncreaseLogger(); KPOTPEncoding enc = KPOTPEncoding.BASE32; bool bFound = false; string seed = null; foreach (KeyValuePair <KPOTPEncoding, string> kvp in m_dHotpStrings) { if (pe.Strings.Exists(kvp.Value)) { enc = kvp.Key; seed = pe.Strings.ReadSafe(kvp.Value); bFound = true; break; } } if (!bFound) { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "OTP data: not defined"); continue; } var otp = OTPDAO.GetOTP(pe); otp.Type = KPOTPType.HOTP; otp.Encoding = enc; otp.OTPSeed = new ProtectedString(true, MigrateString(seed)); otp.HOTPCounter = MigrateInt(pe.Strings.ReadSafe(HOTP_COUNTER), 0); if (otp.Valid) { EntriesMigrated++; try { handler.IgnoreBuffer = true; OTPDAO.SaveOTP(otp, pe); } finally { handler.IgnoreBuffer = false; } if (bRemove) { pe.Strings.Remove(m_dHotpStrings[enc]); pe.Strings.Remove(HOTP_COUNTER); } } else { PluginDebug.AddError("Migration of entry failed", "Uuid: " + pe.Uuid.ToHexString(), "OTP data: " + m_dHotpStrings[enc]); } } } finally { EndLogger(); } MigratePlaceholder(PLACEHOLDER_HOTP, Config.Placeholder); }