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); } } }
private static KPOTP GetSettings(PwEntry pe) { KPOTP myOTP = new KPOTP(); /* * * myOTP.OTPSeed = ProtectedString.EmptyEx; * string settings = pe.Strings.ReadSafe(Config.SETTINGS); * PluginDebug.AddInfo("Set OTP settings", 0, "Uuid: " + pe.Uuid.ToString(), "Settings: " + settings); * myOTP.Settings = settings; * myOTP.OTPSeed = pe.Strings.GetSafe(Config.SEED); */ myOTP.OTPAuthString = pe.Strings.Get(Config.OTPFIELD); string timeCorrection = pe.Strings.ReadSafe(Config.TIMECORRECTION); if (timeCorrection == "OWNURL") { myOTP.TimeCorrectionUrlOwn = true; string url = pe.Strings.GetSafe(PwDefs.UrlField).ReadString(); if (!string.IsNullOrEmpty(url)) { myOTP.TimeCorrectionUrl = url; } } else { myOTP.TimeCorrectionUrlOwn = false; myOTP.TimeCorrectionUrl = timeCorrection; } return(myOTP); }
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 KPOTP GetSettings() { GetOTPEntry(); KPOTP myOTP = new KPOTP(); if (m_peOTP == null) { return(EmptyKPOTDB); // myOTP; } /* * myOTP.OTPSeed = ProtectedString.EmptyEx; * string settings = m_peOTP.Strings.ReadSafe(Config.SETTINGS); * PluginDebug.AddInfo("Get OTP settings", 0, "Uuid: " + m_pe.Uuid.ToHexString(), "OTP Uuid: " + m_peOTP.Uuid.ToHexString(), "Settings: " + settings); */ myOTP.OTPAuthString = m_peOTP.Strings.GetSafe(Config.OTPFIELD); string timeCorrection = m_peOTP.Strings.ReadSafe(Config.TIMECORRECTION); if (timeCorrection == "OWNURL") { myOTP.TimeCorrectionUrlOwn = true; string url = m_pe.Strings.GetSafe(PwDefs.UrlField).ReadString(); if (!string.IsNullOrEmpty(url)) { myOTP.TimeCorrectionUrl = url; } } else { myOTP.TimeCorrectionUrlOwn = false; myOTP.TimeCorrectionUrl = timeCorrection; } return(myOTP); }
public override void SaveOTP(KPOTP myOTP, PwEntry pe) { if (!SetEntry(pe, true)) { return; } //string otpSettings = myOTP.Settings; KPOTP prev = GetOTP(pe); bool OnlyCounterChanged = false; if (!SettingsChanged(pe, prev, myOTP, out OnlyCounterChanged)) { return; } PluginDebug.AddInfo("Update OTP data", "Entry uuid: " + pe.Uuid.ToHexString(), "Only change of HOTP counter: " + OnlyCounterChanged.ToString()); bool bCreated = false; GetOTPEntry(true, out bCreated); if (!OnlyCounterChanged) { //Create backup if something else than only the HOTP counter was changed if (!bCreated) { m_peOTP.CreateBackup(OTPDB); } } m_peOTP.Strings.Set(Config.OTPFIELD, myOTP.OTPAuthString); if (myOTP.TimeCorrectionUrlOwn) { m_peOTP.Strings.Set(Config.TIMECORRECTION, new ProtectedString(false, "OWNURL")); } else if (string.IsNullOrEmpty(myOTP.TimeCorrectionUrl) || (myOTP.TimeCorrectionUrl == "OFF")) { m_peOTP.Strings.Remove(Config.TIMECORRECTION); } else { m_peOTP.Strings.Set(Config.TIMECORRECTION, new ProtectedString(false, myOTP.TimeCorrectionUrl)); } Touch(m_peOTP); if (myOTP.OTPSeed.IsEmpty) { m_pe.Strings.Remove(DBNAME); } else { m_pe.Strings.Set(DBNAME, new ProtectedString(false, StrUtil.BoolToString(true))); } FlagChanged(false); FlagChanged(true); m_pe.Touch(true); }
public void InitIssuerLabel(KPOTP otp, PwEntry pe) { otp.Issuer = pe.Strings.ReadSafe(PwDefs.TitleField); if (string.IsNullOrEmpty(otp.Issuer)) { otp.Issuer = PluginTranslation.PluginTranslate.PluginName; } otp.Label = pe.Strings.ReadSafe(PwDefs.UserNameField); }
public static void SaveOTP(KPOTP myOTP, PwEntry pe) { OTPHandler_Base h = GetOTPHandler(pe); h.SaveOTP(myOTP, pe); myOTP.ResetSanitizedChange(); Program.MainForm.RefreshEntriesList(); bool bModified = (h is OTPHandler_DB) ? (h as OTPHandler_DB).DB == Program.MainForm.ActiveDatabase : true; Program.MainForm.UpdateUI(false, null, false, null, true, null, bModified); }
public static void SaveOTP(KPOTP myOTP, PwEntry pe) { OTPHandler_Base h = GetOTPHandler(pe); h.SaveOTP(myOTP, pe); myOTP.ResetSanitizedChange(); bool bModified = (h is OTPHandler_DB) ? (h as OTPHandler_DB).DB == Program.MainForm.ActiveDatabase : true; System.Windows.Forms.ListView lv = (System.Windows.Forms.ListView)Tools.GetControl("m_lvEntries"); Tools.RefreshEntriesList(bModified); }
private static KPOTP ConvertOTPSettings(string settings) { KPOTP otp = new KPOTP(); string[] setting = settings.ToUpper().Split(';'); if (setting.Length != 5) { setting = new string[] { "30", "6", "TOTP", "BASE32", "SHA1" } } ; try { otp.Type = (KPOTPType)Enum.Parse(typeof(KPOTPType), setting[2]); } catch { PluginDebug.AddError("Invalid OTP data", 0, "Error field: Type", settings.ToUpper()); } try { otp.Encoding = (KPOTPEncoding)Enum.Parse(typeof(KPOTPEncoding), setting[3]); } catch { PluginDebug.AddError("Invalid OTP data", 0, "Error field: Encoding", settings.ToUpper()); } try { otp.Hash = (KPOTPHash)Enum.Parse(typeof(KPOTPHash), setting[4]); } catch { PluginDebug.AddError("Invalid OTP data", 0, "Error field: Hash", settings.ToUpper()); } int i = 0; if (!int.TryParse(setting[0], out i)) { i = 30; PluginDebug.AddError("Invalid OTP data", 0, "Error field: Timestep / Counter", settings.ToUpper()); } if (otp.Type == KPOTPType.TOTP) { otp.TOTPTimestep = i; } else { otp.HOTPCounter = i; } if (!int.TryParse(setting[1], out i)) { i = 6; PluginDebug.AddError("Invalid OTP data", 0, "Error field: Length", settings.ToUpper()); } otp.Length = i; return(otp); }
private bool IsValidOtpAuth(ProtectedString otp) { if (otp == null) { return(false); } if (otp.Length < 11) { return(false); } KPOTP check = new KPOTP(); check.OTPAuthString = otp; return(check.Valid); }
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; } }
public KPOTP Clone() { KPOTP result = new KPOTP(); result.Type = this.Type; result.Encoding = this.Encoding; result.Hash = this.Hash; result.Length = this.Length; result.Issuer = this.Issuer; result.Label = this.Label; result.OTPSeed = this.OTPSeed; result.HOTPCounter = this.HOTPCounter; result.TimeCorrectionUrl = this.TimeCorrectionUrl; result.TimeCorrectionUrlOwn = this.TimeCorrectionUrlOwn; result.TOTPTimestep = this.TOTPTimestep; result.OTPTimeCorrection = this.OTPTimeCorrection; return(result); }
public override void SaveOTP(KPOTP myOTP, PwEntry pe) { KPOTP prev = GetOTP(pe); bool OnlyCounterChanged = false; if (!SettingsChanged(pe, prev, myOTP, out OnlyCounterChanged)) { return; } PluginDebug.AddInfo("Update OTP data", "Entry uuid: " + pe.Uuid.ToString(), "Only change of HOTP counter: " + OnlyCounterChanged.ToString()); if (!OnlyCounterChanged) { //Create backup if something else than only the HOTP counter was changed pe.CreateBackup(pe.GetDB()); } if (myOTP.OTPSeed.IsEmpty) { pe.Strings.Remove(Config.OTPFIELD); pe.Strings.Remove(Config.TIMECORRECTION); } else { //pe.Strings.Set(Config.SETTINGS, new ProtectedString(false, otpSettings)); //pe.Strings.Set(Config.SEED, myOTP.OTPSeed); pe.Strings.Set(Config.OTPFIELD, myOTP.OTPAuthString); if (myOTP.TimeCorrectionUrlOwn) { pe.Strings.Set(Config.TIMECORRECTION, new ProtectedString(false, "OWNURL")); } else if (string.IsNullOrEmpty(myOTP.TimeCorrectionUrl) || (myOTP.TimeCorrectionUrl == "OFF")) { pe.Strings.Remove(Config.TIMECORRECTION); } else { pe.Strings.Set(Config.TIMECORRECTION, new ProtectedString(false, myOTP.TimeCorrectionUrl)); } } pe.Touch(true); }
public void InitEx() { Text = PluginTranslate.PluginName; gSeed.Text = PluginTranslate.SeedSettings; gOTP.Text = PluginTranslate.OTPSettings; gTime.Text = PluginTranslate.TimeCorrection; lSeed.Text = PluginTranslate.Seed; lFormat.Text = PluginTranslate.Format; lType.Text = PluginTranslate.OTPType; lLength.Text = PluginTranslate.OTPLength; lHash.Text = PluginTranslate.OTPHash; lTimestep.Text = PluginTranslate.OTPTimestep; lCounter.Text = PluginTranslate.OTPCounter; lTimeType.Text = PluginTranslate.OTPType; lURL.Text = PluginTranslate.URL; lTime.Text = PluginTranslate.TimeDiff; cbAdvanced.Text = PluginTranslate.AdvancedOptions; pbSearchScreen.Image = Resources.qr_code_screencapture; pbSearchScreen.Text = PluginTranslate.ReadScreenForQRCode; totpTimeCorrectionType.Items.Add(PluginTranslate.TimeCorrectionOff); totpTimeCorrectionType.Items.Add(PluginTranslate.TimeCorrectionEntry); totpTimeCorrectionType.Items.Add(PluginTranslate.TimeCorrectionFixed); m_NoUpdate = true; InitSettings(false); m_NoUpdate = false; UpdatePreview(); CheckAdvancedMode(); m_OTPInitial = OTP; OTP = new KPOTP(); OTP.Issuer = m_OTPInitial.Issuer; OTP.Label = m_OTPInitial.Label; m_timer = new Timer(); m_timer.Interval = 1000; m_timer.Tick += OnValueChanged; m_timer.Start(); }
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); }
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 bool SettingsChanged() { return(!KPOTP.Equals(OTP, m_OTPInitial)); }
internal static ProtectedString ParseGoogleAuthExport(string s, out int iOTPCount) { iOTPCount = 0; ProtectedString psResult = ProtectedString.Empty; try { var u = new Uri(s); var param = System.Web.HttpUtility.ParseQueryString(u.Query); var b = Convert.FromBase64String(param["data"]); GoogleAuthenticatorImport gi = DeserializeGoogleAuthMigrationData(b); GoogleAuthenticatorImport.OtpParameters gAuthData = null; iOTPCount = gi.otp_parameters.Count; if (iOTPCount != 1) { using (GoogleAuthenticatorImportSelection selForm = new GoogleAuthenticatorImportSelection()) { Tools.GlobalWindowManager(selForm); selForm.InitEx(gi.otp_parameters); if (selForm.ShowDialog(KeePass.UI.GlobalWindowManager.TopWindow) == DialogResult.OK) { gAuthData = selForm.SelectedEntry; if (gAuthData != null) { iOTPCount = 1; } } else { iOTPCount = -1; } } if (iOTPCount != 1) { throw new ArgumentException("Expected exactly one OTP object, found: " + iOTPCount.ToString()); } } else { gAuthData = gi.otp_parameters[0]; } KPOTP otp = new KPOTP(); switch (gAuthData.Algorithm) { case GoogleAuthenticatorImport.Algorithm.AlgorithmSha256: otp.Hash = KPOTPHash.SHA256; break; case GoogleAuthenticatorImport.Algorithm.AlgorithmSha512: otp.Hash = KPOTPHash.SHA512; break; default: otp.Hash = KPOTPHash.SHA1; break; } switch (gAuthData.Type) { case GoogleAuthenticatorImport.OtpType.OtpTypeHotp: otp.Type = KPOTPType.HOTP; otp.HOTPCounter = (int)gAuthData.Counter; break; default: otp.Type = KPOTPType.TOTP; break; } switch (gAuthData.Digits) { case GoogleAuthenticatorImport.DigitCount.DigitCountEight: otp.Length = 8; break; default: otp.Length = 6; break; } otp.Issuer = gAuthData.Issuer; otp.Label = string.IsNullOrEmpty(gAuthData.Issuer) ? gAuthData.Name : gAuthData.Name.Remove(0, gAuthData.Issuer.Length + 1); otp.Encoding = KPOTPEncoding.BASE32; byte[] bSeed = ConvertBase64ToBase32(gAuthData.Secret); otp.OTPSeed = new ProtectedString(true, bSeed); psResult = otp.OTPAuthString; } catch { } return(psResult); }
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); }
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 { }; }
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 static bool SettingsChanged(PwEntry pw, KPOTP prev, KPOTP current, out bool OnlyCounterChanged) { bool bEquals = KPOTP.Equals(prev, current, pw.Strings.ReadSafe(PwDefs.UrlField), out OnlyCounterChanged); return(!bEquals); }
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 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 { } }
public static bool Equals(KPOTP otp1, KPOTP otp2, string url, out bool OnlyCounterChanged) { OnlyCounterChanged = false; if ((otp1 == null) && (otp2 == null)) { return(false); } if ((otp1 == null) || (otp2 == null)) { return(true); } if (!otp1.OTPSeed.Equals(otp2.OTPSeed, false)) { return(false); } if (otp1.SanitizeChanged || otp2.SanitizeChanged) { return(false); } if (otp1.Encoding != otp2.Encoding) { return(false); } if (otp1.Hash != otp2.Hash) { return(false); } if (otp1.Type != otp2.Type) { return(false); } if (otp1.Length != otp2.Length) { return(false); } if ((otp1.Type == KPOTPType.TOTP) && (otp1.TOTPTimestep != otp2.TOTPTimestep)) { return(false); } if ((otp1.Type == KPOTPType.TOTP) && (otp1.TimeCorrectionUrlOwn != otp2.TimeCorrectionUrlOwn)) { return(false); } if (otp1.TimeCorrectionUrlOwn && (otp1.Type == KPOTPType.TOTP)) { if (otp1.TimeCorrectionUrl != otp2.TimeCorrectionUrl) { return(false); } if ((otp1.TimeCorrectionUrl == "OWNURL") && !string.IsNullOrEmpty(url) && (otp2.TimeCorrectionUrl != url)) { return(false); } if ((otp2.TimeCorrectionUrl == "OWNURL") && !string.IsNullOrEmpty(url) && (otp1.TimeCorrectionUrl != url)) { return(false); } } if (otp1.Type == KPOTPType.HOTP && (otp1.HOTPCounter != otp2.HOTPCounter)) { OnlyCounterChanged = true; return(false); } return(true); }
public static bool Equals(KPOTP otp1, KPOTP otp2) { bool dummy; return(Equals(otp1, otp2, null, out dummy)); }
public virtual void SaveOTP(KPOTP myOTP, PwEntry pe) { }
private void MainWindow_FileOpened(object sender, KeePass.Forms.FileOpenedEventArgs e) { KPOTP.GetTimingsAsync(e.Database); }
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 static int CheckOTPDataMigration(PwDatabase db) { const string SEED = "KeePassOTP.Seed"; const string SETTINGS = "KeePassOTP.Settings"; //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; } List <PwEntry> lEntries = otpdb.RootGroup.GetEntries(true).Where(x => x.Strings.Exists(SEED) && x.Strings.Exists(SETTINGS)).ToList(); int migrated = 0; foreach (PwEntry pe in lEntries) { ProtectedString seed = pe.Strings.Get(SEED); string settings = pe.Strings.ReadSafe(SETTINGS); string title = pe.Strings.ReadSafe(PwDefs.TitleField); string user = pe.Strings.ReadSafe(PwDefs.UserNameField); if (string.IsNullOrEmpty(title)) { title = PluginTranslation.PluginTranslate.PluginName; } if (!string.IsNullOrEmpty(user)) { user = "******" + user; } KPOTP otp = ConvertOTPSettings(settings); otp.OTPSeed = seed; otp.Issuer = title; otp.Label = user; ProtectedString result = otp.OTPAuthString; pe.CreateBackup(db); pe.Strings.Remove(SEED); pe.Strings.Remove(SETTINGS); pe.Strings.Set(Config.OTPFIELD, result); if (h == null) { pe.Touch(true); } migrated++; } if (migrated > 0) { db.Modified = true; if (h == null) { Program.MainForm.UpdateUI(false, null, false, null, false, null, db == Program.MainForm.ActiveDatabase); } } return(migrated); }