/**************************************************************
 * crack.c -- password cracker for ICS passwords.             *            
 *                                                            *
 * Author: stderr (stderr.dev@gmail.com)                      *
 *                                                            *
 * Compile: gcc -o <name> -lcrypt main.c                      *
 **************************************************************/
   
#include <stdio.h>
#include <unistd.h>
#include <string.h>

/* used to identify the calling program */
char program_name[51];

/* function prototypes */
void usage(void);

/* main function */
int main(int argc, char * argv[])
{
  char encrypted_string[51];       /* contains the encrypted string */
  char salt[3];                    /* password salt */
  char *password;                  /* the password including salts passed to the program */
  char match[51];                  /* if the passwords match */
  char *file_name = "allwords.txt";/* file to open */
  char *temp;                      /* temporary read */
  char gtext[100];

  int counter;                     /* loop counter */
  int pass = 0;                    /* see if a password was gotten */

  FILE *in_file;                   /* password list file */
  FILE *in_profile;                /* used for player profile */

  /* set program name */
  strcpy(program_name,argv[0]);

  while((argc > 1) && (argv[1][0] == '-')) {
    /* switch statement for the options */
    switch(argv[1][1]) {
      /* 
       * -p optioin
       */
    case 'p':
      if (pass != 0) {
	fprintf(stderr,"Can't have 2 password!\n");
	exit(8);
      }
      /* set the password to crack */
      password = &argv[1][2];
      pass = 1;
      break;
      /*
       * -f option
       */
    case 'f':
      if (pass != 0) {
	fprintf(stderr,"Can't have 2 password!\n");
	exit(8);
      }

      pass = 1;
      temp = &argv[1][2];

      /* open and get password from file */
      in_profile = fopen(temp,"r");
      
      /* get to pass line */
      fgets(gtext,sizeof(gtext),in_profile);
      fgets(gtext,sizeof(gtext),in_profile);
      fgets(gtext,sizeof(gtext),in_profile);
      fgets(gtext,sizeof(gtext),in_profile);

      gtext[strlen(gtext)-1] = '\0';
      
      password = &gtext[0];

      fclose(in_profile);
      break;
      /*
       * -l option 
       */
    case 'l':
      file_name = &argv[1][2];
      break;
      /*
       * -h option
       */
    case 'h':
      usage();
      break;
    default:
      fprintf(stderr,"Bad option %s\n",argv[1]);
      usage();
      break;
    }
    /* move arg list up one, and number down 1 */
    ++argv;
    --argc;
  }

  if (pass == 0) {
    fprintf(stderr,"Must set a password to crack\n");
    usage();
  }

  /* open the file */
  in_file = fopen(file_name,"r");

  /* snag the salt */
  salt[0] = password[0];
  salt[1] = password[1];
  salt[3] = '\0';

  /* cracking loop */
  while(1) {
    strcpy(match,"");
    fgets(match,sizeof(match),in_file);
    match[strlen(match)-1] = '\0';

    /* check for EOF */
    if (match[0] == '\0')
      break;

    strcpy(encrypted_string,strdup(crypt(match,salt)));

    if (!strcmp(encrypted_string,password)) {
      printf("Found a match!\n%s\n",match);
      break;
    }
  }
  fclose(in_file);
  return 0;
}

void usage(void)
{
  fprintf(stderr,"Usage is %s [options]\n",program_name);
  fprintf(stderr,"Options\n");
  fprintf(stderr," -f<file>   player file\n");
  fprintf(stderr," -p<pass>   password\n");
  fprintf(stderr," -l<file>   password list file\n");
  fprintf(stderr," -h         display help\n");
  exit(8);
}
