Codebase list hydra / debian/6.5-2 bfg.c
debian/6.5-2

Tree @debian/6.5-2 (Download .tar.gz)

bfg.c @debian/6.5-2raw · history · blame

/*    (c) 2008 Jan Dlabal <dlabaljan@gmail.com>                               */
/*                                                                            */
/*     This file is part of the bfg.                                          */
/*                                                                            */
/*     bfgen is free software: you can redistribute it and/or modify          */
/*     it under the terms of the GNU General Public License as published by   */
/*     the Free Software Foundation, either version 3 of the License, or      */
/*     any later version.                                                     */
/*                                                                            */
/*     bfgen is distributed in the hope that it will be useful,               */
/*     but WITHOUT ANY WARRANTY; without even the implied warranty of         */
/*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
/*     GNU General Public License for more details.                           */
/*                                                                            */
/*     You should have received a copy of the GNU General Public License      */
/*     along with bfgen. If not, see <http://gnu.org/licenses>.               */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include "bfg.h"

bf_option bf_options;

#ifdef HAVE_MATH_H

void bf_recurse(unsigned int len, unsigned int pos, char *string);
int bf_add(char *string);

char *ptr = NULL;

/* return values : 0 on success, 1 on error */
int bf_init(char *arg) {
  int i = 0;
  int crs_len = 1;
  char flags = 0;
  char *tmp = strchr(arg, ':');

//  printf("%s %s, [%s] (c) Jan Dlabal, %s\n", BF_NAME, BF_VERSION, BF_WEBSITE, BF_YEAR);

  if (!tmp) {
    fprintf(stderr, "Error: Invalid option format for -x\n");
    return 1;
  } else {
    tmp[0] = '\0';
  }
  bf_options.crt = atoi(arg);
  arg = tmp + 1;
  tmp++;
  if (!arg[0]) {
    fprintf(stderr, "Error: no maximum length specified for -x min:max:types!\n");
    return 1;
  }
  tmp = strchr(arg, ':');
  if (!tmp) {
    fprintf(stderr, "Error: Invalid option format for -x\n");
    return 1;
  } else {
    tmp[0] = '\0';
  }
  bf_options.max = atoi(arg);
  bf_options.end = 0;
  tmp++;

  if (bf_options.crt > bf_options.max) {
    fprintf(stderr, "Error: you specified a minimum length higher than the maximum length!\n");
    return 1;
  }

  if (!tmp[0]) {
    fprintf(stderr, "Error: charset not specified!\n");
    return 1;
  }
  bf_options.crs = malloc(sizeof(char) * BF_CHARSMAX);

  if (bf_options.crs == NULL) {
    fprintf(stderr, "Error: can't allocate enough memory!\n");
    return 1;
  }
  bf_options.crs[0] = 0;

  for (; tmp[i]; i++) {
    switch (tmp[i]) {
    case 'a':
      crs_len += 26;
      if (BF_CHARSMAX - crs_len < 0) {
        free(bf_options.crs);
        fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX);
        return 1;
      } else if (flags & BF_LOWER) {
        free(bf_options.crs);
        fprintf(stderr, "Error: 'a' specified more than once in charset!\n");
        return 1;
      } else {
        strcat(bf_options.crs, "abcdefghijklmnopqrstuvwxyz");
        flags |= BF_LOWER;
      }
      break;

    case 'A':
      crs_len += 26;
      if (BF_CHARSMAX - crs_len < 0) {
        free(bf_options.crs);
        fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX);
        return 1;
      } else if (flags & BF_UPPER) {
        free(bf_options.crs);
        fprintf(stderr, "Error: 'A' specified more than once in charset!\n");
        return 1;
      } else {
        strcat(bf_options.crs, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
        flags |= BF_UPPER;
      }
      break;

    case '1':
      crs_len += 10;
      if (BF_CHARSMAX - crs_len < 0) {
        free(bf_options.crs);
        fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX);
        return 1;
      } else if (flags & BF_NUMS) {
        free(bf_options.crs);
        fprintf(stderr, "Error: '1' specified more than once in charset!\n");
        return 1;
      } else {
        strcat(bf_options.crs, "0123456789");
        flags |= BF_NUMS;
      }
      break;

    default:
      crs_len += 1;
      if (BF_CHARSMAX - crs_len < 0) {
        free(bf_options.crs);
        fprintf(stderr, "Error: charset specification exceeds %d characters.\n", BF_CHARSMAX);
        return 1;
      } else {
        bf_options.crs[crs_len - 1] = '\0';
        bf_options.crs[crs_len - 2] = tmp[i];
      }
      break;
    }
  }

  ptr = bf_options.ptr;

  return 0;
}


/* returns 0 on success, 1 on error */
int bf_generate() {
  static char *tmp1 = NULL;

  if (tmp1 == NULL) {
    if ((tmp1 = malloc(BF_BUFLEN)) == NULL)
      return 1;
  }

  bf_options.end = 0;

  while (bf_options.end == 0)
    bf_recurse(bf_options.crt, 0, tmp1);

  free(tmp1);
  tmp1 = NULL;

  return 0;
}


void bf_recurse(unsigned int len, unsigned int pos, char *string) {
  // len is the length of the currently tested password,
  // pos is the position of the char that this function has to modify
  // string is the string to test

  int i;
  char last = 0;

  if (bf_options.save[pos] >= strlen(bf_options.crs)) {
    bf_options.save[pos] = 0;
    bf_options.save[pos - 1]++;
    return;
  }

  if (bf_options.last || pos == 0) {
    last = 1;
    bf_options.last = 0;
  }

  for (i = bf_options.save[pos]; ((i < strlen(bf_options.crs)) && (bf_options.end == 0)); i++) {

    if (last && (i + 1 == strlen(bf_options.crs)))
      bf_options.last = 1;

    if (pos < (len - 1)) {
      string[pos] = bf_options.crs[i];
      bf_recurse(len, pos + 1, string);
    } else {
      string[pos] = bf_options.crs[i];
      string[pos + 1] = '\0';
      bf_add(string);
      bf_options.end = 1;
      if (bf_options.last) {
        bf_options.crt++;
        bf_options.last = 0;
      }
    }
  }

  if ((bf_options.end == 1) && (bf_options.last == 0)) {
    if (pos == (len - 1)) {
      bf_options.save[pos] = i;
    } else {
      bf_options.save[pos] = i - 1;
    }
  } else {
    bf_options.save[pos] = 0;
  }
}


// returns 0 when no error is detected, and 1 when the buffer is filled
int bf_add(char *tmp) {
  unsigned int len;

  if (tmp[0] != 0) {
    if ((len = strlen(tmp)) > 0) {
      tmp[len] = 0;             /* ensure null byte at the end of the string */

      bf_options.ptr = tmp;

      return 1;
    }
  }

  return 0;
}


unsigned long int bf_get_pcount() {
  int i;
  unsigned long int count = 0;

  for (i = bf_options.crt; i <= bf_options.max; i++)
    count += (unsigned long int) (pow((float) strlen(bf_options.crs), (float) i));
  return count;
}


char *bf_next() {
  char *tmp2 = malloc(BF_BUFLEN);       // we don't care for freeing - this is handled by others

  if (tmp2 == NULL) {
    fprintf(stderr, "Error: Can not allocate memory for -x data!\n");
    return NULL;
  }

  bf_generate();
  strcpy(tmp2, bf_options.ptr);
  return tmp2;
}

#endif