Line |
Branch |
Exec |
Source |
1 |
|
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- |
2 |
|
|
* |
3 |
|
|
* Copyright 2012 Red Hat, Inc, |
4 |
|
|
* |
5 |
|
|
* This program is free software; you can redistribute it and/or modify |
6 |
|
|
* it under the terms of the GNU General Public License as published by |
7 |
|
|
* the Free Software Foundation; either version 2 of the License, or |
8 |
|
|
* (at your option) any later version. |
9 |
|
|
* |
10 |
|
|
* This program is distributed in the hope that it will be useful, |
11 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
|
|
* GNU General Public License for more details. |
14 |
|
|
* |
15 |
|
|
* You should have received a copy of the GNU General Public License |
16 |
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>. |
17 |
|
|
* |
18 |
|
|
* Written by: Matthias Clasen <mclasen@redhat.com> |
19 |
|
|
*/ |
20 |
|
|
|
21 |
|
|
#include "config.h" |
22 |
|
|
|
23 |
|
|
#include "pw-utils.h" |
24 |
|
|
|
25 |
|
|
#include <glib.h> |
26 |
|
|
#include <glib/gi18n.h> |
27 |
|
|
|
28 |
|
|
#include <pwquality.h> |
29 |
|
|
|
30 |
|
|
static pwquality_settings_t * |
31 |
|
✗ |
get_pwq (void) |
32 |
|
|
{ |
33 |
|
|
static pwquality_settings_t *settings; |
34 |
|
|
|
35 |
|
✗ |
if (settings == NULL) { |
36 |
|
✗ |
gchar *err = NULL; |
37 |
|
✗ |
gint rv = 0; |
38 |
|
|
|
39 |
|
✗ |
settings = pwquality_default_settings (); |
40 |
|
✗ |
pwquality_set_int_value (settings, PWQ_SETTING_MAX_SEQUENCE, 4); |
41 |
|
|
|
42 |
|
✗ |
rv = pwquality_read_config (settings, NULL, (gpointer)&err); |
43 |
|
✗ |
if (rv < 0) { |
44 |
|
✗ |
g_warning ("failed to read pwquality configuration: %s\n", |
45 |
|
|
pwquality_strerror (NULL, 0, rv, err)); |
46 |
|
✗ |
pwquality_free_settings (settings); |
47 |
|
|
|
48 |
|
|
/* Load just default settings in case of failure. */ |
49 |
|
✗ |
settings = pwquality_default_settings (); |
50 |
|
✗ |
pwquality_set_int_value (settings, PWQ_SETTING_MAX_SEQUENCE, 4); |
51 |
|
|
} |
52 |
|
|
} |
53 |
|
|
|
54 |
|
✗ |
return settings; |
55 |
|
|
} |
56 |
|
|
|
57 |
|
|
gint |
58 |
|
✗ |
pw_min_length (void) |
59 |
|
|
{ |
60 |
|
✗ |
gint value = 0; |
61 |
|
|
gint rv; |
62 |
|
|
|
63 |
|
✗ |
rv = pwquality_get_int_value (get_pwq (), PWQ_SETTING_MIN_LENGTH, &value); |
64 |
|
✗ |
if (rv < 0) { |
65 |
|
✗ |
g_warning ("Failed to read pwquality setting: %s\n", |
66 |
|
|
pwquality_strerror (NULL, 0, rv, NULL)); |
67 |
|
|
} |
68 |
|
|
|
69 |
|
✗ |
return value; |
70 |
|
|
} |
71 |
|
|
|
72 |
|
|
gchar * |
73 |
|
✗ |
pw_generate (void) |
74 |
|
|
{ |
75 |
|
|
gchar *res; |
76 |
|
|
gint rv; |
77 |
|
|
|
78 |
|
✗ |
rv = pwquality_generate (get_pwq (), 0, &res); |
79 |
|
|
|
80 |
|
✗ |
if (rv < 0) { |
81 |
|
✗ |
g_warning ("Password generation failed: %s\n", |
82 |
|
|
pwquality_strerror (NULL, 0, rv, NULL)); |
83 |
|
✗ |
return NULL; |
84 |
|
|
} |
85 |
|
|
|
86 |
|
✗ |
return res; |
87 |
|
|
} |
88 |
|
|
|
89 |
|
|
static const gchar * |
90 |
|
✗ |
pw_error_hint (gint error) |
91 |
|
|
{ |
92 |
|
✗ |
switch (error) { |
93 |
|
✗ |
case PWQ_ERROR_SAME_PASSWORD: |
94 |
|
✗ |
return C_("Password hint", "The new password needs to be different from the old one."); |
95 |
|
✗ |
case PWQ_ERROR_CASE_CHANGES_ONLY: |
96 |
|
✗ |
return C_("Password hint", "Try changing some letters and numbers."); |
97 |
|
✗ |
case PWQ_ERROR_TOO_SIMILAR: |
98 |
|
✗ |
return C_("Password hint", "Try changing the password a bit more."); |
99 |
|
✗ |
case PWQ_ERROR_USER_CHECK: |
100 |
|
✗ |
return C_("Password hint", "A password without your user name would be stronger."); |
101 |
|
✗ |
case PWQ_ERROR_GECOS_CHECK: |
102 |
|
✗ |
return C_("Password hint", "Try to avoid using your name in the password."); |
103 |
|
✗ |
case PWQ_ERROR_BAD_WORDS: |
104 |
|
✗ |
return C_("Password hint", "Try to avoid some of the words included in the password."); |
105 |
|
✗ |
case PWQ_ERROR_ROTATED: |
106 |
|
✗ |
return C_("Password hint", "Try changing the password a bit more."); |
107 |
|
✗ |
case PWQ_ERROR_CRACKLIB_CHECK: |
108 |
|
✗ |
return C_("Password hint", "Try to avoid common words."); |
109 |
|
✗ |
case PWQ_ERROR_PALINDROME: |
110 |
|
✗ |
return C_("Password hint", "Try to avoid reordering existing words."); |
111 |
|
✗ |
case PWQ_ERROR_MIN_DIGITS: |
112 |
|
✗ |
return C_("Password hint", "Try to use more numbers."); |
113 |
|
✗ |
case PWQ_ERROR_MIN_UPPERS: |
114 |
|
✗ |
return C_("Password hint", "Try to use more uppercase letters."); |
115 |
|
✗ |
case PWQ_ERROR_MIN_LOWERS: |
116 |
|
✗ |
return C_("Password hint", "Try to use more lowercase letters."); |
117 |
|
✗ |
case PWQ_ERROR_MIN_OTHERS: |
118 |
|
✗ |
return C_("Password hint", "Try to use more special characters, like punctuation."); |
119 |
|
✗ |
case PWQ_ERROR_MIN_CLASSES: |
120 |
|
✗ |
return C_("Password hint", "Try to use a mixture of letters, numbers and punctuation."); |
121 |
|
✗ |
case PWQ_ERROR_MAX_CONSECUTIVE: |
122 |
|
✗ |
return C_("Password hint", "Try to avoid repeating the same character."); |
123 |
|
✗ |
case PWQ_ERROR_MAX_CLASS_REPEAT: |
124 |
|
✗ |
return C_("Password hint", "Try to avoid repeating the same type of character: you need to mix up letters, numbers and punctuation."); |
125 |
|
✗ |
case PWQ_ERROR_MAX_SEQUENCE: |
126 |
|
✗ |
return C_("Password hint", "Try to avoid sequences like 1234 or abcd."); |
127 |
|
✗ |
case PWQ_ERROR_MIN_LENGTH: |
128 |
|
✗ |
return C_("Password hint", "Password needs to be longer. Try to add more letters, numbers and punctuation."); |
129 |
|
✗ |
case PWQ_ERROR_EMPTY_PASSWORD: |
130 |
|
✗ |
return C_("Password hint", "Mix uppercase and lowercase and try to use a number or two."); |
131 |
|
✗ |
default: |
132 |
|
✗ |
return C_("Password hint", "Adding more letters, numbers and punctuation will make the password stronger."); |
133 |
|
|
} |
134 |
|
|
} |
135 |
|
|
|
136 |
|
|
gdouble |
137 |
|
✗ |
pw_strength (const gchar *password, |
138 |
|
|
const gchar *old_password, |
139 |
|
|
const gchar *username, |
140 |
|
|
const gchar **hint, |
141 |
|
|
gint *strength_level) |
142 |
|
|
{ |
143 |
|
✗ |
gint rv, level, length = 0; |
144 |
|
✗ |
gdouble strength = 0.0; |
145 |
|
|
void *auxerror; |
146 |
|
|
|
147 |
|
✗ |
rv = pwquality_check (get_pwq (), |
148 |
|
|
password, old_password, username, |
149 |
|
|
&auxerror); |
150 |
|
|
|
151 |
|
✗ |
if (password != NULL) |
152 |
|
✗ |
length = strlen (password); |
153 |
|
|
|
154 |
|
✗ |
strength = CLAMP (0.01 * rv, 0.0, 1.0); |
155 |
|
✗ |
if (rv < 0) { |
156 |
|
✗ |
level = (length > 0) ? 1 : 0; |
157 |
|
|
} |
158 |
|
✗ |
else if (strength < 0.50) { |
159 |
|
✗ |
level = 2; |
160 |
|
✗ |
} else if (strength < 0.75) { |
161 |
|
✗ |
level = 3; |
162 |
|
✗ |
} else if (strength < 0.90) { |
163 |
|
✗ |
level = 4; |
164 |
|
|
} else { |
165 |
|
✗ |
level = 5; |
166 |
|
|
} |
167 |
|
|
|
168 |
|
✗ |
if (length && length < pw_min_length()) |
169 |
|
✗ |
*hint = pw_error_hint (PWQ_ERROR_MIN_LENGTH); |
170 |
|
|
else |
171 |
|
✗ |
*hint = pw_error_hint (rv); |
172 |
|
|
|
173 |
|
✗ |
if (strength_level) |
174 |
|
✗ |
*strength_level = level; |
175 |
|
|
|
176 |
|
✗ |
return strength; |
177 |
|
|
} |
178 |
|
|
|