|
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