home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / hacking / unix / crackunx.txt / Sources / crack-lib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-25  |  13.8 KB  |  747 lines

  1. /*
  2.  * This program is copyright Alec Muffett 1991 except for some portions of
  3.  * code in "crack-fcrypt.c" which are copyright Robert Baldwin, Icarus Sparry
  4.  * and Alec Muffett.  The author(s) disclaims all responsibility or liability
  5.  * with respect to it's usage or its effect upon hardware or computer
  6.  * systems, and maintain copyright as set out in the "LICENCE" document which
  7.  * accompanies distributions of Crack v4.0 and upwards.
  8.  */
  9.  
  10. #include "crack.h"
  11.  
  12. #define RULE_NOOP    ':'
  13. #define RULE_PREPEND    '^'
  14. #define RULE_APPEND    '$'
  15. #define RULE_REVERSE    'r'
  16. #define RULE_UPPERCASE    'u'
  17. #define RULE_LOWERCASE    'l'
  18. #define RULE_PLURALISE    'p'
  19. #define RULE_CAPITALISE    'c'
  20. #define RULE_DUPLICATE    'd'
  21. #define RULE_REFLECT    'f'
  22. #define RULE_SUBSTITUTE    's'
  23. #define RULE_MATCH    '/'
  24. #define RULE_NOT    '!'
  25. #define RULE_LT        '<'
  26. #define RULE_GT        '>'
  27. #define RULE_EXTRACT    'x'
  28. #define RULE_OVERSTRIKE    'o'
  29. #define RULE_INSERT    'i'
  30. #define RULE_EQUALS    '='
  31. #define RULE_PURGE    '@'
  32. #define RULE_CLASS    '?'    /* class rule? socialist ethic in cracker? */
  33.  
  34. void
  35. Trim (string)            /* remove trailing whitespace from a string */
  36.     register char *string;
  37. {
  38.     register char *ptr;
  39.  
  40.     for (ptr = string; *ptr; ptr++);
  41.     while ((--ptr >= string) && isspace (*ptr));
  42.     *(++ptr) = '\0';
  43. }
  44.  
  45. char *
  46. Clone (string)
  47.     char *string;
  48. {
  49.     register char *retval;
  50.  
  51.     retval = (char *) malloc (strlen (string) + 1);
  52.     if (retval)
  53.     {
  54.     strcpy (retval, string);
  55.     }
  56.     return (retval);
  57. }
  58.  
  59. int
  60. Suffix (word, suffix)
  61.     char *word;
  62.     char *suffix;
  63. {
  64.     register int i;
  65.     register int j;
  66.  
  67.     i = strlen (word);
  68.     j = strlen (suffix);
  69.  
  70.     if (i > j)
  71.     {
  72.     return (STRCMP ((word + i - j), suffix));
  73.     } else
  74.     {
  75.     return (-1);
  76.     }
  77. }
  78.  
  79. char *
  80. Reverse (str)            /* return a pointer to a reversal */
  81.     register char *str;
  82. {
  83.     register int i;
  84.     register int j;
  85.     static char area[STRINGSIZE];
  86.  
  87.     j = i = strlen (str);
  88.     while (*str)
  89.     {
  90.     area[--i] = *str++;
  91.     }
  92.     area[j] = '\0';
  93.     return (area);
  94. }
  95.  
  96. char *
  97. Uppercase (str)            /* return a pointer to an uppercase */
  98.     register char *str;
  99. {
  100.     register char *ptr;
  101.     static char area[STRINGSIZE];
  102.  
  103.     ptr = area;
  104.     while (*str)
  105.     {
  106.     *(ptr++) = CRACK_TOUPPER (*str);
  107.     str++;
  108.     }
  109.     *ptr = '\0';
  110.  
  111.     return (area);
  112. }
  113.  
  114. char *
  115. Lowercase (str)            /* return a pointer to an lowercase */
  116.     register char *str;
  117. {
  118.     register char *ptr;
  119.     static char area[STRINGSIZE];
  120.  
  121.     ptr = area;
  122.     while (*str)
  123.     {
  124.     *(ptr++) = CRACK_TOLOWER (*str);
  125.     str++;
  126.     }
  127.     *ptr = '\0';
  128.  
  129.     return (area);
  130. }
  131.  
  132. char *
  133. Capitalise (str)        /* return a pointer to an capitalised */
  134.     register char *str;
  135. {
  136.     register char *ptr;
  137.     static char area[STRINGSIZE];
  138.  
  139.     ptr = area;
  140.  
  141.     while (*str)
  142.     {
  143.     *(ptr++) = CRACK_TOLOWER (*str);
  144.     str++;
  145.     }
  146.  
  147.     *ptr = '\0';
  148.     area[0] = CRACK_TOUPPER (area[0]);
  149.     return (area);
  150. }
  151.  
  152. char *
  153. Pluralise (string)        /* returns a pointer to a plural */
  154.     register char *string;
  155. {
  156.     register int length;
  157.     static char area[STRINGSIZE];
  158.  
  159.     length = strlen (string);
  160.     strcpy (area, string);
  161.  
  162.     if (!Suffix (string, "ch") ||
  163.     !Suffix (string, "ex") ||
  164.     !Suffix (string, "ix") ||
  165.     !Suffix (string, "sh") ||
  166.     !Suffix (string, "ss"))
  167.     {
  168.     /* bench -> benches */
  169.     strcat (area, "es");
  170.     } else if (length > 2 && string[length - 1] == 'y')
  171.     {
  172.     if (strchr ("aeiou", string[length - 2]))
  173.     {
  174.         /* alloy -> alloys */
  175.         strcat (area, "s");
  176.     } else
  177.     {
  178.         /* gully -> gullies */
  179.         strcpy (area + length - 1, "ies");
  180.     }
  181.     } else if (string[length - 1] == 's')
  182.     {
  183.     /* bias -> biases */
  184.     strcat (area, "es");
  185.     } else
  186.     {
  187.     /* catchall */
  188.     strcat (area, "s");
  189.     }
  190.  
  191.     return (area);
  192. }
  193.  
  194. char *
  195. Substitute (string, old, new)    /* returns pointer to a swapped about copy */
  196.     register char *string;
  197.     register char old;
  198.     register char new;
  199. {
  200.     register char *ptr;
  201.     static char area[STRINGSIZE];
  202.  
  203.     ptr = area;
  204.     while (*string)
  205.     {
  206.     *(ptr++) = (*string == old ? new : *string);
  207.     string++;
  208.     }
  209.     *ptr = '\0';
  210.     return (area);
  211. }
  212.  
  213. char *
  214. Purge (string, target)        /* returns pointer to a purged copy */
  215.     register char *string;
  216.     register char target;
  217. {
  218.     register char *ptr;
  219.     static char area[STRINGSIZE];
  220.  
  221.     ptr = area;
  222.     while (*string)
  223.     {
  224.     if (*string != target)
  225.     {
  226.         *(ptr++) = *string;
  227.     }
  228.     string++;
  229.     }
  230.     *ptr = '\0';
  231.     return (area);
  232. }
  233. /* -------- CHARACTER CLASSES START HERE -------- */
  234.  
  235. /*
  236.  * this function takes two inputs, a class identifier and a character, and
  237.  * returns non-null if the given character is a member of the class, based
  238.  * upon restrictions set out below
  239.  */
  240.  
  241. int
  242. MatchClass (class, input)
  243.     register char class;
  244.     register char input;
  245. {
  246.     register char c;
  247.     register int retval;
  248.  
  249.     retval = 0;
  250.  
  251.     switch (class)
  252.     {
  253.     /* ESCAPE */
  254.  
  255.     case '?':            /* ?? -> ? */
  256.     if (input == '?')
  257.     {
  258.         retval = 1;
  259.     }
  260.     break;
  261.  
  262.     /* ILLOGICAL GROUPINGS (ie: not in ctype.h) */
  263.  
  264.     case 'V':
  265.     case 'v':            /* vowels */
  266.     c = CRACK_TOLOWER (input);
  267.     if (strchr ("aeiou", c))
  268.     {
  269.         retval = 1;
  270.     }
  271.     break;
  272.  
  273.     case 'C':
  274.     case 'c':            /* consonants */
  275.     c = CRACK_TOLOWER (input);
  276.     if (strchr ("bcdfghjklmnpqrstvwxyz", c))
  277.     {
  278.         retval = 1;
  279.     }
  280.     break;
  281.  
  282.     case 'W':
  283.     case 'w':            /* whitespace */
  284.     if (strchr ("\t ", input))
  285.     {
  286.         retval = 1;
  287.     }
  288.     break;
  289.  
  290.     case 'P':
  291.     case 'p':            /* punctuation */
  292.     if (strchr (".`,:;'!?\"", input))
  293.     {
  294.         retval = 1;
  295.     }
  296.     break;
  297.  
  298.     case 'S':
  299.     case 's':            /* symbols */
  300.     if (strchr ("$%%^&*()-_+=|\\[]{}#@/~", input))
  301.     {
  302.         retval = 1;
  303.     }
  304.     break;
  305.  
  306.     /* LOGICAL GROUPINGS */
  307.  
  308.     case 'L':
  309.     case 'l':            /* lowercase */
  310.     if (islower (input))
  311.     {
  312.         retval = 1;
  313.     }
  314.     break;
  315.  
  316.     case 'U':
  317.     case 'u':            /* uppercase */
  318.     if (isupper (input))
  319.     {
  320.         retval = 1;
  321.     }
  322.     break;
  323.  
  324.     case 'A':
  325.     case 'a':            /* alphabetic */
  326.     if (isalpha (input))
  327.     {
  328.         retval = 1;
  329.     }
  330.     break;
  331.  
  332.     case 'X':
  333.     case 'x':            /* alphanumeric */
  334.     if (isalnum (input))
  335.     {
  336.         retval = 1;
  337.     }
  338.     break;
  339.  
  340.     case 'D':
  341.     case 'd':            /* digits */
  342.     if (isdigit (input))
  343.     {
  344.         retval = 1;
  345.     }
  346.     break;
  347.  
  348.     default:
  349.     Log ("MatchClass: unknown class %c\n", class);
  350.     return (0);
  351.     break;
  352.     }
  353.  
  354.     if (isupper (class))
  355.     {
  356.     return (!retval);
  357.     }
  358.     return (retval);
  359. }
  360.  
  361. char *
  362. PolyStrchr (string, class)
  363.     register char *string;
  364.     register char class;
  365. {
  366.     while (*string)
  367.     {
  368.     if (MatchClass (class, *string))
  369.     {
  370.         return (string);
  371.     }
  372.     string++;
  373.     }
  374.     return ((char *) 0);
  375. }
  376.  
  377. char *
  378. PolySubst (string, class, new)    /* returns pointer to a swapped about copy */
  379.     register char *string;
  380.     register char class;
  381.     register char new;
  382. {
  383.     register char *ptr;
  384.     static char area[STRINGSIZE];
  385.  
  386.     ptr = area;
  387.     while (*string)
  388.     {
  389.     *(ptr++) = (MatchClass (class, *string) ? new : *string);
  390.     string++;
  391.     }
  392.     *ptr = '\0';
  393.     return (area);
  394. }
  395.  
  396. char *
  397. PolyPurge (string, class)    /* returns pointer to a purged copy */
  398.     register char *string;
  399.     register char class;
  400. {
  401.     register char *ptr;
  402.     static char area[STRINGSIZE];
  403.  
  404.     ptr = area;
  405.     while (*string)
  406.     {
  407.     if (!MatchClass (class, *string))
  408.     {
  409.         *(ptr++) = *string;
  410.     }
  411.     string++;
  412.     }
  413.     *ptr = '\0';
  414.     return (area);
  415. }
  416. /* -------- BACK TO NORMALITY -------- */
  417.  
  418. int
  419. Char2Int (character)
  420.     char character;
  421. {
  422.     if (isdigit (character))
  423.     {
  424.     return (character - '0');
  425.     } else if (islower (character))
  426.     {
  427.     return (character - 'a' + 10);
  428.     } else if (isupper (character))
  429.     {
  430.     return (character - 'A' + 10);
  431.     }
  432.     return (-1);
  433. }
  434.  
  435. char *
  436. Mangle (input, control)        /* returns a pointer to a controlled Mangle */
  437.     char *input;
  438.     char *control;
  439. {
  440.     int limit;
  441.     register char *ptr;
  442.     static char area[STRINGSIZE];
  443.     char area2[STRINGSIZE];
  444.  
  445.     area[0] = '\0';
  446.     strcpy (area, input);
  447.  
  448.     for (ptr = control; *ptr; ptr++)
  449.     {
  450.     switch (*ptr)
  451.     {
  452.     case RULE_NOOP:
  453.         break;
  454.     case RULE_REVERSE:
  455.         strcpy (area, Reverse (area));
  456.         break;
  457.     case RULE_UPPERCASE:
  458.         strcpy (area, Uppercase (area));
  459.         break;
  460.     case RULE_LOWERCASE:
  461.         strcpy (area, Lowercase (area));
  462.         break;
  463.     case RULE_CAPITALISE:
  464.         strcpy (area, Capitalise (area));
  465.         break;
  466.     case RULE_PLURALISE:
  467.         strcpy (area, Pluralise (area));
  468.         break;
  469.     case RULE_REFLECT:
  470.         strcat (area, Reverse (area));
  471.         break;
  472.     case RULE_DUPLICATE:
  473.         strcpy (area2, area);
  474.         strcat (area, area2);
  475.         break;
  476.     case RULE_GT:
  477.         if (!ptr[1])
  478.         {
  479.         Log ("Mangle: '>' missing argument in '%s'\n", control);
  480.         return ((char *) 0);
  481.         } else
  482.         {
  483.         limit = Char2Int (*(++ptr));
  484.         if (limit < 0)
  485.         {
  486.             Log ("Mangle: '>' weird argument in '%s'\n", control);
  487.             return ((char *) 0);
  488.         }
  489.         if (strlen (area) <= limit)
  490.         {
  491.             return ((char *) 0);
  492.         }
  493.         }
  494.         break;
  495.     case RULE_LT:
  496.         if (!ptr[1])
  497.         {
  498.         Log ("Mangle: '<' missing argument in '%s'\n", control);
  499.         return ((char *) 0);
  500.         } else
  501.         {
  502.         limit = Char2Int (*(++ptr));
  503.         if (limit < 0)
  504.         {
  505.             Log ("Mangle: '<' weird argument in '%s'\n", control);
  506.             return ((char *) 0);
  507.         }
  508.         if (strlen (area) >= limit)
  509.         {
  510.             return ((char *) 0);
  511.         }
  512.         }
  513.         break;
  514.     case RULE_PREPEND:
  515.         if (!ptr[1])
  516.         {
  517.         Log ("Mangle: prepend missing argument in '%s'\n", control);
  518.         return ((char *) 0);
  519.         } else
  520.         {
  521.         area2[0] = *(++ptr);
  522.         strcpy (area2 + 1, area);
  523.         strcpy (area, area2);
  524.         }
  525.         break;
  526.     case RULE_APPEND:
  527.         if (!ptr[1])
  528.         {
  529.         Log ("Mangle: append missing argument in '%s'\n", control);
  530.         return ((char *) 0);
  531.         } else
  532.         {
  533.         register char *string;
  534.  
  535.         string = area;
  536.         while (*(string++));
  537.         string[-1] = *(++ptr);
  538.         *string = '\0';
  539.         }
  540.         break;
  541.     case RULE_EXTRACT:
  542.         if (!ptr[1] || !ptr[2])
  543.         {
  544.         Log ("Mangle: extract missing argument in '%s'\n", control);
  545.         return ((char *) 0);
  546.         } else
  547.         {
  548.         register int i;
  549.         int start;
  550.         int length;
  551.  
  552.         start = Char2Int (*(++ptr));
  553.         length = Char2Int (*(++ptr));
  554.         if (start < 0 || length < 0)
  555.         {
  556.             Log ("Mangle: extract: weird argument in '%s'\n", control);
  557.             return ((char *) 0);
  558.         }
  559.         strcpy (area2, area);
  560.         for (i = 0; length-- && area2[start + i]; i++)
  561.         {
  562.             area[i] = area2[start + i];
  563.         }
  564.         /* cant use strncpy() - no trailing NUL */
  565.         area[i] = '\0';
  566.         }
  567.         break;
  568.     case RULE_OVERSTRIKE:
  569.         if (!ptr[1] || !ptr[2])
  570.         {
  571.         Log ("Mangle: overstrike missing argument in '%s'\n", control);
  572.         return ((char *) 0);
  573.         } else
  574.         {
  575.         register int i;
  576.  
  577.         i = Char2Int (*(++ptr));
  578.         if (i < 0)
  579.         {
  580.             Log ("Mangle: overstrike weird argument in '%s'\n",
  581.              control);
  582.             return ((char *) 0);
  583.         } else
  584.         {
  585.             ++ptr;
  586.             if (area[i])
  587.             {
  588.             area[i] = *ptr;
  589.             }
  590.         }
  591.         }
  592.         break;
  593.     case RULE_INSERT:
  594.         if (!ptr[1] || !ptr[2])
  595.         {
  596.         Log ("Mangle: insert missing argument in '%s'\n", control);
  597.         return ((char *) 0);
  598.         } else
  599.         {
  600.         register int i;
  601.         register char *p1;
  602.         register char *p2;
  603.  
  604.         i = Char2Int (*(++ptr));
  605.         if (i < 0)
  606.         {
  607.             Log ("Mangle: insert weird argument in '%s'\n",
  608.              control);
  609.             return ((char *) 0);
  610.         }
  611.         p1 = area;
  612.         p2 = area2;
  613.         while (i && *p1)
  614.         {
  615.             i--;
  616.             *(p2++) = *(p1++);
  617.         }
  618.         *(p2++) = *(++ptr);
  619.         strcpy (p2, p1);
  620.         strcpy (area, area2);
  621.         }
  622.         break;
  623.         /* THE FOLLOWING RULES REQUIRE CLASS MATCHING */
  624.  
  625.     case RULE_PURGE:    /* @x or @?c */
  626.         if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
  627.         {
  628.         Log ("Mangle: delete missing arguments in '%s'\n", control);
  629.         return ((char *) 0);
  630.         } else if (ptr[1] != RULE_CLASS)
  631.         {
  632.         strcpy (area, Purge (area, *(++ptr)));
  633.         } else
  634.         {
  635.         strcpy (area, PolyPurge (area, ptr[2]));
  636.         ptr += 2;
  637.         }
  638.         break;
  639.     case RULE_SUBSTITUTE:    /* sxy || s?cy */
  640.         if (!ptr[1] || !ptr[2] || (ptr[1] == RULE_CLASS && !ptr[3]))
  641.         {
  642.         Log ("Mangle: subst missing argument in '%s'\n", control);
  643.         return ((char *) 0);
  644.         } else if (ptr[1] != RULE_CLASS)
  645.         {
  646.         strcpy (area, Substitute (area, ptr[1], ptr[2]));
  647.         ptr += 2;
  648.         } else
  649.         {
  650.         strcpy (area, PolySubst (area, ptr[2], ptr[3]));
  651.         ptr += 3;
  652.         }
  653.         break;
  654.     case RULE_MATCH:    /* /x || /?c */
  655.         if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
  656.         {
  657.         Log ("Mangle: '/' missing argument in '%s'\n", control);
  658.         return ((char *) 0);
  659.         } else if (ptr[1] != RULE_CLASS)
  660.         {
  661.         if (!strchr (area, *(++ptr)))
  662.         {
  663.             return ((char *) 0);
  664.         }
  665.         } else
  666.         {
  667.         if (!PolyStrchr (area, ptr[2]))
  668.         {
  669.             return ((char *) 0);
  670.         }
  671.         ptr += 2;
  672.         }
  673.         break;
  674.     case RULE_NOT:        /* !x || !?c */
  675.         if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
  676.         {
  677.         Log ("Mangle: '!' missing argument in '%s'\n", control);
  678.         return ((char *) 0);
  679.         } else if (ptr[1] != RULE_CLASS)
  680.         {
  681.         if (strchr (area, *(++ptr)))
  682.         {
  683.             return ((char *) 0);
  684.         }
  685.         } else
  686.         {
  687.         if (PolyStrchr (area, ptr[2]))
  688.         {
  689.             return ((char *) 0);
  690.         }
  691.         ptr += 2;
  692.         }
  693.         break;
  694.  
  695.         /*
  696.          * alternative use for a boomerang, number 1: a standard throwing
  697.          * boomerang is an ideal thing to use to tuck the sheets under
  698.          * the mattress when making your bed.  The streamlined shape of
  699.          * the boomerang allows it to slip easily 'twixt mattress and
  700.          * bedframe, and it's curve makes it very easy to hook sheets
  701.          * into the gap.
  702.          */
  703.  
  704.     case RULE_EQUALS:    /* =nx || =n?c */
  705.         if (!ptr[1] || !ptr[2] || (ptr[2] == RULE_CLASS && !ptr[3]))
  706.         {
  707.         Log ("Mangle: '=' missing argument in '%s'\n", control);
  708.         return ((char *) 0);
  709.         } else
  710.         {
  711.         register int i;
  712.  
  713.         if ((i = Char2Int (ptr[1])) < 0)
  714.         {
  715.             Log ("Mangle: '=' weird argument in '%s'\n", control);
  716.             return ((char *) 0);
  717.         }
  718.         if (ptr[2] != RULE_CLASS)
  719.         {
  720.             ptr += 2;
  721.             if (area[i] != *ptr)
  722.             {
  723.             return ((char *) 0);
  724.             }
  725.         } else
  726.         {
  727.             ptr += 3;
  728.             if (!MatchClass (*ptr, area[i]))
  729.             {
  730.             return ((char *) 0);
  731.             }
  732.         }
  733.         }
  734.         break;
  735.     default:
  736.         Log ("Mangle: unknown command %c in %s\n", *ptr, control);
  737.         return ((char *) 0);
  738.         break;
  739.     }
  740.     }
  741.     if (!area[0])        /* have we deweted de poor widdle fing away? */
  742.     {
  743.     return ((char *) 0);
  744.     }
  745.     return (area);
  746. }
  747.