[gnome-control-center] users: Separate out password generation and strength calculation



commit 8947cf84688d59d710716616866c68e699ab9972
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed May 23 08:40:56 2012 -0400

    users: Separate out password generation and strength calculation
    
    This is in preparation of using a library for this purpose, and
    is just generally cleaner.

 panels/user-accounts/Makefile.am          |    2 +
 panels/user-accounts/pw-utils.c           |  158 +++++++++++++++++++++++++++++
 panels/user-accounts/pw-utils.h           |   27 +++++
 panels/user-accounts/um-password-dialog.c |  124 ++---------------------
 4 files changed, 195 insertions(+), 116 deletions(-)
---
diff --git a/panels/user-accounts/Makefile.am b/panels/user-accounts/Makefile.am
index 2907f01..692db00 100644
--- a/panels/user-accounts/Makefile.am
+++ b/panels/user-accounts/Makefile.am
@@ -33,6 +33,8 @@ libuser_accounts_la_SOURCES =		\
 	um-account-dialog.c		\
 	um-password-dialog.h		\
 	um-password-dialog.c		\
+	pw-utils.h			\
+	pw-utils.c			\
 	um-photo-dialog.h		\
 	um-photo-dialog.c		\
 	um-crop-area.h			\
diff --git a/panels/user-accounts/pw-utils.c b/panels/user-accounts/pw-utils.c
new file mode 100644
index 0000000..87267d0
--- /dev/null
+++ b/panels/user-accounts/pw-utils.c
@@ -0,0 +1,158 @@
+/* -*- 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 <sys/types.h>
+#include <sys/wait.h>
+
+
+#define MIN_PASSWORD_LEN 6
+
+gint
+pw_min_length (void)
+{
+        return MIN_PASSWORD_LEN;
+}
+
+gchar *
+pw_generate (void)
+{
+        static gchar **generated = NULL;
+        static gint next;
+
+        gint min_len, max_len;
+        gchar *output, *err, *cmdline, *p;
+        gint status;
+        GError *error;
+        gchar *ret;
+
+        if (generated && generated[next]) {
+                return g_strdup (generated[next++]);
+        }
+
+        g_strfreev (generated);
+        generated = NULL;
+        next = 0;
+
+        ret = NULL;
+
+        min_len = 6;
+        max_len = 12;
+        cmdline = g_strdup_printf ("apg -n 10 -M SNC -m %d -x %d", min_len, max_len);
+        error = NULL;
+        output = NULL;
+        err = NULL;
+        if (!g_spawn_command_line_sync (cmdline, &output, &err, &status, &error)) {
+                g_warning ("Failed to run apg: %s", error->message);
+                g_error_free (error);
+        } else if (WEXITSTATUS (status) == 0) {
+                p = output;
+                if (*p == '\n')
+                        p++;
+                if (p[strlen(p) - 1] == '\n')
+                        p[strlen(p) - 1] = '\0';
+                generated = g_strsplit (p, "\n", -1);
+                next = 0;
+
+                ret = g_strdup (generated[next++]);
+        } else {
+                g_warning ("agp returned an error: %s", err);
+        }
+
+        g_free (cmdline);
+        g_free (output);
+        g_free (err);
+
+        return ret;
+}
+
+/* This code is based on the Master Password dialog in Firefox
+ * (pref-masterpass.js)
+ * Original code triple-licensed under the MPL, GPL, and LGPL
+ * so is license-compatible with this file
+ */
+gdouble
+pw_strength (const gchar  *password,
+             const gchar **hint)
+{
+        gint length;
+        gint upper, lower, digit, misc;
+        gint i;
+        gdouble strength;
+
+        length = strlen (password);
+        upper = 0;
+        lower = 0;
+        digit = 0;
+        misc = 0;
+
+        if (length < MIN_PASSWORD_LEN) {
+                *hint = C_("Password strength", "Too short");
+                return 0.0;
+        }
+
+        for (i = 0; i < length ; i++) {
+                if (g_ascii_isdigit (password[i]))
+                        digit++;
+                else if (g_ascii_islower (password[i]))
+                        lower++;
+                else if (g_ascii_isupper (password[i]))
+                        upper++;
+                else
+                        misc++;
+        }
+
+        if (length > 5)
+                length = 5;
+
+        if (digit > 3)
+                digit = 3;
+
+        if (upper > 3)
+                upper = 3;
+
+        if (misc > 3)
+                misc = 3;
+
+        strength = ((length * 0.1) - 0.2) +
+                    (digit * 0.1) +
+                    (misc * 0.15) +
+                    (upper * 0.1);
+
+        strength = CLAMP (strength, 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");
+
+        return strength;
+}
diff --git a/panels/user-accounts/pw-utils.h b/panels/user-accounts/pw-utils.h
new file mode 100644
index 0000000..9e4ad0b
--- /dev/null
+++ b/panels/user-accounts/pw-utils.h
@@ -0,0 +1,27 @@
+/* -*- 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 <glib.h>
+
+gint     pw_min_length (void);
+gchar   *pw_generate   (void);
+gdouble  pw_strength   (const gchar  *password,
+                        const gchar **hint);
diff --git a/panels/user-accounts/um-password-dialog.c b/panels/user-accounts/um-password-dialog.c
index f0544de..991756b 100644
--- a/panels/user-accounts/um-password-dialog.c
+++ b/panels/user-accounts/um-password-dialog.c
@@ -35,8 +35,7 @@
 #include "cc-strength-bar.h"
 #include "um-utils.h"
 #include "run-passwd.h"
-
-#define MIN_PASSWORD_LEN 6
+#include "pw-utils.h"
 
 struct _UmPasswordDialog {
         GtkWidget *dialog;
@@ -69,52 +68,14 @@ static void
 generate_one_password (GtkWidget        *widget,
                        UmPasswordDialog *um)
 {
-        gint min_len, max_len;
-        gchar *output, *err, *cmdline, *p;
-        gint status;
-        GError *error;
-
-        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (um->show_password_button), TRUE);
-
-        if (um->generated && um->generated[um->next_generated]) {
-                gtk_entry_set_text (GTK_ENTRY (um->password_entry), um->generated[um->next_generated]);
-                gtk_entry_set_text (GTK_ENTRY (um->verify_entry), "");
-                um->next_generated++;
-                return;
-        }
-
-        g_strfreev (um->generated);
-        um->generated = NULL;
-        um->next_generated = 0;
+        gchar *pwd;
 
-        min_len = 6;
-        max_len = 12;
+        pwd = pw_generate ();
 
-        cmdline = g_strdup_printf ("apg -n 10 -M SNC -m %d -x %d", min_len, max_len);
-        error = NULL;
-        output = NULL;
-        err = NULL;
-        if (!g_spawn_command_line_sync (cmdline, &output, &err, &status, &error)) {
-                g_warning ("Failed to run apg: %s", error->message);
-                g_error_free (error);
-        } else if (WEXITSTATUS (status) == 0) {
-                p = output;
-                if (*p == '\n')
-                        p++;
-                if (p[strlen(p) - 1] == '\n')
-                        p[strlen(p) - 1] = '\0';
-                um->generated = g_strsplit (p, "\n", -1);
-
-                gtk_entry_set_text (GTK_ENTRY (um->password_entry), um->generated[0]);
-                gtk_entry_set_text (GTK_ENTRY (um->verify_entry), "");
-                um->next_generated = 1;
-        } else {
-                g_warning ("agp returned an error: %s", err);
-        }
+        gtk_entry_set_text (GTK_ENTRY (um->password_entry), pwd);
+        gtk_entry_set_text (GTK_ENTRY (um->verify_entry), "");
 
-        g_free (cmdline);
-        g_free (output);
-        g_free (err);
+        g_free (pwd);
 }
 
 static void
@@ -140,58 +101,6 @@ populate_menu (GtkEntry         *entry,
         gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 }
 
-/* This code is based on the Master Password dialog in Firefox
- * (pref-masterpass.js)
- * Original code triple-licensed under the MPL, GPL, and LGPL
- * so is license-compatible with this file
- */
-static gdouble
-compute_password_strength (const gchar *password)
-{
-        gint length;
-        gint upper, lower, digit, misc;
-        gint i;
-        gdouble strength;
-
-        length = strlen (password);
-        upper = 0;
-        lower = 0;
-        digit = 0;
-        misc = 0;
-
-        for (i = 0; i < length ; i++) {
-                if (g_ascii_isdigit (password[i]))
-                        digit++;
-                else if (g_ascii_islower (password[i]))
-                        lower++;
-                else if (g_ascii_isupper (password[i]))
-                        upper++;
-                else
-                        misc++;
-        }
-
-        if (length > 5)
-                length = 5;
-
-        if (digit > 3)
-                digit = 3;
-
-        if (upper > 3)
-                upper = 3;
-
-        if (misc > 3)
-                misc = 3;
-
-        strength = ((length * 0.1) - 0.2) +
-                    (digit * 0.1) +
-                    (misc * 0.15) +
-                    (upper * 0.1);
-
-        strength = CLAMP (strength, 0.0, 1.0);
-
-        return strength;
-}
-
 static void
 finish_password_change (UmPasswordDialog *um)
 {
@@ -322,8 +231,7 @@ update_sensitivity (UmPasswordDialog *um)
         verify = gtk_entry_get_text (GTK_ENTRY (um->verify_entry));
         old_password = gtk_entry_get_text (GTK_ENTRY (um->old_password_entry));
 
-        /* TODO: configurable policies for acceptable passwords */
-        if (strlen (password) < MIN_PASSWORD_LEN) {
+        if (strlen (password) < pw_min_length ()) {
                 can_change = FALSE;
                 if (password[0] == '\0') {
                         tooltip = _("You need to enter a new password");
@@ -411,23 +319,7 @@ update_password_strength (UmPasswordDialog *um)
 
         password = gtk_entry_get_text (GTK_ENTRY (um->password_entry));
 
-        strength = compute_password_strength (password);
-
-        if (strlen (password) < MIN_PASSWORD_LEN) {
-                strength = 0.0;
-                if (password[0] == '\0')
-                        hint = "";
-                else
-                        hint = C_("Password strength", "Too short");
-        }
-        else 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");
+        strength = pw_strength (password, &hint);
 
         cc_strength_bar_set_fraction (CC_STRENGTH_BAR (um->strength_indicator), strength);
         gtk_label_set_label (GTK_LABEL (um->strength_indicator_label), hint);



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