static void john_log_format(void) { int min_chunk, chunk; #ifdef HAVE_MPI if (mpi_p > 1) log_event("- MPI mode: %u nodes, this one running on %s", mpi_p, mpi_name); #endif /* make sure the format is properly initialized */ fmt_init(database.format); log_event("- Hash type: %.100s (lengths up to %d%s)", database.format->params.format_name, database.format->params.plaintext_length, (database.format == &fmt_DES || database.format == &fmt_LM) ? ", longer passwords split" : ""); log_event("- Algorithm: %.100s", database.format->params.algorithm_name); chunk = min_chunk = database.format->params.max_keys_per_crypt; if (options.flags & (FLG_SINGLE_CHK | FLG_BATCH_CHK) && chunk < SINGLE_HASH_MIN) chunk = SINGLE_HASH_MIN; if (chunk > 1) log_event("- Candidate passwords %s be buffered and " "tried in chunks of %d", min_chunk > 1 ? "will" : "may", chunk); }
static void john_log_format(void) { int min_chunk, chunk; /* make sure the format is properly initialized */ #if HAVE_OPENCL if (!(options.gpu_devices->count && options.fork && strstr(database.format->params.label, "-opencl"))) #endif fmt_init(database.format); log_event("- Hash type: %.100s%s%.100s (lengths up to %d%s)", database.format->params.label, database.format->params.format_name[0] ? ", " : "", database.format->params.format_name, database.format->params.plaintext_length, (database.format == &fmt_DES || database.format == &fmt_LM) ? ", longer passwords split" : ""); log_event("- Algorithm: %.100s", database.format->params.algorithm_name); chunk = min_chunk = database.format->params.max_keys_per_crypt; if (options.flags & (FLG_SINGLE_CHK | FLG_BATCH_CHK) && chunk < SINGLE_HASH_MIN) chunk = SINGLE_HASH_MIN; if (chunk > 1) log_event("- Candidate passwords %s be buffered and " "tried in chunks of %d", min_chunk > 1 ? "will" : "may", chunk); }
void fileinit(Void) { register char *s; register int i, j; lastiolabno = 100000; lastlabno = 0; lastvarno = 0; nliterals = 0; nerr = 0; infile = stdin; maxtoklen = 502; token = (char *)ckalloc(maxtoklen+2); memset(dflttype, tyreal, 26); memset(dflttype + 'i' - 'a', tyint, 6); memset(hextoi_tab, 16, sizeof(hextoi_tab)); for(i = 0, s = "0123456789abcdef"; *s; i++, s++) hextoi(*s) = i; for(i = 10, s = "ABCDEF"; *s; i++, s++) hextoi(*s) = i; for(j = 0, s = "abcdefghijklmnopqrstuvwxyz"; i = *s++; j++) Letters[i] = Letters[i+'A'-'a'] = j; ctls = ALLOCN(maxctl+1, Ctlframe); extsymtab = ALLOCN(maxext, Extsym); eqvclass = ALLOCN(maxequiv, Equivblock); hashtab = ALLOCN(maxhash, Hashentry); labeltab = ALLOCN(maxstno, Labelblock); litpool = ALLOCN(maxliterals, Literal); labarray = (struct Labelblock **)ckalloc(maxlablist* sizeof(struct Labelblock *)); fmt_init(); mem_init(); np_init(); ctlstack = ctls++; lastctl = ctls + maxctl; nextext = extsymtab; lastext = extsymtab + maxext; lasthash = hashtab + maxhash; labtabend = labeltab + maxstno; highlabtab = labeltab; main_alias[0] = '\0'; if (forcedouble) dfltproc[TYREAL] = dfltproc[TYDREAL]; /* Initialize the routines for providing C output */ out_init (); }
void assembler_init(const char *in_file) { char *f_buffer = f_load_file(in_file); if (f_buffer == NULL) { printf("compiler error: error on opening input file ...\n"); exit(EXIT_FAILURE); } ASM_DESCR.MAIN_FILE = f_process_file(f_buffer); fmt_init(); tokenizer_init(); parser_init(); icl_init(); }
static void john_load(void) { struct list_entry *current; #ifndef _MSC_VER umask(077); #endif if (options.flags & FLG_EXTERNAL_CHK) ext_init(options.external, NULL); if (options.flags & FLG_MAKECHR_CHK) { options.loader.flags |= DB_CRACKED; ldr_init_database(&database, &options.loader); if (options.flags & FLG_PASSWD) { ldr_show_pot_file(&database, pers_opts.activepot); database.options->flags |= DB_PLAINTEXTS; if ((current = options.passwd->head)) do { ldr_show_pw_file(&database, current->data); } while ((current = current->next)); } else { database.options->flags |= DB_PLAINTEXTS; ldr_show_pot_file(&database, pers_opts.activepot); } return; } if (options.flags & FLG_STDOUT) { ldr_init_database(&database, &options.loader); database.format = &dummy_format; memset(&dummy_format, 0, sizeof(dummy_format)); dummy_format.params.plaintext_length = options.length; dummy_format.params.flags = FMT_CASE | FMT_8_BIT; if (pers_opts.report_utf8 || pers_opts.target_enc == UTF_8) dummy_format.params.flags |= FMT_UTF8; dummy_format.params.label = "stdout"; dummy_format.methods.clear_keys = &fmt_default_clear_keys; pers_opts.target_enc = pers_opts.input_enc; john_load_conf_db(); } if (options.flags & FLG_PASSWD) { int total; #if FMT_MAIN_VERSION > 11 int i = 0; #endif if (options.flags & FLG_SHOW_CHK) { options.loader.flags |= DB_CRACKED; ldr_init_database(&database, &options.loader); ldr_show_pot_file(&database, pers_opts.activepot); if ((current = options.passwd->head)) do { ldr_show_pw_file(&database, current->data); } while ((current = current->next)); if (john_main_process) printf("%s%d password hash%s cracked, %d left\n", database.guess_count ? "\n" : "", database.guess_count, database.guess_count != 1 ? "es" : "", database.password_count - database.guess_count); return; } if (options.flags & (FLG_SINGLE_CHK | FLG_BATCH_CHK) && status.pass <= 1) options.loader.flags |= DB_WORDS; else if (mem_saving_level) { options.loader.flags &= ~DB_LOGIN; options.max_wordfile_memory = 1; } ldr_init_database(&database, &options.loader); if ((current = options.passwd->head)) do { ldr_load_pw_file(&database, current->data); } while ((current = current->next)); /* Process configuration options that depend on db/format */ john_load_conf_db(); if ((options.flags & FLG_CRACKING_CHK) && database.password_count) { log_init(LOG_NAME, NULL, options.session); if (status_restored_time) log_event("Continuing an interrupted session"); else log_event("Starting a new session"); log_event("Loaded a total of %s", john_loaded_counts()); /* make sure the format is properly initialized */ #if HAVE_OPENCL if (!(options.gpu_devices->count && options.fork && strstr(database.format->params.label, "-opencl"))) #endif fmt_init(database.format); if (john_main_process) printf("Loaded %s (%s%s%s [%s])\n", john_loaded_counts(), database.format->params.label, database.format->params.format_name[0] ? ", " : "", database.format->params.format_name, database.format->params.algorithm_name); // Tell External our max length if (options.flags & FLG_EXTERNAL_CHK) ext_init(options.external, &database); } total = database.password_count; ldr_load_pot_file(&database, pers_opts.activepot); ldr_fix_database(&database); if (!database.password_count) { log_discard(); if (john_main_process) printf("No password hashes %s (see FAQ)\n", total ? "left to crack" : "loaded"); #if FMT_MAIN_VERSION > 11 /* skip tunable cost reporting if no hashes were loaded */ i = FMT_TUNABLE_COSTS; #endif } else if (database.password_count < total) { log_event("Remaining %s", john_loaded_counts()); if (john_main_process) printf("Remaining %s\n", john_loaded_counts()); } #if FMT_MAIN_VERSION > 11 for ( ; i < FMT_TUNABLE_COSTS && database.format->methods.tunable_cost_value[i] != NULL; i++) { if (database.min_cost[i] < database.max_cost[i]) { log_event("Loaded hashes with cost %d (%s)" " varying from %u to %u", i+1, database.format->params.tunable_cost_name[i], database.min_cost[i], database.max_cost[i]); if (john_main_process) printf("Loaded hashes with cost %d (%s)" " varying from %u to %u\n", i+1, database.format->params.tunable_cost_name[i], database.min_cost[i], database.max_cost[i]); } else { // if (database.min_cost[i] == database.max_cost[i]) { log_event("Cost %d (%s) is %u for all loaded hashes", i+1, database.format->params.tunable_cost_name[i], database.min_cost[i]); } } #endif if ((options.flags & FLG_PWD_REQ) && !database.salts) exit(0); if (options.regen_lost_salts) build_fake_salts_for_regen_lost(database.salts); } /* Nefarious hack and memory leak. Among other problems, we'd want ldr_drop_database() after this, but it's built with mem_alloc_tiny() so it's not trivial. Works like a champ though. */ if (options.flags & FLG_LOOPBACK_CHK && database.format != &fmt_LM) { struct db_main loop_db; struct fmt_main *save_list = fmt_list; char *save_pot = pers_opts.activepot; fmt_list = &fmt_LM; options.loader.flags |= DB_CRACKED; ldr_init_database(&loop_db, &options.loader); pers_opts.activepot = options.wordlist ? options.wordlist : pers_opts.activepot; ldr_show_pot_file(&loop_db, pers_opts.activepot); loop_db.options->flags |= DB_PLAINTEXTS; if ((current = options.passwd->head)) do { ldr_show_pw_file(&loop_db, current->data); } while ((current = current->next)); if (loop_db.plaintexts->count) { log_event("- Reassembled %d split passwords for " "loopback", loop_db.plaintexts->count); if (john_main_process && options.verbosity > 3) fprintf(stderr, "Reassembled %d split passwords for " "loopback\n", loop_db.plaintexts->count); } database.plaintexts = loop_db.plaintexts; options.loader.flags &= ~DB_CRACKED; pers_opts.activepot = save_pot; fmt_list = save_list; } #ifdef _OPENMP john_omp_show_info(); #endif if (options.node_count) { if (options.node_min != options.node_max) { log_event("- Node numbers %u-%u of %u%s", options.node_min, options.node_max, #ifndef HAVE_MPI options.node_count, options.fork ? " (fork)" : ""); #else options.node_count, options.fork ? " (fork)" : mpi_p > 1 ? " (MPI)" : ""); #endif if (john_main_process) fprintf(stderr, "Node numbers %u-%u of %u%s\n", options.node_min, options.node_max, #ifndef HAVE_MPI options.node_count, options.fork ? " (fork)" : ""); #else options.node_count, options.fork ? " (fork)" : mpi_p > 1 ? " (MPI)" : ""); #endif } else {
static void john_fork(void) { int i, pid; int *pids; fflush(stdout); fflush(stderr); #if HAVE_MPI /* * We already initialized MPI before knowing this is actually a fork session. * So now we need to tear that "1-node MPI session" down before forking, or * all sorts of funny things might happen. */ mpi_teardown(); #endif /* * It may cost less memory to reset john_main_process to 0 before fork()'ing * the children than to do it in every child process individually (triggering * copy-on-write of the entire page). We then reset john_main_process back to * 1 in the parent, but this only costs one page, not one page per child. */ john_main_process = 0; pids = mem_alloc_tiny((options.fork - 1) * sizeof(*pids), sizeof(*pids)); for (i = 1; i < options.fork; i++) { switch ((pid = fork())) { case -1: pexit("fork"); case 0: sig_preinit(); options.node_min += i; options.node_max = options.node_min; #if HAVE_OPENCL // Poor man's multi-device support if (options.gpu_devices->count && strstr(database.format->params.label, "-opencl")) { // Pick device to use for this child opencl_preinit(); gpu_id = gpu_device_list[i % get_number_of_devices_in_use()]; platform_id = get_platform_id(gpu_id); // Hide any other devices from list gpu_device_list[0] = gpu_id; gpu_device_list[1] = -1; // Postponed format init in forked process fmt_init(database.format); } #endif if (rec_restoring_now) { unsigned int node_id = options.node_min; rec_done(-2); rec_restore_args(1); if (node_id != options.node_min + i) fprintf(stderr, "Inconsistent crash recovery file:" " %s\n", rec_name); options.node_min = options.node_max = node_id; } sig_init_child(); return; default: pids[i - 1] = pid; } } #if HAVE_OPENCL // Poor man's multi-device support if (options.gpu_devices->count && strstr(database.format->params.label, "-opencl")) { // Pick device to use for mother process opencl_preinit(); gpu_id = gpu_device_list[0]; platform_id = get_platform_id(gpu_id); // Hide any other devices from list gpu_device_list[1] = -1; // Postponed format init in mother process fmt_init(database.format); } #endif john_main_process = 1; john_child_pids = pids; john_child_count = options.fork - 1; options.node_max = options.node_min; }
static void john_load(void) { struct list_entry *current; #ifndef _MSC_VER umask(077); #endif if (options.flags & FLG_EXTERNAL_CHK) ext_init(options.external, NULL); if (options.flags & FLG_MAKECHR_CHK) { options.loader.flags |= DB_CRACKED; ldr_init_database(&database, &options.loader); if (options.flags & FLG_PASSWD) { ldr_show_pot_file(&database, options.loader.activepot); database.options->flags |= DB_PLAINTEXTS; if ((current = options.passwd->head)) do { ldr_show_pw_file(&database, current->data); } while ((current = current->next)); } else { database.options->flags |= DB_PLAINTEXTS; ldr_show_pot_file(&database, options.loader.activepot); } return; } if (options.flags & FLG_STDOUT) { ldr_init_database(&database, &options.loader); database.format = &dummy_format; memset(&dummy_format, 0, sizeof(dummy_format)); dummy_format.params.plaintext_length = options.length; dummy_format.params.flags = FMT_CASE | FMT_8_BIT; } if (options.flags & FLG_PASSWD) { int total; if (options.flags & FLG_SHOW_CHK) { options.loader.flags |= DB_CRACKED; ldr_init_database(&database, &options.loader); ldr_show_pot_file(&database, options.loader.activepot); if ((current = options.passwd->head)) do { ldr_show_pw_file(&database, current->data); } while ((current = current->next)); printf("%s%d password hash%s cracked, %d left\n", database.guess_count ? "\n" : "", database.guess_count, database.guess_count != 1 ? "es" : "", database.password_count - database.guess_count); return; } if (options.flags & (FLG_SINGLE_CHK | FLG_BATCH_CHK) && status.pass <= 1) options.loader.flags |= DB_WORDS; else if (mem_saving_level) { options.loader.flags &= ~DB_LOGIN; options.loader.max_wordfile_memory = 0; } ldr_init_database(&database, &options.loader); if ((current = options.passwd->head)) do { ldr_load_pw_file(&database, current->data); } while ((current = current->next)); // Unicode (UTF-16) formats may lack UTF-8 support (initially) if (options.utf8 && database.password_count && database.format->params.flags & FMT_UNICODE && !(database.format->params.flags & FMT_UTF8)) { fprintf(stderr, "This format does not yet support UTF-8 conversion\n"); error(); } if ((options.flags & FLG_CRACKING_CHK) && database.password_count) { log_init(LOG_NAME, NULL, options.session); if (status_restored_time) log_event("Continuing an interrupted session"); else log_event("Starting a new session"); log_event("Loaded a total of %s", john_loaded_counts()); /* make sure the format is properly initialized */ fmt_init(database.format); printf("Loaded %s (%s [%s])\n", john_loaded_counts(), database.format->params.format_name, database.format->params.algorithm_name); // Tell External our max length if (options.flags & FLG_EXTERNAL_CHK) ext_init(options.external, &database); } if (database.password_count) { if (database.format->params.flags & FMT_UNICODE) options.store_utf8 = cfg_get_bool(SECTION_OPTIONS, NULL, "UnicodeStoreUTF8", 0); else options.store_utf8 = cfg_get_bool(SECTION_OPTIONS, NULL, "CPstoreUTF8", 0); } if (!options.utf8) { if (options.report_utf8 && options.log_passwords) log_event("- Passwords in this logfile are UTF-8 encoded"); if (options.store_utf8) log_event("- Passwords will be stored UTF-8 encoded in .pot file"); } total = database.password_count; ldr_load_pot_file(&database, options.loader.activepot); ldr_fix_database(&database); if (!database.password_count) { log_discard(); printf("No password hashes %s (see FAQ)\n", total ? "left to crack" : "loaded"); } else if (database.password_count < total) { log_event("Remaining %s", john_loaded_counts()); printf("Remaining %s\n", john_loaded_counts()); } if (options.regen_lost_salts) { extern void build_fake_salts_for_regen_lost(struct db_salt *); build_fake_salts_for_regen_lost(database.salts); } if ((options.flags & FLG_PWD_REQ) && !database.salts) exit(0); } }
static int ldr_split_line(char **login, char **ciphertext, char **gecos, char **home, char *source, struct fmt_main **format, struct db_options *options, char *line) { struct fmt_main *alt; char *fields[10], *uid, *gid, *shell; int i, retval; fields[0] = *login = ldr_get_field(&line); fields[1] = *ciphertext = ldr_get_field(&line); /* Check for NIS stuff */ if ((!strcmp(*login, "+") || !strncmp(*login, "+@", 2)) && strlen(*ciphertext) < 10 && strncmp(*ciphertext, "$dummy$", 7)) return 0; if (!**ciphertext && !line) { /* Possible hash on a line on its own (no colons) */ char *p = *login; /* Skip leading and trailing whitespace */ while (*p == ' ' || *p == '\t') p++; *ciphertext = p; p += strlen(p) - 1; while (p > *ciphertext && (*p == ' ' || *p == '\t')) p--; p++; /* Some valid dummy hashes may be shorter than 10 characters, so don't subject * them to the length checks. */ if (strncmp(*ciphertext, "$dummy$", 7) && p - *ciphertext != 10 /* not tripcode */) { /* Check for a special case: possibly a traditional crypt(3) hash with * whitespace in its invalid salt. Only support such hashes at the very start * of a line (no leading whitespace other than the invalid salt). */ if (p - *ciphertext == 11 && *ciphertext - *login == 2) (*ciphertext)--; if (p - *ciphertext == 12 && *ciphertext - *login == 1) (*ciphertext)--; if (p - *ciphertext < 13) return 0; } *p = 0; fields[0] = *login = no_username; fields[1] = *ciphertext; } if (source) strcpy(source, line ? line : ""); /* * This check is just a loader performance optimization, so that we can parse * fewer fields when we know we won't need the rest. It should be revised or * removed when there are formats that use higher-numbered fields in prepare(). */ if ((options->flags & DB_WORDS) || options->shells->head) { /* Parse all fields */ for (i = 2; i < 10; i++) fields[i] = ldr_get_field(&line); } else { /* Parse some fields only */ for (i = 2; i < 4; i++) fields[i] = ldr_get_field(&line); for (; i < 10; i++) fields[i] = "/"; } /* /etc/passwd */ uid = fields[2]; gid = fields[3]; *gecos = fields[4]; *home = fields[5]; shell = fields[6]; if (fields[5][0] != '/' && ((!strcmp(fields[5], "0") && !strcmp(fields[6], "0")) || fields[8][0] == '/' || fields[9][0] == '/')) { /* /etc/master.passwd */ *gecos = fields[7]; *home = fields[8]; shell = fields[9]; } else if (fields[3] - fields[2] == 32 + 1) { /* PWDUMP */ uid = fields[1]; *ciphertext = fields[2]; if (!strncmp(*ciphertext, "NO PASSWORD", 11)) *ciphertext = ""; gid = shell = ""; *gecos = fields[4]; *home = fields[5]; /* Re-introduce the previously removed uid field */ if (source) { int shift = strlen(uid); memmove(source + shift + 1, source, strlen(source) + 1); memcpy(source, uid, shift); source[shift] = ':'; } } if (ldr_check_list(options->users, *login, uid)) return 0; if (ldr_check_list(options->groups, gid, gid)) return 0; if (ldr_check_shells(options->shells, shell)) return 0; if (*format) { char *prepared; int valid; prepared = (*format)->methods.prepare(fields, *format); if (prepared) valid = (*format)->methods.valid(prepared, *format); else valid = 0; if (valid) { *ciphertext = prepared; return valid; } alt = fmt_list; do { if (alt == *format) continue; if (alt->params.flags & FMT_WARNED) continue; #ifdef HAVE_CRYPT if (alt == &fmt_crypt && #ifdef __sun strncmp(*ciphertext, "$md5$", 5) && strncmp(*ciphertext, "$md5,", 5) && #endif strncmp(*ciphertext, "$5$", 3) && strncmp(*ciphertext, "$6$", 3)) continue; #endif prepared = alt->methods.prepare(fields, alt); if (alt->methods.valid(prepared, alt)) { alt->params.flags |= FMT_WARNED; fprintf(stderr, "Warning: only loading hashes of type " "\"%s\", but also saw type \"%s\"\n" "Use the \"--format=%s\" option to force " "loading hashes of that type instead\n", (*format)->params.label, alt->params.label, alt->params.label); break; } } while ((alt = alt->next)); return 0; } retval = -1; if ((alt = fmt_list)) do { char *prepared; int valid; #ifdef HAVE_CRYPT /* * Only probe for support by the current system's crypt(3) if this is forced * from the command-line or/and if the hash encoding string looks like one of * those that are only supported in that way. Avoid the probe in other cases * because it may be slow and undesirable (false detection is possible). */ if (alt == &fmt_crypt && fmt_list != &fmt_crypt /* not forced */ && #ifdef __sun strncmp(*ciphertext, "$md5$", 5) && strncmp(*ciphertext, "$md5,", 5) && #endif strncmp(*ciphertext, "$5$", 3) && strncmp(*ciphertext, "$6$", 3)) continue; #endif prepared = alt->methods.prepare(fields, alt); if (!prepared) continue; valid = alt->methods.valid(prepared, alt); if (!valid) continue; if (retval < 0) { retval = valid; *ciphertext = prepared; fmt_init(*format = alt); #ifdef LDR_WARN_AMBIGUOUS if (!source) /* not --show */ continue; #endif break; } #ifdef LDR_WARN_AMBIGUOUS fprintf(stderr, "Warning: detected hash type \"%s\", but the string is " "also recognized as \"%s\"\n" "Use the \"--format=%s\" option to force loading these " "as that type instead\n", (*format)->params.label, alt->params.label, alt->params.label); #endif } while ((alt = alt->next)); return retval; }
int ft_printf(const char *fmt, ...) { va_list args; t_fmt *begin_list; t_fmt *list; int count; t_opt *opt; char *format; format = ft_strdup(fmt); count = 0; list = 0; list = fmt_init(list); begin_list = list; va_start(args, fmt); if (!(opt = (t_opt*)ft_memalloc(sizeof(t_opt)))) return (-1); while (*format) { opt_init(opt); while (*format != '%' && *format) { ft_putchar(*format); format++; count++; } if (*format == '%') { format++; if (!*format) return (count); if (*format == '%') { ft_putchar('%'); count++; } else { format = opt_read(opt, (char*)format); // ft_putendl(format); //juste pour le debug // print_opt(opt); //ici il faut appeler une fct de conv if (*format == 'p') { *format = 'x'; opt->hash = 1; } if (!(list = find_list(begin_list, *format))) { if (*format) { ft_putchar(*format); count++; } } else count += (int)list->fct(va_arg(args, void*), opt); } format++; } }
static int ldr_split_line(char **login, char **ciphertext, char **gecos, char **home, char *source, struct fmt_main **format, struct db_options *db_options, char *line) { char *uid = NULL, *gid = NULL, *shell = NULL; char *tmp; int count; *login = ldr_get_field(&line); if (!strcmp(*login, "+") || !strncmp(*login, "+@", 2)) return 0; if (!*(*ciphertext = ldr_get_field(&line))) if (!line) return 0; if (source) strcpy(source, line ? line : ""); uid = ldr_get_field(&line); if (strlen(uid) == 32) { tmp = *ciphertext; *ciphertext = uid; uid = tmp; if (!strncmp(*ciphertext, "NO PASSWORD", 11)) *ciphertext = ""; /* NT loader hack starts here ! */ if (options.format && (strncmp(options.format, "nt", 2)==0)) { tmp = ldr_get_field(&line); *ciphertext = tmp; if (!strncmp(*ciphertext, "NO PASSWORD", 11)) *ciphertext = ""; else if(strlen(*ciphertext) == 32) { *ciphertext -= 4; strncpy(*ciphertext,"$NT$",4); } else { return 0; } } /* NT loader hack ends here ! */ if (source) sprintf(source, "%s:%s", uid, line); } if (db_options->flags & DB_WORDS || db_options->shells->head) { gid = ldr_get_field(&line); do { *gecos = ldr_get_field(&line); *home = ldr_get_field(&line); shell = ldr_get_field(&line); } while (!**gecos && !strcmp(*home, "0") && !strcmp(shell, "0")); } else if (db_options->groups->head) { gid = ldr_get_field(&line); } if (ldr_check_list(db_options->users, *login, uid)) return 0; if (ldr_check_list(db_options->groups, gid, gid)) return 0; if (ldr_check_shells(db_options->shells, shell)) return 0; if (*format) return (*format)->methods.valid(*ciphertext); if ((*format = fmt_list)) do { if ((count = (*format)->methods.valid(*ciphertext))) { fmt_init(*format); return count; } } while ((*format = (*format)->next)); return -1; }
static int ldr_split_line(char **login, char **ciphertext, char **gecos, char **home, char *source, struct fmt_main **format, struct db_options *db_options, char *line) { struct fmt_main *alt; char *uid = NULL, *gid = NULL, *shell = NULL; char *split_fields[10]; int i, retval, valid; // Note, only 7 are 'defined' in the passwd format. We load 10, so that // other formats can add specific extra stuff. for (i = 0; i < 10; ++i) { split_fields[i] = ldr_get_field(&line, db_options->field_sep_char); if (!line && i == 1 && split_fields[1][0] == 0) { /* Possible hash on a line on its own (no colons) */ char *p = split_fields[0]; /* Skip leading and trailing whitespace */ while (*p == ' ' || *p == '\t') p++; split_fields[1] = p; p += strlen(p) - 1; while (p > split_fields[1] && (*p == ' ' || *p == '\t')) p--; p++; /* Some valid dummy hashes may be shorter than 10 characters, so don't subject * them to the length checks. */ if (strncmp(split_fields[1], "$dummy$", 7) && p - split_fields[1] != 10 /* not tripcode */) { /* Check for a special case: possibly a traditional crypt(3) hash with * whitespace in its invalid salt. Only support such hashes at the very start * of a line (no leading whitespace other than the invalid salt). */ if (p - split_fields[1] == 11 && split_fields[1] - split_fields[0] == 2) split_fields[1]--; if (p - split_fields[1] == 12 && split_fields[1] - split_fields[0] == 1) split_fields[1]--; if (p - split_fields[1] < 13) return 0; } *p = 0; split_fields[0] = no_username; } if (i == 1 && source) strcpy(source, line ? line : ""); } *login = split_fields[0]; *ciphertext = split_fields[1]; /* Check for NIS stuff */ if ((!strcmp(*login, "+") || !strncmp(*login, "+@", 2)) && strlen(*ciphertext) < 10 && strncmp(*ciphertext, "$dummy$", 7)) return 0; /* SPLFLEN(n) is a macro equiv. of strlen(split_fields[n]) (but faster) */ if (SPLFLEN(1) > 0 && SPLFLEN(1) < 7 && (SPLFLEN(3) == 32 || SPLFLEN(2) == 32)) { /* uid for pwdump files. */ uid = split_fields[1]; gid = *gecos = *home = shell = ""; } else if (SPLFLEN(1) == 0 && SPLFLEN(3) >= 16 && SPLFLEN(4) >= 32 && SPLFLEN(5) >= 16) { /* l0phtcrack-style input */ uid = gid = *home = shell = ""; *gecos = split_fields[2]; // in case there's a domain name here } else { /* normal passwd-style input */ uid = split_fields[2]; gid = split_fields[3]; *gecos = split_fields[4]; *home = split_fields[5]; shell = split_fields[6]; } if (ldr_check_list(db_options->users, *login, uid)) return 0; if (ldr_check_list(db_options->groups, gid, gid)) return 0; if (ldr_check_shells(db_options->shells, shell)) return 0; if (*format) { *ciphertext = (*format)->methods.prepare(split_fields, *format); valid = (*format)->methods.valid(*ciphertext, *format); if (!valid) { alt = fmt_list; do { if (alt == *format) continue; if (alt->params.flags & FMT_WARNED) continue; #ifdef HAVE_CRYPT if (alt == &fmt_crypt && #ifdef __sun strncmp(*ciphertext, "$md5$", 5) && strncmp(*ciphertext, "$md5,", 5) && #endif strncmp(*ciphertext, "$5$", 3) && strncmp(*ciphertext, "$6$", 3)) continue; #endif if (alt->methods.valid(*ciphertext,alt)) { alt->params.flags |= FMT_WARNED; #ifdef HAVE_MPI if (mpi_id == 0) #endif fprintf(stderr, "Warning: only loading hashes " "of type \"%s\", but also saw " "type \"%s\"\n" "Use the " "\"--format=%s\" option to force " "loading hashes of that type " "instead\n", (*format)->params.label, alt->params.label, alt->params.label); break; } } while ((alt = alt->next)); } return valid; } retval = -1; if ((alt = fmt_list)) do { int valid; char *prepared_CT = alt->methods.prepare(split_fields, alt); if (!prepared_CT || !*prepared_CT) continue; #ifdef HAVE_CRYPT /* * Only probe for support by the current system's crypt(3) if this is forced * from the command-line or/and if the hash encoding string looks like one of * those that are only supported in that way. Avoid the probe in other cases * because it may be slow and undesirable (false detection is possible). */ if (alt == &fmt_crypt && fmt_list != &fmt_crypt /* not forced */ && #ifdef __sun strncmp(prepared_CT, "$md5$", 5) && strncmp(prepared_CT, "$md5,", 5) && #endif strncmp(prepared_CT, "$5$", 3) && strncmp(prepared_CT, "$6$", 3)) continue; #endif if (!(valid = alt->methods.valid(prepared_CT, alt))) continue; if (retval < 0) { fmt_init(*format = alt); retval = valid; *ciphertext = prepared_CT; #ifdef LDR_WARN_AMBIGUOUS if (!source) /* not --show */ continue; #endif break; } #ifdef LDR_WARN_AMBIGUOUS #ifdef HAVE_MPI if (mpi_id == 0) #endif fprintf(stderr, "Warning: detected hash type \"%s\", but the string is " "also recognized as \"%s\"\n" "Use the \"--format=%s\" option to force loading these " "as that type instead\n", (*format)->params.label, alt->params.label, alt->params.label); #endif } while ((alt = alt->next)); return retval; }