[seahorse/wip/nielsdg/pwquality] gkr: Add strength indicator for new passwords
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse/wip/nielsdg/pwquality] gkr: Add strength indicator for new passwords
- Date: Sat, 16 Feb 2019 16:18:39 +0000 (UTC)
commit 450d28d243ca4e2192f80f1906f9fa4fabe02363
Author: Niels De Graef <nielsdegraef gmail com>
Date: Sat Feb 16 15:25:06 2019 +0100
gkr: Add strength indicator for new passwords
We add [libpwquality] as a dependency for this (it's already part of
GNOME's core-deps group).
libpwquality: https://github.com/libpwquality/libpwquality
build-aux/org.gnome.Seahorse.json | 10 ++++
gkr/gkr-item-add.vala | 29 +++++++---
gkr/meson.build | 3 +
gkr/pwquality.vapi | 116 ++++++++++++++++++++++++++++++++++++++
gkr/seahorse-gkr-add-item.ui | 32 +++++++++--
libseahorse/seahorse.css | 17 ++++++
meson.build | 1 +
7 files changed, 195 insertions(+), 13 deletions(-)
---
diff --git a/build-aux/org.gnome.Seahorse.json b/build-aux/org.gnome.Seahorse.json
index a37163a3..ae8700d3 100644
--- a/build-aux/org.gnome.Seahorse.json
+++ b/build-aux/org.gnome.Seahorse.json
@@ -49,6 +49,16 @@
}
]
},
+ {
+ "name": "libpwquality",
+ "sources": [
+ {
+ "type": "archive",
+ "url":
"https://github.com/libpwquality/libpwquality/releases/download/libpwquality-1.4.0/libpwquality-1.4.0.tar.bz2",
+ "sha256": "a51a0d585ace4ddfb512ff29d80e55db3cb52705113ea9a846a63b9b15ddc9a7"
+ }
+ ]
+ },
{
"name": "seahorse",
"buildsystem": "meson",
diff --git a/gkr/gkr-item-add.vala b/gkr/gkr-item-add.vala
index f27146d4..9e2532b0 100644
--- a/gkr/gkr-item-add.vala
+++ b/gkr/gkr-item-add.vala
@@ -27,7 +27,11 @@ public class Seahorse.Gkr.ItemAdd : Gtk.Dialog {
[GtkChild]
private Gtk.Entry item_entry;
[GtkChild]
- private Gtk.CheckButton show_password_checkbutton;
+ private Gtk.LevelBar password_strength_bar;
+ [GtkChild]
+ private Gtk.Image password_strength_icon;
+
+ private PasswordQuality.Settings pwquality = new PasswordQuality.Settings();
construct {
// Load up a list of all the keyrings, and select the default
@@ -49,15 +53,11 @@ public class Seahorse.Gkr.ItemAdd : Gtk.Dialog {
set_response_sensitive(Gtk.ResponseType.ACCEPT, false);
- var buffer = new Gcr.SecureEntryBuffer();
- this.password_entry = new Gtk.Entry.with_buffer(buffer);
+ this.password_entry = new PasswordEntry();
this.password_entry.visibility = false;
+ this.password_entry.changed.connect(on_password_entry_changed);
this.password_area.add(this.password_entry);
this.password_entry.show();
-
- this.show_password_checkbutton.toggled.connect(() => {
- this.password_entry.visibility = this.show_password_checkbutton.active;
- });
}
public ItemAdd(Gtk.Window? parent) {
@@ -72,6 +72,21 @@ public class Seahorse.Gkr.ItemAdd : Gtk.Dialog {
set_response_sensitive(Gtk.ResponseType.ACCEPT, this.item_entry.text != "");
}
+ private void on_password_entry_changed (Gtk.Editable entry) {
+ void* auxerr;
+ int score = this.pwquality.check(entry.get_chars(), null, null, out auxerr);
+
+ if (score < 0) {
+ PasswordQuality.Error err = ((PasswordQuality.Error) score);
+ this.password_strength_icon.tooltip_text = dgettext("libpwquality", err.to_string(auxerr));
+ this.password_strength_icon.show();
+ } else {
+ this.password_strength_icon.hide();
+ }
+
+ this.password_strength_bar.value = ((score / 25) + 1).clamp(1, 5);
+ }
+
public override void response(int resp) {
if (resp != Gtk.ResponseType.ACCEPT)
return;
diff --git a/gkr/meson.build b/gkr/meson.build
index 5cf37db6..e0e671fc 100644
--- a/gkr/meson.build
+++ b/gkr/meson.build
@@ -17,11 +17,14 @@ gkr_dependencies = [
gcr,
gcr_ui,
libsecret,
+ libpwquality,
common_dep,
]
gkr_vala_args = [
'--gresources', resources_xml,
+ '--vapidir', meson.current_source_dir(),
+ '--pkg=pwquality',
]
gkr_lib = static_library('seahorse-gkr',
diff --git a/gkr/pwquality.vapi b/gkr/pwquality.vapi
new file mode 100644
index 00000000..b56557ab
--- /dev/null
+++ b/gkr/pwquality.vapi
@@ -0,0 +1,116 @@
+/* libpwquality Vala Bindings
+ * Copyright 2013 Evan Nemerson <evan coeus-group com>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+[CCode (lower_case_cprefix = "pwquality_", cheader_filename = "pwquality.h")]
+namespace PasswordQuality {
+ [CCode (cname = "int", cprefix = "PWQ_SETTING_", has_type_id = false)]
+ public enum Setting {
+ DIFF_OK,
+ MIN_LENGTH,
+ DIG_CREDIT,
+ UP_CREDIT,
+ LOW_CREDIT,
+ OTH_CREDIT,
+ MIN_CLASS,
+ MAX_REPEAT,
+ DICT_PATH,
+ MAX_CLASS_REPEAT,
+ GECOS_CHECK,
+ BAD_WORDS,
+ MAX_SEQUENCE
+ }
+
+ [CCode (cname = "int", cprefix = "PWQ_ERROR_", has_type_id = false)]
+ public enum Error {
+ SUCCESS,
+ FATAL_FAILURE,
+ INTEGER,
+ CFGFILE_OPEN,
+ CFGFILE_MALFORMED,
+ UNKNOWN_SETTING,
+ NON_INT_SETTING,
+ NON_STR_SETTING,
+ MEM_ALLOC,
+ TOO_SIMILAR,
+ MIN_DIGITS,
+ MIN_UPPERS,
+ MIN_LOWERS,
+ MIN_OTHERS,
+ MIN_LENGTH,
+ PALINDROME,
+ CASE_CHANGES_ONLY,
+ ROTATED,
+ MIN_CLASSES,
+ MAX_CONSECUTIVE,
+ EMPTY_PASSWORD,
+ SAME_PASSWORD,
+ CRACKLIB_CHECK,
+ RNG,
+ GENERATION_FAILED,
+ USER_CHECK,
+ GECOS_CHECK,
+ MAX_CLASS_REPEAT,
+ BAD_WORDS,
+ MAX_SEQUENCE;
+
+ [CCode (cname = "pwquality_strerror", instance_pos = 2.5)]
+ private void* strerror (void* buf, size_t len, void* auxerror);
+
+ public string to_string (void* auxerror = null) {
+ string ret = null;
+ string** retp = &ret;
+ *retp = GLib.malloc (PasswordQuality.MAX_ERROR_MESSAGE_LEN);
+ void* res = this.strerror (*retp, PasswordQuality.MAX_ERROR_MESSAGE_LEN, auxerror);
+
+ if ( res != *retp ) {
+ GLib.Memory.copy (*retp, res, ((string) res).length + 1);
+ }
+
+ return ret;
+ }
+ }
+
+ [CCode (cname = "PWQ_MAX_ENTROPY_BITS")]
+ public const int MAX_ENTROPY_BITS;
+ [CCode (cname = "PWQ_MIN_ENTROPY_BITS")]
+ public const int MIN_ENTROPY_BITS;
+ [CCode (cname = "PWQ_MAX_ERROR_MESSAGE_LEN")]
+ public const int MAX_ERROR_MESSAGE_LEN;
+
+ [Compact, CCode (cname = "pwquality_settings_t", lower_case_cprefix = "pwquality_", free_function =
"pwquality_free_settings")]
+ public class Settings {
+ [CCode (cname = "pwquality_default_settings")]
+ public Settings ();
+
+ public PasswordQuality.Error read_config (string cfgfile, out void* auxerror);
+ public PasswordQuality.Error set_option (string option);
+ public PasswordQuality.Error set_int_value (PasswordQuality.Setting setting, int value);
+ public PasswordQuality.Error set_str_value (PasswordQuality.Setting setting, string value);
+ public PasswordQuality.Error get_int_value (PasswordQuality.Setting setting, out int value);
+ public PasswordQuality.Error get_str_value (PasswordQuality.Setting setting, out unowned string
value);
+
+ public PasswordQuality.Error generate (int entropy_bits, out string password);
+ public int check (string password, string? oldpassword = null, string? user = null, out void*
auxerror = null);
+ }
+}
diff --git a/gkr/seahorse-gkr-add-item.ui b/gkr/seahorse-gkr-add-item.ui
index 714729e1..8564f5f9 100644
--- a/gkr/seahorse-gkr-add-item.ui
+++ b/gkr/seahorse-gkr-add-item.ui
@@ -89,13 +89,33 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="show_password_checkbutton">
- <property name="label" translatable="yes">_Show Password</property>
+ <object class="GtkImage" id="password_strength_icon">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
+ <property name="halign">end</property>
+ <property name="icon-name">dialog-warning-symbolic</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="left_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLevelBar" id="password_strength_bar">
+ <property name="visible">True</property>
+ <property name="valign">start</property>
+ <property name="min_value">0</property>
+ <property name="max_value">5</property>
+ <property name="mode">discrete</property>
+ <offsets>
+ <offset name="strength-weak" value="1"/>
+ <offset name="strength-low" value="2"/>
+ <offset name="strength-medium" value="3"/>
+ <offset name="strength-good" value="4"/>
+ <offset name="strength-high" value="5"/>
+ </offsets>
</object>
<packing>
<property name="top_attach">3</property>
diff --git a/libseahorse/seahorse.css b/libseahorse/seahorse.css
index b44b7f83..448eb001 100644
--- a/libseahorse/seahorse.css
+++ b/libseahorse/seahorse.css
@@ -14,3 +14,20 @@
border-style: solid;
border-color: shade (@theme_bg_color, 0.66);
}
+
+levelbar .strength-weak {
+ background-color: #cc0000;
+ border-color: #cc0000;
+}
+
+levelbar .strength-low {
+ background-color: #f5ce00;
+ border-color: #f5ce00;
+}
+
+levelbar .strength-medium,
+levelbar .strength-good,
+levelbar .strength-high {
+ background-color: #73d216;
+ border-color: #73d216;
+}
diff --git a/meson.build b/meson.build
index 02eb7365..e29cc1ff 100644
--- a/meson.build
+++ b/meson.build
@@ -47,6 +47,7 @@ gtk = dependency('gtk+-3.0', version: '>= 3.22.0')
gcr = dependency('gcr-3', version: '>=' + min_gcr_version)
gcr_ui = dependency('gcr-ui-3', version: '>=' + min_gcr_version)
libsecret = dependency('libsecret-1', version: '>= 0.16')
+libpwquality = dependency('pwquality')
posix = valac.find_library('posix')
ssh_bin = find_program('ssh')
ssh_keygen = find_program('ssh-keygen')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]