home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / comm / tcp / Crak.lha / craksort2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-27  |  12.1 KB  |  489 lines

  1. /*
  2. VERSION: 0.01 by Sudog Feb '97
  3. So what if I have a non-standard version?
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <string.h>
  8. #ifdef AMIGA
  9. #include <dos/dos.h>
  10. #include <exec/memory.h>
  11. #endif
  12.  
  13. /* duh */
  14. #define TRUE        1  /* generic true/false because I don't want to waste time */
  15. #define FALSE       0  /* including exec/types.h so there. */
  16.  
  17. /* the following for passwd structure traversal */
  18. #define USER        1  /* at user field in line */
  19. #define PASSWD      2  /* at passwd field in passwd entry */
  20. #define SAVE        3  /* after storing user & password, save it */
  21. #define DONE        4  /* and after saving it for later, skip over rest */
  22.  
  23. /* maximum values for internal passwd structure */
  24. #define NAMESIZE   15  /* for struct passwd and for parsepass routine */
  25. #define SALTSIZE    3
  26. #define PASSWDSIZE 14
  27. #define WORDSIZE   20  /* maximum size of password in command line or password in dictfile */
  28.  
  29. /* values for return() from getnextdict */
  30. #define DICT_DONE  1   /* dictionary has been exhausted */
  31. #define DICT_ERROR 2   /* dictionary file is corrupt or something else just as fucked up */
  32.  
  33.  
  34. #define SEPARATOR  ':' /* passwd field separator.. : for unix, | for AmiTCP */
  35.  
  36. /*
  37. ** This is merely a small affectation because I am sometimes curious
  38. ** to have regular status updates..  uncomment this #define if you like
  39. ** something happening everytime the dictionary file has been entirely
  40. ** searched through..
  41. #define ANIMSIZE   4
  42. */
  43.  
  44. #ifdef AMIGA
  45. int CXBRK(void) {return(0);}    /* sorry user we're gonna make SURE that you can't */
  46. int chkabort(void) {return(0);} /* mess us up without giving us chance to clean up */
  47. #endif
  48.  
  49. struct passwd
  50.   {
  51.   char name[NAMESIZE];
  52.   char salt[SALTSIZE];
  53.   char password[PASSWDSIZE];
  54.   struct passwd *nextitem;
  55.   struct passwd *lastitem;
  56.   short cracked;
  57.   };
  58.  
  59. FILE *dictionary;  /* global because we want getnextdict() to have an open-and-ready */
  60.                    /* file handle from which to read words from the dictionary when in */
  61.                    /* dictionary mode */
  62.  
  63. char *crypt(char *, char *);
  64. struct passwd *parsepass(char *);
  65. void cleanup(struct passwd *);
  66. void log(char *, char *, char *);
  67. long getnextdict(char *, char *);
  68.  
  69. int main(int argc, char *argv[])
  70. {
  71. unsigned int counter;
  72. unsigned int c=FALSE;
  73. unsigned char commandword[WORDSIZE];
  74.  
  75. struct passwd *firstitem=NULL;
  76. struct passwd *currentitem=NULL;
  77.  
  78. long status; /* for returns from various functions..  scratchpad */
  79.  
  80. #ifdef ANIMSIZE
  81. char anim[] = "\\|/-";
  82. int animcounter = 0;
  83. #endif
  84.  
  85. #ifdef AMIGA
  86. long actualsigs;
  87. long waitmask = SIGBREAKF_CTRL_C;
  88. #endif
  89.  
  90. dictionary=NULL; /* i don't want to do this more than once */
  91.  
  92. /* do some command line argument parsing */
  93. /* this is hereby hard-coded.*/
  94. printf("sizeof: %d\n", sizeof(struct passwd));
  95. exit(10);
  96. for (counter = 0; counter < argc; counter++)
  97.   {
  98.   if (argv[counter][0] == '-')
  99.     {
  100. /*
  101. ** The following accepts the - as an indicator, and then it copies the
  102. ** rest of this particular argument as a word to search a passwd file for.
  103. ** The reason this isn't hard-coded as argv[2] is for future expandability--
  104. ** sort of a functional work-in-progress.
  105. */
  106.     c = TRUE;
  107.     for (counter=1; counter < WORDSIZE; counter++)
  108.       {
  109.       commandword[counter-1] = argv[2][counter];
  110.       if (commandword[counter-1] == 0) break;
  111.       }
  112.     break;
  113.     }
  114.   if (argv[counter][0] == '?')
  115.     {
  116. /*
  117. ** I could never really see the harm in goto statements within programs.
  118. ** "A Book On C" says that goto statements are bad programming pratice.
  119. ** Whatever..
  120. */
  121. usage:
  122.     printf("Usage: %s <passwdfile> -<word> [outputfile]\n", argv[0]);
  123.     printf("       %s <passwdfile> <dictfile> [outputfile]\n", argv[0]);
  124.     printf("       %s ?\n", argv[0]);
  125.     printf("This program written in Feb, '97 by sudog.\n");
  126.     printf("So there.\n");
  127.     exit(0);
  128.     }
  129.   }
  130.  
  131. counter = 0;
  132.  
  133. if (argc > 2)
  134.   {
  135.   if (firstitem = parsepass(argv[1]))
  136.     {
  137.     currentitem = firstitem;
  138. /*
  139. ** This section deals with a command-line supplied password.
  140. */
  141.     if (c)
  142.       {
  143.       while (currentitem != NULL)
  144.         {
  145.         if (!strcmp(currentitem->password, crypt(commandword, currentitem->salt)))
  146.           {
  147.           printf("%s %s\n", currentitem->name, commandword);
  148.           if (argc > 3)
  149.              {
  150.             log(argv[3], currentitem->name, commandword);
  151.             }
  152.           }
  153. /* This section is amiga-only--it allows the user to break the program,
  154. ** CLEANLY! (Ie: We trap SIGBREAKF_CTRL_C and clean up the memory we allocated.)
  155. */
  156. #ifdef AMIGA
  157.         actualsigs = CheckSignal(waitmask);
  158.         if (actualsigs)
  159.           {
  160.           cleanup(firstitem);
  161.           }
  162. #endif
  163.         currentitem = currentitem->nextitem;
  164.         }
  165.       }
  166. /*
  167. ** This section deals with a dictionary file!
  168. ** TODO:
  169. ** Add place holder so a system crash can be survived and iterations can
  170. ** continue from last point...  VERY cool. let's do som background cracking!
  171. */
  172. /*
  173. ** First priority is to check the entire dictionary against the 
  174. ** current passwd entry. It's MUCH MUCH INCREDIBLY FASTER then.
  175. */
  176.     else
  177.       {
  178.       currentitem=firstitem;
  179. /*
  180. ** A simple while loop to search an entire dictionary on a single
  181. ** password entry. Trust me, this saves a SHITLOAD of time, since
  182. ** for each new salt which is used, crypt() has to re-set all its
  183. ** damned data structure and shit. VERY crappy. Otherwise it zips
  184. ** through things in like, 500 keys per second. At least, on my
  185. ** machine, compared with maybe 10 keys/sec otherwise.
  186. */
  187.       while ( currentitem != NULL )
  188.         {
  189.         while (((status=getnextdict(commandword, argv[2])) != DICT_DONE) && (status != DICT_ERROR))
  190.           {
  191.           if (!currentitem->cracked)
  192.             {
  193.             if (!strcmp(currentitem->password, crypt(commandword, currentitem->salt)))
  194.               {
  195.               printf("%s %s\n", currentitem->name, commandword);
  196.               currentitem->cracked = TRUE;
  197.               if (argc > 3)
  198.                 {
  199.                 log(argv[3], currentitem->name, commandword);
  200.                 }
  201.               }
  202.             }
  203. #ifdef AMIGA
  204.           actualsigs = CheckSignal(waitmask);
  205.           if (actualsigs)
  206.             {
  207.             cleanup(firstitem);
  208.             }
  209. #endif
  210.           }
  211.         if (status == DICT_ERROR)
  212.           {
  213.           printf("Error: Unable to access dictionary file..\n");
  214.           break;
  215.           }
  216.         if (status == DICT_DONE)
  217.           {
  218. #ifdef ANIMSIZE
  219.           printf("%c%c", anim[animcounter], 8);
  220.           animcounter++;
  221.           if (animcounter >= ANIMSIZE)
  222.             {
  223.             animcounter = 0;
  224.             }
  225. #endif
  226.           }
  227.         currentitem=currentitem->nextitem;
  228.         }
  229.       }
  230.     }
  231.   else
  232.     {
  233.     printf("Error in parsing password file.\n");
  234.     }
  235.   }
  236. else
  237.   {
  238.   printf("Error. You don't have a clue. Here. Have one.\n");
  239.   goto usage;
  240.   }
  241.  
  242. cleanup(firstitem);
  243.  
  244. }
  245.  
  246. /*
  247. ** In order that we get dictionary words, we have to 
  248. ** return words in cyclical order. Ie: We have to 
  249. ** get the first word after we got the last word.
  250. ** So we aren't returning any end-of-file conditions.
  251. ** We're just returning words unless an error
  252. ** condition exists.
  253. */
  254.  
  255. long getnextdict(char *commandword, char *filename)
  256. {
  257. long counter=0;
  258. int gotone=FALSE;
  259. char temp;
  260.  
  261. if (commandword == NULL && filename == NULL)
  262.   {
  263.   if (dictionary)
  264.     {
  265.     fclose(dictionary);
  266.     }
  267.   return(0);
  268.   }
  269. if (!dictionary)
  270.   {
  271.   if (!(dictionary = fopen(filename, "r")))
  272.     {
  273.     return(DICT_ERROR);
  274.     }
  275.   }
  276. if (dictionary)
  277.   {
  278.   while ( 1 )
  279.     {
  280.     temp = fgetc(dictionary);
  281.     if (feof(dictionary))
  282.       {
  283.       if (gotone)
  284.         {
  285.         commandword[counter] = 0;
  286.         return(0);
  287.         }
  288.       else
  289.         {
  290. /*
  291. ** We're going to re-use the dictionary file again and again and
  292. ** again until we're TOLD to close it with getnextdict(NULL, NULL);
  293. */
  294.         rewind(dictionary);
  295.         return(DICT_DONE);
  296.         }
  297.       }
  298.     else if (temp > 31 && temp < 127)
  299.       {
  300.       if (gotone == FALSE)
  301.         {
  302.         gotone = TRUE;
  303.         }
  304.       if (counter < WORDSIZE)
  305.         {
  306.         commandword[counter++] = temp;
  307.         }
  308.       }
  309.     else
  310.       {
  311.       if (gotone == TRUE)
  312.         {
  313.         commandword[counter] = 0;
  314.         return(0);
  315.         }
  316.       }
  317.     } /* end of while loop */
  318.   }
  319. }
  320.  
  321. /*
  322. ** Excellently enough, calloc() remembers how big the memory chunks
  323. ** it allocated are, so a call to free() doesn't have to specify anything
  324. ** but the pointer!!  ANSI-C rules!
  325. */
  326. void cleanup(struct passwd *firstitem)
  327. {
  328. struct passwd *currentitem;
  329. while (firstitem != NULL)
  330.   {
  331.   currentitem = firstitem->nextitem;
  332.   free(firstitem);
  333.   firstitem = currentitem;
  334.   }
  335. getnextdict(NULL, NULL);
  336. exit(0);
  337. }
  338.   
  339. void log (char *filename, char *username, char *password)
  340. {
  341. FILE *output;
  342.  
  343. if (output = fopen(filename, "a"))
  344.   {
  345.   fprintf(output, "%s %s\n", username, password);
  346.   fclose(output);
  347.   }
  348. else
  349.   {
  350.   printf("Error: Unable to open output file!\n");
  351.   }
  352. }
  353.  
  354. /*
  355. ** This routine opens a passwd file, and parses it according to the
  356. ** following rules:
  357. **
  358. ** {user}{separator}{passwd field entry}{separator}
  359. ** There MUST be two separators per line..  the separator should be defined as
  360. ** SEPARATOR in the preprocessor.. usually ':' for UNIX-style passwd files.
  361. */
  362.  
  363. /*
  364. ** We use a state variable to define which part of the passwd entry we
  365. ** are currently processing..  it's more used as a sort of directive..
  366. ** if it's USER, store it in the user field of the struct passwd..
  367. ** etc etc..
  368. */
  369. struct passwd *parsepass(char *filename)
  370. {
  371. struct passwd *currentitem=NULL;
  372. struct passwd *firstitem=NULL;
  373. struct passwd *floatitem=NULL;
  374.  
  375. unsigned int counter = 0;
  376. unsigned int state;       /* the part of the field we're parsing right now */
  377. unsigned int ff = FALSE;
  378.  
  379. FILE *input;
  380. char temp;
  381.  
  382.  
  383. if (input = fopen(filename, "r"))
  384.   {
  385.   while ( 1 )
  386.     {
  387.     temp = fgetc(input);
  388.     if (feof(input)) break;
  389.     if (temp > 31 && temp < 127)
  390.       {
  391. /*
  392. ** ff here is being used as a sort of flip-flop switch. It is used for
  393. ** QUICKLY skipping over non-printable characters.
  394. */
  395.       if (ff == FALSE)
  396.         {
  397.         ff = TRUE;
  398.         if (!(floatitem = (struct passwd *)calloc(1, sizeof(struct passwd))))
  399.           {
  400.           printf("Error: Unable to allocate %d bytes. Exiting..\n", sizeof(struct passwd));
  401.           cleanup(firstitem);
  402.           }
  403.         state = USER;
  404.         }
  405.       if (state == USER)
  406.         {
  407.         if (temp != SEPARATOR && counter < NAMESIZE)
  408.           {
  409.           floatitem->name[counter++] = temp;
  410.           }
  411.         if (temp == SEPARATOR)
  412.           {
  413.           state = PASSWD;
  414.           counter = 0;
  415.           }
  416.         }
  417.       else if (state == PASSWD)
  418.         {
  419.         if (temp != SEPARATOR && counter < PASSWDSIZE)
  420.           {
  421.           if (counter < 2)
  422.             {
  423.             floatitem->salt[counter] = temp;
  424.             }
  425.           floatitem->password[counter++] = temp;
  426.           }
  427.         if (temp == SEPARATOR)
  428.           {
  429.           state = SAVE;
  430.           counter = 0;
  431.           }
  432.         }
  433.       if (state == SAVE)
  434.         {
  435.         if (!firstitem)
  436.           {
  437.           firstitem=floatitem;
  438.           }
  439.         else
  440.           {
  441.           currentitem=firstitem;
  442. /*
  443. ** We are using a doubly-linked list to store our list of passwd
  444. ** entries..  doubly-linked lists are cool! buhuhuhuhuhuhuhuhuh hehe
  445. */
  446.           while ( 1 )
  447.             {
  448.             if ((strcmp(floatitem->salt, currentitem->salt)) <= 0)
  449.               {
  450.               floatitem->nextitem=currentitem;
  451.               floatitem->lastitem=currentitem->lastitem;
  452.               currentitem->lastitem = floatitem;
  453.               if (floatitem->lastitem != NULL)
  454.                 {
  455.                 floatitem->lastitem->nextitem = floatitem;
  456.                 }
  457.               else
  458.                 {
  459.                 firstitem = floatitem;
  460.                 }
  461.               break;
  462.               }
  463.             if (currentitem->nextitem == NULL)
  464.               {
  465.               currentitem->nextitem = floatitem;
  466.               floatitem->lastitem = currentitem;
  467.               break;
  468.               }
  469.             currentitem=currentitem->nextitem;
  470.             }
  471.           }
  472.         state = DONE;
  473.         }
  474.       }
  475.     else
  476.       {
  477.       state = USER;
  478.       ff = FALSE;
  479.       }
  480.     }
  481.   fclose(input);
  482.   }
  483. else
  484.   {
  485.   printf("Error: Unable to open specified passwd file.\n");
  486.   }
  487. return(firstitem);
  488. }
  489.