/* * Eventhandler is invoked e. g. in case of generating a new password * in PwEntryForm with password being visible */ private void ColoredSecureTextBoxChanged(object sender, EventArgs e) { if (UseSystemPasswordChar) { return; } if (m_text == null) { return; } //password is shown in plaintext already => no need to protect anything string pw = TextEx.ReadString(); if (pw != m_text.Text) { PluginDebug.AddInfo(Name + " ColoredSecureTextBoxChanged - Text changed"); m_text.Text = pw; } else { PluginDebug.AddInfo(Name + " ColoredSecureTextBoxChanged - Text not changed"); } }
private void OptionsFormShown(object sender, Tools.OptionsFormsEventArgs e) { PluginDebug.AddInfo("Prepare options page", 0); Options options = new Options(); options.cgbCheckTFA.Checked = Config.CheckTFA; options.hkcKPOTP.HotKey = Config.Hotkey; options.cbAutoSubmit.Checked = Config.KPOTPAutoSubmit; options.tbPlaceholder.Text = Config.Placeholder; Dictionary <PwDatabase, Options.DBSettings> dDB = new Dictionary <PwDatabase, Options.DBSettings>(); foreach (PwDatabase db in m_host.MainWindow.DocumentManager.GetOpenDatabases()) { dDB[db] = new Options.DBSettings { UseOTPDB = db.UseDBForOTPSeeds(), Preload = db.PreloadOTPDB() } } ; PluginDebug.AddInfo("Options page prepared, " + dDB.Count.ToString() + " open databases found", 0); options.InitEx(dDB, m_host.Database); PluginDebug.AddInfo(dDB.Count.ToString() + " open databases added to options page", 0); Tools.AddPluginToOptionsForm(this, options); }
public override void PerformCellAction(string strColumnName, PwEntry pe) { //Copy OTP to clipboard if (strColumnName == null) { return; } if (KeePassOTPExt.CopyOTP(pe) || OTPDAO.OTPDefined(pe) != OTPDAO.OTPDefinition.None) { return; } //Show 2FA setup instructions if available if (!Config.CheckTFA) { return; } string url = pe.Strings.ReadSafe(PwDefs.UrlField); string target = TFASites.GetTFAUrl(url); PluginDebug.AddInfo("Show 2FA instructions", 0, "URL: " + target); try { Tools.OpenUrl(target); } catch { } }
private void GlobalWindowManager_WindowAdded(object sender, GwmWindowEventArgs e) { if (!m_bOTPHotkeyPressed) { return; } if (!(e.Form is AutoTypeCtxForm)) { return; } PluginDebug.AddInfo("Auto-Type entry selection window added", 0); List <AutoTypeCtx> lCtx = (List <AutoTypeCtx>)Tools.GetField("m_lCtxs", e.Form); if (lCtx == null) { return; } //Adjust sequence to show correct auto-type sequence //Remove lines that don't have KPOTP defined int PrevCount = lCtx.Count; lCtx.RemoveAll(x => OTPDAO.OTPDefined(x.Entry) == OTPDAO.OTPDefinition.None); PluginDebug.AddInfo("Removed sequences without valid OTP settings", 0, "Before: " + PrevCount.ToString(), "After: " + lCtx.Count.ToString()); //If now 0 or 1 entries remain, we need to hook the Shown event //simply to close it //We do not want to display an entry selection form with less then 2 entries if (lCtx.Count < 2) { e.Form.Shown += OnAutoTypeFormShown; } }
private void OnSelectAllDB_CheckedChanged(object sender, EventArgs e) { if ((m_cbSearchAllDatabases == null) || !m_cbSearchAllDatabases.Enabled) { return; } FindInfo fi = SearchHelp.FindList.Find(x => x.Name == SearchHelp.SearchForm); Config.SearchFormGlobalSession = m_cbSearchAllDatabases.Checked; if (m_cbSearchAllDatabases.Checked) { fi.StandardEventHandlers = m_btnOK.GetEventHandlers("Click"); List <string> lInfos = new List <string>(); foreach (Delegate d in fi.StandardEventHandlers) { lInfos.Add(d.Method.DeclaringType.FullName + " " + d.Method.Name); } lInfos.Insert(0, "Count: " + lInfos.Count.ToString()); lInfos.Insert(0, fi.ToString()); PluginDebug.AddInfo("Replaced eventhandler", 0, lInfos.ToArray()); m_btnOK.RemoveEventHandlers("Click", fi.StandardEventHandlers); m_btnOK.Click += OnSearchExecute; if (fi.StandardEventHandlers.Count == 0) { m_btnOK.DialogResult = DialogResult.None; m_sf.AcceptButton = null; } } else { m_btnOK.Click -= OnSearchExecute; m_btnOK.AddEventHandlers("Click", fi.StandardEventHandlers); PluginDebug.AddInfo("Restored eventhandler", 0); m_btnOK.DialogResult = DialogResult.OK; m_sf.AcceptButton = m_btnOK; } }
private void OptionsClosed(object sender, Tools.OptionsFormsEventArgs e) { ColorConfig.Testmode = false; if (e.form.DialogResult != DialogResult.OK) { return; } bool shown; Options o = (Options)Tools.GetPluginFromOptions(this, out shown); PluginDebug.AddInfo("Plugin options window closed, plugin options shown: " + shown.ToString(), 0); if (!shown) { return; } ColorPasswords(false); ColorConfig.Active = o.cgActive.Checked; ColorConfig.ForeColorDefault = o.bForeColorDefault.BackColor; ColorConfig.BackColorDefault = o.bBackColorDefault.BackColor; ColorConfig.ForeColorDigit = o.bForeColorDigit.BackColor; ColorConfig.BackColorDigit = o.bBackColorDigit.BackColor; ColorConfig.ForeColorSpecial = o.bForeColorSpecial.BackColor; ColorConfig.BackColorSpecial = o.bBackColorSpecial.BackColor; ColorConfig.LowercaseDifferent = o.cbLowercase.Checked; ColorConfig.ForeColorLower = o.bForeColorLower.BackColor; ColorConfig.BackColorLower = o.bBackColorLower.BackColor; ColorConfig.ColorEntryView = o.cbColorEntryView.Checked; ColorConfig.ListViewKeepBackgroundColor = o.cbColorEntryViewKeepBackgroundColor.Checked; SinglePwDisplay.Enabled = ColorConfig.SinglePwDisplayActive = o.cbSinglePwDisplay.Checked; ColorConfig.ColorPwGen = o.cbColorPwGen.Checked; ColorConfig.Write(); if (ColorConfig.Active) { ColorPasswords(ColorConfig.Active); } }
//Color passwords in password generator private void OnPwGeneratorFormShown(object sender, EventArgs e) { (sender as Form).Shown -= OnPwGeneratorFormShown; if (!ColorConfig.Active) { return; } if (!ColorConfig.ColorPwGen) { return; } KeePass.Forms.PwGeneratorForm pg = sender as KeePass.Forms.PwGeneratorForm; TextBox tb = Tools.GetControl("m_tbPreview", pg) as TextBox; if (tb == null) { PluginDebug.AddError("Could not locate m_tbPreview", 0); return; } ColorTextBox rtb = new ColorTextBox(); rtb.Name = "ColoredPassword_" + tb.Name; rtb.Left = tb.Left; rtb.Top = tb.Top; rtb.Width = tb.Width; rtb.Height = tb.Height; rtb.ColorBackground = false; rtb.Multiline = tb.Multiline; rtb.ReadOnly = tb.ReadOnly; rtb.WordWrap = tb.WordWrap; rtb.Font = tb.Font; rtb.ScrollBars = (RichTextBoxScrollBars)tb.ScrollBars; tb.Tag = rtb; tb.Visible = false; tb.Parent.Controls.Add(rtb); tb.TextChanged += Tb_TextChanged; }
private void AddSearchfield(AutoTypeCtxForm f) { var lvShownEntries = Tools.GetControl("m_lvItems", f) as ListView; if (lvShownEntries == null) { PluginDebug.AddError("Could not locate m_lvItems, search-as-you-type field not added"); return; } var c = lvShownEntries.Parent; Label lSearch = new Label(); TextBox tbSearch = new TextBox(); c.Controls.Add(lSearch); c.Controls.Add(tbSearch); lSearch.Text = KeePass.Resources.KPRes.FindEntries; lSearch.AutoSize = true; tbSearch.Left = lvShownEntries.Left + lSearch.Width + DpiUtil.ScaleIntX(10); lSearch.Left = lvShownEntries.Left; tbSearch.Top = lvShownEntries.Top; lSearch.Top = lvShownEntries.Top + tbSearch.Height / 2 - lSearch.Height / 2; tbSearch.Width = lvShownEntries.Width / 2; List <ListViewItem> lvAllEntries = new List <ListViewItem>(lvShownEntries.Items.Cast <ListViewItem>()); tbSearch.Tag = new _SearchAsYouTypeData() { AllEntries = lvAllEntries, ShownEntries = lvShownEntries }; tbSearch.TextChanged += OnFilterSearchResults; int iGap = DpiUtil.ScaleIntY(10); int iHeight = lvShownEntries.Height; tbSearch.Dock = lvShownEntries.Dock = DockStyle.None; lvShownEntries.Top += tbSearch.Height + iGap - 1; lvShownEntries.Height = iHeight - tbSearch.Height - iGap; lvShownEntries.Width = lvShownEntries.Parent.ClientSize.Width - lvShownEntries.Parent.Padding.Left - lvShownEntries.Parent.Padding.Right; }
/* Ensure the internal RichTextBox m_text has the same parent * as the SecureTextBoxEx * Adjust TabIndex as well */ protected override void OnParentChanged(EventArgs e) { PluginDebug.AddInfo(Name + " Adjust parent control"); base.OnParentChanged(e); if (m_text == null) { return; } if (m_text.Parent != null) { m_text.Parent.Controls.Remove(m_text); } if (Parent == null) { return; } Parent.SuspendLayout(); Parent.Controls.Add(m_text); m_text.Parent = Parent; m_text.TabStop = true; m_text.TabIndex = TabIndex; Parent.ResumeLayout(); Parent.PerformLayout(); }
internal static int MoveFilesToTemp(params string[] files) { // 0 = success // -1 = aborted by user // other value = error string from = string.Empty; foreach (string file in files) { from += file + "\0"; } from += "\0"; string sTemp = PluginUpdateHandler.GetTempFolder() + "\0\0"; SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT(); lpFileOp.hwnd = IntPtr.Zero; lpFileOp.wFunc = FILE_OP_TYPE.FO_MOVE; lpFileOp.pFrom = from; lpFileOp.pTo = sTemp; lpFileOp.fFlags = FILE_OP_FLAGS.FOF_NOCONFIRMMKDIR | FILE_OP_FLAGS.FOF_NOCONFIRMATION | FILE_OP_FLAGS.FOF_ALLOWUNDO; lpFileOp.fAnyOperationsAborted = false; lpFileOp.hNameMappings = IntPtr.Zero; lpFileOp.lpszProgressTitle = string.Empty; int result = SHFileOperation(ref lpFileOp); if (result == 0 && lpFileOp.fAnyOperationsAborted) { result = -1; } PluginDebug.AddInfo("Move in UAC mode: " + result.ToString()); return(result); }
private void OTPDB_Synchronize(PwDatabase targetdb, FileFormatProvider fmtImp, byte[] bDecrypted, string text) { IStatusLogger dlgStatus = new OnDemandStatusDialog(true, Program.MainForm); dlgStatus.StartLogging(text, false); try { dlgStatus.SetText(text, LogStatusType.Info); PwDatabase pwImp; pwImp = new PwDatabase(); pwImp.New(new IOConnectionInfo(), targetdb.MasterKey); pwImp.MemoryProtection = targetdb.MemoryProtection.CloneDeep(); pwImp.MasterKey = targetdb.MasterKey; dlgStatus.SetText(text, LogStatusType.Info); using (var s = new MemoryStream(bDecrypted)) { fmtImp.Import(pwImp, s, null); } targetdb.KdfParameters = pwImp.KdfParameters; targetdb.DataCipherUuid = pwImp.DataCipherUuid; targetdb.HistoryMaxItems = pwImp.HistoryMaxItems; targetdb.HistoryMaxSize = pwImp.HistoryMaxSize; PwMergeMethod mm = PwMergeMethod.Synchronize; targetdb.MergeIn(pwImp, mm, dlgStatus); } catch (Exception ex) { PluginDebug.AddError("Error loading OTP db", 0, ex.Message); throw ex; } finally { dlgStatus.EndLogging(); } }
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 void CheckShieldify() { List <string> lShieldify = new List <string>(); try { m_bShieldify = false; if (KeePassLib.Native.NativeLib.IsUnix()) { lShieldify.Add("Detected Unix"); return; } if (!WinUtil.IsAtLeastWindows7) { lShieldify.Add("Detected Windows < 7"); return; } string sPF86 = EnsureNonNull(Environment.GetEnvironmentVariable("ProgramFiles(x86)")); string sPF86_2 = string.Empty; try { sPF86_2 = EnsureNonNull(Environment.GetFolderPath((Environment.SpecialFolder) 42)); } //Environment.SpecialFolder.ProgramFilesX86 catch { sPF86_2 = sPF86; } string sPF = EnsureNonNull(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)); string sKP = EnsureNonNull(UrlUtil.GetFileDirectory(WinUtil.GetExecutable(), true, false)); m_bShieldify = sKP.StartsWith(sPF86) || sKP.StartsWith(sPF) || sKP.StartsWith(sPF86_2); lShieldify.Add("KeePass folder inside ProgramFiles(x86): " + sKP.StartsWith(sPF86)); lShieldify.Add("KeePass folder inside Environment.SpecialFolder.ProgramFilesX86: " + sKP.StartsWith(sPF86_2)); lShieldify.Add("KeePass folder inside Environment.SpecialFolder.ProgramFiles: " + sKP.StartsWith(sPF)); return; } catch (Exception ex) { lShieldify.Add("Exception: " + ex.Message); return; } finally { lShieldify.Insert(0, "Shieldify: " + m_bShieldify.ToString()); PluginDebug.AddInfo("Check Shieldify", 0, lShieldify.ToArray()); } }
/// <summary> /// Release (and potentially restore) the mutex used for limiting KeePass to a single instance /// In some cases the restart with WinUtil.Restart is done while the global mutex is not yet released /// </summary> /// <param name="release"></param> private void HandleMutex(bool release) { List <string> lStrings = new List <string>(); lStrings.Add("Mutex: " + KeePass.App.AppDefs.MutexName); lStrings.Add("Release: " + release.ToString()); lStrings.Add("Single Instance: " + KeePass.Program.Config.Integration.LimitToSingleInstance.ToString()); //Get number of loaded databases //KeePass creates an initial PwDocument during startup which must NOT be considered here // //Initial = No LockedIoc and PwDatabase is not opened (!IsOpen) int iOpenedDB = 0; foreach (PwDocument pd in KeePass.Program.MainForm.DocumentManager.Documents) { if (!string.IsNullOrEmpty(pd.LockedIoc.Path)) { iOpenedDB++; } else if ((pd.Database != null) && pd.Database.IsOpen) { iOpenedDB++; } } lStrings.Add("Opened databases: " + iOpenedDB.ToString()); if (!KeePass.Program.Config.Integration.LimitToSingleInstance) { lStrings.Add("Action required: No"); PluginDebug.AddInfo("Handle global mutex", 0, lStrings.ToArray()); return; } if (release) { bool bSuccess = GlobalMutexPool.ReleaseMutex(KeePass.App.AppDefs.MutexName); lStrings.Add("Action required: Yes"); lStrings.Add("Success: " + bSuccess.ToString()); PluginDebug.AddInfo("Handle global mutex", 0, lStrings.ToArray()); return; } else if (iOpenedDB > 0) { //Only recreate mutex if at least document is loaded (lock flag is not relevant here) //If no db is open, Restart is in progress already lStrings.Add("Action required: Yes"); lStrings.Add("Success: See next entry"); PluginDebug.AddInfo("Handle global mutex", 0, lStrings.ToArray()); Thread t = new Thread(new ThreadStart(() => { Thread.Sleep(PluginConfig.RestoreMutexThreshold); bool bSuccess = GlobalMutexPool.CreateMutex(KeePass.App.AppDefs.MutexName, true); PluginDebug.AddInfo("Handle global mutex", 0, "Recreate mutex sucessful: " + bSuccess.ToString()); })); t.IsBackground = true; t.Start(); return; } lStrings.Add("Action required: No"); PluginDebug.AddInfo("Handle global mutex", 0, lStrings.ToArray()); }
private void OnTrayOpening(object sender, EventArgs e) { PluginDebug.AddInfo("Tray setup: Start", 0); m_TrayMenu.DropDownItems.Clear(); List <PwDatabase> lDB = m_host.MainWindow.DocumentManager.GetOpenDatabases(); SearchParameters sp = new SearchParameters(); sp.ExcludeExpired = !Program.Config.Integration.AutoTypeExpiredCanMatch; //exclude expired entries only if they can not match sp.SearchInStringNames = true; Dictionary <string, PwObjectList <PwEntry> > dEntries = new Dictionary <string, PwObjectList <PwEntry> >(); foreach (PwDatabase db in lDB) { string dbName = UrlUtil.GetFileName(db.IOConnectionInfo.Path); if (!string.IsNullOrEmpty(db.Name)) { dbName = db.Name + " (" + dbName + ")"; } PwObjectList <PwEntry> entries = new PwObjectList <PwEntry>(); if (Config.UseDBForOTPSeeds(db)) { sp.SearchString = OTPDAO.OTPHandler_DB.DBNAME; } else { sp.SearchString = Config.OTPFIELD; // Config.SEED + " " + Config.SETTINGS; } db.RootGroup.SearchEntries(sp, entries); PluginDebug.AddInfo("Tray setup: Check database", 0, "DB: " + dbName, "Entries: " + entries.UCount.ToString()); if ((entries == null) || (entries.UCount == 0)) { continue; } //Ignore deleted entries PwGroup pgRecycle = db.RecycleBinEnabled ? db.RootGroup.FindGroup(db.RecycleBinUuid, true) : null; if (pgRecycle != null) { for (int i = (int)entries.UCount - 1; i >= 0; i--) { PwEntry pe = entries.GetAt((uint)i); if (pe.IsContainedIn(pgRecycle)) { entries.Remove(pe); } } } entries.Sort(SortEntries); dEntries.Add(dbName, entries); } foreach (var kvp in dEntries) { ToolStripMenuItem parent = null; //If entries of only one DB are found don't include the DB as additional menu level if (dEntries.Count == 1) { parent = m_TrayMenu; } else { parent = new ToolStripMenuItem(kvp.Key); m_TrayMenu.DropDownItems.Add(parent); } foreach (PwEntry pe in kvp.Value) { ToolStripMenuItem entry = new ToolStripMenuItem(); string[] text = GetTrayText(pe); PluginDebug.AddInfo("Tray setup: Add entry", 0, "Uuid: " + text[2]); // Do NOT add username and entry title to debugfile if (text[0] == string.Empty) { entry.Text = StrUtil.EncodeMenuText(string.Format(PluginTranslate.User, text[1])); } else if (text[1] == string.Empty) { entry.Text = StrUtil.EncodeMenuText(text[0]); } else { entry.Text = StrUtil.EncodeMenuText(text[0] + " (" + text[1] + ")"); } entry.Name = "KPOTP_" + pe.Uuid.ToString(); entry.Click += OnOTPTray; entry.Tag = pe; parent.DropDownItems.Add(entry); } } m_TrayMenu.Enabled = dEntries.Count > 0; m_TrayMenu.Text = m_TrayMenu.Enabled ? PluginTranslate.OTPCopyTrayEntries : PluginTranslate.OTPCopyTrayNoEntries; }
public void ColorText() { int nCursorPos = SelectionStart; //save cursor position SelectAll(); List <CharRange> lCR = GetRanges(this.Text); List <string> lMsg = new List <string>(); bool bError = false; foreach (var cr in lCR) { lMsg.Add(cr.ToString()); Select(cr.Range.First, cr.Range.Length); switch (cr.CharType) { case CharType.Digit: SelectionColor = ColorConfig.ForeColorDigit; if (ColorBackground) { SelectionBackColor = ColorConfig.BackColorDigit; } break; case CharType.Letter: SelectionColor = ColorConfig.ForeColorDefault; if (ColorBackground) { SelectionBackColor = ColorConfig.BackColorDefault; } break; case CharType.Lowercase: SelectionColor = ColorConfig.ForeColorLower; if (ColorBackground) { SelectionBackColor = ColorConfig.BackColorLower; } break; case CharType.Special: SelectionColor = ColorConfig.ForeColorSpecial; if (ColorBackground) { SelectionBackColor = ColorConfig.BackColorSpecial; } break; default: lMsg[lMsg.Count - 1] += " unknown character type"; bError = true; continue; } } if (bError) { PluginDebug.AddError(Name + " Color password", 0, lMsg.ToArray()); } else { PluginDebug.AddInfo(Name + " Color password", 0, lMsg.ToArray()); } Select(nCursorPos, 0); //restore cursor position }
private void ProfilesOpening(object sender, System.ComponentModel.CancelEventArgs e) { string lastProfile = string.Empty; string pcaFormProfile = m_pcaForm == null ? string.Empty : m_pcaForm.Profile; if (m_pweForm != null) { lastProfile = m_pweForm.EntryStrings.ReadSafeEx(Config.ProfileLastUsedProfile); PluginDebug.AddInfo("Profiles opened in entry form", 0, "Last used profile:" + lastProfile); } else { PwEntry entry = m_host.MainWindow.GetSelectedEntry(true); if (entry != null) { lastProfile = entry.Strings.ReadSafeEx(Config.ProfileLastUsedProfile); } PluginDebug.AddInfo("Profiles opened in Entry form", 0, "Selected profile: " + m_pcaForm.Profile, "Last used profile:" + lastProfile); if (entry == null) { return; } } if (string.IsNullOrEmpty(lastProfile) && string.IsNullOrEmpty(pcaFormProfile)) { return; } List <string> lMsg = new List <string>(); lMsg.Add("Checking special profiles (selected / last used)"); foreach (ToolStripItem profile in (sender as ContextMenuStrip).Items) { if (!(profile is ToolStripMenuItem)) { continue; } string profText = profile.Text.Replace("&", ""); string msg = "Checking profile '" + profText + "'"; if (profText == pcaFormProfile) { msg += "; Selected: true"; profile.Font = new System.Drawing.Font(profile.Font, profile.Font.Style | System.Drawing.FontStyle.Bold); } else { if (m_pcaForm != null) { msg += "; Selected: false"; } profile.Font = new System.Drawing.Font(profile.Font, profile.Font.Style & ~System.Drawing.FontStyle.Bold); } if ((profText == lastProfile) || ((profText == "(" + KPRes.AutoGeneratedPasswordSettings + ")") && (lastProfile == Config.ProfileAutoGenerated))) { profile.Image = SmallIcon; msg += "; Last used: true"; //break; } else { msg += "; Last used: false"; } lMsg.Add(msg); } PluginDebug.AddInfo("Password profile context menu", 0, lMsg.ToArray()); }
private void OnPwGeneratorFormShown(object sender, EventArgs e) { List <string> lMsg = new List <string>(); Control cGroup = Tools.GetControl("m_grpCurOpt", m_pwgForm); ComboBox cbProfile = Tools.GetControl("m_cmbProfiles", m_pwgForm) as ComboBox; if (cbProfile == null) { lMsg.Add("Could not locate m_cmbProfiles"); } else { cbProfile.SelectedIndexChanged += PwProfile1PerSet.EnablePwGeneratorControls; lMsg.Add("Found and hooked " + cbProfile.Name); } if (cGroup == null) { lMsg.Add("Could not locate m_grpCurOpt"); } else { foreach (Control c in cGroup.Controls) { if (c is RadioButton) { (c as RadioButton).CheckedChanged += PwProfile1PerSet.EnablePwGeneratorControls; } else if (c is CheckBox) { (c as CheckBox).CheckedChanged += PwProfile1PerSet.EnablePwGeneratorControls; } else if (c is ComboBox) { (c as ComboBox).SelectedIndexChanged += PwProfile1PerSet.EnablePwGeneratorControls; } else if (c is TextBox) { (c as TextBox).TextChanged += PwProfile1PerSet.EnablePwGeneratorControls; } else if (c is NumericUpDown) { (c as NumericUpDown).ValueChanged += PwProfile1PerSet.EnablePwGeneratorControls; } else { continue; } lMsg.Add("Found and hooked " + c.Name); } } PluginDebug.AddInfo("Prepare PwGenerator", 0, lMsg.ToArray()); if ((cbProfile != null) && (m_pweForm != null) && !m_pweForm.Disposing && !m_pweForm.IsDisposed) { string sProfile = m_pweForm.EntryRef.Strings.ReadSafeEx(Config.ProfileLastUsedProfile); if (!string.IsNullOrEmpty(sProfile) && cbProfile.Items.Contains(sProfile)) { cbProfile.SelectedIndex = cbProfile.Items.IndexOf(sProfile); } } PwProfile1PerSet.EnablePwGeneratorControls(sender, e); }
private static TimeSpan GetTimeCorrection(string value) { Uri fullUrl = null; TimeSpan timeCorrection = TimeSpan.Zero; bool bKeyFound = m_timeCorrectionUrls.ContainsKey(value); //Quick check for 'valid' URL if (value.IndexOf(":") <= 0) { if (!string.IsNullOrEmpty(value) && !bKeyFound) { PluginDebug.AddError("OTP time correction", 0, "Invalid URL: " + value, "Time correction: " + TimeSpan.Zero.ToString()); } lock (m_timeCorrectionUrls) { m_timeCorrectionUrls[value] = TimeSpan.Zero; } return(m_timeCorrectionUrls[value]); } //check for given string if (bKeyFound) { m_timeCorrectionUrls.TryGetValue(value, out timeCorrection); return(timeCorrection); } //Calculate time offset try { fullUrl = new Uri(value); } catch (Exception ex) { lock (m_timeCorrectionUrls) { m_timeCorrectionUrls[value] = TimeSpan.Zero; } PluginDebug.AddError("OTP time correction", 0, "URL: " + value, "Error: " + ex.Message, "Time correction: " + m_timeCorrectionUrls[value].ToString()); return(m_timeCorrectionUrls[value]); } string url = fullUrl.Scheme + "://" + fullUrl.Host; if (m_timeCorrectionUrls.ContainsKey(url)) { m_timeCorrectionUrls.TryGetValue(url, out timeCorrection); if (!m_timeCorrectionUrls.ContainsKey(value)) { lock (m_timeCorrectionUrls) { m_timeCorrectionUrls[value] = timeCorrection; } } PluginDebug.AddInfo("OTP time correction", 0, "URL: " + value, "Mapped URL: " + url, "Time correction: " + m_timeCorrectionUrls[value].ToString()); return(timeCorrection); } bool bException = false; try { System.Net.WebClient WebClient = new System.Net.WebClient(); if (miConfigureWebClient != null) // Try to set KeePass' proxy settings { try { miConfigureWebClient.Invoke(null, new object[] { WebClient }); } catch { } } WebClient.DownloadData(url); var DateHeader = WebClient.ResponseHeaders.Get("Date"); timeCorrection = DateTime.UtcNow - DateTime.Parse(DateHeader, System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat).ToUniversalTime(); } catch (Exception ex) { timeCorrection = TimeSpan.Zero; bException = true; PluginDebug.AddError("OTP time correction", 0, "URL: " + url, "Error: " + ex.Message, "Time correction: " + timeCorrection.ToString()); } lock (m_timeCorrectionUrls) { if (!m_timeCorrectionUrls.ContainsKey(value) && !bException) { PluginDebug.AddInfo("OTP time correction", 0, "URL: " + url, "Time correction: " + timeCorrection.ToString()); } m_timeCorrectionUrls[value] = timeCorrection; m_timeCorrectionUrls[url] = timeCorrection; } return(timeCorrection); }
private void OnFormShown(object sender, EventArgs e) { PwEditMode m = PwEditMode.Invalid; PropertyInfo pEditMode = typeof(PwEntryForm).GetProperty("EditModeEx"); if (pEditMode != null) //will work starting with KeePass 2.41, preferred way as it's a public attribute { m = (PwEditMode)pEditMode.GetValue(m_pweForm, null); } else // try reading private field { m = (PwEditMode)Tools.GetField("m_pwEditMode", m_pweForm); } PluginDebug.AddSuccess("Entryform shown, editmode: " + m.ToString(), 0); if ((m != PwEditMode.AddNewEntry) && (m != PwEditMode.EditExistingEntry)) { return; } CustomContextMenuStripEx ctx = (CustomContextMenuStripEx)Tools.GetField("m_ctxDefaultTimes", m_pweForm); if (ctx != null) { ctx.Items.Add(new ToolStripSeparator()); ToolStripMenuItem tsmiPED = CreatePEDMenu(false, true); ctx.Items.Add(tsmiPED); PluginDebug.AddSuccess("Found m_ctxDefaultTimes", 0); } else { PluginDebug.AddError("Could not find m_ctxDefaultTimes", 0); } PEDCalcValue ped = m_pweForm.EntryRef.GetPEDValue(true); CheckBox cbExpires = (CheckBox)Tools.GetControl("m_cbExpires", m_pweForm); DateTimePicker dtExpireDate = (DateTimePicker)Tools.GetControl("m_dtExpireDateTime", m_pweForm); DateTime expiry = ped.NewExpiryDateUtc.ToLocalTime(); if (m == PwEditMode.EditExistingEntry) { cbExpires.CheckedChanged += (o, e1) => CheckShowNewExpireDate(); dtExpireDate.ValueChanged += (o, e1) => CheckShowNewExpireDate(); SecureTextBoxEx password = (SecureTextBoxEx)Tools.GetControl("m_tbPassword", m_pweForm); password.TextChanged += (o, e1) => CheckShowNewExpireDate(); Label lNewExpireDate = new Label(); lNewExpireDate.Name = "PEDCalc_NewExpireDate"; string sDate = string.Empty; m_iSelectedEntries = (int)m_host.MainWindow.GetSelectedEntriesCount(); if ((Tools.KeePassVersion >= Configuration.KeePassMultipleEntries) && (m_iSelectedEntries > 1)) { PropertyInfo piMultiple = typeof(KeePass.Resources.KPRes).GetProperty("MultipleValues"); if (piMultiple != null) { sDate = piMultiple.GetValue(null, null) as string; } else { sDate = "?"; } } else if (dtExpireDate.Format == DateTimePickerFormat.Long) { sDate = expiry.ToLongDateString(); } else if (dtExpireDate.Format == DateTimePickerFormat.Short) { sDate = expiry.ToShortDateString(); } else if (dtExpireDate.Format == DateTimePickerFormat.Time) { sDate = expiry.ToLongTimeString(); } else { sDate = expiry.ToString(dtExpireDate.CustomFormat); } lNewExpireDate.Text = PluginTranslate.PluginName + ": " + sDate; lNewExpireDate.Left = dtExpireDate.Left; lNewExpireDate.Top = dtExpireDate.Top + dtExpireDate.Height + 2; lNewExpireDate.Width = dtExpireDate.Width; ToolTip tt = new ToolTip(); tt.ToolTipTitle = PluginTranslate.PluginName; tt.ToolTipIcon = ToolTipIcon.Info; tt.SetToolTip(lNewExpireDate, PluginTranslate.NewExpiryDateTooltip); dtExpireDate.Parent.Controls.Add(lNewExpireDate); int h = dtExpireDate.Parent.ClientSize.Height; if (h < lNewExpireDate.Top + lNewExpireDate.Height + 2) { h = lNewExpireDate.Top + lNewExpireDate.Height + 2 - h; } else { h = 0; } try { dtExpireDate.Parent.Parent.Height += h; } catch { } CheckShowNewExpireDate(); } if (m == PwEditMode.AddNewEntry) { if (ped.Off) { return; } if ((cbExpires == null) || (dtExpireDate == null)) { Tools.ShowError(string.Format(PluginTranslate.ErrorInitExpiryDate, expiry.ToString())); return; } m_pweForm.EntryRef.ExpiryTime = dtExpireDate.Value = expiry; m_pweForm.EntryRef.Expires = cbExpires.Checked = true; PwEntry peInitialEntry = (PwEntry)Tools.GetField("m_pwInitialEntry", m_pweForm); if (peInitialEntry != null) { peInitialEntry.Expires = true; peInitialEntry.ExpiryTime = expiry.ToUniversalTime(); } } }
private static void ReadOTPSites(object s) { lock (m_TFAReadLock) { if (m_LoadState == TFALoadProcess.Loading) { return; } if (m_LoadState == TFALoadProcess.Loaded) { return; } if (m_LoadState == TFALoadProcess.FileNotFound) { return; } m_LoadState = TFALoadProcess.Loading; } m_dTFA.Clear(); JsonObject j = null; bool bException = false; IOConnectionInfo ioc = IOConnectionInfo.FromPath(TFA_JSON_FILE); try { byte[] b = IOConnection.ReadFile(ioc); if (b != null) { j = new JsonObject(new CharStream(StrUtil.Utf8.GetString(b))); } } catch (Exception ex) { PluginDebug.AddError("Error reading OTP sites", 0, "Error: " + ex.Message); bException = true; } if (j == null) { if (!IOConnection.FileExists(ioc)) { lock (m_TFAReadLock) { m_LoadState = TFALoadProcess.FileNotFound; } Tools.ShowError("Error reading OTP sites: File does not exist\n\n" + TFA_JSON_FILE); } else { lock (m_TFAReadLock) { m_LoadState = TFALoadProcess.Error; } } if (!bException) { PluginDebug.AddError("Error reading OTP sites", 0); } return; } DateTime dtStart = DateTime.Now; foreach (KeyValuePair <string, object> kvp in j.Items) { List <string> keys = (kvp.Value as JsonObject).Items.Keys.ToList(); for (int i = 0; i < keys.Count; i++) { JsonObject k = (kvp.Value as JsonObject).GetValue <JsonObject>(keys[i]); TFAData tfa = new TFAData(); var tfaDetails = k.GetValueArray <string>("tfa"); tfa.tfa = tfaDetails != null && tfaDetails.Length > 0; if (!tfa.tfa) { continue; } tfa.name = k.GetValue <string>("name"); tfa.sms = tfaDetails.Contains("sms") || k.GetValue <bool>("sms", false); tfa.email = tfaDetails.Contains("email") || k.GetValue <bool>("email", false); tfa.phone = tfaDetails.Contains("phone") || k.GetValue <bool>("phone", false); tfa.software = tfaDetails.Contains("software") || k.GetValue <bool>("software", false); tfa.hardware = tfaDetails.Contains("hardwar") || k.GetValue <bool>("hardware", false); tfa.url = k.GetValue <string>("url"); tfa.img = k.GetValue <string>("img"); tfa.doc = k.GetValue <string>("doc"); tfa.category = kvp.Key; m_dTFA[CreatePattern(tfa.url)] = tfa; } } DateTime dtEnd = DateTime.Now; lock (m_TFAReadLock) { m_LoadState = TFALoadProcess.Loaded; PluginDebug.AddInfo("OTP sites read", 0, "Required time: " + (dtEnd - dtStart).ToString(), "Number of sites: " + m_dTFA.Count.ToString()); } }
private void Restart() { PluginDebug.AddInfo("Restart started", DebugPrint); if (m_kpf != null) { PluginDebug.AddInfo("Closing KeyPromptForm", 0, DebugPrint); m_kpf.DialogResult = DialogResult.Cancel; if (m_kpf != null) { m_kpf.Close(); } if (m_kpf != null) { m_kpf.Dispose(); } Application.DoEvents(); if (m_kpf != null) { GlobalWindowManager.RemoveWindow(m_kpf); } } if (m_slUpdateCheck != null) { PluginDebug.AddInfo("Closing update check progress form", 0, DebugPrint); m_slUpdateCheck.EndLogging(); } if (MonoWorkarounds.IsRequired(620618)) { MethodInfo miSetEnabled = typeof(MonoWorkarounds).GetMethod("SetEnabled", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (miSetEnabled == null) { PluginDebug.AddError("Could not locate MonoWorkarounds.SetEnabled", 0); } else { miSetEnabled.Invoke(null, new object[] { "620618", false }); } if (MonoWorkarounds.IsRequired(620618)) { PluginDebug.AddError("Could not disable MonoWorkaround 620618"); } else { PluginDebug.AddSuccess("Disabled MonoWorkaround 620618"); } } else { PluginDebug.AddSuccess("Disabling MonoWorkaround 620618 not required"); } FieldInfo fi = m_host.MainWindow.GetType().GetField("m_bRestart", BindingFlags.NonPublic | BindingFlags.Instance); if (fi != null) { PluginDebug.AddInfo("Restart started, m_bRestart found", DebugPrint); RemoveAndBackupFormLoadPostHandlers(); HandleMutex(true); fi.SetValue(m_host.MainWindow, true); m_host.MainWindow.ProcessAppMessage((IntPtr)KeePass.Program.AppMessage.Exit, IntPtr.Zero); HandleMutex(false); } else { PluginDebug.AddError("Restart started, m_bRestart not found" + DebugPrint); } }
private bool OTPDB_Reload() { try { byte[] bOTPDB = GetOTPDBData(); if (bOTPDB == null) { return(false); } //Create DB if required if (!OTPDB_Exists) { SetDB(DB, true); } else if (!OTPDB_Opened) { if (Config.ShowHintSyncRequiresUnlock) { Tools.ShowInfo(PluginTranslate.HintSyncRequiresUnlock); } while (!EnsureOTPSetupPossible(null)) { if (Tools.AskYesNo(PluginTranslate.HintSyncRequiresUnlock) == DialogResult.No) { PwEntry peOTPDBBackup = new PwEntry(true, true); string sTitle = DBNAME + " Backup " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); peOTPDBBackup.Strings.Set(PwDefs.TitleField, new ProtectedString(false, sTitle)); if (!string.IsNullOrEmpty(m_sInitialOTPDB)) { peOTPDBBackup.Binaries.Set(DBNAME + ".kdbx", new ProtectedBinary(true, ConvertFromCustomData(m_sInitialOTPDB))); } DB.RootGroup.AddEntry(peOTPDBBackup, true); peOTPDBBackup.Expires = false; FlagChanged(false); Tools.ShowInfo(string.Format(PluginTranslate.OTPBackupDone, sTitle)); break; } } //DB was not opened yet //Try loading initially remembered database //This is required to not lose local changes during a sync //Current content of CustomData might already be replaced if (!string.IsNullOrEmpty(m_sInitialOTPDB)) { byte[] bInitial = ConvertFromCustomData(m_sInitialOTPDB); m_sInitialOTPDB = string.Empty; OTPDB_Synchronize(OTPDB, m_FFP, bInitial, PluginTranslate.OTPDB_Opening); } } OTPDB_Synchronize(OTPDB, m_FFP, bOTPDB, PluginTranslate.OTPDB_Sync); InitEntries(DB); UpdateDBHeader(); PluginDebug.AddInfo("OTP db reloaded"); OTPDB_Opened = (OTPDB != null) && OTPDB.IsOpen; if (OTPDB_Opened && CheckAndMigrate(DB)) { FlagChanged(false); } return(true); } catch (Exception ex) { PluginDebug.AddError("Reloading OTP db failed", 0, ex.Message); return(false); } }
private void OnUIStateUpdated(object sender, EventArgs e) { if (!Config.AlreadyExpiredActive && !Config.SoonExpiredActive) { return; } if ((m_host == null) || (m_host.Database == null) || !m_host.Database.IsOpen) { PluginDebug.AddInfo("No active database or database is not opened, nothing to do", 0); return; } ListView lv = (ListView)Tools.GetControl("m_lvEntries"); if (lv == null) { PluginDebug.AddError("Could not find m_lvEntries", 0); return; } DateTime dtSoon = DateTime.Now.AddDays(Program.Config.Application.ExpirySoonDays); bool canHideExpired = true; int hidden = 0; PwGroup recycle = null; if (Config.HideExpired && Config.AlreadyExpiredActive) { canHideExpired = HidingAllowed(sender); recycle = m_host.Database.RecycleBinEnabled ? m_host.Database.RootGroup.FindGroup(m_host.Database.RecycleBinUuid, true) : null; } else { PluginDebug.AddInfo("Hiding of expired entries", 0, "Active: " + false.ToString()); } if (!canHideExpired && !Config.AlreadyExpiredActive && !Config.SoonExpiredActive) { return; } try { lv.BeginUpdate(); //don't use foreach and change the number of items... (thanks to darkdragon) //foreach (ListViewItem lvi in lv.Items) for (int i = lv.Items.Count - 1; i >= 0; i--) { ListViewItem lvi = null; PwListItem li = null; try { //This can throw if multiple concurrent changes are in progress //Can happen when e. g. doing Edit Entries (quick) - Expire npw lvi = lv.Items[i]; li = (lvi.Tag as PwListItem); } catch { } if (li == null) { continue; } if (li.Entry == null) { PluginDebug.AddError("List entry does not contain valid PwEntry", 0, lvi.Text); continue; //should never happen but on the other side... you never know } ExpiryStatus expiry = EntryExpiry(li.Entry, dtSoon); if ((expiry == ExpiryStatus.Expired) && Config.AlreadyExpiredActive) { if (Config.HideExpired && canHideExpired) { if (!li.Entry.IsContainedIn(recycle)) { try { //This can throw if multiple concurrent changes are in progress //Can happen when e. g. doing Edit Entries (quick) - Expire npw lv.Items.Remove(lvi); } catch { } hidden++; PluginDebug.AddInfo("Hidden entry: " + li.Entry.Uuid.ToHexString(), 0, "Removed from list"); } else { PluginDebug.AddInfo("Hidden entry: " + li.Entry.Uuid.ToHexString(), 0, "Not removed from list, contained in recycle bin"); } } else { lvi.ImageIndex = Config.AlreadyExpiredIcon; lvi.BackColor = Config.AlreadyExpiredColor; if (!lvi.UseItemStyleForSubItems) { for (int j = 0; j < lvi.SubItems.Count; j++) { lvi.SubItems[i].BackColor = lvi.BackColor; } } } } else if (Config.SoonExpiredActive && (expiry == ExpiryStatus.ExpiringSoon)) { lvi.ImageIndex = Config.SoonExpiredIcon; lvi.BackColor = Config.SoonExpiredColor; if (!lvi.UseItemStyleForSubItems) { for (int j = 0; j < lvi.SubItems.Count; j++) { lvi.SubItems[i].BackColor = lvi.BackColor; } } } } if (hidden > 0) { UIUtil.SetAlternatingBgColors(lv, UIUtil.GetAlternateColor(lv.BackColor), Program.Config.MainWindow.EntryListAlternatingBgColors); m_host.MainWindow.SetStatusEx(string.Format(PluginTranslate.HiddenExpired, hidden)); } } catch (Exception ex) { bool bDM = PluginDebug.DebugMode; PluginDebug.DebugMode = true; PluginDebug.AddError("Exception during OnUIStateUpdate", -1, ex.Message, ex.Source, ex.StackTrace); PluginDebug.DebugMode = bDM; } finally { if (lv != null) { lv.EndUpdate(); } } }
private bool HidingAllowed(object sender) { System.Diagnostics.StackTrace callStack = new System.Diagnostics.StackTrace(); bool HidingAllowed = true; string m = string.Empty; foreach (var timer in m_OtherTimers) { if ((timer.Value != null) && (timer.Value == sender)) { HidingAllowed = false; m = timer.Key; break; } } if (HidingAllowed) { for (int i = 0; i < callStack.FrameCount; i++) { System.Reflection.MethodBase mbMethod = callStack.GetFrame(i).GetMethod(); string methodname = mbMethod.Name; HidingAllowed &= methodname != "ShowExpiredEntries"; if (!Config.ProgressiveHidingAllowedCheck) { HidingAllowed &= !methodname.StartsWith("OnPwList"); } HidingAllowed &= !methodname.StartsWith("OnFind"); HidingAllowed &= methodname != "PerformQuickFind"; //KeePass <= 2.46 HidingAllowed &= !methodname.StartsWith("PerformSearch"); //KeePass >= 2.47 HidingAllowed &= methodname != "ShowSearchResults"; //KeePass >= 2.47 if ((mbMethod.DeclaringType.FullName == "GlobalSearch.GlobalSearchExt") && methodname.StartsWith("OnClickFindEntry")) { HidingAllowed = false; methodname = mbMethod.DeclaringType.Namespace + "-" + methodname; } if ((mbMethod.Name == "RefreshEntriesList") && (mbMethod.DeclaringType.FullName == "PluginTools.Tools") && Tools.PreserveEntriesShown) { HidingAllowed = false; methodname = mbMethod.DeclaringType.Namespace + "-" + methodname; } //HidingAllowed &= methodname != "OpenDatabase"; //HidingAllowed &= methodname != "OnFileLock"; if (methodname == "UpdateUIState") { if ((mbMethod.DeclaringType.FullName == "PluginTools.Tools") && Program.Config.CustomConfig.GetBool("Rookiestyle.PreserveEntriesShown", true)) { HidingAllowed = false; methodname = mbMethod.DeclaringType.Namespace + "-" + methodname; } else if (i < callStack.FrameCount - 1) { methodname = callStack.GetFrame(i + 1).GetMethod().Name; if (methodname == "WndProc") { HidingAllowed = false; methodname = "WndProc - message: m_nTaskbarButtonMessage"; } } } if (!HidingAllowed) { m = methodname; break; } } } List <string> lMsg = new List <string>(); lMsg.Add("Active:" + Config.HideExpired.ToString()); lMsg.Add("Progressive hiding check:" + Config.ProgressiveHidingAllowedCheck.ToString()); //Progressive = Remember setting //Reset only if current callstack does not allow hiding expired entries if (Config.ProgressiveHidingAllowedCheck) { if (!HidingAllowed) { Config.ProgressiveHidingAllowed = Config.HidingStatus.NotAllowed; if (!string.IsNullOrEmpty(m)) { lMsg.Add("Found method: " + m); } else { lMsg.Add("Reuse previous check result: " + true.ToString()); } } //Set hiding status if not yet defined if (Config.ProgressiveHidingAllowed == Config.HidingStatus.Unknown) { if (HidingAllowed) { Config.ProgressiveHidingAllowed = Config.HidingStatus.Allowed; } else { Config.ProgressiveHidingAllowed = Config.HidingStatus.NotAllowed; lMsg.Add("Found method: " + m); } } lMsg.Add("Hiding possible: " + (Config.ProgressiveHidingAllowed == Config.HidingStatus.Allowed).ToString() + " - " + HidingAllowed.ToString()); PluginDebug.AddInfo("Hiding of expired entries", 0, lMsg.ToArray()); return(Config.ProgressiveHidingAllowed == Config.HidingStatus.Allowed); } if (!HidingAllowed) { lMsg.Add("Found method: " + m); } lMsg.Add("Hiding possible:" + HidingAllowed.ToString()); PluginDebug.AddInfo("Hiding of expired entries", 0, lMsg.ToArray()); return(HidingAllowed); }
private void UpdateCheckBackground() { List <string> lMsg = new List <string>(); string sBackup = KeePass.Program.Config.Application.LastUpdateCheck; KeePass.Program.Config.Application.LastUpdateCheck = TimeUtil.SerializeUtc(DateTime.UtcNow); bool bOK = true; MethodInfo miGetInstalledComponents = typeof(UpdateCheckEx).GetMethod("GetInstalledComponents", BindingFlags.Static | BindingFlags.NonPublic); if (miGetInstalledComponents == null) { bOK = false; lMsg.Add("Could not locate UpdateCheckEx.GetInstalledComponents"); } MethodInfo miGetUrls = typeof(UpdateCheckEx).GetMethod("GetUrls", BindingFlags.Static | BindingFlags.NonPublic); if (miGetUrls == null) { bOK = false; lMsg.Add("Could not locate UpdateCheckEx.GetUrls"); } MethodInfo miDownloadInfoFiles = typeof(UpdateCheckEx).GetMethod("DownloadInfoFiles", BindingFlags.Static | BindingFlags.NonPublic); if (miDownloadInfoFiles == null) { bOK = false; lMsg.Add("Could not locate UpdateCheckEx.DownloadInfoFiles"); } MethodInfo miMergeInfo = typeof(UpdateCheckEx).GetMethod("MergeInfo", BindingFlags.Static | BindingFlags.NonPublic); if (miMergeInfo == null) { bOK = false; lMsg.Add("Could not locate UpdateCheckEx.MergeInfo"); } try { m_bRestartInvoke = true; KeePassLib.Delegates.GAction actUpdateCheck = new KeePassLib.Delegates.GAction(() => { //taken from UpdateCheckExt.RunPriv //MainForm.InvokeRequired is not true on Mono :( try { lock (m_lock) { m_UpdateCheckStatus = UpdateCheckStatus.Checking; } List <UpdateComponentInfo> lInst = (List <UpdateComponentInfo>)miGetInstalledComponents.Invoke(null, null); List <string> lUrls = (List <string>)miGetUrls.Invoke(null, new object[] { lInst }); Dictionary <string, List <UpdateComponentInfo> > dictAvail = (Dictionary <string, List <UpdateComponentInfo> >)miDownloadInfoFiles.Invoke(null, new object[] { lUrls, null /* m_slUpdateCheck */ }); if (dictAvail == null) { return; // User cancelled } miMergeInfo.Invoke(null, new object[] { lInst, dictAvail }); bool bUpdAvail = false; foreach (UpdateComponentInfo uc in lInst) { if (uc.Status == UpdateComponentStatus.NewVerAvailable) { bUpdAvail = true; break; } } if (m_slUpdateCheck != null) { m_host.MainWindow.Invoke(new KeePassLib.Delegates.GAction(() => { m_slUpdateCheck.EndLogging(); })); m_slUpdateCheck = null; } KeePassLib.Delegates.GAction actShowUpdateForm_UIThread = new KeePassLib.Delegates.GAction(() => { try { // Do not show the update dialog while auto-typing; // https://sourceforge.net/p/keepass/bugs/1265/ if (SendInputEx.IsSending) { return; } UpdateCheckForm dlg = new UpdateCheckForm(); dlg.InitEx(lInst, false); var dr = UIUtil.ShowDialogAndDestroy(dlg); } catch (Exception ex) { bOK = false; lMsg.Add(ex.Message); } }); if (bUpdAvail) { m_host.MainWindow.BeginInvoke(actShowUpdateForm_UIThread); } } catch (Exception ex) { bOK = false; lMsg.Add(ex.Message); } finally { try { if (m_slUpdateCheck != null) { m_slUpdateCheck.EndLogging(); } } catch (Exception) { } if (bOK) { lock (m_lock) { m_UpdateCheckStatus = UpdateCheckStatus.Checked; } } else { lock (m_lock) { m_UpdateCheckStatus = UpdateCheckStatus.Error; } } } }); if (bOK) { try { m_slUpdateCheck = CreateUpdateCheckLogger(); lMsg.Add("Initialising StatusLogger create: " + DebugPrint); } catch (Exception ex) { lMsg.Add("Initialising StatusLogger failed:\n" + ex.Message + "\n" + DebugPrint); } ThreadPool.QueueUserWorkItem(new WaitCallback((object o) => { actUpdateCheck(); })); } while (true) { if ((m_slUpdateCheck != null) && !m_slUpdateCheck.ContinueWork()) { break; } lock (m_lock) { if (m_UpdateCheckStatus == UpdateCheckStatus.Checked) { break; } if (m_UpdateCheckStatus == UpdateCheckStatus.Error) { break; } } } if (m_slUpdateCheck != null) { m_slUpdateCheck.EndLogging(); } if (bOK) { return; } } catch (Exception ex) { bOK = false; lMsg.Add(ex.Message); } finally { lMsg.Insert(0, "Successful: " + bOK.ToString()); if (bOK) { PluginDebug.AddSuccess("Run updatecheck in background", 0, lMsg.ToArray()); } else { PluginDebug.AddError("Run updatecheck in background", 0, lMsg.ToArray()); } } }
private void CheckPEDCalc() { List <string> lMsg = new List <string>(); try { PwEntry pe = Program.MainForm.GetSelectedEntry(true); if (pe == null) { lMsg.Add("Error identifying selected entry"); return; } KeePass.Plugins.Plugin ped = (KeePass.Plugins.Plugin)Tools.GetPluginInstance("PEDCalc"); if (ped == null) { lMsg.Add("PEDCalc not found"); return; } lMsg.Add("PEDCalc found"); Type tC = ped.GetType().Assembly.GetType("PEDCalc.Configuration"); if (tC != null) { bool bActive = false; PropertyInfo piActive = tC.GetProperty("Active", BindingFlags.Public | BindingFlags.Static); if (piActive != null) { bActive = (bool)piActive.GetValue(null, null); } if (!bActive) { lMsg.Add("PEDCalc inactive"); return; } } Type tEE = ped.GetType().Assembly.GetType("PEDCalc.EntryExtensions"); if (tEE == null) { lMsg.Add("Error retrieving PEDCalc.EntryExtensions"); return; } MethodInfo miGetPEDValue = tEE.GetMethod("GetPEDValue", BindingFlags.NonPublic | BindingFlags.Static); if (miGetPEDValue == null) { lMsg.Add("Error retrieving method GetPEDValue"); return; } try { object pedNewExpireDate = miGetPEDValue.Invoke(null, new object[] { pe, true }); bool bOff = (bool)pedNewExpireDate.GetType().GetProperty("Off").GetValue(pedNewExpireDate, null); if (bOff) { lMsg.Add("PEDCalc result: Off, no recalculation neccessary"); return; } DateTime dtNewExpireDate = (DateTime)pedNewExpireDate.GetType().GetProperty("NewExpiryDateUtc").GetValue(pedNewExpireDate, null);; EntryExpiry.Value = dtNewExpireDate.ToLocalTime(); lMsg.Add("PEDCalc result: " + pedNewExpireDate.ToString()); lMsg.Add("nNew expiry date:" + dtNewExpireDate.ToLocalTime().ToString()); } catch { } } finally { PluginDebug.AddInfo("Adjust expiry date according to PEDCalc", 0, lMsg.ToArray()); } }
private void OnUpdateCheckFormShown(object sender, EventArgs e) { m_lEventHandlerItemActivate = null; PluginDebug.AddSuccess("OUCFS 1", 0); if (!PluginConfig.Active || !PluginConfig.OneClickUpdate) { return; } PluginDebug.AddSuccess("OUCFS 2", 0); CustomListViewEx lvPlugins = (CustomListViewEx)Tools.GetControl("m_lvInfo", sender as UpdateCheckForm); if (lvPlugins == null) { PluginDebug.AddError("m_lvInfo not found", 0); return; } else { PluginDebug.AddSuccess("m_lvInfo found", 0); } PluginUpdateHandler.LoadPlugins(false); if (PluginUpdateHandler.Plugins.Count == 0) { return; } SetPluginSelectionStatus(false); bool bColumnAdded = false; m_lEventHandlerItemActivate = EventHelper.GetItemActivateHandlers(lvPlugins); if (m_lEventHandlerItemActivate.Count > 0) { EventHelper.RemoveItemActivateEventHandlers(lvPlugins, m_lEventHandlerItemActivate); lvPlugins.ItemActivate += LvPlugins_ItemActivate; } //https://github.com/mono/mono/issues/17747 //Do NOT use ListView.SmallImageList if (m_ImgApply == null) { m_ImgApply = (Image)KeePass.Program.Resources.GetObject("B16x16_Apply"); } if (m_ImgUnselected == null) { m_ImgUnselected = m_ImgApply == null ? null : UIUtil.CreateGrayImage(m_ImgApply); } foreach (ListViewItem item in lvPlugins.Items) { PluginDebug.AddInfo("Check plugin update status", 0, item.SubItems[0].Text, item.SubItems[1].Text); if (!item.SubItems[1].Text.Contains(KeePass.Resources.KPRes.NewVersionAvailable)) { continue; } foreach (PluginUpdate upd in PluginUpdateHandler.Plugins) { if (item.SubItems[0].Text != upd.Title) { continue; } if (upd.UpdateMode == UpdateOtherPluginMode.Unknown) { continue; } if (!bColumnAdded) { lvPlugins.Columns.Add(PluginTranslate.PluginUpdate); bColumnAdded = true; } ListViewItem.ListViewSubItem lvsiUpdate = new ListViewItem.ListViewSubItem(item, PluginTranslate.PluginUpdate); lvsiUpdate.Tag = upd; item.SubItems.Add(lvsiUpdate); upd.Selected = true; try { upd.VersionAvailable = new Version(item.SubItems[3].Text); } catch (Exception ex) { PluginDebug.AddError("Could not parse new version", 0, upd.Name, item.SubItems[3].Text, ex.Message); } break; } } if (bColumnAdded) { UIUtil.ResizeColumns(lvPlugins, new int[] { 3, 3, 2, 2, 1 }, true); lvPlugins.MouseClick += OnUpdateCheckFormPluginMouseClick; lvPlugins.OwnerDraw = true; lvPlugins.DrawSubItem += LvPlugins_DrawSubItem; lvPlugins.DrawColumnHeader += LvPlugins_DrawColumnHeader; ShowUpdateButton(sender as Form, true); } if (m_lEventHandlerItemActivate.Count == 0) { if (lvPlugins.ContextMenuStrip == null) { lvPlugins.ContextMenuStrip = new ContextMenuStrip(); string sMenuText = KeePass.Resources.KPRes.PluginsDesc; try { sMenuText = Tools.GetControl("m_linkPlugins", sender as UpdateCheckForm).Text; } catch { } lvPlugins.ContextMenuStrip.Items.Add(new ToolStripMenuItem(sMenuText, null, OnReleasePageClick)); lvPlugins.ContextMenuStrip.Opening += ContextMenuStrip_Opening; } else { PluginDebug.AddWarning("m_lvEntries.ContextMenuStrip already defined, special handling for added 'go to release page' to be defined", 0); } } }
private void UpdateAvailableTranslations() { Dictionary <string, List <UpdateComponentInfo> > dUpdateInfo = new Dictionary <string, List <UpdateComponentInfo> >(); Dictionary <string, long> dResult = new Dictionary <string, long>(); Type t = typeof(KeePass.Program).Assembly.GetType("KeePass.Util.UpdateCheckEx"); if (t == null) { PluginDebug.AddError("Could not locate class 'UpdateCheckEx'", 0); return; } MethodInfo mi = t.GetMethod("DownloadInfoFiles", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Static); if (mi == null) { PluginDebug.AddError("Could not locate method 'DownloadInfoFiles'", 0); return; } if (string.IsNullOrEmpty(VersionURL)) { PluginDebug.AddError("Could not read plugin update url", 0); return; } dUpdateInfo = mi.Invoke(null, new object[] { new List <string>() { VersionURL }, null }) as Dictionary <string, List <UpdateComponentInfo> >; List <string> lTranslationsNew = new List <string>(); string[] cSplit = new string[] { "!", "!!!" }; foreach (KeyValuePair <string, List <UpdateComponentInfo> > kvp in dUpdateInfo) { if (kvp.Value == null) { continue; } Version vCheck = null; foreach (UpdateComponentInfo uci in kvp.Value) { //Github: <Plugin>!<language identifier> string[] sParts = uci.Name.Split(cSplit, StringSplitOptions.RemoveEmptyEntries); if (sParts.Length == 1) { vCheck = new Version(StrUtil.VersionToString(uci.VerAvailable, 2)); if (VersionAvailableIsUnknown()) { VersionAvailable = vCheck; } } if (!PluginUpdateHandler.VersionsEqual(VersionInstalled, vCheck)) { return; //Different version might require different translation files } if (sParts.Length != 2) { continue; } long lVer = 0; if (!long.TryParse(StrUtil.VersionToString(uci.VerAvailable), out lVer)) { continue; } string sLang = Name + "." + sParts[1].ToLowerInvariant() + ".language.xml"; TranslationVersionCheck tvc = Translations.Find(x => x.LangugageFile == sLang); if (tvc == null) { tvc = new TranslationVersionCheck() { LangugageFile = sLang }; Translations.Add(tvc); } tvc.Available = lVer; } } }
private void UpdatePlugins(bool bUpdateTranslationsOnly) { PluginDebug.AddInfo("UpdatePlugins start ", DebugPrint); Form fUpdateLog = null; m_slUpdatePlugins = StatusUtil.CreateStatusDialog(GlobalWindowManager.TopWindow, out fUpdateLog, PluginTranslate.PluginUpdateCaption, string.Empty, true, true); bool success = false; string sTempPluginsFolder = PluginUpdateHandler.GetTempFolder(); ThreadStart ts = new ThreadStart(() => { m_slUpdatePlugins.StartLogging(PluginTranslate.PluginUpdateCaption, false); PluginDebug.AddInfo("Use temp folder", PluginUpdateHandler.Shieldify.ToString(), sTempPluginsFolder, DebugPrint); //Download files foreach (PluginUpdate upd in PluginUpdateHandler.Plugins) { if (!upd.Selected) { continue; } success |= UpdatePlugin(upd, sTempPluginsFolder, bUpdateTranslationsOnly); } }); Thread t = new Thread(ts); t.IsBackground = true; t.Start(); while (true && t.IsAlive) { if (!m_slUpdatePlugins.ContinueWork()) { t.Abort(); break; } } if (t != null && t.IsAlive) { t.Abort(); } if (m_slUpdatePlugins != null) { m_slUpdatePlugins.EndLogging(); m_slUpdatePlugins = null; } if (fUpdateLog != null) { fUpdateLog.Dispose(); } //Move files from temp folder to plugin folder success &= PluginUpdateHandler.MoveAll(sTempPluginsFolder); foreach (var pu in PluginUpdateHandler.Plugins) { if (!pu.Selected) { continue; } if (pu is OwnPluginUpdate) { (pu as OwnPluginUpdate).UpdateTranslationInfo(true); } } if (success) { PluginUpdateHandler.Cleanup(sTempPluginsFolder); } success = true; //Restart KeePass to use new plugin versions PluginDebug.AddInfo("Update finished", "Succes: " + success.ToString(), DebugPrint); if (success && !bUpdateTranslationsOnly) { if (Tools.AskYesNo(PluginTranslate.PluginUpdateSuccess, PluginTranslate.PluginUpdateCaption) == DialogResult.Yes) { if (m_bRestartInvoke) { m_host.MainWindow.Invoke(new KeePassLib.Delegates.GAction(() => { Restart(); })); } else { Restart(); } } } }