diff -u -p -N -X src/diff_exclude.dat src-orig/formats.h src/formats.h --- src-orig/formats.h Sun Aug 28 23:14:51 2011 +++ src/formats.h Sun Aug 28 23:40:06 2011 @@ -186,6 +186,7 @@ struct fmt_private { /* * A structure to keep a list of supported ciphertext formats. */ +#define FMT_MAIN_VERSION 7 /* change if structure changes */ struct fmt_main { struct fmt_params params; struct fmt_methods methods; diff -u -p -N -X src/diff_exclude.dat src-orig/john.c src/john.c --- src-orig/john.c Sun Aug 28 23:14:51 2011 +++ src/john.c Sun Aug 28 23:38:51 2011 @@ -108,6 +108,80 @@ static void john_register_one(struct fmt fmt_register(format); } +#include +/* + * Load format modules from DLLs specified by using the --dynamic-fmt=dllfile + * command line option or Dynamic-fmt config file option. The DLL must + * define a function FMT_LOADER with the prototype: + * struct fmt_main *FMT_LOADER ( int fmt_version ); + * + * version is the version number of the fmt_main structure. It must be + * changed whenever the fmt_main layout or semantics change. The FMT_LOADER + * returns the address of a fmt_main structure or NULL if a version mismatch + * or other error occurs. + */ +static void **dll_handle; /* List of handles for cleanup */ + +static void register_dlls ( struct list_main *dll_list, char *config_param ) +{ + struct list_entry *le; + struct fmt_main *(*loader)(int fmt_version ); + struct fmt_main *fmt; + struct list_main *cfg_list; + int ndx; + char *dll_name, *cfg_names; + /* + * Convert config_param string into list structure and chain it + * and dll_list together temporarily. Set le to the list head. + */ + list_init ( &cfg_list ); + if ( config_param ) { + cfg_names = strdup ( config_param ); /* so strtok can modify */ + for ( dll_name = strtok(strdup(cfg_names),","); dll_name; + dll_name = strtok(0,",") ) { + dll_name += strspn(dll_name, " \t"); /* skip whitespace */ + if ( *dll_name ) list_add ( cfg_list, dll_name ); + } + } + if ( cfg_list->count > 0 ) { + le = cfg_list->head; /* Start with config_param files */ + if ( !dll_list ) printf ( "Missing options.fmt_dlls!\n" ); + else if ( dll_list->count > 0 ) cfg_list->tail->next = dll_list->head; + } else if ( !dll_list ) { + printf ( "/bugcheck/ options.fmt_dlls did not intialize\n" ); + } else if ( dll_list->count > 0 ) { + le = dll_list->head; /* config_param empty, start with dll_list */ + } else { + return; /* both lists empty, bail out */ + } + /* + * Step through list and load files named. + */ + dll_handle = malloc ( sizeof(void *) * (cfg_list->count+dll_list->count) ); + ndx = 0; + for ( ; le; le = le->next ) { + + dll_name = le->data; + dll_handle[ndx] = dlopen ( dll_name, 0 ); + if ( dll_handle[ndx] ) { + loader = dlsym ( dll_handle[ndx], "FMT_LOADER" ); + if ( loader ) { + fmt = loader ( FMT_MAIN_VERSION ); + if ( fmt ) john_register_one ( fmt ); + else { + fprintf ( stderr, "Unsupported version for DLL FMT\n" ); + } + } else { + fprintf ( stderr, "Failed to load symbol '%s'\n", "FMT_LOADER" ); + fprintf ( stderr, "%s\n", dlerror() ); + } + } else { + fprintf ( stderr, "Failed to open DLL '%s'\n", dll_name ); + fprintf ( stderr, "%s\n", dlerror ( ) ); + } + } + if ( cfg_list->count > 0 ) cfg_list->tail->next = 0; +} static void john_register_all(void) { @@ -158,6 +232,8 @@ static void john_register_all(void) john_register_one(&fmt_dummy); + register_dlls ( options.fmt_dlls, + cfg_get_param(SECTION_OPTIONS, NULL, "dynamic-fmt") ); if (!fmt_list) { #ifdef HAVE_MPI diff -u -p -N -X src/diff_exclude.dat src-orig/options.c src/options.c --- src-orig/options.c Sun Aug 28 23:14:52 2011 +++ src/options.c Sun Aug 28 23:31:10 2011 @@ -78,7 +78,7 @@ static struct opt_entry opt_list[] = { FLG_CRACKING_SUP, OPT_REQ_PARAM, OPT_FMT_STR_ALLOC, &options.session}, {"status", FLG_STATUS_SET, FLG_STATUS_CHK, - 0, ~FLG_STATUS_SET & ~OPT_REQ_PARAM, + 0, ~FLG_STATUS_SET & ~OPT_REQ_PARAM & ~FLG_DYNFMT, OPT_FMT_STR_ALLOC, &options.session}, {"make-charset", FLG_MAKECHR_SET, FLG_MAKECHR_CHK, 0, FLG_CRACKING_CHK | FLG_SESSION | OPT_REQ_PARAM, @@ -87,7 +87,7 @@ static struct opt_entry opt_list[] = { 0, FLG_CRACKING_SUP | FLG_MAKECHR_CHK, OPT_FMT_STR_ALLOC, &options.showuncracked_str}, {"test", FLG_TEST_SET, FLG_TEST_CHK, - 0, ~FLG_TEST_SET & ~FLG_FORMAT & ~FLG_SAVEMEM & ~FLG_CONFIG_CLI & + 0, ~FLG_TEST_SET & ~FLG_FORMAT & ~FLG_SAVEMEM & ~FLG_CONFIG_CLI & ~FLG_DYNFMT & ~OPT_REQ_PARAM & ~FLG_NOLOG & ~FLG_INP_ENCODING, "%u", &benchmark_time}, {"users", FLG_NONE, 0, FLG_PASSWD, OPT_REQ_PARAM, OPT_FMT_ADD_LIST_MULTI, &options.loader.users}, @@ -107,6 +107,8 @@ static struct opt_entry opt_list[] = { OPT_FMT_STR_ALLOC, &options.subformat}, {"save-memory", FLG_SAVEMEM, FLG_SAVEMEM, 0, OPT_REQ_PARAM, "%u", &mem_saving_level}, + {"dynamic-fmt", FLG_DYNFMT, 0, 0, OPT_REQ_PARAM, + OPT_FMT_ADD_LIST_MULTI, &options.fmt_dlls}, {"mem-file-size", FLG_NONE, FLG_NONE, 0, OPT_REQ_PARAM, "%u", &options.loader.max_wordfile_memory}, {"fix-state-delay", FLG_NONE, FLG_NONE, 0, OPT_REQ_PARAM, @@ -231,6 +233,7 @@ void opt_init(char *name, int argc, char list_init(&options.loader.users); list_init(&options.loader.groups); list_init(&options.loader.shells); + list_init(&options.fmt_dlls); options.length = -1; diff -u -p -N -X src/diff_exclude.dat src-orig/options.h src/options.h --- src-orig/options.h Sun Aug 28 23:14:52 2011 +++ src/options.h Sun Aug 28 23:24:00 2011 @@ -88,6 +88,8 @@ #define FLG_FORMAT 0x02000000 /* Memory saving enabled */ #define FLG_SAVEMEM 0x04000000 +/* dynamic load of foreign format module */ +#define FLG_DYNFMT 0x08000000 /* Command-line config file */ #define FLG_CONFIG_CLI 0x10000000 /* Turn off logging */ @@ -170,6 +172,10 @@ struct options_main { /* Write cracked passwords to log (default is just username) */ int log_passwords; + +/* Load format from DLL */ + struct list_main *fmt_dlls; + }; extern struct options_main options; Common subdirectories: src-orig/unused and src/unused