1 /* vi: set sw=4 ts=4: */
3 * Copyright 1989 - 1994, Julianne Frances Haugh <jockgrrl@austin.rr.com>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * This version of obscure.c contains modifications to support "cracklib"
33 * by Alec Muffet (alec.muffett@uk.sun.com). You must obtain the Cracklib
34 * library source code for this function to operate.
44 * can't be a palindrome - like `R A D A R' or `M A D A M'
47 static int palindrome(const char *old, const char *newval)
53 for (j = 0; j < i; j++)
54 if (newval[i - j - 1] != newval[j])
61 * more than half of the characters are different ones.
64 static int similiar(const char *old, const char *newval)
68 for (i = j = 0; newval[i] && old[i]; i++)
69 if (strchr(newval, old[i]))
79 * a nice mix of characters.
82 static int simple(const char *old, const char *newval)
91 for (i = 0; newval[i]; i++) {
92 if (isdigit(newval[i]))
94 else if (isupper(newval[i]))
96 else if (islower(newval[i]))
103 * The scam is this - a password of only one character type
104 * must be 8 letters long. Two types, 7, and so on.
123 static char *str_lower(char *string)
127 for (cp = string; *cp; cp++)
132 static char *password_check(const char *old, const char *newval, const struct passwd *pwdp)
135 char *oldmono, *newmono, *wrapped;
137 if (strcmp(newval, old) == 0)
140 newmono = str_lower(xstrdup(newval));
141 oldmono = str_lower(xstrdup(old));
142 wrapped = (char *) xmalloc(strlen(oldmono) * 2 + 1);
143 strcpy(wrapped, oldmono);
144 strcat(wrapped, oldmono);
146 if (palindrome(oldmono, newmono))
147 msg = "a palindrome";
149 if (!msg && strcmp(oldmono, newmono) == 0)
150 msg = "case changes only";
152 if (!msg && similiar(oldmono, newmono))
153 msg = "too similiar";
155 if (!msg && simple(old, newval))
158 if (!msg && strstr(wrapped, newmono))
161 bzero(newmono, strlen(newmono));
162 bzero(oldmono, strlen(oldmono));
163 bzero(wrapped, strlen(wrapped));
171 static char *obscure_msg(const char *old, const char *newval, const struct passwd *pwdp)
173 int maxlen, oldlen, newlen;
174 char *new1, *old1, *msg;
176 oldlen = strlen(old);
177 newlen = strlen(newval);
179 #if 0 /* why not check the password when set for the first time? --marekm */
189 * Remaining checks are optional.
191 /* Not for us -- Sean
192 *if (!getdef_bool("OBSCURE_CHECKS_ENAB"))
195 msg = password_check(old, newval, pwdp);
199 /* The traditional crypt() truncates passwords to 8 chars. It is
200 possible to circumvent the above checks by choosing an easy
201 8-char password and adding some random characters to it...
202 Example: "password$%^&*123". So check it again, this time
203 truncated to the maximum length. Idea from npasswd. --marekm */
206 if (oldlen <= maxlen && newlen <= maxlen)
209 new1 = (char *) xstrdup(newval);
210 old1 = (char *) xstrdup(old);
216 msg = password_check(old1, new1, pwdp);
227 * Obscure - see if password is obscure enough.
229 * The programmer is encouraged to add as much complexity to this
230 * routine as desired. Included are some of my favorite ways to
234 extern int obscure(const char *old, const char *newval, const struct passwd *pwdp)
236 char *msg = obscure_msg(old, newval, pwdp);
240 printf("Bad password: %s.\n", msg);