[gdm/wip/initial-setup2] initial-setup: Implement password quality checks



commit 3832e648d74d370edd01078f1dc860f16b65767b
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat May 19 20:39:12 2012 -0400

    initial-setup: Implement password quality checks
    
    This optionally uses libpwquality for centralized, configurable
    password quality policy.

 configure.ac                           |    6 ++
 gui/initial-setup/Makefile.am          |    7 ++
 gui/initial-setup/gdm-initial-setup.c  |   14 ++--
 gui/initial-setup/pw-utils-pwquality.c |  117 ++++++++++++++++++++++++++++++++
 4 files changed, 136 insertions(+), 8 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 39d76e4..019fd01 100644
--- a/configure.ac
+++ b/configure.ac
@@ -194,6 +194,12 @@ PKG_CHECK_MODULES(INITIAL_SETUP,
 
 AC_DEFINE(HAVE_CHEESE, 1, [Define to 1 to enable cheese webcam support])
 
+AC_CHECK_HEADER([pwquality.h], [have_pwquality=yes], [have_pwquality=no])
+AM_CONDITIONAL(HAVE_PWQUALITY, [test x$have_pwquality = xyes])
+if test x$have_pwquality = xyes ; then
+  INITIAL_SETUP_LIBS="$INITIAL_SETUP_LIBS -lpwquality"
+fi
+
 # Unit testing framework
 PKG_CHECK_MODULES(CHECK,
                   [check >= 0.9.4],
diff --git a/gui/initial-setup/Makefile.am b/gui/initial-setup/Makefile.am
index 4b39656..15f2a02 100644
--- a/gui/initial-setup/Makefile.am
+++ b/gui/initial-setup/Makefile.am
@@ -27,12 +27,19 @@ timedated.h: Makefile.am timedated1-interface.xml
 setup_resources.c: setup.gresource.xml setup.ui welcome-image.png
 	$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate-source $(srcdir)/setup.gresource.xml
 
+if HAVE_PWQUALITY
+pw_utils_sources = pw-utils-pwquality.c pw-utils.h
+else
+pw_utils_sources = pw-utils.c pw-utils.h
+endif
+
 gdm_initial_setup_SOURCES =	\
 	gdm-initial-setup.c \
 	panel-cell-renderer-signal.c panel-cell-renderer-signal.h \
 	panel-cell-renderer-mode.c panel-cell-renderer-mode.h \
 	panel-cell-renderer-security.c panel-cell-renderer-security.h \
 	cc-timezone-map.c cc-timezone-map.h \
+	$(pw_utils_sources) \
 	um-utils.c um-utils.h \
 	um-crop-area.c um-crop-area.h \
 	um-photo-dialog.c um-photo-dialog.h \
diff --git a/gui/initial-setup/gdm-initial-setup.c b/gui/initial-setup/gdm-initial-setup.c
index 1d93f09..30ad4fe 100644
--- a/gui/initial-setup/gdm-initial-setup.c
+++ b/gui/initial-setup/gdm-initial-setup.c
@@ -65,6 +65,7 @@ typedef struct {
         gboolean valid_name;
         gboolean valid_username;
         gboolean valid_password;
+        const gchar *password_reason;
         ActUserPasswordMode password_mode;
         ActUserAccountType account_type;
 
@@ -953,7 +954,7 @@ update_password_entries (SetupData *setup)
         GtkWidget *username_combo;
         gdouble strength;
         const gchar *hint;
-        const gchar *long_hint;
+        const gchar *long_hint = NULL;
 
         password_entry = WID("account-password-entry");
         confirm_entry = WID("account-confirm-entry");
@@ -967,9 +968,11 @@ update_password_entries (SetupData *setup)
 
         if (strength == 0.0) {
                 setup->valid_password = FALSE;
+                setup->password_reason = long_hint ? long_hint : hint;
         }
         else if (strcmp (password, verify) != 0) {
                 setup->valid_password = FALSE;
+                setup->password_reason = _("Passwords do not match");
         }
         else {
                 setup->valid_password = TRUE;
@@ -1011,13 +1014,9 @@ confirm_entry_focus_out (GtkWidget     *entry,
         verify = gtk_entry_get_text (confirm_entry);
 
         if (strlen (password) > 0 && strlen (verify) > 0) {
-                if (strlen (password) < MIN_PASSWORD_LEN) {
+                if (!setup->valid_password) {
                         set_entry_validation_error (confirm_entry,
-                                                    _("The new password is too short"));
-                }
-                else if (strcmp (password, verify) != 0) {
-                        set_entry_validation_error (confirm_entry,
-                                                    _("Passwords do not match"));
+                                                    setup->password_reason);
                 }
                 else {
                         clear_entry_validation_error (confirm_entry);
@@ -2125,7 +2124,6 @@ prepare_summary_page (SetupData *setup)
                                           "Summary", "summary-details",
                                           NULL, NULL);
         if (s) {
-                g_print ("replacing summary details\n");
                 gtk_label_set_text (GTK_LABEL (WID ("summary-details")), s);
         }
         g_free (s);
diff --git a/gui/initial-setup/pw-utils-pwquality.c b/gui/initial-setup/pw-utils-pwquality.c
new file mode 100644
index 0000000..8d2fde0
--- /dev/null
+++ b/gui/initial-setup/pw-utils-pwquality.c
@@ -0,0 +1,117 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2012  Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Written by: Matthias Clasen <mclasen redhat com>
+ */
+
+#include "config.h"
+
+#include "pw-utils.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <pwquality.h>
+
+
+static pwquality_settings_t *
+get_pwq (void)
+{
+        static pwquality_settings_t *settings;
+
+        if (settings == NULL) {
+                gchar *err = NULL;
+                settings = pwquality_default_settings ();
+                if (pwquality_read_config (settings, NULL, (gpointer)&err) < 0) {
+                        g_error ("failed to read pwquality configuration: %s\n", err);
+                }
+        }
+
+        return settings;
+}
+
+gint
+pw_min_length (void)
+{
+        gint value = 0;
+
+        if (pwquality_get_int_value (get_pwq (), PWQ_SETTING_MIN_LENGTH, &value) < 0) {
+                g_error ("Failed to read pwquality setting\n" );
+        }
+
+        return value;
+}
+
+gchar *
+pw_generate (void)
+{
+        gchar *res;
+        gint rv;
+
+        rv = pwquality_generate (get_pwq (), 0, &res);
+
+        if (rv < 0) {
+                g_error ("Password generation failed: %s\n",
+                         pwquality_strerror (NULL, 0, rv, NULL));
+                return NULL;
+        }
+
+        return res;
+}
+
+gdouble
+pw_strength (const gchar  *password,
+             const gchar  *old_password,
+             const gchar  *username,
+             const gchar **hint,
+             const gchar **long_hint)
+{
+        gint rv;
+        gdouble strength;
+        void *auxerror;
+
+        rv = pwquality_check (get_pwq (),
+                              password, old_password, username,
+                              &auxerror);
+
+        if (rv == PWQ_ERROR_MIN_LENGTH) {
+                *hint = C_("Password strength", "Too short");
+                *long_hint = pwquality_strerror (NULL, 0, rv, auxerror);
+                return 0.0;
+        }
+        else if (rv < 0) {
+                *hint = C_("Password strength", "Not good enough");
+                *long_hint = pwquality_strerror (NULL, 0, rv, auxerror);
+                return 0.0;
+        }
+
+        strength = CLAMP (0.01 * rv, 0.0, 1.0);
+
+        if (strength < 0.50)
+                *hint = C_("Password strength", "Weak");
+        else if (strength < 0.75)
+                *hint = C_("Password strength", "Fair");
+        else if (strength < 0.90)
+                *hint = C_("Password strength", "Good");
+        else
+                *hint = C_("Password strength", "Strong");
+
+        *long_hint = NULL;
+
+         return strength;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]