private void bwSearchWeak_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { bwSearchHibp.ReportProgress(0, new ProgressState("Searching for weak passwords...")); var sw = Stopwatch.StartNew(); var count = this.Document.Entries.Count; for (var i = 0; i < count; i++) { var entry = this.Document.Entries[i]; foreach (var record in entry.Records) { if (record.RecordType == RecordType.Password) { if (BadPasswords.IsCommon(record.Text, out var matchedPassword)) { var lvi = new ListViewItem(entry.Title) { Tag = entry, ImageIndex = 0, ToolTipText = $"Password is similar to a common password ({matchedPassword})." }; bwSearchWeak.ReportProgress(i * 100 / count, new ProgressState(lvi)); break; } } } if (bwSearchWeak.CancellationPending) { e.Cancel = true; return; } } Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Items searched at {0:0.0} ms", sw.ElapsedMilliseconds)); }
private void FillRecords() { pnl.Visible = false; pnl.Controls.Clear(); var unitHeight = (new TextBox() { Font = this.Font }).Height; var labelWidth = pnl.ClientSize.Width / 4; var labelBuffer = SystemInformation.VerticalScrollBarWidth + 1; var y = 0; TextBox titleTextBox; { var record = this.Item[RecordType.Title]; titleTextBox = new TextBox() { Font = this.Font, Location = new Point(labelWidth + labelBuffer, 0), Tag = record, Text = record.ToString(), Width = pnl.ClientSize.Width - labelWidth - labelBuffer, ReadOnly = !this.Editable, Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right }; titleTextBox.GotFocus += (object sender2, EventArgs e2) => { ((TextBox)sender2).SelectAll(); }; titleTextBox.TextChanged += (object sender2, EventArgs e2) => { btnOK.Enabled = (((Control)sender2).Text.Trim().Length > 0); }; pnl.Controls.Add(titleTextBox); var label = new Label() { AutoEllipsis = true, Location = new Point(0, y), Size = new Size(labelWidth, unitHeight), Text = "Name:", TextAlign = ContentAlignment.MiddleLeft, UseMnemonic = false }; pnl.Controls.Add(label); y += titleTextBox.Height + (label.Height / 4); } ComboBox categoryComboBox; { var record = this.Item[RecordType.Group]; categoryComboBox = new ComboBox() { Font = this.Font, Location = new Point(labelWidth + labelBuffer, y), Tag = record, Text = record.ToString(), Width = pnl.ClientSize.Width - labelWidth - labelBuffer, Enabled = this.Editable, Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right }; categoryComboBox.GotFocus += (object sender2, EventArgs e2) => { ((ComboBox)sender2).SelectAll(); }; foreach (var category in this.Categories) { categoryComboBox.Items.Add(category); } if (this.DefaultCategory != null) { categoryComboBox.Text = this.DefaultCategory; } pnl.Controls.Add(categoryComboBox); var label = new Label() { AutoEllipsis = true, Location = new Point(0, y), Size = new Size(labelWidth, unitHeight), Text = "Category:", TextAlign = ContentAlignment.MiddleLeft, UseMnemonic = false }; pnl.Controls.Add(label); if (!string.IsNullOrEmpty(record.Text)) { var renameButton = NewCustomCommandButton(categoryComboBox, delegate { using (var frm = new InputBox($"Rename all categories named \"{record.Text}\" to:", categoryComboBox.Text)) { if (frm.ShowDialog(this) == DialogResult.OK) { var groupFrom = this.Item.Group; var groupTo = frm.Text; foreach (var entry in this.Document.Entries) { if (string.Equals(groupFrom, entry.Group, StringComparison.CurrentCultureIgnoreCase)) { entry.Group = groupTo; } } categoryComboBox.Text = groupTo; } } }, "Rename group", "btnGroupRename"); pnl.Controls.Add(renameButton); renameButton.Enabled = categoryComboBox.Enabled; btnEdit.Click += delegate { renameButton.Enabled = categoryComboBox.Enabled; }; } y += titleTextBox.Height + (label.Height / 4); } y += unitHeight / 2; int yH; foreach (var record in this.Item.Records) { var label = new Label() { AutoEllipsis = true, Location = new Point(0, y), Size = new Size(labelWidth, unitHeight), Text = Helpers.GetRecordCaption(record) + ":", TextAlign = ContentAlignment.MiddleLeft, UseMnemonic = false }; switch (record.RecordType) { case RecordType.Uuid: case RecordType.Group: case RecordType.Title: case RecordType.CreationTime: case RecordType.LastAccessTime: case RecordType.LastModificationTime: case RecordType.PasswordExpiryTime: case RecordType.PasswordModificationTime: case RecordType.PasswordHistory: case RecordType.Autotype: continue; case RecordType.UserName: case RecordType.CreditCardExpiration: { var textBox = NewTextBox(labelWidth, y, record); pnl.Controls.Add(textBox); pnl.Controls.Add(NewCopyButton(textBox, record.RecordType)); yH = textBox.Height; } break; case RecordType.CreditCardVerificationValue: case RecordType.CreditCardPin: { var textBox = NewTextBox(labelWidth, y, record); textBox.UseSystemPasswordChar = true; pnl.Controls.Add(textBox); pnl.Controls.Add(NewCopyButton(textBox, record.RecordType)); pnl.Controls.Add(NewShowPasswordButton(textBox)); yH = textBox.Height; } break; case RecordType.Password: { var textBox = NewTextBox(labelWidth, y, record); textBox.UseSystemPasswordChar = true; pnl.Controls.Add(textBox); pnl.Controls.Add(NewCopyButton(textBox, record.RecordType)); pnl.Controls.Add(NewConfigureButton(textBox, delegate { using (var frm = new PasswordDetailsForm(this.Item, textBox.ReadOnly)) { frm.ShowDialog(this); } }, "Password policy configuration.")); pnl.Controls.Add(NewShowPasswordButton(textBox)); pnl.Controls.Add(NewGeneratePasswordButton(textBox)); void showPasswordWarnings() { if (BadPasswords.IsCommon(textBox.Text, out var matchedPassword)) { erp.SetIconAlignment(textBox, ErrorIconAlignment.MiddleLeft); erp.SetIconPadding(textBox, SystemInformation.BorderSize.Width); erp.SetError(textBox, $"Password is similar to a common password ({matchedPassword})."); } else { erp.SetError(textBox, null); } } showPasswordWarnings(); textBox.TextChanged += delegate { showPasswordWarnings(); }; yH = textBox.Height; } break; case RecordType.Url: { var textBox = NewTextBox(labelWidth, y, record, urlLookAndFeel: true); pnl.Controls.Add(textBox); pnl.Controls.Add(NewCopyFilteredButton(textBox, record.RecordType, copyText: delegate { return(Execute.NormalizeUrl(textBox.Text)); })); pnl.Controls.Add(NewExecuteUrlButton(textBox)); pnl.Controls.Add(NewExecuteUrlQRButton(textBox)); yH = textBox.Height; } break; case RecordType.EmailAddress: { var textBox = NewTextBox(labelWidth, y, record, urlLookAndFeel: true); pnl.Controls.Add(textBox); pnl.Controls.Add(NewCopyButton(textBox, record.RecordType)); pnl.Controls.Add(NewExecuteEmailButton(textBox)); yH = textBox.Height; } break; case RecordType.Notes: { var textBox = NewTextBox(labelWidth, y, record, multiline: true); pnl.Controls.Add(textBox); yH = textBox.Height; } break; case RecordType.TwoFactorKey: { var bytes = record.GetBytes(); var textBox = NewTextBox(labelWidth, y, record, text: OneTimePassword.ToBase32(bytes, bytes.Length, SecretFormatFlags.Spacing | SecretFormatFlags.Padding)); textBox.UseSystemPasswordChar = true; pnl.Controls.Add(textBox); Array.Clear(bytes, 0, bytes.Length); pnl.Controls.Add(NewCopyFilteredButton(textBox, record.RecordType, tipText: "Copy two-factor number to clipboard.", copyText: delegate { return(Helpers.GetTwoFactorCode(textBox.Text)); })); pnl.Controls.Add(NewViewTwoFactorCode(textBox)); pnl.Controls.Add(NewExecuteOAuthQRButton(textBox)); pnl.Controls.Add(NewShowPasswordButton(textBox, tipText: "Show two-factor key.")); yH = textBox.Height; } if (Settings.ShowNtpDriftWarning && !bwCheckTime.IsBusy) { bwCheckTime.RunWorkerAsync(); } break; case RecordType.CreditCardNumber: { var textBox = NewTextBox(labelWidth, y, record); pnl.Controls.Add(textBox); pnl.Controls.Add(NewCopyFilteredButton(textBox, record.RecordType, allowedCopyCharacters: Helpers.NumberCharacters, tipText: "Copy only numbers to clipboard.")); pnl.Controls.Add(NewCopyButton(textBox, record.RecordType)); yH = textBox.Height; } break; case RecordType.QRCode: { var textBox = NewTextBox(labelWidth, y, record); pnl.Controls.Add(textBox); pnl.Controls.Add(NewExecuteQRButton(textBox)); yH = textBox.Height; } break; case RecordType.RunCommand: { var textBox = NewTextBox(labelWidth, y, record); pnl.Controls.Add(textBox); pnl.Controls.Add(NewExecuteCommandButton(textBox)); yH = textBox.Height; } break; default: yH = label.Height; break; } pnl.Controls.Add(label); y += yH + (label.Height / 4); } if (pnl.VerticalScroll.Visible == true) { foreach (Control control in pnl.Controls) { var label = control as Label; if (label == null) { control.Left -= SystemInformation.VerticalScrollBarWidth; } } } pnl.Visible = true; if (this.IsNew) { titleTextBox.Select(); } }