password checking (was Re: System Security)
Chris Torek
chris at mimsy.UUCP
Fri Dec 9 15:23:34 AEST 1988
In article <375 at stca77.stc.oz> peter at stca77.stc.oz (Peter Jeremy) writes:
>... other logical approach is an improved PASSWD(1) program that prevents
>users using trivial passwords. Does anyone have such a beast? What is
>a good (quick*) way of deciding whether a password is trivial?
The following code fragments are from a local password checker. (This
is used when setting up accounts for the first time. The requester
types the password into a `form', and no one ever sees it. No staff
have access to the original unencrypted password [unless of course
we hack the programs :-) ].)
This is the verifier itself. try() should compare forwards and
backwards, case-independent. The `hard' part is the dictionary lookup
code (here NOT taken from /usr/bin/look); that is appended.
if (strlen(p) < 6) {
gripe("Must be at least 6 characters");
return (0);
}
if (alldigits(p)) {
gripe("Must have at least one non-digit");
return (0);
}
/* Try login name */
if (try(Fields[X_LOGIN].e_space, p))
goto tooeasy;
/* Try full name, all pieces */
strcpy(buf, Fields[X_FULLNAME].e_space);
for (np = buf; np && *np;) {
if ((sp = strchr(np, ' ')) != NULL)
*sp = 0;
if (try(np, p))
goto tooeasy;
np = sp ? sp + 1 : NULL;
}
/* Try word lists */
if (lookup(p, dictionary) || lookup(p, localdict) ||
lookup(p, badpasswds))
goto tooeasy;
...
tooeasy:
gripe("Too easy to guess");
return (0);
Here is the dictionary binary-search code. N.B.: there is a hard
limit on 9 characters for the key (this is enforced by the caller).
FILE *wordfile;
/*
* Perform a case independent binary search for target in the (sorted) word
* list in file filenam.
*/
lookup(target, filenam)
char *target, *filenam;
{
register int c;
long high, low, mid;
char key[10], word[80];
#define CMP(s, t) (*(s) == *(t) ? strcmp((s), (t)) : *(s) - *(t))
if (wordfile != NULL)
fclose(wordfile);
if ((wordfile = fopen(filenam, "r")) == NULL)
return (0);
strcpy(key, target);
lower(key);
low = 0;
fseek(wordfile, 0L, 2);
high = ftell(wordfile);
for (;;) {
mid = (high + low) >> 1;
fseek(wordfile, mid, 0);
do {
mid++;
c = getc(wordfile);
} while (c != EOF && c != '\n');
if (!getword(word))
break;
c = CMP(key, word);
if (c == 0) /* found it */
return (1);
if (c < 0) { /* too far */
if (high == mid)
break; /* stop spinning the wheels */
high = mid;
} else /* not far enough */
low = mid;
}
/*
* at this point we've narrowed the range as much as we can; now
* search until either we find the word, or we go past the key.
*/
fseek(wordfile, low, 0);
for (;;) {
if (!getword(word))
return (0);
c = CMP(key, word);
if (c < 0)
return (0);
if (c == 0)
return (1);
}
#undef CMP
}
/*
* Read a word and lowercasify it.
*/
getword(w)
char *w;
{
register char *p = w;
register int c;
while ((c = getc(wordfile)) != '\n') {
if (c == EOF)
if (p == w)
return (0);
else
break;
*p++ = c;
}
*p = 0;
lower(w);
return (1);
}
/*
* Lowercasify a word.
*/
lower(s)
register char *s;
{
register int c;
while ((c = *s) != 0) {
if (isupper(c))
*s = tolower(c);
s++;
}
}
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at mimsy.umd.edu Path: uunet!mimsy!chris
More information about the Comp.unix.wizards
mailing list