private static int SanitizeSeeds(PwDatabase db) { //Get DB to work on PwDatabase otpdb = db; OTPDAO.OTPHandler_DB h = GetOTPHandler(db); if (h != null) { if (!h.EnsureOTPUsagePossible(null)) { return(-1); } otpdb = h.OTPDB; } int i = 0; foreach (PwEntry pe in otpdb.RootGroup.GetEntries(true)) { KPOTP otp = OTPDAO.GetOTP(pe); if (!otp.Valid) { continue; } otp.OTPSeed = otp.OTPSeed; if (otp.SanitizeChanged) { i++; pe.CreateBackup(otpdb); pe.Strings.Set(Config.OTPFIELD, otp.OTPAuthString); } } return(i); }
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); } } }
public override string GetCellData(string strColumnName, PwEntry pe) { if (strColumnName == null) { return(string.Empty); } if (pe == null) { return(string.Empty); } Random r = new Random(); string otp = string.Empty; bool bForUsage = new System.Diagnostics.StackTrace().GetFrames().FirstOrDefault(x => x.GetMethod().Name == "OnPwListItemDrag") != null; if (bForUsage) { otp = OTPDAO.GetOTP(pe).GetOTP(); } else { otp = OTPDAO.GetReadableOTP(pe); } if (!string.IsNullOrEmpty(otp)) { if (bForUsage || strColumnName == OTPColumn_Verbose) { return(otp); } return(PluginTranslation.PluginTranslate.TFADefined); } if (!Config.CheckTFA) { return(string.Empty); } string url = pe.Strings.ReadSafe(PwDefs.UrlField); if (string.IsNullOrEmpty(url)) { return(string.Empty); } TFASites.TFAPossible TFAPossible = TFASites.IsTFAPossible(url); if (TFAPossible == TFASites.TFAPossible.Yes) { return(PluginTranslation.PluginTranslate.SetupTFA); } else if (TFAPossible == TFASites.TFAPossible.Unknown) { return("Checking 2FA"); } else { return(string.Empty); } }
private void OnEntryContextMenuOpening(object sender, EventArgs e) { m_ContextMenuCopy.ShortcutKeys = m_MainMenuCopy.ShortcutKeys = Config.Hotkey; if (m_host.MainWindow.GetSelectedEntriesCount() != 1) { m_ContextMenu.Enabled = m_ContextMenuAutotype.Enabled = false; m_MainMenu.Enabled = m_MainMenuAutotype.Enabled = false; } else { KPOTP myOTP = OTPDAO.GetOTP(m_host.MainWindow.GetSelectedEntry(true)); m_ContextMenu.Enabled = m_MainMenu.Enabled = true; m_ContextMenuCopy.Enabled = m_ContextMenuAutotype.Enabled = m_ContextMenuQRCode.Enabled = myOTP.Valid; m_MainMenuCopy.Enabled = m_MainMenuAutotype.Enabled = m_MainMenuQRCode.Enabled = myOTP.Valid; } }
private static int ProcessReferences(PwDatabase db) { //Get DB to work on PwDatabase otpdb = db; OTPDAO.OTPHandler_DB h = GetOTPHandler(db); if (h != null) { if (!h.EnsureOTPUsagePossible(null)) { return(-1); } otpdb = h.OTPDB; } if (otpdb == null || !otpdb.IsOpen) { return(-1); } int i = 0; var b = new OTPHandler_Base(); foreach (PwEntry pe in otpdb.RootGroup.GetEntries(true)) { KPOTP otp = OTPDAO.GetOTP(pe); if (!otp.Valid) { continue; } if (!otp.Issuer.ToLowerInvariant().Contains("{ref:") && !otp.Label.ToLowerInvariant().EndsWith("{ref")) { continue; } PwEntry peMain = h is OTPHandler_DB ? (h as OTPHandler_DB).GetMainPwEntry(pe) : pe; b.InitIssuerLabel(otp, peMain); pe.CreateBackup(otpdb); pe.Strings.Set(Config.OTPFIELD, otp.OTPAuthString); i++; } return(i); }
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(); }
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 static int OTPAuthFormatCorrection(PwDatabase db) { //Get DB to work on PwDatabase otpdb = db; OTPDAO.OTPHandler_DB h = GetOTPHandler(db); if (h != null) { if (!h.EnsureOTPUsagePossible(null)) { return(-1); } otpdb = h.OTPDB; } int i = 0; foreach (PwEntry pe in otpdb.RootGroup.GetEntries(true).Where(x => x.Strings.Exists(Config.OTPFIELD))) { //Don't compare strings because strings are not protected and will remain in memory char[] ps = pe.Strings.Get(Config.OTPFIELD).ReadChars(); try { if (ps.Length < 15) { continue; } bool bConvert = false; foreach (char[] check in lOTPAuthStart) { if (check.Length > ps.Length) { continue; } bConvert = true; for (int j = 0; j < check.Length; j++) { if (Char.ToLowerInvariant(check[j]) != Char.ToLowerInvariant(ps[j])) { bConvert = false; break; } } if (bConvert) { break; } } if (!bConvert) { break; } KPOTP otp = OTPDAO.GetOTP(pe); if (!otp.Valid) { continue; } i++; pe.CreateBackup(otpdb); pe.Strings.Set(Config.OTPFIELD, otp.OTPAuthString); } finally { MemUtil.ZeroArray(ps); } } return(i); }
private void OnOTPQRCode(object sender, EventArgs e) { if (m_host.MainWindow.GetSelectedEntriesCount() != 1) { return; } KPOTP otp = OTPDAO.GetOTP(m_host.MainWindow.GetSelectedEntry(true)); if (!otp.Valid) { return; } try { byte[] bOTP = otp.OTPAuthString.ReadUtf8(); QRCoder.QRCodeData qrd = QRCoder.QRCodeGenerator.GenerateQrCode(bOTP, QRCoder.QRCodeGenerator.ECCLevel.Q); MemUtil.ZeroByteArray(bOTP); QRCoder.QRCode qrc = new QRCoder.QRCode(qrd); Bitmap bmp = qrc.GetGraphic(8); QRForm f = new QRForm(); f.FormBorderStyle = FormBorderStyle.FixedDialog; f.StartPosition = FormStartPosition.CenterParent; f.Text = PluginTranslate.PluginName; f.MinimizeBox = false; f.MaximizeBox = false; PictureBox pb = new PictureBox(); pb.Size = new Size(bmp.Width, bmp.Height); pb.Location = new Point(0, 0); f.ClientSize = pb.Size; pb.Image = bmp; f.Controls.Add(pb); if (!string.IsNullOrEmpty(otp.Issuer) && (otp.Issuer != PluginTranslate.PluginName)) { Label lIssuer = new Label(); lIssuer.Width = f.ClientSize.Width; lIssuer.Text = otp.Issuer; lIssuer.Location = new Point(0, f.ClientSize.Height + 10); f.Controls.Add(lIssuer); f.Height += lIssuer.Height + 10; } if (!string.IsNullOrEmpty(otp.Label)) { Label lLabel = new Label(); lLabel.Width = f.ClientSize.Width; lLabel.Text = otp.Label; lLabel.Location = new Point(0, f.ClientSize.Height + 10); f.Controls.Add(lLabel); f.Height += lLabel.Height + 10; } f.Height += 5; Timer tClose = new Timer(); tClose.Interval = 30000; tClose.Tick += (o, e1) => { tClose.Stop(); tClose.Dispose(); if (f != null) { f.Close(); } }; f.Shown += (o, e2) => { KeePass.UI.GlobalWindowManager.AddWindow(f, f); tClose.Start(); }; f.FormClosed += (o, e1) => { if (f != null) { KeePass.UI.GlobalWindowManager.RemoveWindow(f); } }; f.ShowDialog(KeePass.UI.GlobalWindowManager.TopWindow); pb.Image.Dispose(); f.Dispose(); qrc.Dispose(); qrd.Dispose(); } catch { } }
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); }
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 OnOTPQRCode(object sender, EventArgs e) { if (m_host.MainWindow.GetSelectedEntriesCount() != 1) { return; } KPOTP otp = OTPDAO.GetOTP(m_host.MainWindow.GetSelectedEntry(true)); if (!otp.Valid) { return; } try { ZXing.BarcodeWriter zBW = new ZXing.BarcodeWriter(); zBW.Options.Height = 320; zBW.Options.Width = 320; zBW.Format = ZXing.BarcodeFormat.QR_CODE; Bitmap bmp = zBW.Write(otp.OTPAuthString.ReadString()); QRForm f = new QRForm(); f.FormBorderStyle = FormBorderStyle.FixedDialog; f.StartPosition = FormStartPosition.CenterParent; f.Text = PluginTranslate.PluginName; f.MinimizeBox = false; f.MaximizeBox = false; PictureBox pb = new PictureBox(); pb.Location = new Point(0, 0); pb.Image = new Bitmap(bmp, bmp.Size); //Assigning bmp directly did not work in my Ubuntu VM... pb.ClientSize = pb.Image.Size; f.ClientSize = pb.Size; f.Controls.Add(pb); if (!string.IsNullOrEmpty(otp.Issuer) && (otp.Issuer != PluginTranslate.PluginName)) { Label lIssuer = new Label(); lIssuer.Width = f.ClientSize.Width; lIssuer.Text = otp.Issuer; lIssuer.Location = new Point(0, f.ClientSize.Height + 10); f.Controls.Add(lIssuer); f.Height += lIssuer.Height + 10; } if (!string.IsNullOrEmpty(otp.Label)) { Label lLabel = new Label(); lLabel.Width = f.ClientSize.Width; lLabel.Text = otp.Label; lLabel.Location = new Point(0, f.ClientSize.Height + 10); f.Controls.Add(lLabel); f.Height += lLabel.Height + 10; } f.Height += 5; Timer tClose = new Timer(); tClose.Interval = 30000; tClose.Tick += (o, e1) => { tClose.Stop(); tClose.Dispose(); if (f != null) { f.Close(); } }; f.Shown += (o, e2) => { KeePass.UI.GlobalWindowManager.AddWindow(f, f); tClose.Start(); }; f.FormClosed += (o, e1) => { if (f != null) { KeePass.UI.GlobalWindowManager.RemoveWindow(f); } }; f.ShowDialog(KeePass.UI.GlobalWindowManager.TopWindow); pb.Image.Dispose(); f.Dispose(); bmp.Dispose(); } catch { }; }
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); }
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); }