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); } } }
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); } } }