static char *prepare(char *split_fields[10], struct fmt_main *self) { char *cp; int i; if (!strncmp(split_fields[1], "$DCC2$", 6)) { if (valid(split_fields[1], self)) return split_fields[1]; // see if this is a form $DCC2$salt#hash. If so, make it $DCC2$10240#salt#hash and retest (insert 10240# into the line). cp = mem_alloc(strlen(split_fields[1]) + 7); sprintf(cp, "$DCC2$10240#%s", &(split_fields[1][6])); if (valid(cp, self)) { char *cipher = str_alloc_copy(cp); MEM_FREE(cp); return cipher; } return split_fields[1]; } if (!split_fields[0]) return split_fields[1]; // ONLY check, if this string split_fields[1], is ONLY a 32 byte hex string. for (i = 0; i < 32; i++) if (atoi16[ARCH_INDEX(split_fields[1][i])] == 0x7F) return split_fields[1]; cp = mem_alloc(strlen(split_fields[0]) + strlen(split_fields[1]) + 14); sprintf(cp, "$DCC2$10240#%s#%s", split_fields[0], split_fields[1]); if (valid(cp, self)) { char *cipher = str_alloc_copy(cp); MEM_FREE(cp); return cipher; } MEM_FREE(cp); return split_fields[1]; }
static void ldr_show_pot_line(struct db_main *db, char *line) { char *ciphertext, *pos; int hash; struct db_cracked *current, *last; ciphertext = ldr_get_field(&line); if (line) { pos = line; do { if (*pos == '\r' || *pos == '\n') *pos = 0; } while (*pos++); if (db->options->flags & DB_PLAINTEXTS) { list_add(db->plaintexts, line); return; } hash = ldr_cracked_hash(ciphertext); last = db->cracked_hash[hash]; current = db->cracked_hash[hash] = mem_alloc_tiny(sizeof(struct db_cracked), MEM_ALIGN_WORD); current->next = last; current->ciphertext = str_alloc_copy(ciphertext); current->plaintext = str_alloc_copy(line); } }
void cfg_init(char *name, int allow_missing) { FILE *file; char line[LINE_BUFFER_SIZE]; int number; if (cfg_database && !cfg_recursion) return; cfg_name = str_alloc_copy(path_expand(name)); file = fopen(cfg_name, "r"); if (!file) { cfg_name = str_alloc_copy(path_expand_ex(name)); file = fopen(cfg_name, "r"); if (!file) { if (allow_missing && errno == ENOENT) return; pexit("fopen: %s", cfg_name); } } number = 0; while (fgetl(line, sizeof(line), file)) if (cfg_process_line(line, ++number)) cfg_error(cfg_name, number); if (ferror(file)) pexit("fgets"); if (fclose(file)) pexit("fclose"); }
// Only called at load time, so does not have to be overly optimal char *dynamic_Demangle(char *Line, int *Len) { char *tmp, *cp, *cp2, digits[3]; if (!Line || !strlen(Line)) { if (Len) *Len = 0; return str_alloc_copy(""); } tmp = str_alloc_copy(Line); cp = tmp; cp2 = Line; while (*cp2) { if (*cp2 != '\\') *cp++ = *cp2++; else { ++cp2; if (*cp2 == '\\') *cp++ = *cp2++; else { unsigned val; if (*cp2 != 'x') { *cp++ = '\\'; continue; } ++cp2; if (!cp2[0]) { *cp++ = '\\'; *cp++ = 'x'; continue; } digits[0] = *cp2++; if (!cp2[0] || !ishexdigit(digits[0])) { *cp++ = '\\'; *cp++ = 'x'; *cp++ = digits[0]; continue; } digits[1] = *cp2++; if (!ishexdigit(digits[1])) { *cp++ = '\\'; *cp++ = 'x'; *cp++ = digits[0]; *cp++ = digits[1]; continue; } digits[2] = 0; val = (unsigned)strtol(digits, NULL, 16); sprintf(cp, "%c", val); ++cp; } } } *cp = 0; if (Len) *Len = cp-tmp; return tmp; }
static void cfg_add_param(char *name, char *value) { struct cfg_param *current, *last; last = cfg_database->params; current = cfg_database->params = mem_alloc_tiny( sizeof(struct cfg_param), MEM_ALIGN_WORD); current->next = last; current->name = str_alloc_copy(name); current->value = str_alloc_copy(value); }
char *prepare_regex(char *regex, int *bCase, char **regex_alpha) { char *cp, *cp2; if (!regex || !bCase || !regex_alpha) { if (options.verbosity >= 4) log_event("- NO Rexgen used"); return 0; } cp = str_alloc_copy(regex); cp2 = cp; while (*cp2) { if (isupper((unsigned char)(*cp2))) *cp2 = tolower((unsigned char)(*cp2)); ++cp2; } *bCase = 0; *regex_alpha = NULL; if ((cp2 = strstr(cp, "case=")) != NULL) { // found case option. Set case and remove it. *bCase = 1; memmove(®ex[cp2-cp], ®ex[cp2-cp+5], strlen(®ex[cp2-cp+4])); memmove(cp2, &cp2[5], strlen(&cp2[4])); } cp2 = strstr(cp, "alpha:"); if (!cp2) cp2 = strstr(cp, "alpha="); if (cp2 != NULL) { // found case option. Set case and remove it. int i; *regex_alpha = str_alloc_copy(cp2); for (i = 1; (*regex_alpha)[i] && (*regex_alpha)[i] != '='; ++i) { } if ((*regex_alpha)[i] == '=') { (*regex_alpha)[i] = 0; } memmove(®ex[cp2-cp], ®ex[cp2-cp+i], strlen(®ex[cp2-cp+i-1])); memmove(cp2, &cp2[i], strlen(&cp2[i-1])); } if (*regex == '=') ++regex; if (!strstr(regex, "\\0") && !(*regex_alpha)) { fprintf(stderr, "--regex need to contain \"\\0\" in combination" " with wordist, or an alpha option\n"); error(); } else { log_event("- Rexgen (after rules): %s", regex); } return regex; }
static void process_shadow_line(char *line) { static struct shadow_entry **entry = NULL; struct shadow_entry *last; char *login, *passwd, *tail; if (!(passwd = strchr(line, ':'))) { while (*line == ' ' || *line == '\t') line++; /* AIX */ if (!strncmp(line, "password = "******"u_name=", 7)) { if ((passwd = strstr(passwd, ":u_pwd="))) passwd += 7; } else /* HP-UX tcb */ if (!strncmp(passwd, "u_pwd=", 6) && entry) { passwd += 6; if ((tail = strchr(passwd, ':'))) *tail = 0; (*entry)->passwd = str_alloc_copy(passwd); return; } if (passwd && (tail = strchr(passwd, ':'))) *tail = 0; entry = &shadow_table[login_hash(login)]; last = *entry; *entry = mem_alloc_tiny(sizeof(struct shadow_entry), MEM_ALIGN_WORD); (*entry)->next = last; (*entry)->login = str_alloc_copy(login); (*entry)->passwd = passwd ? str_alloc_copy(passwd) : "*"; }
static char *convert_old_name_if_needed(char *cpI) { if (!strncmp(cpI, "md5_gen(", 8)) { char *cp = mem_alloc_tiny(strlen(cpI)+6, MEM_ALIGN_NONE); char *cpo = &cp[sprintf(cp, "$dynamic_")]; cpI += 8; while (*cpI >= '0' && *cpI <= '9') *cpo++ = *cpI++; ++cpI; *cpo++ = '$'; strcpy(cpo, cpI); return cp; } return str_alloc_copy(cpI); }
static int opt_process_param(char *param, char *format, void *buffer) { if (format[0] == OPT_FMT_STR_ALLOC[0]) { *(char **)buffer = str_alloc_copy(param); return 0; } else if (format[0] == OPT_FMT_ADD_LIST[0]) { list_add(*(struct list_main **)buffer, param); return 0; } else if (format[0] == OPT_FMT_ADD_LIST_MULTI[0]) { list_add_multi(*(struct list_main **)buffer, param); return 0; } else return sscanf(param, format, buffer) != 1; }
static char *prepare(char *split_fields[10], struct fmt_main *self) { char *cp; if (!strncmp(split_fields[1], "M$", 2) && valid(split_fields[1], self)) return split_fields[1]; if (!split_fields[0]) return split_fields[1]; cp = mem_alloc(strlen(split_fields[0]) + strlen(split_fields[1]) + 14); sprintf(cp, "M$%s#%s", split_fields[0], split_fields[1]); if (valid(cp, self)) { char *cipher = str_alloc_copy(cp); MEM_FREE(cp); return cipher; } MEM_FREE(cp); return split_fields[1]; }
static void cfg_add_line(char *line, int number) { struct cfg_list *list; struct cfg_line *entry; entry = mem_alloc_tiny(sizeof(struct cfg_line), MEM_ALIGN_WORD); entry->next = NULL; entry->data = str_alloc_copy(line); entry->number = number; list = cfg_database->list; if (list->tail) list->tail = list->tail->next = entry; else list->tail = list->head = entry; }
static char *prepare(char *split_fields[10], struct fmt_main *self) { char *srv_challenge = split_fields[3]; char *nethashv2 = split_fields[4]; char *cli_challenge = split_fields[5]; char *login = split_fields[0]; char *uid = split_fields[2]; char *identity = NULL, *tmp; if (!strncmp(split_fields[1], "$NETLMv2$", 9)) return split_fields[1]; if (!split_fields[0]||!split_fields[2]||!split_fields[3]||!split_fields[4]||!split_fields[5]) return split_fields[1]; /* DOMAIN\USER: -or- USER::DOMAIN: */ if ((tmp = strstr(login, "\\")) != NULL) { identity = (char *) mem_alloc(strlen(login)); strcpy(identity, tmp + 1); /* Upper-Case Username - Not Domain */ enc_strupper(identity); strncat(identity, login, tmp - login); } else { identity = (char *) mem_alloc(strlen(login) + strlen(uid) + 1); strcpy(identity, login); enc_strupper(identity); strcat(identity, uid); } tmp = (char *) mem_alloc(9 + strlen(identity) + 1 + strlen(srv_challenge) + 1 + strlen(nethashv2) + 1 + strlen(cli_challenge) + 1); sprintf(tmp, "$NETLMv2$%s$%s$%s$%s", identity, srv_challenge, nethashv2, cli_challenge); MEM_FREE(identity); if (valid(tmp, self)) { char *cp = str_alloc_copy(tmp); MEM_FREE(tmp); return cp; } MEM_FREE(tmp); return split_fields[1]; }
static void cfg_add_section(char *name) { struct cfg_section *last; last = cfg_database; cfg_database = mem_alloc_tiny( sizeof(struct cfg_section), MEM_ALIGN_WORD); cfg_database->next = last; cfg_database->name = str_alloc_copy(name); cfg_database->params = NULL; if (!strncmp(name, "list.", 5)) { cfg_database->list = mem_alloc_tiny( sizeof(struct cfg_list), MEM_ALIGN_WORD); cfg_database->list->head = cfg_database->list->tail = NULL; } else { cfg_database->list = NULL; } }
static void ldr_load_pw_line(struct db_main *db, char *line) { static int skip_dupe_checking = 0; struct fmt_main *format; int index, count; char *login, *ciphertext, *gecos, *home; char *piece; void *binary, *salt; int salt_hash, pw_hash; struct db_salt *current_salt, *last_salt; struct db_password *current_pw, *last_pw; struct list_main *words; size_t pw_size, salt_size; count = ldr_split_line(&login, &ciphertext, &gecos, &home, NULL, &db->format, db->options, line); if (count <= 0) return; if (count >= 2) db->options->flags |= DB_SPLIT; format = db->format; words = NULL; if (db->options->flags & DB_WORDS) { pw_size = sizeof(struct db_password); salt_size = sizeof(struct db_salt); } else { if (db->options->flags & DB_LOGIN) pw_size = sizeof(struct db_password) - sizeof(struct list_main *); else pw_size = sizeof(struct db_password) - (sizeof(char *) + sizeof(struct list_main *)); salt_size = sizeof(struct db_salt) - sizeof(struct db_keys *); } if (!db->password_hash) ldr_init_password_hash(db); for (index = 0; index < count; index++) { piece = format->methods.split(ciphertext, index, format); binary = format->methods.binary(piece); pw_hash = db->password_hash_func(binary); if (!(db->options->flags & DB_WORDS) && !skip_dupe_checking) { int collisions = 0; if ((current_pw = db->password_hash[pw_hash])) do { if (!memcmp(binary, current_pw->binary, format->params.binary_size) && !strcmp(piece, format->methods.source( current_pw->source, current_pw->binary))) { db->options->flags |= DB_NODUP; break; } if (++collisions <= LDR_HASH_COLLISIONS_MAX) continue; if (format->params.binary_size) fprintf(stderr, "Warning: " "excessive partial hash " "collisions detected\n%s", db->password_hash_func != fmt_default_binary_hash ? "" : "(cause: the \"format\" lacks " "proper binary_hash() function " "definitions)\n"); else fprintf(stderr, "Warning: " "check for duplicates partially " "bypassed to speedup loading\n"); skip_dupe_checking = 1; current_pw = NULL; /* no match */ break; } while ((current_pw = current_pw->next_hash)); if (current_pw) continue; } salt = format->methods.salt(piece); salt_hash = format->methods.salt_hash(salt); if ((current_salt = db->salt_hash[salt_hash])) do { if (!memcmp(current_salt->salt, salt, format->params.salt_size)) break; } while ((current_salt = current_salt->next)); if (!current_salt) { last_salt = db->salt_hash[salt_hash]; current_salt = db->salt_hash[salt_hash] = mem_alloc_tiny(salt_size, MEM_ALIGN_WORD); current_salt->next = last_salt; current_salt->salt = mem_alloc_copy(salt, format->params.salt_size, format->params.salt_align); current_salt->index = fmt_dummy_hash; current_salt->bitmap = NULL; current_salt->list = NULL; current_salt->hash = ¤t_salt->list; current_salt->hash_size = -1; current_salt->count = 0; if (db->options->flags & DB_WORDS) current_salt->keys = NULL; db->salt_count++; } current_salt->count++; db->password_count++; last_pw = current_salt->list; current_pw = current_salt->list = mem_alloc_tiny( pw_size, MEM_ALIGN_WORD); current_pw->next = last_pw; last_pw = db->password_hash[pw_hash]; db->password_hash[pw_hash] = current_pw; current_pw->next_hash = last_pw; /* If we're not going to use the source field for its usual purpose, see if we * can pack the binary value in it. */ if (format->methods.source != fmt_default_source && sizeof(current_pw->source) >= format->params.binary_size) current_pw->binary = memcpy(¤t_pw->source, binary, format->params.binary_size); else current_pw->binary = mem_alloc_copy(binary, format->params.binary_size, format->params.binary_align); if (format->methods.source == fmt_default_source) current_pw->source = str_alloc_copy(piece); if (db->options->flags & DB_WORDS) { if (!words) words = ldr_init_words(login, gecos, home); current_pw->words = words; } if (db->options->flags & DB_LOGIN) { if (count >= 2 && count <= 9) { current_pw->login = mem_alloc_tiny( strlen(login) + 3, MEM_ALIGN_NONE); sprintf(current_pw->login, "%s:%d", login, index + 1); } else if (login == no_username) current_pw->login = login; else if (words && *login) current_pw->login = words->head->data; else current_pw->login = str_alloc_copy(login); } } }
int main(int argc, char **argv) { int i, retval = SUCCESS; #if defined (HAVE_WORKING_FORK) pid_t cpid; FILE *fscore; #endif #if defined (HAVE_ASSERT_H) && defined (SHORT_PASSWORDS) assert(MAX_PLAIN_SIZE < 16); #endif /* set the default values for `usr_opt' */ memset(&usr_opt, 0, sizeof(usr_opt)); usr_opt.verbose = 1; #if defined (DEV_RANDOM_SUPPORT) usr_opt.cryptopt.get_entropy = get_dev_entropy; #elif defined (EGD_SUPPORT) usr_opt.cryptopt.get_entropy = get_egd_entropy; #else usr_opt.cryptopt.get_entropy = get_sys_entropy; #endif opt_parse(argc, argv, &usr_opt); #if defined (HAVE_UMASK) /* set umask for security reasons */ umask(0077); #endif switch (usr_opt.action) { case crypt_ios: case crypt_pix: if (argc != optind + 1) tty_error(ERR_USAGE, "no string to crypt"); usr_opt.cryptopt.plain = (u_char *) str_alloc_copy(argv[optind]); retval = (usr_opt.action == crypt_ios) ? crypt_ios_fe(usr_opt.cryptopt.plain, usr_opt.cryptopt.salt) : crypt_pix_fe(usr_opt.cryptopt.plain); break; case decrypt_bf: case decrypt_wl: if (argc != optind + 1) tty_error(ERR_USAGE, "no password to decrypt"); usr_opt.decryptopt.cipher = (u_char *) str_alloc_copy(argv[optind]); /* no break here! */ case resume: /* if `decrypt_bf', `decrypt_wl', `resume_bf', `resume_wl', * create the restore file in case of an abort event */ save_session_if_signal_abort = true; if (usr_opt.action == resume) { if (argc != optind) tty_error(ERR_USAGE, "bad argument found `%s'", argv[optind]); session_load(usr_opt.decryptopt.restore_file); /* `usr_opt.decryptopt.regexpr' can be NULL, * so we must check `usr_opt.decryptopt.wordlist' */ usr_opt.action = usr_opt.decryptopt.wordlist ? resume_wl: resume_bf; } #if defined (HAVE_WORKING_FORK) if (usr_opt.daemonize) { cpid = fork(); if (cpid == (pid_t) 0) { /* child process */ /* checks the SCORE_FILE format */ fcheck(SCORE_FILE, HEAD_SCORE_TEXT); /* add the line `HEAD_SCORE_TEXT"\n"' at the begin, * if the file do not exists */ if (!(fscore = fopen(SCORE_FILE, "r"))) { fscore = fopen(SCORE_FILE, "w"); fprintf(fscore, HEAD_SCORE_TEXT"\n"); } fclose(fscore); tty_message ("%s -- running in daemon mode" #if defined (HAVE_GETPID) " [pid: %d]" #endif "...\n** WARNING: " "sensible data could be written in the file `%s'!\n", *argv, #if defined (HAVE_GETPID) (int) getpid(), #endif SCORE_FILE); /* point stdin/stdout/stderr to /dev/null */ for (i = 0; i < 3; i++) close(i); i = open(NULL_DEV, O_RDWR); if (i >= 0) { dup2(i, 0); dup2(i, 1); dup2(i, 2); if (i > 2) close(i); } retval = cisco_decrypt(); return retval; } else if (cpid < (pid_t) 0) tty_error(ERR_FORKING, "cannot run in daemon mode : %s", strerror(errno)); else return SUCCESS; /* parent process */ } else #endif retval = cisco_decrypt(); break; default: /* not enought paramethers entered */ tty_error(ERR_USAGE, "nothing to do (?)"); } mem_free_all(); return retval; }
void rec_restore_args(int lock) { char line[LINE_BUFFER_SIZE]; int index, argc; char **argv; char *save_rec_name; rec_name_complete(); if (!(rec_file = fopen(path_expand(rec_name), "r+"))) { if (options.fork && !john_main_process && errno == ENOENT) { fprintf(stderr, "%u Session completed\n", options.node_min); if (options.flags & FLG_STATUS_CHK) return; log_event("No crash recovery file, terminating"); log_done(); exit(0); } pexit("fopen: %s", path_expand(rec_name)); } rec_fd = fileno(rec_file); if (lock) rec_lock(); if (!fgetl(line, sizeof(line), rec_file)) rec_format_error("fgets"); rec_version = 0; if (!strcmp(line, RECOVERY_V4)) rec_version = 4; else if (!strcmp(line, RECOVERY_V3)) rec_version = 3; else if (!strcmp(line, RECOVERY_V2)) rec_version = 2; else if (!strcmp(line, RECOVERY_V1)) rec_version = 1; else if (strcmp(line, RECOVERY_V0)) rec_format_error(NULL); if (fscanf(rec_file, "%d\n", &argc) != 1) rec_format_error("fscanf"); if (argc < 2) rec_format_error(NULL); argv = mem_alloc_tiny(sizeof(char *) * (argc + 1), MEM_ALIGN_WORD); argv[0] = "john"; for (index = 1; index < argc; index++) if (fgetl(line, sizeof(line), rec_file)) argv[index] = str_alloc_copy(line); else rec_format_error("fgets"); argv[argc] = NULL; save_rec_name = rec_name; opt_init(argv[0], argc, argv); rec_name = save_rec_name; rec_name_completed = 1; if (fscanf(rec_file, "%u\n%u\n%x\n%x\n", &status_restored_time, &status.guess_count, &status.combs.lo, &status.combs.hi) != 4) rec_format_error("fscanf"); if (!status_restored_time) status_restored_time = 1; if (rec_version >= 4) { if (fscanf(rec_file, "%x\n%x\n%x\n%x\n%x\n%d\n", &status.combs_ehi, &status.crypts.lo, &status.crypts.hi, &status.cands.lo, &status.cands.hi, &status.compat) != 6) rec_format_error("fscanf"); } else { /* Historically, we were reusing what became the combs field for candidates * count when in --stdout mode */ status.cands = status.combs; status.compat = 1; } if (rec_version == 0) { status.pass = 0; status.progress = -1; } else if (fscanf(rec_file, "%d\n%d\n", &status.pass, &status.progress) != 2) rec_format_error("fscanf"); if (status.pass < 0 || status.pass > 3) rec_format_error(NULL); if (rec_version < 3) rec_check = 0; else if (fscanf(rec_file, "%x\n", &rec_check) != 1) rec_format_error("fscanf"); rec_restoring_now = 1; }
void rec_restore_args(int lock) { char line[LINE_BUFFER_SIZE]; int index, argc; char **argv; char *save_rec_name; rec_name_complete(); if (!(rec_file = fopen(path_expand(rec_name), "r+"))) { #ifndef HAVE_MPI if (options.fork && !john_main_process && errno == ENOENT) { #else if (options.node_min > 1 && errno == ENOENT) { #endif fprintf(stderr, "%u Session completed\n", options.node_min); if (options.flags & FLG_STATUS_CHK) return; log_event("No crash recovery file, terminating"); log_done(); #ifdef HAVE_MPI mpi_teardown(); #endif exit(0); } #ifdef HAVE_MPI if (mpi_p > 1) { fprintf(stderr, "%u@%s: fopen: %s: %s\n", mpi_id + 1, mpi_name, path_expand(rec_name), strerror(errno)); error(); } #endif pexit("fopen: %s", path_expand(rec_name)); } rec_fd = fileno(rec_file); if (lock) rec_lock(lock); if (!fgetl(line, sizeof(line), rec_file)) rec_format_error("fgets"); rec_version = 0; if (!strcmp(line, RECOVERY_V4)) rec_version = 4; else if (!strcmp(line, RECOVERY_V3)) rec_version = 3; else if (!strcmp(line, RECOVERY_V2)) rec_version = 2; else if (!strcmp(line, RECOVERY_V1)) rec_version = 1; else if (strcmp(line, RECOVERY_V0)) rec_format_error(NULL); if (fscanf(rec_file, "%d\n", &argc) != 1) rec_format_error("fscanf"); if (argc < 2) rec_format_error(NULL); argv = mem_alloc_tiny(sizeof(char *) * (argc + 1), MEM_ALIGN_WORD); argv[0] = "john"; for (index = 1; index < argc; index++) if (fgetl(line, sizeof(line), rec_file)) argv[index] = str_alloc_copy(line); else rec_format_error("fgets"); argv[argc] = NULL; save_rec_name = rec_name; opt_init(argv[0], argc, argv, 0); rec_name = save_rec_name; rec_name_completed = 1; if (fscanf(rec_file, "%u\n%u\n%x\n%x\n", &status_restored_time, &status.guess_count, &status.combs.lo, &status.combs.hi) != 4) rec_format_error("fscanf"); if (!status_restored_time) status_restored_time = 1; if (rec_version >= 4) { if (fscanf(rec_file, "%x\n%x\n%x\n%x\n%x\n%d\n", &status.combs_ehi, &status.crypts.lo, &status.crypts.hi, &status.cands.lo, &status.cands.hi, &status.compat) != 6) rec_format_error("fscanf"); } else { /* Historically, we were reusing what became the combs field for candidates * count when in --stdout mode */ status.cands = status.combs; status.compat = 1; } if (rec_version == 0) { status.pass = 0; status.progress = -1; } else if (fscanf(rec_file, "%d\n%d\n", &status.pass, &status.progress) != 2) rec_format_error("fscanf"); if (status.pass < 0 || status.pass > 3) rec_format_error(NULL); if (rec_version < 3) rec_check = 0; else if (fscanf(rec_file, "%x\n", &rec_check) != 1) rec_format_error("fscanf"); rec_restoring_now = 1; } void rec_restore_mode(int (*restore_mode)(FILE *file)) { rec_name_complete(); if (!rec_file) return; if (restore_mode) if (restore_mode(rec_file)) rec_format_error("fscanf"); if (options.flags & FLG_MASK_STACKED) if (mask_restore_state(rec_file)) rec_format_error("fscanf"); /* * Unlocking the file explicitly is normally not necessary since we're about to * close it anyway (which would normally release the lock). However, when * we're the main process running with --fork, our newborn children may hold a * copy of the fd for a moment (until they close the fd themselves). Thus, if * we don't explicitly remove the lock, there may be a race condition between * our children closing the fd and us proceeding to re-open and re-lock it. */ rec_unlock(); if (fclose(rec_file)) pexit("fclose"); rec_file = NULL; rec_restoring_now = 0; }
void SetupAlpha(const char *regex_alpha) { int i; struct cfg_list *list; // first off, set 'normal' strings for each char (i.e. 'a' outputs "a") for (i = 0; i < 256; ++i) { char *cp = (char*)mem_alloc_tiny(2,1); *cp = i; cp[1] = 0; rexgen_alphabets[i] = cp; } // we have to escape these (they are regex 'special' chars), so when we SEE them in code, we output them exactly as we see them rexgen_alphabets[(unsigned char)('[')] = str_alloc_copy("(\\[)"); rexgen_alphabets[(unsigned char)(']')] = str_alloc_copy("(\\])"); rexgen_alphabets[(unsigned char)('(')] = str_alloc_copy("(\\()"); rexgen_alphabets[(unsigned char)(')')] = str_alloc_copy("(\\))"); rexgen_alphabets[(unsigned char)('{')] = str_alloc_copy("(\\{)"); rexgen_alphabets[(unsigned char)('}')] = str_alloc_copy("(\\})"); rexgen_alphabets[(unsigned char)('|')] = str_alloc_copy("(\\|)"); rexgen_alphabets[(unsigned char)('.')] = str_alloc_copy("(\\.)"); rexgen_alphabets[(unsigned char)('?')] = str_alloc_copy("(\\?)"); rexgen_alphabets[(unsigned char)('\\')] = str_alloc_copy("(\\\\)"); // Now add the replacements from john.conf file. if ((list = cfg_get_list("list.rexgen.alpha", (char*) (®ex_alpha[5])))) { struct cfg_line *x = list->head; while (x) { if (x->data && x->data[1] == '=') rexgen_alphabets[(unsigned char)(x->data[0])] = str_alloc_copy(&(x->data[2])); x = x->next; } } }
static u_char bruteforce(void) { u_char salt[MD5_SALT_SIZE], *plaintext; #if defined(HAVE_TERMIOS_H) && defined(HAVE_DEV_TTY) char ch; #endif char **alphabet; int *chposi, *vsize, i, j; #if defined (HAVE_WORKING_FORK) FILE *fout; #endif /* initialize data */ strncpy((char *) salt, (char *) (usr_opt.decryptopt.cipher + MD5_MAGIC_SIZE), MD5_SALT_SIZE); plaintext = zmem_alloc(MAX_PLAIN_SIZE + 1); if (usr_opt.action != resume_bf) chpos = zmem_alloc(MAX_PLAIN_SIZE * sizeof(*chpos)); chpos_safe = zmem_alloc(MAX_PLAIN_SIZE * sizeof(*chpos_safe)); vsize = zmem_alloc(MAX_PLAIN_SIZE * sizeof(*vsize)); /* set the alphabet(s) used reading/parsing the relate argv */ alphabet = zmem_alloc(MAX_PLAIN_SIZE * sizeof(*alphabet)); /* option `-b' with no `regexpr' set */ if (!usr_opt.decryptopt.regexpr) usr_opt.decryptopt.regexpr = str_alloc_copy(ALPHABET_FULL); regex_explode(alphabet, usr_opt.decryptopt.regexpr, &usr_opt.decryptopt.fromlen, &usr_opt.decryptopt.tolen); if (usr_opt.action == resume_bf) { for (i = 0; i < usr_opt.decryptopt.tolen; i++) { vsize[i] = strlen(alphabet[i]); if (chpos[i] > vsize[i]) tty_error(ERR_INFO_RFILE, "illegal `chpos' value load from restore file"); } /* no errors in the restore file, so it can be safely removed here */ if (remove(usr_opt.decryptopt.restore_file) == -1) tty_warning("cannot remove the file `%s'", usr_opt.decryptopt.restore_file); } else { actual_len = usr_opt.decryptopt.fromlen; for (i = 0; i < usr_opt.decryptopt.tolen; i++) { chpos[i] = chpos_safe[i] = 0; vsize[i] = strlen(alphabet[i]); } } if (usr_opt.verbose) { /* some infos, just to let the user check the input entered */ tty_message("trying to crack : \"%s\"\n" "method used : bruteforce\n" "password scheme : ", usr_opt.decryptopt.cipher); tty_message("%s %s\n", usr_opt.decryptopt.regexpr, !strcmp(usr_opt.decryptopt.regexpr, ALPHABET_FULL) ? "(full search)" : ""); if (usr_opt.verbose > 2) { tty_message("expanded password scheme :\n"); i = 0; while (i < usr_opt.decryptopt.tolen) { for (j = i + 1; j < usr_opt.decryptopt.tolen && alphabet[j] == alphabet[i]; j++); if (j - 1 > i) { tty_message(" p[%d..%d] = \"%s\"\n", i, j - 1, alphabet[i]); i = j; } else { tty_message(" p[%d] = \"%s\"\n", i, alphabet[i]); i++; } } } tty_message("length of strings : "); if (usr_opt.decryptopt.fromlen != usr_opt.decryptopt.tolen) tty_message("[%d..%d]\n", usr_opt.decryptopt.fromlen, usr_opt.decryptopt.tolen); else tty_message("%d\n", usr_opt.decryptopt.fromlen); if (usr_opt.action == resume_bf) tty_message("\nrestoring session stopped on %s\n", usr_opt.decryptopt.saved_date); tty_message("\nplease wait... "); #if defined(HAVE_TERMIOS_H) && defined(HAVE_DEV_TTY) tty_message("\n[type <ENTER> to display the current plaintext] "); #endif } /* initialize the first plaintext to be used */ for (i = 0; i < actual_len; i++) plaintext[i] = alphabet[i][chpos[i]]; while (1) { #if defined(HAVE_TERMIOS_H) && defined(HAVE_DEV_TTY) if (read(tty_fd, &ch, 1) > 0 && usr_opt.verbose) tty_message("%s", plaintext); #endif #if 0 /* begin of DEBUG CODE */ fprintf(stderr, "\n%s\n", plaintext); for (i = 0; i < usr_opt.decryptopt.tolen; i++) fprintf(stderr, "chpos[%d] = %d\n", i, chpos[i]); fflush(stderr); /* end of DEBUG CODE */ #endif if (!strcmp((cipher_engine == cisco_ios_cipher ? cisco_ios_crypt(plaintext, salt) : cisco_pix_crypt(plaintext)) + MD5_PREAMBLE_SIZE, (char *) (usr_opt.decryptopt.cipher + MD5_PREAMBLE_SIZE))) { #if defined(HAVE_WORKING_FORK) if (usr_opt.daemonize) { if ((fout = fopen(SCORE_FILE, "a"))) { fprintf(fout, "** FOUND: \"%s\" (%s)\n", plaintext, usr_opt.decryptopt.cipher); fclose(fout); } } else #endif tty_message(usr_opt.verbose ? "\n** FOUND: \"%s\"\n" : "%s\n", plaintext); i = 0; while (i < actual_len) { mem_free(alphabet[i++]); /* skip the duplicates alphabets */ while (alphabet[i] == alphabet[i - 1]) i++; } return SUCCESS; } /* if `++chpos[i] % vsize[i]' is zero then all the letters of * `alphabet[i]' has been checked, so skip to the previous * letter (`i--') of `plaintext' */ i = 0; memcpy(chpos_safe, chpos, MAX_PLAIN_SIZE * sizeof(*chpos_safe)); do { chposi = chpos + i; *chposi = ++(*chposi) % vsize[i]; plaintext[i] = alphabet[i][*chposi]; } while (++i != actual_len && !*chposi); if (i == actual_len && !chpos[actual_len - 1]) { if (actual_len++ == usr_opt.decryptopt.tolen) { #if defined (HAVE_WORKING_FORK) if (usr_opt.daemonize) { if ((fout = fopen(SCORE_FILE, "a"))) { fprintf(fout, "** FAILURE: (%s)\n" " password scheme : %s\n" " length of strings : [%d..%d]\n", usr_opt.decryptopt.cipher, usr_opt.decryptopt.regexpr, usr_opt.decryptopt.fromlen, usr_opt.decryptopt.tolen); fclose(fout); } } else #endif tty_message("\n** FAILURE: the cipher string doesn't " "match the password scheme you set\n"); i = 0; while (i < actual_len) { mem_free(alphabet[i++]); /* skip the duplicates alphabets */ while (alphabet[i] == alphabet[i - 1]) i++; } return FAILURE; } tty_message("\n** NOTE: switching to lenght `%ld', " "please wait... ", actual_len); plaintext[actual_len - 1] = alphabet[actual_len - 1][0]; } } }
static void john_load_conf(void) { int internal, target; if (!(options.flags & FLG_VERBOSITY)) { options.verbosity = cfg_get_int(SECTION_OPTIONS, NULL, "Verbosity"); if (options.verbosity == -1) options.verbosity = 3; if (options.verbosity < 1 || options.verbosity > 5) { if (john_main_process) fprintf(stderr, "Invalid verbosity " "level in config file, use 1-5\n"); error(); } } if (pers_opts.activepot == NULL) { if (options.secure) pers_opts.activepot = str_alloc_copy(SEC_POT_NAME); else pers_opts.activepot = str_alloc_copy(POT_NAME); } if (pers_opts.activewordlistrules == NULL) if (!(pers_opts.activewordlistrules = cfg_get_param(SECTION_OPTIONS, NULL, "BatchModeWordlistRules"))) pers_opts.activewordlistrules = str_alloc_copy(SUBSECTION_WORDLIST); if (pers_opts.activesinglerules == NULL) if (!(pers_opts.activesinglerules = cfg_get_param(SECTION_OPTIONS, NULL, "SingleRules"))) pers_opts.activesinglerules = str_alloc_copy(SUBSECTION_SINGLE); if ((options.flags & FLG_LOOPBACK_CHK) && !(options.flags & FLG_RULES)) { if ((pers_opts.activewordlistrules = cfg_get_param(SECTION_OPTIONS, NULL, "LoopbackRules"))) options.flags |= FLG_RULES; } if ((options.flags & FLG_WORDLIST_CHK) && !(options.flags & FLG_RULES)) { if ((pers_opts.activewordlistrules = cfg_get_param(SECTION_OPTIONS, NULL, "WordlistRules"))) options.flags |= FLG_RULES; } options.secure = cfg_get_bool(SECTION_OPTIONS, NULL, "SecureMode", 0); options.reload_at_crack = cfg_get_bool(SECTION_OPTIONS, NULL, "ReloadAtCrack", 1); options.reload_at_save = cfg_get_bool(SECTION_OPTIONS, NULL, "ReloadAtSave", 1); options.abort_file = cfg_get_param(SECTION_OPTIONS, NULL, "AbortFile"); options.pause_file = cfg_get_param(SECTION_OPTIONS, NULL, "PauseFile"); /* This is --crack-status. We toggle here, so if it's enabled in john.conf, we can disable it using the command line option */ if (cfg_get_bool(SECTION_OPTIONS, NULL, "CrackStatus", 0)) options.flags ^= FLG_CRKSTAT; #if HAVE_OPENCL if (cfg_get_bool(SECTION_OPTIONS, SUBSECTION_OPENCL, "ForceScalar", 0)) options.flags |= FLG_SCALAR; #endif options.loader.log_passwords = options.secure || cfg_get_bool(SECTION_OPTIONS, NULL, "LogCrackedPasswords", 0); if (!pers_opts.input_enc && !(options.flags & FLG_TEST_CHK)) { if ((options.flags & FLG_LOOPBACK_CHK) && cfg_get_bool(SECTION_OPTIONS, NULL, "UnicodeStoreUTF8", 0)) pers_opts.input_enc = cp_name2id("UTF-8"); else { pers_opts.input_enc = cp_name2id(cfg_get_param(SECTION_OPTIONS, NULL, "DefaultEncoding")); } pers_opts.default_enc = pers_opts.input_enc; } /* Pre-init in case some format's prepare() needs it */ internal = pers_opts.internal_enc; target = pers_opts.target_enc; initUnicode(UNICODE_UNICODE); pers_opts.internal_enc = internal; pers_opts.target_enc = target; pers_opts.unicode_cp = CP_UNDEF; }
int dynamic_LOAD_PARSER_FUNCTIONS(int which, struct fmt_main *pFmt) { int ret, cnt; struct cfg_line *gen_line; nPreloadCnt = 0; nFuncCnt = 0; if (!dynamic_LOAD_PARSER_SIGNATURE(which)) { #ifdef HAVE_MPI if (mpi_id == 0) #endif fprintf(stderr, "Could not find section [List.Generic:dynamic_%d] in the john.ini/conf file\n", which); error(); } // Setup the 'default' format name sprintf(SetupName, "$dynamic_%d$", which); sprintf(SetupNameID, "dynamic_%d", which); Setup.szFORMAT_NAME = str_alloc_copy(SetupName); // allocate (and set null) enough file pointers cnt = Count_Items("Func="); Setup.pFuncs = mem_alloc_tiny((cnt+1)*sizeof(DYNAMIC_primitive_funcp), MEM_ALIGN_WORD); memset(Setup.pFuncs, 0, (cnt+1)*sizeof(DYNAMIC_primitive_funcp)); // allocate (and set null) enough Preloads cnt = Count_Items("Test="); cnt += Count_Items("TestU="); cnt += Count_Items("TestA="); Setup.pPreloads = mem_alloc_tiny((cnt+1)*sizeof(struct fmt_tests), MEM_ALIGN_WORD); memset(Setup.pPreloads, 0, (cnt+1)*sizeof(struct fmt_tests)); // allocate (and set null) enough constants (if we have 8, we still need a null to specify the end of the list) cnt = Count_Items("CONST"); Setup.pConstants = mem_alloc_tiny((cnt+1)*sizeof(DYNAMIC_Constants), MEM_ALIGN_WORD); memset(Setup.pConstants, 0, (cnt+1)*sizeof(DYNAMIC_Constants)); Setup.flags = 0; Setup.startFlags = 0; Setup.SaltLen = 0; Setup.MaxInputLen = 0; // Ok, now 'grind' through the data I do know know how to use // the config stuff too much, so will grind for now, and later // go back over this, and do it 'right', if there is a right way gen_line = gen_source->head; while (gen_line) { if (!dynamic_LOAD_PARSER_FUNCTIONS_LoadLINE(gen_line)) { #ifdef HAVE_MPI if (mpi_id == 0) #endif fprintf(stderr, "Error parsing section [List.Generic:dynamic_%d]\nError in line %d file is %s\n", which, gen_line->number, gen_line->cfg_name); error(); } gen_line = gen_line->next; } ret = dynamic_SETUP(&Setup, pFmt); return ret; }
int dynamic_LOAD_PARSER_FUNCTIONS_LoadLINE(struct cfg_line *_line) { int nConst, j; char *Line = _line->data; char c = *Line; if (c >= 'A' && c <= 'Z') c ^= 0x20; // lower case. if (c == 't' && !strncasecmp(Line, "Test=", 5)) { char *cp; cp = convert_old_name_if_needed(&Line[5]); cp = GetFld(&(Setup.pPreloads[nPreloadCnt].ciphertext), cp); if (!Setup.pPreloads[nPreloadCnt].ciphertext || strncmp(Setup.pPreloads[nPreloadCnt].ciphertext, SetupName, strlen(SetupName))) return !fprintf(stderr, "Error, invalid test line (wrong generic type): %s\n", Line); cp = GetFld(&(Setup.pPreloads[nPreloadCnt].plaintext), cp); Setup.pPreloads[nPreloadCnt].plaintext = dynamic_Demangle(Setup.pPreloads[nPreloadCnt].plaintext); Setup.pPreloads[nPreloadCnt].flds[1] = str_alloc_copy(Setup.pPreloads[nPreloadCnt].ciphertext); for (j = 0; j < 10; ++j) { if (j==1) continue; cp = GetFld(&(Setup.pPreloads[nPreloadCnt].flds[j]), cp); } ++nPreloadCnt; return 1; } if (c == 't' && !strncasecmp(Line, "TestU=", 6)) { char *cp; if (!options.utf8) return 1; cp = convert_old_name_if_needed(&Line[6]); cp = GetFld(&(Setup.pPreloads[nPreloadCnt].ciphertext), cp); if (!Setup.pPreloads[nPreloadCnt].ciphertext || strncmp(Setup.pPreloads[nPreloadCnt].ciphertext, SetupName, strlen(SetupName))) return !fprintf(stderr, "Error, invalid test line (wrong generic type): %s\n", Line); cp = GetFld(&(Setup.pPreloads[nPreloadCnt].plaintext), cp); Setup.pPreloads[nPreloadCnt].plaintext = dynamic_Demangle(Setup.pPreloads[nPreloadCnt].plaintext); Setup.pPreloads[nPreloadCnt].flds[1] = str_alloc_copy(Setup.pPreloads[nPreloadCnt].ciphertext); for (j = 0; j < 10; ++j) { if (j==1) continue; cp = GetFld(&(Setup.pPreloads[nPreloadCnt].flds[j]), cp); } ++nPreloadCnt; return 1; } if (c == 't' && !strncasecmp(Line, "TestA=", 6)) { char *cp; if (options.utf8) return 1; cp = convert_old_name_if_needed(&Line[6]); cp = GetFld(&(Setup.pPreloads[nPreloadCnt].ciphertext), cp); if (!Setup.pPreloads[nPreloadCnt].ciphertext || strncmp(Setup.pPreloads[nPreloadCnt].ciphertext, SetupName, strlen(SetupName))) return !fprintf(stderr, "Error, invalid test line (wrong generic type): %s\n", Line); cp = GetFld(&(Setup.pPreloads[nPreloadCnt].plaintext), cp); Setup.pPreloads[nPreloadCnt].plaintext = dynamic_Demangle(Setup.pPreloads[nPreloadCnt].plaintext); Setup.pPreloads[nPreloadCnt].flds[1] = str_alloc_copy(Setup.pPreloads[nPreloadCnt].ciphertext); for (j = 0; j < 10; ++j) { if (j==1) continue; cp = GetFld(&(Setup.pPreloads[nPreloadCnt].flds[j]), cp); } ++nPreloadCnt; return 1; } if (c == 'c' && !strncasecmp(Line, "ColonChar=", 10)) { char *tmp = dynamic_Demangle(&Line[10]); if (!tmp) return !fprintf(stderr, "Error, invalid test line: %s\n", Line); options.loader.field_sep_char = *tmp; return 1; } if (c == 'f' && !strncasecmp(Line, "Func=", 5)) { int i; for (i = 0; MD5Gen_Predicate[i].name; ++i) { if (!strcmp(MD5Gen_Predicate[i].name, &Line[5])) { Setup.pFuncs[nFuncCnt++] = MD5Gen_Predicate[i].func; return 1; } } return !fprintf(stderr, "Error, unknown function: %s\n", Line); } if (c == 'f' && !strncasecmp(Line, "Flag=", 5)) { int i; for (i = 0; MD5Gen_Str_Flag[i].name; ++i) { if (!strcmp(MD5Gen_Str_Flag[i].name, &Line[5])) { Setup.flags |= MD5Gen_Str_Flag[i].flag_bit; return 1; } } for (i = 0; MD5Gen_Str_sFlag[i].name; ++i) { if (!strcmp(MD5Gen_Str_sFlag[i].name, &Line[5])) { Setup.startFlags |= MD5Gen_Str_sFlag[i].flag_bit; return 1; } } return !fprintf(stderr, "Error, unknown flag: %s\n", Line); } if (c == 's' && !strncasecmp(Line, "SaltLen=", 8)) { if (sscanf(&Line[7], "=%d", &Setup.SaltLen) == 1) return 1; return !fprintf(stderr, "Error, Invalid SaltLen= line: %s \n", Line); } if (c == 'm' && !strncasecmp(Line, "MaxInputLen=", 12)) { if (sscanf(&Line[11], "=%d", &Setup.MaxInputLen) == 1) return 1; return !fprintf(stderr, "Error, Invalid MaxInputLen= line: %s \n", Line); } if (c == 'e' && !strncasecmp(Line, "Expression=", 11)) { char tmp[256]; sprintf(tmp, "%s %s", SetupNameID, &Line[11]); Setup.szFORMAT_NAME = str_alloc_copy(tmp); return 1; } if (c == 'c' && !strncasecmp(Line, "const", 5)) { if (sscanf(&Line[5], "%d=", &nConst)!=1) return !fprintf(stderr, "Error, invalid const line. Line: %s\n", Line); if (nConst < 1 || nConst > 8) return !fprintf(stderr, "Error, only constants from 1 to 8 are valid. Line: %s\n", Line); if (strlen(Line) == 7) return !fprintf(stderr, "Error, a 'blank' constant is not valid. Line: %s\n", Line); if (Setup.pConstants[nConst-1].Const) return !fprintf(stderr, "Error, this constant has already entered. Line: %s\n", Line); Setup.pConstants[nConst-1].Const = dynamic_Demangle(&Line[7]); return 1; } return !fprintf(stderr, "Error, unknown line: %s\n", Line); }
static void ldr_load_pw_line(struct db_main *db, char *line) { struct fmt_main *format; int index, count; char *login, *ciphertext, *gecos, *home; char *piece; void *binary, *salt; int salt_hash, pw_hash; struct db_salt *current_salt, *last_salt; struct db_password *current_pw, *last_pw; struct list_main *words; size_t pw_size, salt_size; extern struct fmt_main fmt_mscash; extern struct fmt_main fmt_oracle; count = ldr_split_line(&login, &ciphertext, &gecos, &home, NULL, &db->format, db->options, line); if (count <= 0) return; if (count >= 2) db->options->flags |= DB_SPLIT; format = db->format; words = NULL; if (db->options->flags & DB_WORDS) { pw_size = sizeof(struct db_password); salt_size = sizeof(struct db_salt); } else { if (db->options->flags & DB_LOGIN) pw_size = sizeof(struct db_password) - sizeof(struct list_main *); else pw_size = sizeof(struct db_password) - (sizeof(char *) + sizeof(struct list_main *)); salt_size = sizeof(struct db_salt) - sizeof(struct db_keys *); } for (index = 0; index < count; index++) { if (db->format == &fmt_mscash) { piece = (char *) mem_alloc_tiny(strlen(login) + strlen(ciphertext) + 4, MEM_ALIGN_NONE); sprintf(piece, "M$%s#%s", login, ciphertext); } else if (db->format == &fmt_oracle) { piece = (char *) mem_alloc_tiny(strlen(login) + strlen(ciphertext) + 4, MEM_ALIGN_NONE); sprintf(piece, "O$%s#%s", login, ciphertext); } else piece = format->methods.split(ciphertext, index); binary = format->methods.binary(piece); pw_hash = LDR_HASH_FUNC(binary); if ((current_pw = db->password_hash[pw_hash])) do { if (!memcmp(current_pw->binary, binary, format->params.binary_size) && !strcmp(current_pw->source, piece)) { if (!(db->options->flags & DB_WORDS) || !strcmp(current_pw->login, login)) break; } } while ((current_pw = current_pw->next_hash)); if (current_pw) continue; salt = format->methods.salt(piece); salt_hash = format->methods.salt_hash(salt); if ((current_salt = db->salt_hash[salt_hash])) do { if (!memcmp(current_salt->salt, salt, format->params.salt_size)) break; } while ((current_salt = current_salt->next)); if (!current_salt) { last_salt = db->salt_hash[salt_hash]; current_salt = db->salt_hash[salt_hash] = mem_alloc_tiny(salt_size, MEM_ALIGN_WORD); current_salt->next = last_salt; current_salt->salt = mem_alloc_copy( format->params.salt_size, MEM_ALIGN_WORD, salt); current_salt->index = fmt_dummy_hash; current_salt->list = NULL; current_salt->hash = ¤t_salt->list; current_salt->hash_size = -1; current_salt->count = 0; if (db->options->flags & DB_WORDS) current_salt->keys = NULL; db->salt_count++; } current_salt->count++; db->password_count++; last_pw = current_salt->list; current_pw = current_salt->list = mem_alloc_tiny( pw_size, MEM_ALIGN_WORD); current_pw->next = last_pw; last_pw = db->password_hash[pw_hash]; db->password_hash[pw_hash] = current_pw; current_pw->next_hash = last_pw; current_pw->binary = mem_alloc_copy( format->params.binary_size, MEM_ALIGN_WORD, binary); current_pw->source = str_alloc_copy(piece); if (db->options->flags & DB_WORDS) { if (!words) words = ldr_init_words(login, gecos, home); current_pw->words = words; } if (db->options->flags & DB_LOGIN) { if (count > 1) { current_pw->login = mem_alloc_tiny( strlen(login) + 3, MEM_ALIGN_NONE); sprintf(current_pw->login, "%s:%d", login, index + 1); } else if (words) current_pw->login = words->head->data; else current_pw->login = str_alloc_copy(login); } } }
static void opt_parse(int argc, char **argv, t_options *opt) { int argval, n, opt_set[opt_last]; /* initialize `opt_set' with the value 0 (option not used) */ for (n = 0; n < opt_last; n++) opt_set[n] = opt_unset; /* process the options */ opterr = 0; while (1) { argval = getopt_long(argc, argv, optstring, longopts, NULL); if (argval == -1) break; switch (argval) { case 0: break; case 'c': opt_set[opt_c]++; opt->action = crypt_ios; break; case 's': /* set the salt string (4 character long) */ opt_set[opt_s]++; opt->action = crypt_ios; if (strlen(optarg) != MD5_SALT_SIZE) tty_error(ERR_USAGE, "bad length (not %d bytes) for salt `%s'", MD5_SALT_SIZE, optarg); opt->cryptopt.salt = (u_char *) str_alloc_copy(optarg); break; #ifdef EGD_SUPPORT case 'e': opt_set[opt_e]++; opt->cryptopt.get_entropy = get_egd_entropy; if (optarg) opt->cryptopt.egd_path = str_alloc_copy(optarg); break; #endif #ifdef DEV_RANDOM_SUPPORT case 'd': opt_set[opt_d]++; opt->cryptopt.get_entropy = get_dev_entropy; break; #endif #if defined (EGD_SUPPORT) || defined (DEV_RANDOM_SUPPORT) case 'y': opt_set[opt_y]++; opt->cryptopt.get_entropy = get_sys_entropy; break; #endif case 'p': opt_set[opt_p]++; opt->action = crypt_pix; break; case 'l': opt_set[opt_l]++; n = sscanf(optarg, "%d:%d", &opt->decryptopt.fromlen, &opt->decryptopt.tolen); switch (n) { case 0: /* option --length used with no values */ usage(ERR_USAGE); break; case 1: /* only 'fromlen' set */ opt->decryptopt.tolen = opt->decryptopt.fromlen; case 2: if (opt->decryptopt.fromlen > opt->decryptopt.tolen) tty_error(ERR_USAGE, "bad order for `--length' limits"); if (opt->decryptopt.fromlen < 1) tty_error(ERR_USAGE, "illegal downlimit for `--length'"); if (opt->decryptopt.tolen > MAX_PLAIN_SIZE) tty_error(ERR_USAGE, "the `--length' upperlimit exceed `%d'", MAX_PLAIN_SIZE); } break; case 'b': /* try the brute-force attack */ opt_set[opt_b]++; opt->action = decrypt_bf; if (optarg) opt->decryptopt.regexpr = str_alloc_copy(optarg); break; case 'w': /* try the vocabulary attack */ opt_set[opt_w]++; opt->action = decrypt_wl; opt->decryptopt.wordlist = str_alloc_copy(optarg); break; #if defined (HAVE_WORKING_FORK) case 'D': opt_set[opt_D]++; opt->daemonize = 1; break; #endif case 'r': opt_set[opt_r]++; opt->action = resume; /* default rescue file is `RESTORE_FILE' */ opt->decryptopt.restore_file = optarg ? str_alloc_copy(optarg) : str_alloc_copy(RESTORE_FILE); break; case 'q': /* minimize the program output */ opt_set[opt_q]++; opt->verbose = 0; break; case 'h': /* help */ #if 0 opt_set[opt_h]++; #endif usage(SUCCESS); break; case 'v': /* verbose mode */ opt_set[opt_v]++; opt->verbose++; break; case 'L': #if 0 opt_set[opt_L]++; #endif license(); /* GPL license message */ exit(SUCCESS); break; case 'V': /* program name, version, etc. */ #if 0 opt_set[opt_V]++; #endif version(); exit(SUCCESS); break; case '?': tty_error(ERR_USAGE, "ambiguous match or extraneous parameter `%s'", argv[optind - 1]); break; default: /* should catch nothing (?) */ tty_error(ERR_USAGE, "illegal command line argument"); } } /* check for option inconsistences */ opt_check(opt_set); }