Esempio n. 1
0
static int single_process_salt(struct db_salt *salt, char *rule)
{
    struct db_keys *keys;
    struct db_password *pw, **last;
    int status, have_words = 0;

    keys = salt->keys;

    if (!keys->have_words)
        goto no_own_words;

    last = &salt->list;
    pw = *last;
    do {
        /*
         * "binary" is set to NULL on entries marked for removal (so we remove them
         * here) or already removed (yet we might hit them once in some obscure cases).
         */
        if (pw->binary) {
            if (!(status = single_process_pw(salt, pw, rule))) {
                have_words = 1;
                goto next;
            }
            if (status < 0) /* no words for this hash */
                goto next;
            if (status == 2) /* no hashes left for this salt */
                return 0;
            return 1; /* no hashes left to crack for all salts */
        } else {
            *last = pw->next; /* remove */
        }
next:
        last = &pw->next;
    } while ((pw = pw->next));

    if (keys->count && rule_number - keys->rule > (key_count << 1))
        if (single_process_buffer(salt))
            return 1;

    if (!keys->count)
        keys->rule = rule_number;

    if (!have_words) {
        keys->have_words = 0;
no_own_words:
        if (keys->count && single_process_buffer(salt))
            return 1;
    }

    return 0;
}
Esempio n. 2
0
static int single_process_buffer(struct db_salt *salt)
{
	struct db_salt *current;
	struct db_keys *keys;
	size_t size;

	if (crk_process_salt(salt)) return 1;

/*
 * Flush the keys list (since we've just processed the keys), but not the hash
 * table to allow for more effective checking for duplicates.  We could flush
 * the hash table too, such as by calling single_alloc_keys() here, which would
 * allow us to drop the update-hash-before-list-entry-reuse code from
 * single_add_key().  This would speed things up in terms of this source file's
 * code overhead, however it would allow more duplicates to pass.  The apparent
 * c/s rate (counting duplicates as if they were distinct combinations) would
 * be higher, but the number of passwords cracked per unit of time might be
 * lower or higher depending on many things including the relative speed of
 * password hash computations vs. the "overhead".
 */
	keys = salt->keys;
	keys->count = 0;
	keys->ptr = keys->buffer;
	keys->lock++;

	if (guessed_keys->count) {
		keys = mem_alloc(size = sizeof(struct db_keys) - 1 +
			length * guessed_keys->count);
		memcpy(keys, guessed_keys, size);

		keys->ptr = keys->buffer;
		do {
			current = single_db->salts;
			do {
				if (current == salt) continue;
				if (!current->list) continue;

				if (single_add_key(current->keys, keys->ptr))
				if (single_process_buffer(current)) return 1;
			} while ((current = current->next));
			keys->ptr += length;
		} while (--keys->count);

		MEM_FREE(keys);
	}

	keys = salt->keys;
	keys->lock--;
	if (!keys->count && !keys->lock) keys->rule = rule_number;

	return 0;
}
Esempio n. 3
0
static int single_add_key(struct db_salt *salt, char *key, int is_from_guesses)
{
    struct db_keys *keys = salt->keys;
    int index, new_hash, reuse_hash;
    struct db_keys_hash_entry *entry;

    /* Check if this is a known duplicate, and reject it if so */
    if ((index = keys->hash->hash[new_hash = single_key_hash(key)]) >= 0)
        do {
            entry = &keys->hash->list[index];
            if (!strncmp(key, &keys->buffer[entry->offset], length))
                return 0;
        } while ((index = entry->next) >= 0);

    /* Update the hash table removing the list entry we're about to reuse */
    index = keys->hash->hash[reuse_hash = single_key_hash(keys->ptr)];
    if (index == keys->count)
        keys->hash->hash[reuse_hash] = keys->hash->list[index].next;
    else if (index >= 0) {
        entry = &keys->hash->list[index];
        while ((index = entry->next) >= 0) {
            if (index == keys->count) {
                entry->next = keys->hash->list[index].next;
                break;
            }
            entry = &keys->hash->list[index];
        }
    }

    /* Add the new entry */
    index = keys->hash->hash[new_hash];
    entry = &keys->hash->list[keys->count];
    entry->next = index;
    entry->offset = keys->ptr - keys->buffer;
    keys->hash->hash[new_hash] = keys->count;

    strnfcpy(keys->ptr, key, length);
    keys->ptr += length;

    keys->count_from_guesses += is_from_guesses;

    if (++(keys->count) >= key_count)
        return single_process_buffer(salt);

    return 0;
}
Esempio n. 4
0
static void single_done(void)
{
	struct db_salt *salt;

	if (!event_abort) {
		if ((salt = single_db->salts)) {
			log_event("- Processing the remaining buffered "
				"candidate passwords, if any");

			do {
				if (!salt->list) continue;
				if (salt->keys->count)
				if (single_process_buffer(salt)) break;
			} while ((salt = salt->next));
		}

		progress = 100;
	}

	rec_done(event_abort || (status.pass && single_db->salts));
}
Esempio n. 5
0
static int single_process_pw(struct db_salt *salt, struct db_password *pw,
	char *rule)
{
	struct db_keys *keys;
	struct list_entry *first, *second;
	int first_number, second_number;
	char pair[RULE_WORD_SIZE];
	int split;
	char *key;
	unsigned int c;

	if (!(first = pw->words->head))
		return -1;

	keys = salt->keys;

	first_number = 0;
	do {
		if ((key = rules_apply(first->data, rule, 0, NULL)))
		if (ext_filter(key))
		if (single_add_key(keys, key))
		if (single_process_buffer(salt)) return 1;
		if (!salt->list) return 2;
		if (!pw->binary) return 0;

		if (++first_number > SINGLE_WORDS_PAIR_MAX) continue;

		c = (unsigned int)first->data[0] | 0x20;
		if (c < 'a' || c > 'z') continue;

		second_number = 0;
		second = pw->words->head;

		do
		if (first != second) {
			if ((split = strlen(first->data)) < length) {
				strnzcpy(pair, first->data, RULE_WORD_SIZE);
				strnzcat(pair, second->data, RULE_WORD_SIZE);

				if ((key = rules_apply(pair, rule, split, NULL)))
				if (ext_filter(key))
				if (single_add_key(keys, key))
				if (single_process_buffer(salt)) return 1;
				if (!salt->list) return 2;
				if (!pw->binary) return 0;
			}

			if (first->data[1]) {
				pair[0] = first->data[0];
				pair[1] = 0;
				strnzcat(pair, second->data, RULE_WORD_SIZE);

				if ((key = rules_apply(pair, rule, 1, NULL)))
				if (ext_filter(key))
				if (single_add_key(keys, key))
				if (single_process_buffer(salt)) return 1;
				if (!salt->list) return 2;
				if (!pw->binary) return 0;
			}
		} while (++second_number <= SINGLE_WORDS_PAIR_MAX &&
			(second = second->next));
	} while ((first = first->next));

	return 0;
}