diff -u john-1.7.9.6-newform/src/AFS_fmt.c john-1.7.9.6-newform/src/AFS_fmt.c --- john-1.7.9.6-newform/src/AFS_fmt.c 2012-07-17 16:53:44 +0000 +++ john-1.7.9.6-newform/src/AFS_fmt.c 2012-07-18 01:45:58 +0000 @@ -450,6 +450,7 @@ }, { init, fmt_default_done, + fmt_default_reset, fmt_default_prepare, valid, fmt_default_split, diff -u john-1.7.9.6-newform/src/BF_fmt.c john-1.7.9.6-newform/src/BF_fmt.c --- john-1.7.9.6-newform/src/BF_fmt.c 2012-07-17 16:53:53 +0000 +++ john-1.7.9.6-newform/src/BF_fmt.c 2012-07-18 01:46:04 +0000 @@ -293,6 +293,7 @@ }, { init, fmt_default_done, + fmt_default_reset, fmt_default_prepare, valid, fmt_default_split, diff -u john-1.7.9.6-newform/src/BSDI_fmt.c john-1.7.9.6-newform/src/BSDI_fmt.c --- john-1.7.9.6-newform/src/BSDI_fmt.c 2012-07-17 16:53:57 +0000 +++ john-1.7.9.6-newform/src/BSDI_fmt.c 2012-07-18 01:46:06 +0000 @@ -407,6 +407,7 @@ }, { init, fmt_default_done, + fmt_default_reset, fmt_default_prepare, valid, fmt_default_split, diff -u john-1.7.9.6-newform/src/DES_fmt.c john-1.7.9.6-newform/src/DES_fmt.c --- john-1.7.9.6-newform/src/DES_fmt.c 2012-07-17 16:54:02 +0000 +++ john-1.7.9.6-newform/src/DES_fmt.c 2012-07-18 01:46:10 +0000 @@ -370,6 +370,7 @@ DES_std_init, #endif fmt_default_done, + fmt_default_reset, fmt_default_prepare, valid, split, diff -u john-1.7.9.6-newform/src/LM_fmt.c john-1.7.9.6-newform/src/LM_fmt.c --- john-1.7.9.6-newform/src/LM_fmt.c 2012-07-17 16:54:08 +0000 +++ john-1.7.9.6-newform/src/LM_fmt.c 2012-07-18 01:46:12 +0000 @@ -211,6 +211,7 @@ }, { init, fmt_default_done, + fmt_default_reset, prepare, valid, split, diff -u john-1.7.9.6-newform/src/MD5_fmt.c john-1.7.9.6-newform/src/MD5_fmt.c --- john-1.7.9.6-newform/src/MD5_fmt.c 2012-07-17 16:54:11 +0000 +++ john-1.7.9.6-newform/src/MD5_fmt.c 2012-07-18 01:46:15 +0000 @@ -248,6 +248,7 @@ }, { init, fmt_default_done, + fmt_default_reset, fmt_default_prepare, valid, fmt_default_split, diff -u john-1.7.9.6-newform/src/c3_fmt.c john-1.7.9.6-newform/src/c3_fmt.c --- john-1.7.9.6-newform/src/c3_fmt.c 2012-07-17 16:54:15 +0000 +++ john-1.7.9.6-newform/src/c3_fmt.c 2012-07-18 01:46:18 +0000 @@ -435,6 +435,7 @@ }, { fmt_default_init, fmt_default_done, + fmt_default_reset, fmt_default_prepare, valid, fmt_default_split, diff -u john-1.7.9.6-newform/src/dummy.c john-1.7.9.6-newform/src/dummy.c --- john-1.7.9.6-newform/src/dummy.c 2012-07-17 16:54:21 +0000 +++ john-1.7.9.6-newform/src/dummy.c 2012-07-18 01:46:22 +0000 @@ -277,6 +277,7 @@ }, { fmt_default_init, fmt_default_done, + fmt_default_reset, fmt_default_prepare, valid, fmt_default_split, diff -u john-1.7.9.6-newform/src/formats.c john-1.7.9.6-newform/src/formats.c --- john-1.7.9.6-newform/src/formats.c 2012-07-17 16:55:57 +0000 +++ john-1.7.9.6-newform/src/formats.c 2012-07-18 01:48:21 +0000 @@ -80,6 +80,8 @@ fmt_init(format); + format->methods.reset(NULL); + if (!(current = format->params.tests)) return NULL; ntests = 0; while ((current++)->ciphertext) @@ -236,6 +238,10 @@ { } +void fmt_default_reset(struct db_main *db) +{ +} + char *fmt_default_prepare(char *fields[10], struct fmt_main *self) { return fields[1]; diff -u john-1.7.9.6-newform/src/formats.h john-1.7.9.6-newform/src/formats.h --- john-1.7.9.6-newform/src/formats.h 2012-07-18 01:38:42 +0000 +++ john-1.7.9.6-newform/src/formats.h 2012-07-18 01:44:33 +0000 @@ -13,6 +13,12 @@ #include "params.h" /* + * The reset() format method accepts a pointer to struct db_main, yet we can't + * just include loader.h here because that would be a circular dependency. + */ +struct db_main; + +/* * Format property flags. */ /* Uses case-sensitive passwords */ @@ -103,6 +109,14 @@ /* De-initializes this format, which must have been previously initialized */ void (*done)(void); +/* Called whenever the set of password hashes being cracked changes, such as + * after self-test, but before actual cracking starts. When called before a + * self-test or benchmark rather than before actual cracking, db may be NULL. + * Normally, this is a no-op since a format implementation shouldn't mess with + * the database unnecessarily. However, when there is a good reason to do so + * this may e.g. transfer the salts and hashes onto a GPU card. */ + void (*reset)(struct db_main *db); + /* Extracts the ciphertext string out of the input file fields. Normally, this * will simply return field[1], but in some special cases it may use another * field (e.g., when the hash type is commonly used with PWDUMP rather than @@ -226,6 +240,7 @@ */ extern void fmt_default_init(struct fmt_main *self); extern void fmt_default_done(void); +extern void fmt_default_reset(struct db_main *db); extern char *fmt_default_prepare(char *fields[10], struct fmt_main *self); extern int fmt_default_valid(char *ciphertext, struct fmt_main *self); extern char *fmt_default_split(char *ciphertext, int index, diff -u john-1.7.9.6-newform/src/john.c john-1.7.9.6-newform/src/john.c --- john-1.7.9.6-newform/src/john.c 2012-07-17 17:02:44 +0000 +++ john-1.7.9.6-newform/src/john.c 2012-07-18 02:00:20 +0000 @@ -322,6 +322,7 @@ where); error(); } + database.format->methods.reset(&database); log_init(LOG_NAME, POT_NAME, options.session); status_init(NULL, 1); john_log_format(); diff -u john-1.7.9.6-newform/src/trip_fmt.c john-1.7.9.6-newform/src/trip_fmt.c --- john-1.7.9.6-newform/src/trip_fmt.c 2012-07-17 16:54:18 +0000 +++ john-1.7.9.6-newform/src/trip_fmt.c 2012-07-18 01:46:20 +0000 @@ -593,6 +593,7 @@ }, { init, fmt_default_done, + fmt_default_reset, fmt_default_prepare, valid, fmt_default_split, only in patch2: unchanged: --- john-1.7.9.6/src/cracker.c 2012-07-14 13:36:44 +0000 +++ john-1.7.9.6-newform/src/cracker.c 2012-07-18 01:59:45 +0000 @@ -56,7 +56,15 @@ void crk_init(struct db_main *db, void ( char *where; size_t size; - if (db->loaded) +/* + * We should have already called fmt_self_test() from john.c. This redundant + * self-test is only to catch some more obscure bugs in debugging builds (it + * is a no-op in normal builds). Additionally, we skip it even in debugging + * builds if we're running in --stdout mode (there's no format involved then) + * or if the format has a custom reset() method (we've already called reset(db) + * from john.c, and we don't want to mess with the format's state). + */ + if (db->loaded && db->format->methods.reset == fmt_default_reset) if ((where = fmt_self_test(db->format))) { log_event("! Self test failed (%s)", where); fprintf(stderr, "Self test failed (%s)\n", where);