1 /* vi: set sw=4 ts=4: */
3 * Copyright 1989 - 1994, Julianne Frances Haugh <jockgrrl@austin.rr.com>
4 * Copyright 2006, Bernhard Fischer <busybox@busybox.net>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * This version of obscure.c contains modifications to support "cracklib"
34 * by Alec Muffet (alec.muffett@uk.sun.com). You must obtain the Cracklib
35 * library source code for this function to operate.
45 * can't be a palindrome - like `R A D A R' or `M A D A M'
48 static int palindrome(const char *newval)
54 for (j = 0; j < i; j++)
55 if (newval[i - j - 1] != newval[j])
62 * more than half of the characters are different ones.
65 static int similiar(const char *old, const char *newval)
69 for (i = j = 0; newval[i] && old[i]; i++)
70 if (strchr(newval, old[i]))
80 * a nice mix of characters.
83 static int simple(const char *newval)
93 for (i = 0; (c = *newval++) != 0; i++) {
105 * The scam is this - a password of only one character type
106 * must be 8 letters long. Two types, 7, and so on.
110 if (is_simple & digits)
112 if (is_simple & uppers)
114 if (is_simple & lowers)
116 if (is_simple & others)
129 static char *str_lower(char *string)
133 for (cp = string; *cp; cp++)
139 password_check(const char *old, const char *newval, const struct passwd *pwdp)
142 char *newmono, *wrapped;
145 if (strcmp(newval, old) == 0)
151 newmono = str_lower(bb_xstrdup(newval));
152 lenwrap = strlen(old);
153 wrapped = (char *) xmalloc(lenwrap * 2 + 1);
154 str_lower(strcpy(wrapped, old));
156 if (palindrome(newmono))
157 msg = "a palindrome";
159 else if (strcmp(wrapped, newmono) == 0)
160 msg = "case changes only";
162 else if (similiar(wrapped, newmono))
163 msg = "too similiar";
165 else if ( strstr(newval, pwdp->pw_name) )
166 msg = "don't use something like your username as password";
169 safe_strncpy(wrapped + lenwrap, wrapped, lenwrap + 1);
170 if (strstr(wrapped, newmono))
174 memset(newmono, 0, strlen(newmono));
175 memset(wrapped, 0, lenwrap * 2);
183 obscure_msg(const char *old, const char *newval, const struct passwd *pwdp)
185 int maxlen, oldlen, newlen;
189 oldlen = strlen(old);
190 newlen = strlen(newval);
192 #if 0 /* why not check the password when set for the first time? --marekm */
202 * Remaining checks are optional.
204 /* Not for us -- Sean
205 *if (!getdef_bool("OBSCURE_CHECKS_ENAB"))
208 msg = password_check(old, newval, pwdp);
212 /* The traditional crypt() truncates passwords to 8 chars. It is
213 possible to circumvent the above checks by choosing an easy
214 8-char password and adding some random characters to it...
215 Example: "password$%^&*123". So check it again, this time
216 truncated to the maximum length. Idea from npasswd. --marekm */
219 if (oldlen <= maxlen && newlen <= maxlen)
222 new1 = (char *) bb_xstrdup(newval);
223 old1 = (char *) bb_xstrdup(old);
229 msg = password_check(old1, new1, pwdp);
231 memset(new1, 0, newlen);
232 memset(old1, 0, oldlen);
240 * Obscure - see if password is obscure enough.
242 * The programmer is encouraged to add as much complexity to this
243 * routine as desired. Included are some of my favorite ways to
247 extern int obscure(const char *old, const char *newval, const struct passwd *pwdp)
249 const char *msg = obscure_msg(old, newval, pwdp);
253 printf("Bad password: %s.\n", msg);