|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 8402 (0x20d2)
Types: TextFile
Names: »goodpass.c«
└─⟦4f9d7c866⟧ Bits:30007245 EUUGD6: Sikkerheds distributionen
└─⟦123909933⟧ »./npasswd/npasswd.tar.Z«
└─⟦22a202e7d⟧
└─⟦this⟧ »npass-new/cracklib/goodpass.c«
└─⟦this⟧ »npass-new/npasswd_jpl/cracklib/goodpass.c«
#include <ctype.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <sys/file.h>
/*
* goodpass.c : A simple yes/no password sensibility function to be wired
* into "passwd" & "yppasswd", etc. (c) ADE Muffett, 1991 (aem@aber.ac.uk).
* This module is freely redistributable for use in software so long as this
* copyright notice remains intact. Distributed as part of the 'Crack' suite
* of password testing programs.
*/
/* Usage:- */
/* char *result = GoodPass(char *password); */
/* where password is a text string to be tested for suitability */
/* GoodPass returns NULL if the password is OK */
/* GoodPass returns a diagnostic string if the password is NOT ok */
#define PWLENGTH 8 /* significant length of text */
#define MINDIFF 5 /* minimum number of different characters */
#define MAXSTEP 3 /* max number of steps up/down in char set */
#define MINLENGTH 6 /* minimum length of a password */
#define STRINGSIZE 255 /* a standard buffer size */
#define STRIDE 4 /* word skipping length */
char *dikshunarys[100] = /* dank 7 Sept 91 - see add_dict() */
{
NULL
};
static int
Pmatch (control, string)
char *control;
char *string;
{
while (*control)
{
if (!*string)
{
return (0);
}
switch (*control)
{
case 'u':
if (!isupper (*string))
{
return (0);
}
break;
case 'l':
if (!islower (*string))
{
return (0);
}
break;
case 'd':
if (!isdigit (*string))
{
return (0);
}
break;
case 'c':
if (!isalpha (*string))
{
return (0);
}
break;
case '.':
default:
if (!isalnum (*string))
{
return (0);
}
break;
}
control++;
string++;
}
return (1);
}
static void
Trim (string) /* remove trailing whitespace from a string */
register char *string;
{
register char *ptr;
for (ptr = string; *ptr; ptr++);
while ((--ptr >= string) && isspace (*ptr));
*(++ptr) = '\0';
}
static char *
Reverse (str) /* return a pointer to a reversal */
register char *str;
{
register int i;
register int j;
register char *ptr;
static char area[STRINGSIZE];
j = i = strlen (str);
while (*str)
{
area[--i] = *str++;
}
area[j] = '\0';
return (area);
}
/******* THE TEST FUNCTION *******/
static int
Try (input, guess)
register char *input;
register char *guess;
{
if (!strncasecmp (input, guess, PWLENGTH) ||
!strncasecmp (input, Reverse (guess), PWLENGTH))
{
return (-1);
}
return (0);
}
/******* DICTIONARY SEARCHING *******/
static int
GetWord (fp, buff)
FILE *fp;
char *buff;
{
register int c;
for (;;)
{
c = getc (fp);
if (c == EOF)
{
return (-1);
}
if (c == '\n')
{
break;
}
*(buff++) = (char) c;
}
*buff = 0;
return (0);
}
static int
DictSearch (input)
char *input;
{
int i;
int loops;
register long top;
register long bot;
register long mid;
long scratch;
char word[STRINGSIZE];
FILE *fp;
char **dictionary;
for (dictionary = dikshunarys; *dictionary; dictionary++)
{
#ifdef DEBUG
printf("Checking dictionary %s\n", *dictionary);
#endif
if (!(fp = fopen (*dictionary, "r")))
{
perror (*dictionary);
continue;
}
bot = 0L; /* start of file */
fseek (fp, 0L, 2); /* to end of file */
top = ftell (fp);
for (loops = 0; loops < 1000; loops++)
{
mid = (top + bot) / 2; /* calculate the middle */
scratch = mid;
stride_loop:
scratch -= STRIDE; /* calculate a bit beforehand */
if (scratch < 0) /* error fixing */
{
mid = scratch = 0L;
fseek (fp, 0L, 0);
} else
{ /* find the start of the current word */
fseek (fp, scratch, 0); /* go read the scratch buffer */
fread (word, 1, STRIDE, fp);
for (i = STRIDE - 1; i >= 0; i--)
{
if (word[i] == '\n') /* where 'mid' is is start of
* word */
{
break;
} else
{ /* mid is between words */
mid--;
}
}
if (i < 0)
{
goto stride_loop;
}
}
fseek (fp, mid, 0);
GetWord (fp, word);
i = strncasecmp (input, word, PWLENGTH);
if (i > 0)
{
bot = mid + strlen (word) + 1; /* why retest this word ever */
} else if (i < 0)
{
if (mid >= top)
{
break;
}
top = mid;
} else
{
fclose (fp);
return (-1); /* found it */
}
}
fclose (fp);
}
return (0);
}
/******* THE EXTERNAL CALL *******/
char *
GoodPass (input)
char *input;
{
register int i;
register char *ptr;
register char *ptr2;
struct passwd *pwd;
char junk[STRINGSIZE];
char password[STRINGSIZE];
/* back it up. */
strcpy (password, input);
Trim (password);
/* who is it ? */
pwd = getpwuid (getuid ());
if (!pwd)
{
perror ("getpwuid");
return ("Error - no password entry found to verify against.");
}
/* size */
if (strlen (password) < MINLENGTH)
{
return ("it is too short - use more characters.");
}
/* username */
if (Try (password, pwd -> pw_name))
{
return ("it is your username");
}
/* usernameusername */
strcpy (junk, pwd -> pw_name);
strcat (junk, pwd -> pw_name);
if (Try (password, junk))
{
return ("it is your username, doubled");
}
/* Gecos information field */
strcpy (junk, pwd -> pw_gecos);
ptr = junk;
if (*ptr == '-') /* never seen this, but... */
{
ptr++;
}
if (ptr2 = strchr (ptr, ';')) /* trim off junk */
{
*ptr2 = '\0';
}
if (ptr2 = strchr (ptr, ',')) /* trim off more junk */
{
*ptr2 = '\0';
}
for (;;)
{
if (ptr2 = strchr (ptr, ' '))
{
*(ptr2++) = '\0';
}
if (Try (password, ptr))
{
return ("it is part of your name. Use something less obvious.");
}
if (ptr2)
{
ptr = ptr2;
while (*ptr && isspace (*ptr))
{
ptr++;
}
} else
{
break;
}
}
/* check for repeated characters */
bzero (junk, sizeof (junk));
for (i = 0; i < PWLENGTH && password[i]; i++)
{
if (!strchr (junk, password[i]))
{
strncat (junk, password + i, 1);
}
}
if (strlen (junk) < MINDIFF)
{
return ("it does not contain enough different characters.\nUse more different characters.");
}
/* check for over simplicity */
i = 0;
ptr = password;
while (ptr[0] && ptr[1])
{
if ((ptr[1] == (ptr[0] + 1)) ||
(ptr[0] == (ptr[1] + 1)))
{
i++;
}
ptr++;
}
if (i > MAXSTEP)
{
return ("it is too simplistic. Try something more random.");
}
/* lets get a little silly... */
if (Pmatch ("cdddccc", password))
{
return ("it looks like a new style car registration.");
}
if (Pmatch ("cccdddc", password))
{
return ("it looks like a old style car registration.");
}
if (Pmatch ("cccddd", password) || Pmatch ("dddccc", password))
{
return ("it looks like an old-style car registration.");
}
if (Pmatch ("ccddddddc", password))
{
return ("it looks like a National Insurance number.");
}
strcpy (junk, input);
/* do a dictionary search here */
if (DictSearch (junk))
{
return ("it is a guessable dictionary word.");
}
if (DictSearch (Reverse (junk)))
{
return ("it is a guessable reversed dictionary word.");
}
/* strip off possible initial number and do a dictionary search here */
if (isdigit (junk[0]))
{
if (DictSearch (junk + 1))
{
return ("it is a digit + guessable dictionary word.");
}
if (DictSearch (Reverse (junk + 1)))
{
return ("it is a digit + guessable reversed dictionary word.");
}
}
i = strlen (junk) - 1;
if (isdigit (junk[i]))
{
junk[i] = '\0';
if (DictSearch (junk))
{
return ("it is a guessable dictionary word + digit.");
}
if (DictSearch (Reverse (junk)))
{
return ("it is a guessable reversed dictionary word + digit.");
}
} else if (junk[i] == 's')
{
junk[i] = '\0';
if (DictSearch (junk))
{
return ("it is a pluralised dictionary word.");
}
}
return ((char *) NULL);
}
#ifdef DEBUG_MAIN
main (argc, argv)
int argc;
char *argv[];
{
int i;
char *p;
for (i = 1; i < argc; i++)
{
printf ("'%s'\n", argv[i]);
if (p = GoodPass (argv[i]))
{
printf ("\t%s\n", p);
} else
{
printf ("\tok\n");
}
}
}
#endif