home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume38 / shadow / part11 / obscure.c < prev    next >
C/C++ Source or Header  |  1993-08-14  |  4KB  |  230 lines

  1. /*
  2.  * Copyright 1989, 1990, 1991, 1992, 1993, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Permission is granted to copy and create derivative works for any
  6.  * non-commercial purpose, provided this copyright notice is preserved
  7.  * in all copies of source code, or included in human readable form
  8.  * and conspicuously displayed on all copies of object code or
  9.  * distribution media.
  10.  */
  11.  
  12. /*
  13.  * This version of obscure.c contains modifications to support "cracklib"
  14.  * by Alec Muffet (alec.muffett@uk.sun.com).  You must obtain the Cracklib
  15.  * library source code for this function to operate.
  16.  */
  17.  
  18. #include <ctype.h>
  19. #ifndef    BSD
  20. #include <string.h>
  21. #include <memory.h>
  22. #else
  23. #include <strings.h>
  24. #define    strchr    index
  25. #define    strrchr    rindex
  26. #endif
  27. #include "config.h"
  28.  
  29. #ifndef    lint
  30. static    char    sccsid[] = "@(#)obscure.c    3.7    18:10:59    03 Jul 1993";
  31. #endif
  32.  
  33. extern    int    getdef_bool();
  34. extern    int    getdef_num();
  35.  
  36. #ifdef    NEED_STRSTR
  37. /*
  38.  * strstr - find substring in string
  39.  */
  40.  
  41. char *
  42. strstr (string, pattern)
  43. char    *string;
  44. char    *pattern;
  45. {
  46.     char    *cp;
  47.     int    len;
  48.  
  49.     len = strlen (pattern);
  50.  
  51.     for (cp = string;cp = strchr (cp, *pattern);) {
  52.         if (strncmp (cp, pattern, len) == 0)
  53.             return cp;
  54.  
  55.         cp++;
  56.     }
  57.     return 0;
  58. }
  59. #endif
  60.  
  61. /*
  62.  * Obscure - see if password is obscure enough.
  63.  *
  64.  *    The programmer is encouraged to add as much complexity to this
  65.  *    routine as desired.  Included are some of my favorite ways to
  66.  *    check passwords.
  67.  */
  68.  
  69. /*ARGSUSED*/
  70. int    obscure (old, new)
  71. char    *old;
  72. char    *new;
  73. {
  74.     int    i;
  75.     char    oldmono[32];
  76.     char    newmono[32];
  77.     char    wrapped[64];
  78. #ifdef    CRACKLIB_DICTPATH
  79.     char    *msg;
  80.     char    *FascistCheck();
  81. #endif
  82.  
  83.     if (old[0] == '\0')
  84.         return (1);
  85.  
  86.     if ( strlen(new) < getdef_num("PASS_MIN_LEN", 0) ) {
  87.         printf ("Too short.  ");
  88.         return (0);
  89.     }
  90.  
  91.     /*
  92.      * Remaining checks are optional.
  93.      */
  94.     if ( !getdef_bool("OBSCURE_CHECKS_ENAB") )
  95.         return (1);
  96.  
  97.     for (i = 0;new[i];i++)
  98.         newmono[i] = tolower (new[i]);
  99.  
  100.     for (i = 0;old[i];i++)
  101.         oldmono[i] = tolower (old[i]); 
  102.  
  103.     if (strcmp (new, old) == 0) {    /* the same */
  104.         printf ("No Change.  ");
  105.         return (0);
  106.     }
  107.     if (palindrome (newmono, oldmono))    /* a palindrome */
  108.         return (0);
  109.  
  110.     if (strcmp (newmono, oldmono) == 0) {    /* case shifted */
  111.         printf ("Case changes only.  ");
  112.         return (0);
  113.     }
  114.     if (similiar (newmono, oldmono))    /* jumbled version */
  115.         return (0);
  116.  
  117.     if (simple (old, new))            /* keyspace size */
  118.         return (0);
  119.  
  120.     strcpy (wrapped, oldmono);
  121.     strcat (wrapped, oldmono);
  122.     if (strstr (wrapped, newmono)) {
  123.         printf ("Rotated.  ");
  124.         return (0);
  125.     }
  126. #ifdef CRACKLIB_DICTPATH    
  127.  
  128.     /*
  129.      * Invoke Alec Muffett's cracklib routines.
  130.      */
  131.  
  132.     if (msg = FascistCheck (new, CRACKLIB_DICTPATH)) {
  133.         printf("Bad Password: %s.  ", msg);
  134.         return (0);
  135.     }
  136. #endif /* CRACKLIB_DICTPATH */
  137.  
  138.     return (1);
  139. }
  140.  
  141. /*
  142.  * can't be a palindrome - like `R A D A R' or `M A D A M'
  143.  */
  144.  
  145. /*ARGSUSED*/
  146. int    palindrome (old, new)
  147. char    *old;
  148. char    *new;
  149. {
  150.     int    i, j;
  151.  
  152.     i = strlen (new);
  153.  
  154.     for (j = 0;j < i;j++)
  155.         if (new[i - j - 1] != new[j])
  156.             return (0);
  157.  
  158.     printf ("A palindrome.  ");
  159.     return (1);
  160. }
  161.  
  162. /*
  163.  * more than half of the characters are different ones.
  164.  */
  165.  
  166. /*ARGSUSED*/
  167. int    similiar (old, new)
  168. char    *old;
  169. char    *new;
  170. {
  171.     int    i, j;
  172.     char    *strchr ();
  173.  
  174.     for (i = j = 0;new[i] && old[i];i++)
  175.         if (strchr (new, tolower (old[i])))
  176.             j++;
  177.  
  178.     if (i >= j * 2)
  179.         return (0);
  180.  
  181.     printf ("Too similiar.  ");
  182.     return (1);
  183. }
  184.  
  185. /*
  186.  * a nice mix of characters.
  187.  */
  188.  
  189. /*ARGSUSED*/
  190. int    simple (old, new)
  191. char    *old;
  192. char    *new;
  193. {
  194.     int    digits = 0;
  195.     int    uppers = 0;
  196.     int    lowers = 0;
  197.     int    others = 0;
  198.     int    size;
  199.     int    i;
  200.  
  201.     for (i = 0;new[i];i++) {
  202.         if (isdigit (new[i]))
  203.             digits++;
  204.         else if (isupper (new[i]))
  205.             uppers++;
  206.         else if (islower (new[i]))
  207.             lowers++;
  208.         else
  209.             others++;
  210.     }
  211.  
  212.     /*
  213.      * The scam is this - a password of only one character type
  214.      * must be 8 letters long.  Two types, 7, and so on.
  215.      */
  216.  
  217.     size = 9;
  218.     if (digits) size--;
  219.     if (uppers) size--;
  220.     if (lowers) size--;
  221.     if (others) size--;
  222.  
  223.     if (size <= i)
  224.         return 0;
  225.  
  226.     printf ("Too Simple.  Use a longer password, or a mix of upper\n");
  227.     printf ("and lower case letters and numerics.  ");
  228.     return 1;
  229. }
  230.