home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / programs / kc9_src.arj / PWP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-07  |  27.6 KB  |  963 lines

  1. /****************************************************************************\
  2. **        Password Preprocesser v2.00 - Password Cracker Guess Mutator      **
  3. ** ======================================================================== **
  4. **                Sourcefile: pwp.c -- Last Update: 09/20/91                **
  5. ** ======================================================================== **
  6. **           Written By Doctor Dissector, Copyright (C) 1990, 1991          **
  7. ** ======================================================================== **
  8. **                   LIMITED EDITION -- DO NOT DISTRIBUTE                   **
  9. \****************************************************************************/
  10.  
  11. /*=[ License ]==============================================================*/
  12.  
  13. /*
  14. ** Password Preprocesser - Version 2.00
  15. ** Copyright (C) 1991 By Doctor Dissector
  16. **
  17. ** This program is NOT free software BUT may be used without charge or
  18. ** payment in any form IF your copy is a "registered" distributed version.
  19. ** You may modify it as much as you please, however, you MAY NOT re-
  20. ** distribute it, in any shape or for: ie. modified OR unmodified,
  21. ** without the expressed written consent (ie. e-mail) of
  22. ** Doctor Dissector.
  23. **
  24. ** This program was initially distributed in the hope that it will be
  25. ** useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  27. */
  28.  
  29. /*=[ Disclaimer ]===========================================================*/
  30.  
  31. /*
  32. **  The author of this package, Doctor Dissector, will not assume liability
  33. **  for ANY of the effects of the use or distribution of this package.  If
  34. **  you, at ANY time compile or use this package, you will assume full
  35. **  liability for your own actions; Doctor Dissector can neither enforce the
  36. **  lawful use of this package nor your actions before, during, or after
  37. **  exposure to this package.  Doctor Dissector does NOT endorse your unlawful
  38. **  use of this package to appropriate computer accounts not under your lawful
  39. **  ownership.
  40. **
  41. **  The original intent of this package was to prove that Un*x accounts can be
  42. **  easily, efficiently, and effectively cracked utilizing modified DES
  43. **  encryption routines and proper statistical, mathematical, logical, and
  44. **  programming skills.
  45. */
  46.  
  47. /*=[ Copyright ]============================================================*/
  48.  
  49. char pwp_c_msg[] = "Source: pwp.c, Copyright (C) 1990, 1991 By Doctor Dissector";
  50.  
  51. /*=[ Include Header Files ]=================================================*/
  52.  
  53. #include <stdio.h>
  54. #include <string.h>
  55. #include "pwp.h"
  56.  
  57. /*=[ Global Variables ]=====================================================*/
  58.  
  59. char progname[MAX_FILE];        /* calling name of the program */
  60.  
  61. int  double_w,                  /* double words?               0 = NO       */
  62.      gecos,                     /* use GECOS fields?           0 = NO       */
  63.      include,                   /* include sourcefile?         0 = NO       */
  64.      kc,                        /* killer cracker format?      0 = NO       */
  65.      logins,                    /* use login fields?           0 = NO       */
  66.      lowercase,                 /* all lowercase?              0 = NO       */
  67.      lowreverse,                /* lowercase & reverse?        0 = NO       */
  68.      minlength,                 /* minimum length              0 = Inactive */
  69.      nonalpha,                  /* minimum non-alpha chars     0 = Inactive */
  70.      novowels,                  /* remove vowels?              0 = NO       */
  71.      reverse,                   /* reverse?                    0 = NO       */
  72.      upchar,                    /* make one char uppercase     0 = Inactive */
  73.      uplast,                    /* last char uppercase?        0 = NO       */
  74.      uppercase,                 /* all uppercase?              0 = NO       */
  75.      upreverse,                 /* uppercase & reverse?        0 = NO       */
  76.      translate;                 /* character/character xlate?  0 = Inactive */
  77.  
  78. char prefixes[MAX_TAIL],        /* prefix characters */
  79.      suffixes[MAX_TAIL],        /* suffix characters */
  80.      xchar[MAX_XCHAR][2];       /* xlate character table */
  81.  
  82. /*==========================================================================*/
  83.  
  84. /*
  85. **     function: void print_usage(void)
  86. **  description: displays program usage & options
  87. **      returns: nothing
  88. */
  89.  
  90. void print_usage()
  91. {
  92.     printf("\n");
  93.     printf("Password Preprocesser, Version 2.00 (9/20/91)\n");
  94.     printf("Copyright (C) 1991, By Doctor Dissector\n");
  95.     printf("*** DO NOT DISTRIBUTE THIS VERSION ***\n\n");
  96.     printf("Brief:  Mutates a wordlist read from the standard input into other possible\n");
  97.     printf("        guesses for use with password 'crackers' and outputs the result to\n");
  98.     printf("        the standard output.\n\n");
  99.     printf("Usage:  %s [[flag] ...] < [wordlist|pwfile] > [resultfile]\n\n", progname);
  100.     printf("Flags:  -?                  display this usage menu\n");
  101.     printf("        -Double             doubles the original word\n");
  102.     printf("        -Gecos              create result words from GECOS fields of pwfile\n");
  103.     printf("        -Help               display this usage menu\n");
  104.     printf("        -Include            include original words into resultfile\n");
  105.     printf("        -Kc                 save login/GECOS words in KC9 'single-crack' form\n");
  106.     printf("        -LOGins             create result words from login fields of pwfile\n");
  107.     printf("        -LOWErcase          convert original words to lowercase\n");
  108.     printf("        -LOWReverse         convert original words to lowercase & reverse\n");
  109.     printf("        -Minlength:<#>      min length <#> of result words\n");
  110.     printf("        -NONalpha:<#>       min non-alphabetic chars <#> in result words\n");
  111.     printf("        -NOVowels           remove vowels from original words\n");
  112.     printf("        -Prefixes:<string>  prepend chars in <string> to original words\n");
  113.     printf("        -Reverse            reverse original words\n");
  114.     printf("        -Suffixes:<string>  append chars in <string> to original words\n");
  115.     printf("        -Translate:<o><n>   translate char <o> in original words char <n>\n");
  116.     printf("        -UPChar:<#>         convert char <#> in original words to uppercase\n");
  117.     printf("        -UPLast             convert last char in original words to uppercase\n");
  118.     printf("        -UPPercase          convert original words to uppercase\n");
  119.     printf("        -UPReverse          convert original words to uppercase & reverse\n\n");
  120. }
  121.  
  122. /*==========================================================================*/
  123.  
  124. /*
  125. **     function: void init_vars(void)
  126. **  description: pre-initialize global variables
  127. **      returns: nothing
  128. */
  129.  
  130. void init_vars()
  131. {
  132.     progname[0]=0;
  133.     double_w=0;
  134.     gecos=0;
  135.     include=0;
  136.     kc=0;
  137.     logins=0;
  138.     lowercase=0;
  139.     lowreverse=0;
  140.     minlength=0;
  141.     nonalpha=0;
  142.     novowels=0;
  143.     reverse=0;
  144.     translate=0;
  145.     upchar=0;
  146.     uplast=0;
  147.     uppercase=0;
  148.     upreverse=0;
  149.     prefixes[0]=0;
  150.     suffixes[0]=0;
  151. }
  152.  
  153. /*==========================================================================*/
  154.  
  155. /*
  156. **     function: void eexit(int exitcode, char *desc1, char *desc2)
  157. **  description: displays an exit/error message and exits with an exit
  158. **               code of <exitcode>
  159. **      returns: nothing
  160. */
  161.  
  162. void eexit(exitcode, desc1, desc2)
  163.     int  exitcode;
  164.     char *desc1, *desc2;
  165. {
  166.     fprintf(stderr, "\n%s: ", progname);
  167.     if (desc1)
  168.         fprintf(stderr, "%s", desc1);
  169.     else
  170.         fprintf(stderr, "abnormal program termination");
  171.     if (desc2)
  172.         fprintf(stderr, ": %s", desc2);
  173.     fprintf(stderr, "\n");
  174.     exit(exitcode);
  175. }
  176.  
  177. /*==========================================================================*/
  178.  
  179. /*
  180. **     function: int chstrnum(char xc, char *word)
  181. **  description: counts the number occurrances of <xc> in <word>
  182. **      returns: number of occurrances, 0 if none
  183. */
  184.  
  185. int chstrnum(xc, word)
  186.     char xc, *word;
  187. {
  188.     register int i;
  189.  
  190.     for(i=0; (*word); word++)
  191.         if (xc==(*word))
  192.             i++;
  193.     return(i);
  194. }
  195.  
  196. /*==========================================================================*/
  197.  
  198. /*
  199. **     function: char upcharacter(char c)
  200. **  description: converts <c> to an uppercase equivalent
  201. **      returns: uppercase <c> if any
  202. */
  203.  
  204. char upcharacter(c)
  205.     register char c;
  206. {
  207.     return((c>='a') && (c<='z') ? c-32 : c);
  208. }
  209.  
  210. /*==========================================================================*/
  211.  
  212. /*
  213. **     function: char *lowcase(char *str)
  214. **  description: converts <str> to its lowercase equivalent
  215. **      returns: lowercase of <str>
  216. */
  217.  
  218. char *lowcase(str)
  219.     register char *str;
  220. {
  221.     register char *ptr;
  222.     static   char s[MAX_WORD];
  223.  
  224.     ptr=s;
  225.     while(*str)
  226.         (*ptr++)=(((*str)>='A') && ((*str)<='Z') ? (*str++)+32 : (*str++));
  227.     *ptr=0;
  228.     return(s);
  229. }
  230.  
  231. /*==========================================================================*/
  232.  
  233. /*
  234. **     function: char *upcase(char *str)
  235. **  description: converts <str> to its uppercase equivalent
  236. **      returns: uppercase of <str>
  237. */
  238.  
  239. char *upcase(str)
  240.     register char *str;
  241. {
  242.     register char *ptr;
  243.     static   char s[MAX_WORD];
  244.  
  245.     ptr=s;
  246.     while(*str)
  247.         (*ptr++)=(((*str)>='a') && ((*str)<='z') ? (*str++)-32 : (*str++));
  248.     *ptr=0;
  249.     return(s);
  250. }
  251.  
  252. /*==========================================================================*/
  253.  
  254. /*
  255. **     function: char *reverse_string(char *str)
  256. **  description: reverse string <str>
  257. **      returns: the reverse of <str>
  258. */
  259.  
  260. char *reverse_string(str)
  261.     register char *str;
  262. {
  263.     register int  i, j;
  264.     static   char s[MAX_WORD];
  265.  
  266.     i=strlen(str);
  267.     s[i]=0;
  268.     while(*str)
  269.         s[--i]=(*str++);
  270.     return(s);
  271. }
  272.  
  273. /*==========================================================================*/
  274.  
  275. /*
  276. **     function: char *do_lowercase(char *word)
  277. **  description: creates lowercase equivalent of <word>
  278. **      returns: lowercase equivalent of <word> or "\0" if both words match
  279. */
  280.  
  281. char *do_lowercase(word)
  282.     char *word;
  283. {
  284.     static char s[MAX_WORD];
  285.  
  286.     strcpy(s, lowcase(word));
  287.     if (include)
  288.         if (!strcmp(s, word))
  289.             s[0]=0;
  290.     return(s);
  291. }
  292.  
  293. /*==========================================================================*/
  294.  
  295. /*
  296. **     function: char *do_uppercase(char *word)
  297. **  description: creates uppercase equivalent of <word>
  298. **      returns: uppercase equivalent of <word> or "\0" if both words match
  299. */
  300.  
  301. char *do_uppercase(word)
  302.     char *word;
  303. {
  304.     static char s[MAX_WORD];
  305.  
  306.     strcpy(s, upcase(word));
  307.     if (include)
  308.         if (!strcmp(s, word))
  309.             s[0]=0;
  310.     return(s);
  311. }
  312.  
  313. /*==========================================================================*/
  314.  
  315. /*
  316. **     function: char *do_reverse(char *word)
  317. **  description: reverses <word>
  318. **      returns: reverse of <word> or "\0" if both words match
  319. */
  320.  
  321. char *do_reverse(word)
  322.     char *word;
  323. {
  324.     static char s[MAX_WORD];
  325.  
  326.     strcpy(s, reverse_string(word));
  327.     if (include)
  328.         if (!strcmp(s, word))
  329.             s[0]=0;
  330.     return(s);
  331. }
  332.  
  333. /*==========================================================================*/
  334.  
  335. /*
  336. **     function: char *do_lowreverse(char *word)
  337. **  description: converts <word> to lowercase & reverses it
  338. **      returns: lowered/reversed <word> or "\0" if both words match
  339. */
  340.  
  341. char *do_lowreverse(word)
  342.     char *word;
  343. {
  344.     static char s[MAX_WORD];
  345.  
  346.     strcpy(s, lowcase(reverse_string(word)));
  347.     if (reverse)
  348.         if (!strcmp(s, reverse_string(word)))
  349.             s[0]=0;
  350.     if ((lowercase) && (s[0]))
  351.         if (!strcmp(s, lowcase(word)))
  352.             s[0]=0;
  353.     if ((include) && (s[0]))
  354.         if (!strcmp(s, word))
  355.             s[0]=0;
  356.     return(s);
  357. }
  358.  
  359. /*==========================================================================*/
  360.  
  361. /*
  362. **     function: char *do_upreverse(char *word)
  363. **  description: converts <word> to uppercase & reverses it
  364. **      returns: uppered/reversed <word> or "\0" if both words match
  365. */
  366.  
  367. char *do_upreverse(word)
  368.     char *word;
  369. {
  370.     static char s[MAX_WORD];
  371.  
  372.     strcpy(s, upcase(reverse_string(word)));
  373.     if (reverse)
  374.         if (!strcmp(s, reverse_string(word)))
  375.             s[0]=0;
  376.     if ((uppercase) && (s[0]))
  377.         if (!strcmp(s, upcase(word)))
  378.             s[0]=0;
  379.     if ((include) && (s[0]))
  380.         if (!strcmp(s, word))
  381.             s[0]=0;
  382.     return(s);
  383. }
  384.  
  385. /*==========================================================================*/
  386.  
  387. /*
  388. **     function: char *uplast_word(char *word)
  389. **  description: converts the last character in <word> to uppercase
  390. **      returns: converted <word>
  391. */
  392.  
  393. char *uplast_word(word)
  394.     char *word;
  395. {
  396.     static char s[MAX_WORD];
  397.  
  398.     strcpy(s, word);
  399.     s[strlen(word)-1]=upcharacter(word[strlen(word)-1]);
  400.     return(s);
  401. }
  402.  
  403. /*==========================================================================*/
  404.  
  405. /*
  406. **     function: char *do_uplast(char *word)
  407. **  description: converts the last character in <word> to uppercase
  408. **      returns: converted <word> or "\0" if both words match
  409. */
  410.  
  411. char *do_uplast(word)
  412.     char *word;
  413. {
  414.     static char s[MAX_WORD];
  415.  
  416.     strcpy(s, uplast_word(word));
  417.     if (uppercase)
  418.         if (!strcmp(s, upcase(word)))
  419.             s[0]=0;
  420.     if ((include) && (s[0]))
  421.         if (!strcmp(s, word))
  422.             s[0]=0;
  423.     return(s);
  424. }
  425.  
  426. /*==========================================================================*/
  427.  
  428. /*
  429. **     function: char *do_upchar(char *word, int ch)
  430. **  description: converts the character at index <ch-1> in <word> to uppercase
  431. **      returns: converted <word> or "\0" if both words match
  432. */
  433.  
  434. char *do_upchar(word, ch)
  435.     char *word;
  436.           int  ch;
  437. {
  438.     static char s[MAX_WORD];
  439.  
  440.     strcpy(s, word);
  441.     s[ch-1]=upcharacter(word[ch-1]);
  442.     if (uppercase)
  443.         if (!strcmp(s, upcase(word)))
  444.             s[0]=0;
  445.     if (uplast)
  446.         if (!strcmp(s, uplast_word(word)))
  447.             s[0]=0;
  448.     if (strlen(word)<ch)
  449.         s[0]=0;
  450.     if ((include) && (s[0]))
  451.         if (!strcmp(s, word))
  452.             s[0]=0;
  453.     return(s);
  454. }
  455.  
  456. /*==========================================================================*/
  457.  
  458. /*
  459. **     function: char *do_novowels(char *word)
  460. **  description: removes vowels from <word>
  461. **      returns: vowel-less <word> or "\0" if both words match
  462. */
  463.  
  464. char *do_novowels(word)
  465.     char *word;
  466. {
  467.     register int  i, j;
  468.     static   char s[MAX_WORD], c;
  469.  
  470.     for(i=0, j=0; word[i]; i++) {
  471.         c=upcharacter(word[i]);
  472.         if (!((c=='A') || (c=='E') || (c=='I') || (c=='O') || (c=='U')))
  473.             s[j++]=word[i];
  474.     }
  475.     s[j]=0;
  476.     if (include)
  477.         if (!strcmp(s, word))
  478.             s[0]=0;
  479.     return(s);
  480. }
  481.  
  482. /*==========================================================================*/
  483.  
  484. /*
  485. **     function: char *do_double(char *word)
  486. **  description: doubles the <word> if its length is less than 8
  487. **      returns: doubled <word> or "\0" if <word> is longer than 7 chars
  488. */
  489.  
  490. char *do_double(word)
  491.     char *word;
  492. {
  493.     static   char s[MAX_WORD];
  494.  
  495.     if (strlen(word)<8)
  496.         sprintf(s, "%s%s", word, word);
  497.     else
  498.         s[0]=0;
  499.     return(s);
  500. }
  501.  
  502. /*==========================================================================*/
  503.  
  504. /*
  505. **     function: char *do_prefixes(char *word, char prechar)
  506. **  description: pre-pends the <word> with the character <prechar>
  507. **      returns: pre-pended <word>
  508. */
  509.  
  510. char *do_prefixes(word, prechar)
  511.     char *word, prechar;
  512. {
  513.     static char s[MAX_WORD];
  514.  
  515.     sprintf(s, "%c%s", prechar, word);
  516.     return(s);
  517. }
  518.  
  519. /*==========================================================================*/
  520.  
  521. /*
  522. **     function: char *do_suffixes(char *word, char postchar)
  523. **  description: post-pends the <word> with the character <word>'s length
  524. **               is less than 8 characters
  525. **      returns: post-pended <word> or "\0" if the <word> is 8 characters
  526. **               or longer
  527. */
  528.  
  529. char *do_suffixes(word, postchar)
  530.     char *word, postchar;
  531. {
  532.     static char s[MAX_WORD];
  533.  
  534.     if (strlen(word)<8)
  535.         sprintf(s, "%s%c", word, postchar);
  536.     else
  537.         s[0]=0;
  538.     return(s);
  539. }
  540.  
  541. /*==========================================================================*/
  542.  
  543. /*
  544. **     function: char *do_xlate_char(char *word, char *xc, int pos)
  545. **  description: translates the <pos>th occurance xc[0] to xc[1]
  546. **      returns: translated word
  547. */
  548.  
  549. char *do_xlate_char(word, xc, pos)
  550.     char *word, *xc;
  551.     int  pos;
  552. {
  553.     register int  i, j;
  554.     static   char s[MAX_WORD];
  555.  
  556.     strcpy(s, word);
  557.     for(i=0, j=0; (s[i]); i++) {
  558.         if (s[i]==xc[0])
  559.             if (++j>pos)
  560.                 break;
  561.     }
  562.     if (s[i])
  563.         s[i]=xc[1];
  564.     else
  565.         s[0]=0;
  566.     return(s);
  567. }
  568.  
  569. /*==========================================================================*/
  570.  
  571. /*
  572. **     function: char *do_xlate_all(char *word, char *xc)
  573. **  description: translates all occurances of xc[0] to xc[1]
  574. **      returns: translated <word>
  575. */
  576.  
  577. char *do_xlate_all(word, xc)
  578.     char *word, *xc;
  579. {
  580.     register int  i;
  581.     static   char s[MAX_WORD];
  582.  
  583.     for(i=0; word[i]; i++) {
  584.         if (word[i]==xc[0])
  585.             s[i]=xc[1];
  586.         else
  587.             s[i]=word[i];
  588.     }
  589.     s[i]=0;
  590.     return(s);
  591. }
  592.  
  593. /*==========================================================================*/
  594.  
  595. /*
  596. **     function: int do_nonalpha(char *word)
  597. **  description: counts the number of non-alphabetic characters in <word>
  598. **      returns: number of non-alphabetic characters in <word>
  599. */
  600.  
  601. int do_nonalpha(word)
  602.     char *word;
  603. {
  604.     register int i, okchars;
  605.  
  606.     for(i=0, okchars=0; word[i]; i++) {
  607.         if (!(((word[i]>='A') && (word[i]<='Z')) ||
  608.             ((word[i]>='a') && (word[i]<='z'))))
  609.             okchars++;
  610.     }
  611.     return(okchars);
  612. }
  613.  
  614. /*==========================================================================*/
  615.  
  616. /*
  617. **     function: void do_result(char *word)
  618. **  description: checks for minimum length of <word> and minimum
  619. **               non-alphabetic characters in <word> before writing
  620. **               the <word> to stdout
  621. **      returns: nothing
  622. */
  623.  
  624. void do_result(word)
  625.     char *word;
  626. {
  627.     if (!word[0])
  628.         return;
  629.     if (minlength)
  630.         if (strlen(word)<minlength)
  631.             return;
  632.     if (nonalpha)
  633.         if (do_nonalpha(word)<nonalpha)
  634.             return;
  635.     printf("%s\n", word);
  636. }
  637.  
  638. /*==========================================================================*/
  639.  
  640. /*
  641. **     function: void process_word(char *word)
  642. **  description: processes one original <word> for mutation
  643. **      returns: nothing
  644. */
  645.  
  646. void process_word(word)
  647.     char *word;
  648. {
  649.     int i, j, k;
  650.  
  651.     if (include)
  652.         do_result(word);
  653.     if (lowercase)
  654.         do_result(do_lowercase(word));
  655.     if (uppercase)
  656.         do_result(do_uppercase(word));
  657.     if (reverse)
  658.         do_result(do_reverse(word));
  659.     if (lowreverse)
  660.         do_result(do_lowreverse(word));
  661.     if (upreverse)
  662.         do_result(do_upreverse(word));
  663.     if (uplast)
  664.         do_result(do_uplast(word));
  665.     if (upchar)
  666.         do_result(do_upchar(word, upchar));
  667.     if (novowels)
  668.         do_result(do_novowels(word));
  669.     if (double_w)
  670.         do_result(do_double(word));
  671.     if (prefixes[0]) {
  672.         for(i=0; prefixes[i]; i++)
  673.             do_result(do_prefixes(word, prefixes[i]));
  674.     }
  675.     if (suffixes[0]) {
  676.         for(i=0; suffixes[i]; i++)
  677.             do_result(do_suffixes(word, suffixes[i]));
  678.     }
  679.     if (translate) {
  680.         for(i=0; i<translate; i++) {
  681.             j=chstrnum(xchar[i][0], word);
  682.             if (j) {
  683.                 for(k=0; k<j; k++)
  684.                     do_result(do_xlate_char(word, &xchar[i], k));
  685.                 if (j>1)
  686.                     do_result(do_xlate_all(word, &xchar[i]));
  687.             }
  688.         }
  689.     }
  690. }
  691.  
  692. /*==========================================================================*/
  693.  
  694. /*
  695. **     function: int okgf(char gfc)
  696. **  description: checks to see if the character is a GECOS delimiting char
  697. **      returns: 1 if it is a delimiter, 0 if not
  698. */
  699.  
  700. int okgf(gfc)
  701.     char gfc;
  702. {
  703.     if ((gfc!=',') && (gfc!=' ') && (gfc!='*') && (gfc!=':') && (gfc!='.') &&
  704.         (gfc!='-') && (gfc!='/') && (gfc!=')') && (gfc!='('))
  705.         return(1);
  706.     return(0);
  707. }
  708.  
  709. /*==========================================================================*/
  710.  
  711. /*
  712. **     function: void process_line(char *line)
  713. **  description: processes a single line of /etc/passwd information
  714. **      returns: nothing
  715. */
  716.  
  717. void process_line(line)
  718.     char *line;
  719. {
  720.     int  i, ok=0;
  721.     char *login, *epw, *gec, *gecw;
  722.  
  723.     for(login=line; (*line!=':') && (*line); line++)
  724.         ;
  725.     if (*line) {
  726.         *line=0;
  727.         for(epw=++line; (*line!=':') && (*line); line++)
  728.             ;
  729.         if (*line) {
  730.             *line=0;
  731.             for(++line; (*line!=':') && (*line); line++)
  732.                 ;
  733.             if (*line) {
  734.                 *line=0;
  735.                 for(++line; (*line!=':') && (*line); line++)
  736.                     ;
  737.                 if (*line) {
  738.                     *line=0;
  739.                     for(gec=++line; (*line!=':') && (*line); line++)
  740.                         ;
  741.                     if (*line) {
  742.                         *line=0;
  743.                         ok=1;
  744.                     }
  745.                 }
  746.             }
  747.         }
  748.     }
  749.     if (ok) {
  750.         if (strlen(epw)>13)
  751.             epw[13]=0;
  752.         if ((epw[0]!='*') && (strlen(epw)==13) && (login[0]!='+')) {
  753.             if (logins)
  754.                 process_word(login);
  755.             if (gecos) {
  756.                 while(*gec) {
  757.                     for(; (*gec) && (!okgf(*gec)); gec++)
  758.                         ;
  759.                     if (*gec) {
  760.                         gecw=gec;
  761.                         for(; (*gec) && (okgf(*gec)); gec++)
  762.                             ;
  763.                         if (*gec)
  764.                             *gec++=0;
  765.                         process_word(gecw);
  766.                     }
  767.                 }
  768.             }
  769.             if (kc)
  770.                 printf("***!***\n");
  771.         }
  772.     }
  773. }
  774.  
  775. /*==========================================================================*/
  776.  
  777. /*
  778. **     function: void process_pwfile(void)
  779. **  description: processes /etc/passwd file type info (login/GECOS)
  780. **      returns: nothing
  781. */
  782.  
  783. void process_pwfile()
  784. {
  785.     char line[MAX_LINE];
  786.  
  787.     while(gets(line))
  788.         process_line(line);
  789. }
  790.  
  791.  
  792. /*==========================================================================*/
  793.  
  794. /*
  795. **     function: void process_wordlist(void)
  796. **  description: processes each word from a wordlist
  797. **      returns: nothing
  798. */
  799.  
  800. void process_wordlist()
  801. {
  802.     char word[MAX_WORD];
  803.  
  804.     while(gets(word)) {
  805.         if (strcmp(word, "***!***"))
  806.             process_word(word);
  807.         else
  808.             printf("***!***\n");
  809.     }
  810. }
  811.  
  812. /*==========================================================================*/
  813.  
  814. /*
  815. **     function: int getcmd(char *name)
  816. **  description: searches [cmdtab] for a matching command
  817. **      returns: value assigned to each command in [cmdtab] or ERROR_FLAG
  818. **               upon error
  819. */
  820.  
  821. int getcmd(name)
  822.     char *name;
  823. {
  824.     struct cmd *c;
  825.  
  826.     for(c=cmdtab; c; c++) {
  827.         if (!strncmp(name, c->cmd_name, c->unique)) {
  828.             if (strlen(name)<=strlen(c->cmd_name)) {
  829.                 if (!strncmp(name, c->cmd_name, strlen(name)))
  830.                     return(c->cmd_code);
  831.             }
  832.             return(ERROR_FLAG);
  833.         }
  834.     }
  835.     return(ERROR_FLAG);
  836. }
  837.  
  838. /*==========================================================================*/
  839.  
  840. /*
  841. **     function: void process_arg(char *arg)
  842. **  description: processes the value of one command line argument
  843. **      returns: nothing
  844. */
  845.  
  846. void process_arg(arg)
  847.     char *arg;
  848. {
  849.     int  result_code, i;
  850.     char tail[MAX_TAIL];
  851.  
  852.     tail[0]=0;
  853.     for(i=0; (arg[i]!=':') && (arg[i]); i++)
  854.         ;
  855.     if (arg[i]) {
  856.         strcpy(tail, &arg[i+1]);
  857.         arg[i]=0;
  858.     }
  859.     result_code=getcmd(lowcase(arg));
  860.     switch(result_code) {
  861.         case DOUBLE_FLAG:
  862.             double_w=1;
  863.             break;
  864.         case GECOS_FLAG:
  865.             gecos=1;
  866.             break;
  867.         case HELP_FLAG:
  868.             print_usage();
  869.             exit(0);
  870.             break;
  871.         case INCLUDE_FLAG:
  872.             include=1;
  873.             break;
  874.         case KC_FLAG:
  875.             kc=1;
  876.             break;
  877.         case LOGINS_FLAG:
  878.             logins=1;
  879.             break;
  880.         case LOWERCASE_FLAG:
  881.             lowercase=1;
  882.             break;
  883.         case LOWREVERSE_FLAG:
  884.             lowreverse=1;
  885.             break;
  886.         case MINLENGTH_FLAG:
  887.             minlength=atoi(tail);
  888.             break;
  889.         case NONALPHA_FLAG:
  890.             nonalpha=atoi(tail);
  891.             break;
  892.         case NOVOWELS_FLAG:
  893.             novowels=1;
  894.             break;
  895.         case PREFIXES_FLAG:
  896.             strcpy(prefixes, tail);
  897.             break;
  898.         case REVERSE_FLAG:
  899.             reverse=1;
  900.             break;
  901.         case SUFFIXES_FLAG:
  902.             strcpy(suffixes, tail);
  903.             break;
  904.         case UPCHAR_FLAG:
  905.             upchar=atoi(tail);
  906.             break;
  907.         case UPLAST_FLAG:
  908.             uplast=1;
  909.             break;
  910.         case UPPERCASE_FLAG:
  911.             uppercase=1;
  912.             break;
  913.         case UPREVERSE_FLAG:
  914.             upreverse=1;
  915.             break;
  916.         case TRANSLATE_FLAG:
  917.             if (strlen(tail)>1) {
  918.                 xchar[translate  ][0]=tail[0];
  919.                 xchar[translate++][1]=tail[1];
  920.             }
  921.             break;
  922.         default:
  923.             eexit(1, "invalid argument", arg);
  924.             break;
  925.     }
  926. }
  927.  
  928. /*==========================================================================*/
  929.  
  930. /*
  931. **     function: void main(int argc, char **argv)
  932. **  description: main function
  933. **      returns: nothing
  934. */
  935.  
  936. void main(argc, argv)
  937.     int  argc;
  938.     char **argv;
  939. {
  940.     char s[MAX_LINE];
  941.  
  942.     init_vars();
  943.     strcpy(progname, *argv);
  944.     if (argc==1) {
  945.         print_usage();
  946.         exit(0);
  947.     }
  948.     for(; --argc; ) {
  949.         strcpy(s, *++argv);
  950.         if ((s[0]=='-') || (s[0]=='/'))
  951.             process_arg(&s[1]);
  952.         else
  953.             eexit(1, "invalid argument", s);
  954.     }
  955.     if ((kc) && (!gecos) && (!logins))
  956.         eexit(1, "flag 'kc' must be used with 'logins' or 'gecos'", NULL);
  957.     if ((gecos) || (logins))
  958.         process_pwfile();
  959.     else
  960.         process_wordlist();
  961.     exit(0);
  962. }
  963.