1 /*
2 * This file is part of John the Ripper password cracker,
3 * Copyright (c) 1996-2004,2006,2009-2013,2015 by Solar Designer
4 *
5 * ...with changes in the jumbo patch, by JimF and magnum (and various others?)
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted.
9 *
10 * There's ABSOLUTELY NO WARRANTY, express or implied.
11 *
12 * Please note that although this main john.c file is under the cut-down BSD
13 * license above (so that you may reuse sufficiently generic pieces of code
14 * from this file under these relaxed terms), some other source files that it
15 * uses are under GPLv2. For licensing terms for John the Ripper as a whole,
16 * see doc/LICENSE.
17 */
18
19 #if AC_BUILT
20 #include "autoconfig.h"
21 #else
22 #define _GNU_SOURCE 1 /* for strcasestr */
23 #ifdef __SIZEOF_INT128__
24 #define HAVE___INT128 1
25 #endif
26 #endif
27
28 #define NEED_OS_FORK
29 #define NEED_OS_TIMER
30 #include "os.h"
31
32 #include <stdio.h>
33 #if HAVE_DIRENT_H && HAVE_SYS_TYPES_H
34 #include <dirent.h>
35 #include <sys/types.h>
36 #elif _MSC_VER || __MINGW32__
37 #include <windows.h>
38 char CPU_req_name[48];
39 #endif
40 #if (!AC_BUILT || HAVE_UNISTD_H) && !_MSC_VER
41 #include <unistd.h>
42 #endif
43 #include <errno.h>
44 #if !AC_BUILT
45 #include <string.h>
46 #ifndef _MSC_VER
47 #include <strings.h>
48 #endif
49 #else
50 #if STRING_WITH_STRINGS
51 #include <string.h>
52 #include <strings.h>
53 #elif HAVE_STRING_H
54 #include <string.h>
55 #elif HAVE_STRINGS_H
56 #include <strings.h>
57 #endif
58 #endif
59 #include <stdlib.h>
60 #include <sys/stat.h>
61 #if OS_FORK
62 #include <sys/wait.h>
63 #include <signal.h>
64 #endif
65 #if !AC_BUILT || HAVE_LOCALE_H
66 #include <locale.h>
67 #endif
68
69 #include "params.h"
70
71 #ifdef _OPENMP
72 #include <omp.h>
73 static int john_omp_threads_orig = 0;
74 static int john_omp_threads_new;
75 #endif
76
77 #include "arch.h"
78 #include "openssl_local_overrides.h"
79 #include "misc.h"
80 #include "path.h"
81 #include "memory.h"
82 #include "list.h"
83 #include "tty.h"
84 #include "signals.h"
85 #include "common.h"
86 #include "idle.h"
87 #include "formats.h"
88 #include "dyna_salt.h"
89 #include "loader.h"
90 #include "logger.h"
91 #include "status.h"
92 #include "recovery.h"
93 #include "options.h"
94 #include "config.h"
95 #include "bench.h"
96 #ifdef HAVE_FUZZ
97 #include "fuzz.h"
98 #endif
99 #include "charset.h"
100 #include "single.h"
101 #include "wordlist.h"
102 #include "prince.h"
103 #include "inc.h"
104 #include "mask.h"
105 #include "mkv.h"
106 #include "subsets.h"
107 #include "external.h"
108 #include "batch.h"
109 #include "dynamic.h"
110 #include "dynamic_compiler.h"
111 #include "fake_salts.h"
112 #include "listconf.h"
113 #include "crc32.h"
114 #include "john_mpi.h"
115 #include "regex.h"
116
117 #include "unicode.h"
118 #include "gpu_common.h"
119 #include "opencl_common.h"
120 #ifdef NO_JOHN_BLD
121 #define JOHN_BLD "unk-build-type"
122 #else
123 #include "john_build_rule.h"
124 #endif
125
126 #if HAVE_MPI
127 #ifdef _OPENMP
128 #define _MP_VERSION " MPI + OMP"
129 #else
130 #define _MP_VERSION " MPI"
131 #endif
132 #else
133 #ifdef _OPENMP
134 #define _MP_VERSION " OMP"
135 #else
136 #define _MP_VERSION ""
137 #endif
138 #endif
139 #include "omp_autotune.h"
140
141 #if CPU_DETECT
142 extern int CPU_detect(void);
143 extern char CPU_req_name[];
144 #endif
145
146 extern struct fmt_main fmt_DES, fmt_BSDI, fmt_MD5, fmt_md5crypt_long, fmt_BF;
147 extern struct fmt_main fmt_scrypt;
148 extern struct fmt_main fmt_AFS, fmt_LM;
149 #ifdef HAVE_CRYPT
150 extern struct fmt_main fmt_crypt;
151 #endif
152 extern struct fmt_main fmt_trip;
153 extern struct fmt_main fmt_dummy;
154 extern struct fmt_main fmt_NT;
155 #ifdef HAVE_ZTEX
156 extern struct fmt_main fmt_ztex_descrypt;
157 extern struct fmt_main fmt_ztex_bcrypt;
158 extern struct fmt_main fmt_ztex_sha512crypt;
159 extern struct fmt_main fmt_ztex_drupal7;
160 extern struct fmt_main fmt_ztex_sha256crypt;
161 extern struct fmt_main fmt_ztex_md5crypt;
162 extern struct fmt_main fmt_ztex_phpass;
163 #endif
164
165 #include "fmt_externs.h"
166
167 extern int unshadow(int argc, char **argv);
168 extern int unafs(int argc, char **argv);
169 extern int unique(int argc, char **argv);
170 extern int undrop(int argc, char **argv);
171
172 extern int base64conv(int argc, char **argv);
173 extern int zip2john(int argc, char **argv);
174 extern int gpg2john(int argc, char **argv);
175 extern int rar2john(int argc, char **argv);
176
177 int john_main_process = 1;
178 #if OS_FORK
179 int john_child_count = 0;
180 int *john_child_pids = NULL;
181 #endif
182 char *john_terminal_locale ="C";
183
184 unsigned long long john_max_cands;
185
186 static int children_ok = 1;
187
188 static struct db_main database;
189 static struct fmt_main dummy_format;
190
191 static int exit_status = 0;
192
john_register_one(struct fmt_main * format)193 static void john_register_one(struct fmt_main *format)
194 {
195 static int override_disable = 0;
196
197 if (options.format && !strcasecmp(options.format, "all")) {
198 override_disable = 1;
199 options.format = NULL;
200 } else
201 if (options.format && !strncasecmp(options.format, "all-", 4)) {
202 override_disable = 1;
203 options.format += 4;
204 }
205
206 if (options.format) {
207 char *pos = strchr(options.format, '*');
208
209 if (!strncasecmp(options.format, "dynamic=", 8))
210 pos = NULL;
211 else
212 if (pos != strrchr(options.format, '*')) {
213 if (john_main_process)
214 fprintf(stderr, "Only one wildcard allowed in format "
215 "name\n");
216 error();
217 }
218
219 if (pos) {
220 /* Wildcard, as in --format=office* */
221 if (strncasecmp(format->params.label, options.format,
222 (int)(pos - options.format)))
223 return;
224 /* Trailer wildcard, as in *office or raw*ng */
225 if (pos[1]) {
226 int wild_len = strlen(++pos);
227 int label_len = strlen(format->params.label);
228 const char *p;
229
230 if (wild_len > label_len)
231 return;
232
233 p = &format->params.label[label_len - wild_len];
234
235 if (strcasecmp(p, pos))
236 return;
237 }
238 } else if (strncasecmp(options.format, "dynamic=", 8) &&
239 (pos = strchr(options.format, '@'))) {
240 char *reject, *algo = strdup(++pos);
241
242 /* Rejections */
243 if ((reject = strcasestr(algo, "-dynamic"))) {
244 if (format->params.flags & FMT_DYNAMIC) {
245 MEM_FREE (algo);
246 return;
247 }
248 memmove(reject, reject + 8, strlen(reject + 7));
249 }
250 if ((reject = strcasestr(algo, "-opencl"))) {
251 if (strstr(format->params.label, "-opencl")) {
252 MEM_FREE (algo);
253 return;
254 }
255 memmove(reject, reject + 7, strlen(reject + 6));
256 }
257 /* Algo match, eg. --format=@xop or --format=@sha384 */
258 if (!strcasestr(format->params.algorithm_name, algo)) {
259 MEM_FREE (algo);
260 return;
261 }
262 MEM_FREE (algo);
263 }
264 else if (!strcasecmp(options.format, "dynamic") ||
265 !strcasecmp(options.format, "dynamic-all")) {
266 if ((format->params.flags & FMT_DYNAMIC) == 0)
267 return;
268 }
269 else if (!strcasecmp(options.format, "cpu")) {
270 if (strstr(format->params.label, "-opencl") ||
271 strstr(format->params.label, "-ztex"))
272 return;
273 }
274 else if (!strcasecmp(options.format, "cpu-dynamic")) {
275 if (strstr(format->params.label, "-opencl"))
276 return;
277 if (format->params.flags & FMT_DYNAMIC)
278 return;
279 }
280 else if (!strcasecmp(options.format, "opencl")) {
281 if (!strstr(format->params.label, "-opencl"))
282 return;
283 }
284 else if (!strcasecmp(options.format, "mask")) {
285 if (!(format->params.flags & FMT_MASK))
286 return;
287 }
288 #ifdef _OPENMP
289 else if (!strcasecmp(options.format, "omp")) {
290 if (!(format->params.flags & FMT_OMP))
291 return;
292 }
293 else if (!strcasecmp(options.format, "cpu+omp")) {
294 if (!(format->params.flags & FMT_OMP))
295 return;
296 if (strstr(format->params.label, "-opencl"))
297 return;
298 }
299 else if (!strcasecmp(options.format, "cpu+omp-dynamic")) {
300 if (!(format->params.flags & FMT_OMP))
301 return;
302 if (strstr(format->params.label, "-opencl"))
303 return;
304 if (format->params.flags & FMT_DYNAMIC)
305 return;
306 }
307 #endif
308 else if (strcasecmp(options.format, format->params.label)) {
309 #ifndef DYNAMIC_DISABLED
310 if (!strncasecmp(options.format, "dynamic=", 8) &&
311 !strcasecmp(format->params.label, "dynamic=")) {
312 DC_HANDLE H;
313 if (!dynamic_compile(options.format, &H)) {
314 if (dynamic_assign_script_to_format(
315 H, format))
316 return;
317 } else
318 return;
319 } else
320 #endif
321 return;
322 }
323 }
324
325 /* Format disabled in john.conf */
326 if (!override_disable &&
327 cfg_get_bool(SECTION_DISABLED, SUBSECTION_FORMATS,
328 format->params.label, 0)) {
329 #ifdef DEBUG
330 if (format->params.flags & FMT_DYNAMIC) {
331 /* in debug mode, we 'allow' dyna */
332 } else
333 #else
334 if (options.format &&
335 !strcasecmp(options.format, "dynamic-all") &&
336 (format->params.flags & FMT_DYNAMIC)) {
337 /* allow dyna if '-format=dynamic-all' was selected */
338 } else
339 #endif
340 if (options.format &&
341 !strcasecmp(options.format, format->params.label)) {
342 /* allow if specifically requested */
343 } else
344 return;
345 }
346
347 fmt_register(format);
348 }
349
john_register_all(void)350 static void john_register_all(void)
351 {
352 #ifndef DYNAMIC_DISABLED
353 int i, cnt;
354 struct fmt_main *selfs;
355 #endif
356
357 if (options.format) {
358 /* The case of the expression for this format is significant */
359 if (strncasecmp(options.format, "dynamic=", 8))
360 strlwr(options.format);
361 }
362
363 /* Let ZTEX formats appear before CPU formats */
364 #ifdef HAVE_ZTEX
365 john_register_one(&fmt_ztex_descrypt);
366 john_register_one(&fmt_ztex_bcrypt);
367 john_register_one(&fmt_ztex_sha512crypt);
368 john_register_one(&fmt_ztex_drupal7);
369 john_register_one(&fmt_ztex_sha256crypt);
370 john_register_one(&fmt_ztex_md5crypt);
371 john_register_one(&fmt_ztex_phpass);
372 #endif
373 john_register_one(&fmt_DES);
374 john_register_one(&fmt_BSDI);
375 john_register_one(&fmt_MD5);
376 john_register_one(&fmt_md5crypt_long);
377 john_register_one(&fmt_BF);
378 john_register_one(&fmt_scrypt);
379 john_register_one(&fmt_LM);
380 john_register_one(&fmt_AFS);
381 john_register_one(&fmt_trip);
382
383 /* Add all plug-in formats */
384 #include "fmt_registers.h"
385
386 #ifndef DYNAMIC_DISABLED
387 /* Add dynamic formats last so they never have precedence */
388 cnt = dynamic_Register_formats(&selfs);
389
390 for (i = 0; i < cnt; ++i)
391 john_register_one(&(selfs[i]));
392 #endif
393
394 john_register_one(&fmt_dummy);
395 #if HAVE_CRYPT
396 john_register_one(&fmt_crypt);
397 #endif
398
399 if (!fmt_list) {
400 if (john_main_process)
401 fprintf(stderr, "Unknown ciphertext format name requested\n");
402 error();
403 }
404 }
405
john_log_format(void)406 static void john_log_format(void)
407 {
408 int enc_len, utf8_len;
409 char max_len_s[128];
410
411 /* make sure the format is properly initialized */
412 #if HAVE_OPENCL
413 if (!(options.acc_devices->count && options.fork &&
414 strstr(database.format->params.label, "-opencl")))
415 #endif
416 fmt_init(database.format);
417
418 utf8_len = enc_len = database.format->params.plaintext_length;
419 if (options.target_enc == UTF_8)
420 utf8_len /= 3;
421
422 if (!(database.format->params.flags & FMT_8_BIT) ||
423 options.target_enc != UTF_8) {
424 /* Not using UTF-8 so length is not ambiguous */
425 snprintf(max_len_s, sizeof(max_len_s), "%d", enc_len);
426 } else if (!fmt_raw_len || fmt_raw_len == enc_len) {
427 /* Example: Office and thin dynamics */
428 snprintf(max_len_s, sizeof(max_len_s),
429 "%d [worst case UTF-8] to %d [ASCII]",
430 utf8_len, enc_len);
431 } else if (enc_len == 3 * fmt_raw_len) {
432 /* Example: NT */
433 snprintf(max_len_s, sizeof(max_len_s), "%d", utf8_len);
434 } else {
435 /* Example: SybaseASE */
436 snprintf(max_len_s, sizeof(max_len_s),
437 "%d [worst case UTF-8] to %d [ASCII]",
438 utf8_len, fmt_raw_len);
439 }
440
441 log_event("- Hash type: %.100s%s%.100s (min-len %d, max-len %s%s)",
442 database.format->params.label,
443 database.format->params.format_name[0] ? ", " : "",
444 database.format->params.format_name,
445 database.format->params.plaintext_min_length,
446 max_len_s,
447 (database.format == &fmt_DES || database.format == &fmt_LM) ?
448 ", longer passwords split" : "");
449
450 log_event("- Algorithm: %.100s",
451 database.format->params.algorithm_name);
452 }
453
john_log_format2(void)454 static void john_log_format2(void)
455 {
456 int min_chunk, chunk;
457
458 /* Messages require extra info not available in john_log_format().
459 These are delayed until mask_init(), fmt_reset() */
460 chunk = min_chunk = database.format->params.max_keys_per_crypt;
461 if (options.flags & (FLG_SINGLE_CHK | FLG_BATCH_CHK) &&
462 chunk < SINGLE_HASH_MIN)
463 chunk = SINGLE_HASH_MIN;
464 if (chunk > 1)
465 log_event("- Candidate passwords %s be buffered and "
466 "tried in chunks of %d",
467 min_chunk > 1 ? "will" : "may",
468 chunk);
469 }
470
471 #ifdef _OPENMP
john_omp_init(void)472 static void john_omp_init(void)
473 {
474 john_omp_threads_new = omp_get_max_threads();
475 if (!john_omp_threads_orig)
476 john_omp_threads_orig = john_omp_threads_new;
477 }
478
479 #if OMP_FALLBACK
480 #if defined(__DJGPP__)
481 #error OMP_FALLBACK is incompatible with the current DOS code
482 #endif
483 #define HAVE_JOHN_OMP_FALLBACK
john_omp_fallback(char ** argv)484 static void john_omp_fallback(char **argv) {
485 if (!getenv("JOHN_NO_OMP_FALLBACK") && john_omp_threads_new <= 1) {
486 rec_done(-2);
487 #ifdef JOHN_SYSTEMWIDE_EXEC
488 #define OMP_FALLBACK_PATHNAME JOHN_SYSTEMWIDE_EXEC "/" OMP_FALLBACK_BINARY
489 #else
490 #define OMP_FALLBACK_PATHNAME path_expand("$JOHN/" OMP_FALLBACK_BINARY)
491 #endif
492 #if HAVE_MPI
493 mpi_teardown();
494 #endif
495 execv(OMP_FALLBACK_PATHNAME, argv);
496 #ifdef JOHN_SYSTEMWIDE_EXEC
497 perror("execv: " OMP_FALLBACK_PATHNAME);
498 #else
499 perror("execv: $JOHN/" OMP_FALLBACK_BINARY);
500 #endif
501 }
502 }
503 #endif
504
john_omp_maybe_adjust_or_fallback(char ** argv)505 static void john_omp_maybe_adjust_or_fallback(char **argv)
506 {
507 if (options.fork && !getenv("OMP_NUM_THREADS")) {
508 john_omp_threads_new /= options.fork;
509 if (john_omp_threads_new < 1)
510 john_omp_threads_new = 1;
511 omp_set_num_threads(john_omp_threads_new);
512 john_omp_init();
513 #ifdef HAVE_JOHN_OMP_FALLBACK
514 john_omp_fallback(argv);
515 #endif
516 }
517 }
518
john_omp_show_info(void)519 static void john_omp_show_info(void)
520 {
521 if (options.verbosity >= VERB_DEFAULT)
522 #if HAVE_MPI
523 if (mpi_p == 1)
524 #endif
525 if (database.format && database.format->params.label &&
526 !strstr(database.format->params.label, "-opencl") &&
527 !strstr(database.format->params.label, "-ztex"))
528 if (!options.fork && john_omp_threads_orig > 1 &&
529 database.format && database.format != &dummy_format &&
530 !rec_restoring_now) {
531 const char *msg = NULL;
532 if (!(database.format->params.flags & FMT_OMP))
533 msg = "no OpenMP support";
534 else if ((database.format->params.flags & FMT_OMP_BAD))
535 msg = "poor OpenMP scalability";
536 if (msg) {
537 #if OS_FORK
538 if (!(options.flags & (FLG_PIPE_CHK | FLG_STDIN_CHK)))
539 fprintf(stderr, "Warning: %s for this hash type, "
540 "consider --fork=%d\n",
541 msg, john_omp_threads_orig);
542 else
543 #endif
544 fprintf(stderr, "Warning: %s for this hash type\n",
545 msg);
546 }
547 }
548
549 /*
550 * Only show OpenMP info if one of the following is true:
551 * - we have a format detected for the loaded hashes and it is OpenMP-enabled;
552 * - we're doing --test and no format is specified (so we will test all,
553 * including some that are presumably OpenMP-enabled);
554 * - we're doing --test and the specified format is OpenMP-enabled.
555 */
556 {
557 int show = 0;
558 if (database.format &&
559 (database.format->params.flags & FMT_OMP))
560 show = 1;
561 else if ((options.flags & (FLG_TEST_CHK | FLG_FORMAT)) ==
562 FLG_TEST_CHK)
563 show = 1;
564 else if ((options.flags & FLG_TEST_CHK) &&
565 (fmt_list->params.flags & FMT_OMP))
566 show = 1;
567
568 if (!show)
569 return;
570 }
571
572 #if HAVE_MPI
573 /*
574 * If OMP_NUM_THREADS is set, we assume the user knows what
575 * he is doing. Here's how to pass it to remote hosts:
576 * mpirun -x OMP_NUM_THREADS=4 -np 4 -host ...
577 */
578 if (mpi_p > 1) {
579 if (getenv("OMP_NUM_THREADS") == NULL &&
580 cfg_get_bool(SECTION_OPTIONS, SUBSECTION_MPI,
581 "MPIOMPmutex", 1)) {
582 if (cfg_get_bool(SECTION_OPTIONS, SUBSECTION_MPI,
583 "MPIOMPverbose", 1) && mpi_id == 0)
584 fprintf(stderr, "MPI in use, disabling OMP "
585 "(see doc/README.mpi)\n");
586 omp_set_num_threads(1);
587 john_omp_threads_orig = 0; /* Mute later warning */
588 } else if (john_omp_threads_orig > 1 &&
589 cfg_get_bool(SECTION_OPTIONS, SUBSECTION_MPI,
590 "MPIOMPverbose", 1) && mpi_id == 0)
591 fprintf(stderr, "Note: Running both MPI and OMP"
592 " (see doc/README.mpi)\n");
593 } else
594 #endif
595 if (options.fork) {
596 #if OS_FORK
597 if (john_omp_threads_new > 1)
598 fprintf(stderr,
599 "Will run %d OpenMP threads per process "
600 "(%u total across %u processes)\n",
601 john_omp_threads_new,
602 john_omp_threads_new * options.fork, options.fork);
603 else if (john_omp_threads_orig > 1)
604 fputs("Warning: OpenMP was disabled due to --fork; "
605 "a non-OpenMP build may be faster\n", stderr);
606 #endif
607 } else {
608 if (john_omp_threads_new > 1)
609 fprintf(stderr,
610 "Will run %d OpenMP threads\n",
611 john_omp_threads_new);
612 }
613
614 if (john_omp_threads_orig == 1)
615 if (options.verbosity >= VERB_DEFAULT)
616 if (john_main_process) {
617 const char *format = database.format ?
618 database.format->params.label : options.format;
619 if (format && strstr(format, "-opencl"))
620 fputs("Warning: OpenMP is disabled; "
621 "GPU may be under-utilized\n", stderr);
622 else
623 fputs("Warning: OpenMP is disabled; "
624 "a non-OpenMP build may be faster\n", stderr);
625 }
626 }
627 #endif
628
629 #if OS_FORK
john_fork(void)630 static void john_fork(void)
631 {
632 int i, pid;
633 int *pids;
634
635 fflush(stdout);
636 fflush(stderr);
637
638 #if HAVE_MPI
639 /*
640 * We already initialized MPI before knowing this is actually a fork session.
641 * So now we need to tear that "1-node MPI session" down before forking, or
642 * all sorts of funny things might happen.
643 */
644 mpi_teardown();
645 #endif
646 /*
647 * It may cost less memory to reset john_main_process to 0 before fork()'ing
648 * the children than to do it in every child process individually (triggering
649 * copy-on-write of the entire page). We then reset john_main_process back to
650 * 1 in the parent, but this only costs one page, not one page per child.
651 */
652 john_main_process = 0;
653
654 pids = mem_alloc_tiny((options.fork - 1) * sizeof(*pids),
655 sizeof(*pids));
656
657 for (i = 1; i < options.fork; i++) {
658 switch ((pid = fork())) {
659 case -1:
660 pexit("fork");
661
662 case 0:
663 sig_preinit();
664 options.node_min += i;
665 options.node_max = options.node_min;
666 #if HAVE_OPENCL
667 /* Poor man's multi-device support */
668 if (options.acc_devices->count &&
669 strstr(database.format->params.label, "-opencl")) {
670 /* Postponed format init in forked process */
671 fmt_init(database.format);
672 }
673 #endif
674 if (rec_restoring_now) {
675 unsigned int node_id = options.node_min;
676 rec_done(-2);
677 rec_restore_args(1);
678 if (node_id != options.node_min + i)
679 fprintf(stderr,
680 "Inconsistent crash recovery file:"
681 " %s\n", rec_name);
682 options.node_min = options.node_max = node_id;
683 }
684 sig_init_child();
685 return;
686
687 default:
688 pids[i - 1] = pid;
689 }
690 }
691
692 #if HAVE_OPENCL
693 /* Poor man's multi-device support */
694 if (options.acc_devices->count &&
695 strstr(database.format->params.label, "-opencl")) {
696 /* Postponed format init in mother process */
697 fmt_init(database.format);
698 }
699 #endif
700 john_main_process = 1;
701 john_child_pids = pids;
702 john_child_count = options.fork - 1;
703
704 options.node_max = options.node_min;
705 }
706
707 /*
708 * This is the "equivalent" of john_fork() for MPI runs. We are mostly
709 * mimicing a -fork run, especially for resuming a session.
710 */
711 #if HAVE_MPI
john_set_mpi(void)712 static void john_set_mpi(void)
713 {
714 options.node_min += mpi_id;
715 options.node_max = options.node_min;
716
717 if (mpi_p > 1) {
718 if (!john_main_process) {
719 if (rec_restoring_now) {
720 unsigned int node_id = options.node_min;
721 rec_done(-2);
722 rec_restore_args(1);
723 if (node_id != options.node_min + mpi_id)
724 fprintf(stderr,
725 "Inconsistent crash recovery file:"
726 " %s\n", rec_name);
727 options.node_min = options.node_max = node_id;
728 }
729 }
730 }
731 fflush(stdout);
732 fflush(stderr);
733 }
734 #endif
735
john_wait(void)736 static void john_wait(void)
737 {
738 int waiting_for = john_child_count;
739
740 log_event("Waiting for %d child%s to terminate",
741 waiting_for, waiting_for == 1 ? "" : "ren");
742 log_flush();
743 fprintf(stderr, "Waiting for %d child%s to terminate\n",
744 waiting_for, waiting_for == 1 ? "" : "ren");
745
746 log_flush();
747
748 /* Tell our friends there is nothing more to crack! */
749 if (!database.password_count && !options.reload_at_crack &&
750 cfg_get_bool(SECTION_OPTIONS, NULL, "ReloadAtDone", 0))
751 raise(SIGUSR2);
752
753 /*
754 * Although we may block on wait(2), we still have signal handlers and a timer
755 * in place, so we're relaying keypresses to child processes via signals.
756 */
757 while (waiting_for) {
758 int i, status;
759 int pid = wait(&status);
760 if (pid == -1) {
761 if (errno != EINTR)
762 perror("wait");
763 } else
764 for (i = 0; i < john_child_count; i++) {
765 if (john_child_pids[i] == pid) {
766 john_child_pids[i] = 0;
767 waiting_for--;
768 children_ok = children_ok &&
769 WIFEXITED(status) && !WEXITSTATUS(status);
770 break;
771 }
772 }
773 }
774
775 /* Close and possibly remove our .rec file now */
776 rec_done((children_ok && !event_abort) ? -1 : -2);
777 }
778 #endif
779
780 #if HAVE_MPI
john_mpi_wait(void)781 static void john_mpi_wait(void)
782 {
783 if (!database.password_count && !options.reload_at_crack) {
784 int i;
785
786 for (i = 0; i < mpi_p; i++) {
787 if (i == mpi_id)
788 continue;
789 if (mpi_req[i] == NULL)
790 mpi_req[i] = mem_alloc_tiny(sizeof(MPI_Request),
791 MEM_ALIGN_WORD);
792 else
793 if (*mpi_req[i] != MPI_REQUEST_NULL)
794 continue;
795 MPI_Isend("r", 1, MPI_CHAR, i, JOHN_MPI_RELOAD,
796 MPI_COMM_WORLD, mpi_req[i]);
797 }
798 }
799
800 if (john_main_process) {
801 log_event("Waiting for other node%s to terminate",
802 mpi_p > 2 ? "s" : "");
803 fprintf(stderr, "Waiting for other node%s to terminate\n",
804 mpi_p > 2 ? "s" : "");
805 mpi_teardown();
806 }
807
808 /* Close and possibly remove our .rec file now */
809 rec_done(!event_abort ? -1 : -2);
810 }
811 #endif
812
john_loaded_counts(void)813 static char *john_loaded_counts(void)
814 {
815 static char s_loaded_counts[80];
816 char nbuf[24];
817
818 if (database.password_count == 1)
819 return "1 password hash";
820
821 sprintf(s_loaded_counts,
822 "%d password hashes with %s different salts",
823 database.password_count,
824 database.salt_count > 1 ?
825 jtr_itoa(database.salt_count, nbuf, 24, 10) : "no");
826
827 return s_loaded_counts;
828 }
829
john_load_conf(void)830 static void john_load_conf(void)
831 {
832 int internal, target;
833
834 if (!(options.flags & FLG_VERBOSITY)) {
835 options.verbosity = cfg_get_int(SECTION_OPTIONS, NULL,
836 "Verbosity");
837
838 /* If it doesn't exist in john.conf it ends up as -1 */
839 if (options.verbosity == -1)
840 options.verbosity = VERB_DEFAULT;
841
842 if (options.verbosity < 1 || options.verbosity > VERB_DEBUG) {
843 if (john_main_process)
844 fprintf(stderr, "Invalid verbosity level in "
845 "config file, use 1-%u (default %u)"
846 " or %u for debug\n",
847 VERB_MAX, VERB_DEFAULT, VERB_DEBUG);
848 error();
849 }
850 }
851
852 if (options.activepot == NULL) {
853 if (options.secure)
854 options.activepot = str_alloc_copy(SEC_POT_NAME);
855 else
856 options.activepot = str_alloc_copy(POT_NAME);
857 }
858
859 if (options.activewordlistrules == NULL)
860 if (!(options.activewordlistrules =
861 cfg_get_param(SECTION_OPTIONS, NULL,
862 "BatchModeWordlistRules")))
863 options.activewordlistrules =
864 str_alloc_copy(SUBSECTION_WORDLIST);
865
866 if (options.activesinglerules == NULL)
867 if (!(options.activesinglerules =
868 cfg_get_param(SECTION_OPTIONS, NULL,
869 "SingleRules")))
870 options.activesinglerules =
871 str_alloc_copy(SUBSECTION_SINGLE);
872
873 if ((options.flags & FLG_LOOPBACK_CHK) &&
874 !(options.flags & FLG_RULES)) {
875 if ((options.activewordlistrules =
876 cfg_get_param(SECTION_OPTIONS, NULL,
877 "LoopbackRules")))
878 options.flags |= FLG_RULES;
879 }
880
881 if ((options.flags & FLG_WORDLIST_CHK) &&
882 !(options.flags & FLG_RULES)) {
883 if ((options.activewordlistrules =
884 cfg_get_param(SECTION_OPTIONS, NULL,
885 "WordlistRules")))
886 {
887 if (strlen(options.activewordlistrules) == 0)
888 options.activewordlistrules = NULL;
889 else
890 options.flags |= FLG_RULES;
891 }
892 }
893
894 /* EmulateBrokenEncoding feature */
895 options.replacement_character = 0;
896 if (cfg_get_bool(SECTION_OPTIONS, NULL, "EmulateBrokenEncoding", 0)) {
897 const char *value;
898
899 value = cfg_get_param(SECTION_OPTIONS, NULL, "ReplacementCharacter");
900 if (value != NULL)
901 options.replacement_character = value[0];
902 }
903
904 options.secure = cfg_get_bool(SECTION_OPTIONS, NULL, "SecureMode", 0);
905 options.show_uid_in_cracks = cfg_get_bool(SECTION_OPTIONS, NULL, "ShowUIDinCracks", 0);
906 options.reload_at_crack =
907 cfg_get_bool(SECTION_OPTIONS, NULL, "ReloadAtCrack", 0);
908 options.reload_at_save =
909 cfg_get_bool(SECTION_OPTIONS, NULL, "ReloadAtSave", 1);
910 options.abort_file = cfg_get_param(SECTION_OPTIONS, NULL, "AbortFile");
911 options.pause_file = cfg_get_param(SECTION_OPTIONS, NULL, "PauseFile");
912
913 /* This is --crack-status. We toggle here, so if it's enabled in
914 john.conf, we can disable it using the command line option */
915 if (cfg_get_bool(SECTION_OPTIONS, NULL, "CrackStatus", 0))
916 options.flags ^= FLG_CRKSTAT;
917
918 #if HAVE_OPENCL
919 if (cfg_get_bool(SECTION_OPTIONS, SUBSECTION_OPENCL, "ForceScalar", 0))
920 options.flags |= FLG_SCALAR;
921 #endif
922
923 options.loader.log_passwords = options.secure ||
924 cfg_get_bool(SECTION_OPTIONS, NULL, "LogCrackedPasswords", 0);
925
926 if (!options.input_enc && !(options.flags & FLG_TEST_CHK)) {
927 if ((options.flags & FLG_LOOPBACK_CHK) &&
928 cfg_get_bool(SECTION_OPTIONS, NULL, "UnicodeStoreUTF8", 0))
929 options.input_enc = cp_name2id("UTF-8");
930 else {
931 options.input_enc =
932 cp_name2id(cfg_get_param(SECTION_OPTIONS, NULL,
933 "DefaultEncoding"));
934 }
935 options.default_enc = options.input_enc;
936 }
937
938 /* Pre-init in case some format's prepare() needs it */
939 internal = options.internal_cp;
940 target = options.target_enc;
941 initUnicode(UNICODE_UNICODE);
942 options.internal_cp = internal;
943 options.target_enc = target;
944 options.unicode_cp = CP_UNDEF;
945 }
946
john_load_conf_db(void)947 static void john_load_conf_db(void)
948 {
949 if (options.flags & FLG_STDOUT) {
950 /* john.conf alternative for --internal-codepage */
951 if (!options.internal_cp &&
952 options.target_enc == UTF_8 && options.flags &
953 (FLG_RULES | FLG_SINGLE_CHK | FLG_BATCH_CHK | FLG_MASK_CHK))
954 if (!(options.internal_cp =
955 cp_name2id(cfg_get_param(SECTION_OPTIONS, NULL,
956 "DefaultInternalCodepage"))))
957 options.internal_cp =
958 cp_name2id(cfg_get_param(SECTION_OPTIONS, NULL,
959 "DefaultInternalEncoding"));
960 }
961
962 if (!options.unicode_cp)
963 initUnicode(UNICODE_UNICODE);
964
965 options.report_utf8 = cfg_get_bool(SECTION_OPTIONS,
966 NULL, "AlwaysReportUTF8", 0);
967
968 /* Unicode (UTF-16) formats may lack encoding support. We
969 must stop the user from trying to use it because it will
970 just result in false negatives. */
971 if (database.format && options.target_enc != ASCII &&
972 options.target_enc != ISO_8859_1 &&
973 database.format->params.flags & FMT_UNICODE &&
974 !(database.format->params.flags & FMT_ENC)) {
975 if (john_main_process)
976 fprintf(stderr, "This format does not yet support"
977 " other encodings than ISO-8859-1\n");
978 error();
979 }
980
981 if (database.format && database.format->params.flags & FMT_UNICODE)
982 options.store_utf8 = cfg_get_bool(SECTION_OPTIONS,
983 NULL, "UnicodeStoreUTF8", 0);
984 else
985 options.store_utf8 = options.target_enc != ASCII &&
986 cfg_get_bool(SECTION_OPTIONS, NULL, "CPstoreUTF8", 0);
987
988 if (options.target_enc != options.input_enc &&
989 options.input_enc != UTF_8) {
990 if (john_main_process)
991 fprintf(stderr, "Target encoding can only be specified"
992 " if input encoding is UTF-8\n");
993 error();
994 }
995
996 if (john_main_process)
997 if (!(options.flags & FLG_SHOW_CHK) && !options.loader.showuncracked) {
998 if (options.flags & (FLG_PASSWD | FLG_WORDLIST_CHK |
999 FLG_STDIN_CHK | FLG_PIPE_CHK))
1000 if (options.default_enc && options.input_enc != ASCII)
1001 fprintf(stderr, "Using default input encoding: %s\n",
1002 cp_id2name(options.input_enc));
1003
1004 if (options.target_enc != options.input_enc &&
1005 (!database.format ||
1006 !(database.format->params.flags & FMT_UNICODE))) {
1007 if (options.default_target_enc)
1008 fprintf(stderr, "Using default target "
1009 "encoding: %s\n",
1010 cp_id2name(options.target_enc));
1011 else
1012 fprintf(stderr, "Target encoding: %s\n",
1013 cp_id2name(options.target_enc));
1014 }
1015
1016 if (options.input_enc != options.internal_cp)
1017 if (database.format &&
1018 (database.format->params.flags & FMT_UNICODE))
1019 fprintf(stderr, "Rules/masks using %s\n",
1020 cp_id2name(options.internal_cp));
1021 }
1022 }
1023
load_extra_pots(struct db_main * db,void (* process_file)(struct db_main * db,char * name))1024 static void load_extra_pots(struct db_main *db, void (*process_file)(struct db_main *db, char *name))
1025 {
1026 struct cfg_list *list;
1027 struct cfg_line *line;
1028
1029 if ((list = cfg_get_list("List.Extra:", "Potfiles")))
1030 if ((line = list->head))
1031 do {
1032 struct stat s;
1033 char *name = (char*)path_expand(line->data);
1034
1035 if (!stat(name, &s) && s.st_mode & S_IFREG)
1036 process_file(db, name);
1037 #if HAVE_DIRENT_H && HAVE_SYS_TYPES_H
1038 else if (s.st_mode & S_IFDIR) {
1039 DIR *dp;
1040
1041 dp = opendir(name);
1042 if (dp != NULL) {
1043 struct dirent *ep;
1044
1045 while ((ep = readdir(dp))) {
1046 char dname[2 * PATH_BUFFER_SIZE];
1047 char *p;
1048
1049 if (!(p = strrchr(ep->d_name, '.')) ||
1050 strcmp(p, ".pot"))
1051 continue;
1052
1053 snprintf(dname, sizeof(dname), "%s/%s",
1054 name, ep->d_name);
1055
1056 if (!stat(dname, &s) &&
1057 s.st_mode & S_IFREG)
1058 process_file(db, dname);
1059 }
1060 (void)closedir(dp);
1061 }
1062 }
1063 #elif _MSC_VER || __MINGW32__
1064 else if (s.st_mode & S_IFDIR) {
1065 WIN32_FIND_DATA f;
1066 HANDLE h;
1067 char dname[PATH_BUFFER_SIZE];
1068
1069 snprintf(dname, sizeof(dname), "%s/*.pot", name);
1070 h = FindFirstFile(dname, &f);
1071
1072 if (h != INVALID_HANDLE_VALUE)
1073 do {
1074 snprintf(dname, sizeof(dname), "%s/%s",
1075 name, f.cFileName);
1076 process_file(db, dname);
1077 } while (FindNextFile(h, &f));
1078
1079 FindClose(h);
1080 }
1081 #endif
1082 } while ((line = line->next));
1083 }
1084
db_main_free(struct db_main * db)1085 static void db_main_free(struct db_main *db)
1086 {
1087 if (db->format &&
1088 (db->format->params.flags & FMT_DYNA_SALT) == FMT_DYNA_SALT) {
1089 struct db_salt *psalt = db->salts;
1090 while (psalt) {
1091 dyna_salt_remove(psalt->salt);
1092 psalt = psalt->next;
1093 }
1094 }
1095 MEM_FREE(db->salt_hash);
1096 MEM_FREE(db->cracked_hash);
1097 }
1098
john_load(void)1099 static void john_load(void)
1100 {
1101 struct list_entry *current;
1102
1103 #ifndef _MSC_VER
1104 umask(077);
1105 #endif
1106
1107 if (options.flags & FLG_EXTERNAL_CHK)
1108 ext_init(options.external, NULL);
1109
1110 if (options.flags & FLG_MAKECHR_CHK) {
1111 options.loader.flags |= DB_CRACKED;
1112 ldr_init_database(&database, &options.loader);
1113
1114 if (options.flags & FLG_PASSWD) {
1115 ldr_show_pot_file(&database, options.activepot);
1116
1117 database.options->flags |= DB_PLAINTEXTS;
1118 if ((current = options.passwd->head))
1119 do {
1120 ldr_show_pw_file(&database, current->data);
1121 } while ((current = current->next));
1122 } else {
1123 database.options->flags |= DB_PLAINTEXTS;
1124 ldr_show_pot_file(&database, options.activepot);
1125 }
1126
1127 return;
1128 }
1129
1130 if (options.flags & FLG_STDOUT) {
1131 ldr_init_database(&database, &options.loader);
1132 database.format = &dummy_format;
1133 memset(&dummy_format, 0, sizeof(dummy_format));
1134 dummy_format.params.plaintext_length = options.length;
1135 dummy_format.params.flags = FMT_CASE | FMT_8_BIT | FMT_TRUNC;
1136 if (options.report_utf8 || options.target_enc == UTF_8)
1137 dummy_format.params.flags |= FMT_ENC;
1138 dummy_format.params.label = "stdout";
1139 dummy_format.methods.reset = &fmt_default_reset;
1140 dummy_format.methods.clear_keys = &fmt_default_clear_keys;
1141
1142 if (!options.target_enc || options.input_enc != UTF_8)
1143 options.target_enc = options.input_enc;
1144
1145 if (!(options.flags & FLG_LOOPBACK_CHK) &&
1146 options.req_maxlength > options.length) {
1147 fprintf(stderr, "Can't set max length larger than %u "
1148 "for stdout format\n", options.length);
1149 error();
1150 }
1151 if (options.verbosity <= 1)
1152 if (john_main_process)
1153 fprintf(stderr, "Warning: Verbosity decreased to minimum, candidates will not be printed!\n");
1154 john_load_conf_db();
1155 }
1156
1157 if (options.flags & FLG_PASSWD) {
1158 int total;
1159 int i = 0;
1160
1161 if (options.flags & FLG_SHOW_CHK) {
1162 options.loader.flags |= DB_CRACKED;
1163 ldr_init_database(&database, &options.loader);
1164
1165 if (!options.loader.showformats) {
1166 ldr_show_pot_file(&database, options.activepot);
1167 /*
1168 * Load optional extra (read-only) pot files. If an entry is a directory,
1169 * we read all files in it. We currently do NOT recurse.
1170 */
1171 load_extra_pots(&database, &ldr_show_pot_file);
1172 }
1173
1174 if ((current = options.passwd->head))
1175 do {
1176 ldr_show_pw_file(&database, current->data);
1177 } while ((current = current->next));
1178
1179 if (john_main_process && options.loader.showinvalid)
1180 fprintf(stderr,
1181 "%d valid hash%s, %d invalid hash%s\n",
1182 database.guess_count,
1183 database.guess_count != 1 ? "es" : "",
1184 database.password_count,
1185 database.password_count != 1 ? "es" : "");
1186 else
1187 if (john_main_process && !options.loader.showformats)
1188 printf("%s%d password hash%s cracked, %d left\n",
1189 database.guess_count ? "\n" : "",
1190 database.guess_count,
1191 database.guess_count != 1 ? "es" : "",
1192 database.password_count -
1193 database.guess_count);
1194
1195 if (options.loader.showformats &&
1196 !options.loader.showformats_old)
1197 puts("]");
1198
1199 fmt_all_done();
1200
1201 return;
1202 }
1203
1204 if (options.flags & (FLG_SINGLE_CHK | FLG_BATCH_CHK) &&
1205 status.pass <= 1)
1206 options.loader.flags |= DB_WORDS;
1207 else
1208 if (mem_saving_level) {
1209 options.loader.flags &= ~DB_LOGIN;
1210 options.show_uid_in_cracks = 0;
1211 }
1212
1213 if (mem_saving_level >= 2)
1214 options.max_wordfile_memory = 1;
1215
1216 ldr_init_database(&database, &options.loader);
1217
1218 if ((current = options.passwd->head))
1219 do {
1220 ldr_load_pw_file(&database, current->data);
1221 } while ((current = current->next));
1222
1223 /* Process configuration options that depend on db/format */
1224 john_load_conf_db();
1225
1226 if ((options.flags & FLG_CRACKING_CHK) &&
1227 database.password_count) {
1228 log_init(LOG_NAME, NULL, options.session);
1229 if (status_restored_time)
1230 log_event("Continuing an interrupted session");
1231 else
1232 log_event("Starting a new session");
1233 log_event("Loaded a total of %s", john_loaded_counts());
1234 /* only allow --device for OpenCL or ZTEX formats */
1235 #if HAVE_OPENCL || HAVE_ZTEX
1236 if (options.acc_devices->count &&
1237 !(strstr(database.format->params.label, "-opencl") ||
1238 strstr(database.format->params.label, "-ztex"))) {
1239 if (john_main_process)
1240 fprintf(stderr,
1241 "The \"--devices\" option is valid only for OpenCL or ZTEX formats\n");
1242 error();
1243 }
1244 #endif
1245
1246 /* make sure the format is properly initialized */
1247 #if HAVE_OPENCL
1248 if (!(options.acc_devices->count && options.fork &&
1249 strstr(database.format->params.label, "-opencl")))
1250 #endif
1251 fmt_init(database.format);
1252 if (john_main_process)
1253 printf("Loaded %s (%s%s%s [%s])\n",
1254 john_loaded_counts(),
1255 database.format->params.label,
1256 database.format->params.format_name[0] ? ", " : "",
1257 database.format->params.format_name,
1258 database.format->params.algorithm_name);
1259
1260 /* Tell External our max length */
1261 if (options.flags & FLG_EXTERNAL_CHK)
1262 ext_init(options.external, &database);
1263 }
1264
1265 total = database.password_count;
1266
1267 ldr_load_pot_file(&database, options.activepot);
1268
1269 /*
1270 * Load optional extra (read-only) pot files. If an entry is a directory,
1271 * we read all files in it. We currently do NOT recurse.
1272 */
1273 load_extra_pots(&database, &ldr_load_pot_file);
1274
1275 ldr_fix_database(&database);
1276
1277 if (!database.password_count) {
1278 log_discard();
1279 if (john_main_process)
1280 printf("No password hashes %s (see FAQ)\n",
1281 total ? "left to crack" : "loaded");
1282 /* skip tunable cost reporting if no hashes were loaded */
1283 i = FMT_TUNABLE_COSTS;
1284 } else
1285 if (database.password_count < total) {
1286 log_event("Remaining %s", john_loaded_counts());
1287 if (john_main_process)
1288 printf("Remaining %s\n", john_loaded_counts());
1289 }
1290
1291 for ( ; i < FMT_TUNABLE_COSTS &&
1292 database.format->methods.tunable_cost_value[i] != NULL; i++) {
1293 if (database.min_cost[i] < database.max_cost[i]) {
1294 log_event("Loaded hashes with cost %d (%s)"
1295 " varying from %u to %u",
1296 i+1, database.format->params.tunable_cost_name[i],
1297 database.min_cost[i], database.max_cost[i]);
1298 if (john_main_process)
1299 printf("Loaded hashes with cost %d (%s)"
1300 " varying from %u to %u\n",
1301 i+1, database.format->params.tunable_cost_name[i],
1302 database.min_cost[i], database.max_cost[i]);
1303 }
1304 else { // if (database.min_cost[i] == database.max_cost[i]) {
1305 log_event("Cost %d (%s) is %u for all loaded hashes",
1306 i+1, database.format->params.tunable_cost_name[i],
1307 database.min_cost[i]);
1308 if (options.verbosity >= VERB_DEFAULT &&
1309 john_main_process)
1310 printf("Cost %d (%s) is %u for all loaded "
1311 "hashes\n", i+1,
1312 database.format->params.tunable_cost_name[i],
1313 database.min_cost[i]);
1314 }
1315 }
1316 if ((options.flags & FLG_PWD_REQ) && !database.salts) exit(0);
1317
1318 if (options.regen_lost_salts)
1319 build_fake_salts_for_regen_lost(database.salts);
1320 }
1321
1322 /*
1323 * Nefarious hack and memory leak. Among other problems, we'd want
1324 * ldr_drop_database() after this, but it's built with mem_alloc_tiny()
1325 * so it's not trivial. Works like a champ though, except with
1326 * DEScrypt. I have no idea why, maybe because LM and DES share code?
1327 */
1328 if (options.flags & FLG_LOOPBACK_CHK &&
1329 database.format != &fmt_LM && database.format != &fmt_DES) {
1330 struct db_main loop_db;
1331 struct fmt_main *save_list = fmt_list;
1332 char *loop_pot = options.wordlist ?
1333 options.wordlist : options.activepot;
1334
1335 fmt_list = &fmt_LM;
1336
1337 options.loader.flags |= DB_CRACKED;
1338 ldr_init_database(&loop_db, &options.loader);
1339
1340 ldr_show_pot_file(&loop_db, loop_pot);
1341 /*
1342 * Load optional extra (read-only) pot files. If an entry is a directory,
1343 * we read all files in it. We currently do NOT recurse.
1344 */
1345 load_extra_pots(&loop_db, &ldr_show_pot_file);
1346
1347 loop_db.options->flags |= DB_PLAINTEXTS;
1348
1349 if ((current = options.passwd->head))
1350 do {
1351 ldr_show_pw_file(&loop_db, current->data);
1352 } while ((current = current->next));
1353
1354 if (loop_db.plaintexts->count) {
1355 log_event("- Reassembled %d split passwords for "
1356 "loopback", loop_db.plaintexts->count);
1357 if (john_main_process &&
1358 options.verbosity >= VERB_DEFAULT)
1359 fprintf(stderr,
1360 "Reassembled %d split passwords for "
1361 "loopback\n",
1362 loop_db.plaintexts->count);
1363 }
1364 database.plaintexts = loop_db.plaintexts;
1365 options.loader.flags &= ~DB_CRACKED;
1366 fmt_list = save_list;
1367 db_main_free(&loop_db);
1368 }
1369
1370 #ifdef _OPENMP
1371 john_omp_show_info();
1372 #endif
1373
1374 if (options.node_count) {
1375 if (options.node_min != options.node_max) {
1376 log_event("- Node numbers %u-%u of %u%s",
1377 options.node_min, options.node_max,
1378 #ifndef HAVE_MPI
1379 options.node_count, options.fork ? " (fork)" : "");
1380 #else
1381 options.node_count, options.fork ? " (fork)" :
1382 mpi_p > 1 ? " (MPI)" : "");
1383 #endif
1384 if (john_main_process)
1385 fprintf(stderr, "Node numbers %u-%u of %u%s\n",
1386 options.node_min, options.node_max,
1387 #ifndef HAVE_MPI
1388 options.node_count, options.fork ? " (fork)" : "");
1389 #else
1390 options.node_count, options.fork ? " (fork)" :
1391 mpi_p > 1 ? " (MPI)" : "");
1392 #endif
1393 } else {
1394 log_event("- Node number %u of %u",
1395 options.node_min, options.node_count);
1396 if (john_main_process)
1397 fprintf(stderr, "Node number %u of %u\n",
1398 options.node_min, options.node_count);
1399 }
1400
1401 #if OS_FORK
1402 if (options.fork)
1403 {
1404 /*
1405 * flush before forking, to avoid multiple log entries
1406 */
1407 log_flush();
1408 john_fork();
1409 }
1410 #endif
1411 #if HAVE_MPI
1412 if (mpi_p > 1)
1413 john_set_mpi();
1414 #endif
1415 }
1416 #if HAVE_OPENCL
1417 /*
1418 * Check if the --devices list contains more OpenCL devices than the
1419 * number of forks or MPI processes.
1420 * Exception: mscash2-OpenCL has built-in multi-device support.
1421 */
1422 #if OS_FORK
1423 if (database.format &&
1424 strstr(database.format->params.label, "-opencl") &&
1425 !strstr(database.format->params.label, "mscash2-opencl") &&
1426 #if HAVE_MPI
1427 (mpi_p_local ? mpi_p_local : mpi_p) *
1428 #endif
1429 (options.fork ? options.fork : 1) < get_number_of_requested_devices())
1430 {
1431 int dev_as_number = 1;
1432 struct list_entry *current;
1433
1434 if ((current = options.acc_devices->head)) {
1435 do {
1436 if (current->data[0] < '0' ||
1437 current->data[0] > '9')
1438 dev_as_number = 0;
1439 } while ((current = current->next));
1440 }
1441
1442 if (john_main_process)
1443 fprintf(stderr, "%s: To fully use the %d devices %s, "
1444 "you must specify --fork=%d\n"
1445 #if HAVE_MPI
1446 "or run %d MPI processes per node "
1447 #endif
1448 "(see doc/README-OPENCL)\n",
1449 dev_as_number ? "Error" : "Warning",
1450 get_number_of_requested_devices(),
1451 dev_as_number ? "requested" : "available",
1452 #if HAVE_MPI
1453 get_number_of_requested_devices(),
1454 #endif
1455 get_number_of_requested_devices());
1456
1457 if (dev_as_number)
1458 error();
1459 }
1460 #else
1461 if (database.format &&
1462 strstr(database.format->params.label, "-opencl") &&
1463 !strstr(database.format->params.label, "mscash2-opencl") &&
1464 get_number_of_devices_in_use() > 1) {
1465 fprintf(stderr, "The usage of multiple OpenCL devices at once "
1466 "is unsupported in this build for the selected format\n");
1467 error();
1468 }
1469 #endif /* OS_FORK */
1470 #endif /* HAVE_OPENCL */
1471 }
1472
1473 #if CPU_DETECT
CPU_detect_or_fallback(char ** argv,int make_check)1474 static void CPU_detect_or_fallback(char **argv, int make_check)
1475 {
1476 if (!getenv("CPUID_DISABLE"))
1477 if (!CPU_detect()) {
1478 #if CPU_REQ
1479 #if CPU_FALLBACK
1480 #if defined(__DJGPP__)
1481 #error CPU_FALLBACK is incompatible with the current DOS code
1482 #endif
1483 if (!make_check) {
1484 #ifdef JOHN_SYSTEMWIDE_EXEC
1485 #define CPU_FALLBACK_PATHNAME JOHN_SYSTEMWIDE_EXEC "/" CPU_FALLBACK_BINARY
1486 #else
1487 #define CPU_FALLBACK_PATHNAME path_expand("$JOHN/" CPU_FALLBACK_BINARY)
1488 #endif
1489 execv(CPU_FALLBACK_PATHNAME, argv);
1490 #ifdef JOHN_SYSTEMWIDE_EXEC
1491 perror("execv: " CPU_FALLBACK_PATHNAME);
1492 #else
1493 perror("execv: $JOHN/" CPU_FALLBACK_BINARY);
1494 #endif
1495 }
1496 #endif
1497 fprintf(stderr, "Sorry, %s is required for this build\n",
1498 CPU_req_name);
1499 if (make_check)
1500 exit(0);
1501 error();
1502 #endif
1503 }
1504
1505 /*
1506 * Init the crc table here, so that tables are fully setup for any
1507 * ancillary program
1508 */
1509 CRC32_Init_tab();
1510
1511 }
1512 #else
1513 #define CPU_detect_or_fallback(argv, make_check) CRC32_Init_tab()
1514 #endif
1515
john_init(char * name,int argc,char ** argv)1516 static void john_init(char *name, int argc, char **argv)
1517 {
1518 int show_usage = 0;
1519 int make_check = (argc == 2 && !strcmp(argv[1], "--make_check"));
1520 if (make_check)
1521 argv[1] = "--test=0";
1522
1523 CPU_detect_or_fallback(argv, make_check);
1524
1525 #if HAVE_MPI
1526 mpi_setup(argc, argv);
1527 #else
1528 if (getenv("OMPI_COMM_WORLD_SIZE"))
1529 if (atoi(getenv("OMPI_COMM_WORLD_SIZE")) > 1) {
1530 fprintf(stderr, "ERROR: Running under MPI, but this is NOT an"
1531 " MPI build of John.\n");
1532 error();
1533 }
1534 #endif
1535 #ifdef _OPENMP
1536 john_omp_init();
1537 #endif
1538
1539 if (!make_check) {
1540 #ifdef HAVE_JOHN_OMP_FALLBACK
1541 john_omp_fallback(argv);
1542 #endif
1543 }
1544
1545 #if (!AC_BUILT || HAVE_LOCALE_H)
1546 if (setlocale(LC_ALL, "")) {
1547 john_terminal_locale = str_alloc_copy(setlocale(LC_ALL, NULL));
1548 #if HAVE_OPENCL
1549 if (strchr(john_terminal_locale, '.'))
1550 sprintf(gpu_degree_sign, "%ls", DEGREE_SIGN);
1551 #endif
1552 /* We misuse ctype macros so this must be reset */
1553 setlocale(LC_CTYPE, "C");
1554 }
1555 #endif
1556
1557 status_init(NULL, 1);
1558 if (argc < 2 ||
1559 (argc == 2 &&
1560 (!strcasecmp(argv[1], "--help") ||
1561 !strcasecmp(argv[1], "-h") ||
1562 !strcasecmp(argv[1], "-help"))))
1563 {
1564 john_register_all(); /* for printing by opt_init() */
1565 show_usage = 1;
1566 }
1567 opt_init(name, argc, argv, show_usage);
1568
1569 if (options.listconf)
1570 listconf_parse_early();
1571
1572 if (!make_check) {
1573 if (options.config) {
1574 cfg_init(options.config, 0);
1575 #if JOHN_SYSTEMWIDE
1576 cfg_init(CFG_PRIVATE_FULL_NAME, 1);
1577 #endif
1578 cfg_init(CFG_FULL_NAME, 1);
1579 }
1580 else {
1581 #if JOHN_SYSTEMWIDE
1582 cfg_init(CFG_PRIVATE_FULL_NAME, 1);
1583 #endif
1584 cfg_init(CFG_FULL_NAME, 0);
1585 }
1586 }
1587
1588 #if HAVE_OPENCL
1589 gpu_id = NO_GPU;
1590 engaged_devices[0] = engaged_devices[1] = DEV_LIST_END;
1591 #endif
1592 /* Process configuration options that depend on cfg_init() */
1593 john_load_conf();
1594
1595 #ifdef _OPENMP
1596 john_omp_maybe_adjust_or_fallback(argv);
1597 #endif
1598 omp_autotune_init();
1599 if (!(options.flags & FLG_STDOUT))
1600 john_register_all(); /* maybe restricted to one format by options */
1601 common_init();
1602 sig_init();
1603
1604 if (!make_check && !(options.flags & (FLG_SHOW_CHK | FLG_STDOUT))) {
1605 fflush(stdout);
1606 #ifdef _MSC_VER
1607 /* VC allows 2<=len<=INT_MAX and be a power of 2. A debug build will
1608 * assert if len=0. Release fails setvbuf, but execution continues */
1609 setvbuf(stdout, NULL, _IOLBF, 256);
1610 #else
1611 setvbuf(stdout, NULL, _IOLBF, 0);
1612 #endif
1613 }
1614
1615 john_load();
1616
1617 /* Init the Unicode system */
1618 if (options.internal_cp) {
1619 if (options.internal_cp != options.input_enc &&
1620 options.input_enc != UTF_8) {
1621 if (john_main_process)
1622 fprintf(stderr, "-internal-codepage can only be "
1623 "specified if input encoding is UTF-8\n");
1624 error();
1625 }
1626 }
1627
1628 if (!options.unicode_cp)
1629 initUnicode(UNICODE_UNICODE);
1630
1631 if ((options.subformat && !strcasecmp(options.subformat, "list")) ||
1632 options.listconf)
1633 listconf_parse_late();
1634
1635 /* Log the expanded command line used for this session. */
1636 {
1637 int i;
1638 size_t s = 1;
1639 char *cl;
1640
1641 for (i = 0; i < argc; i++)
1642 s += strlen(argv[i]) + 1;
1643 cl = mem_alloc(s);
1644
1645 s = 0;
1646 for (i = 0; i < argc; i++)
1647 s += sprintf(cl + s, "%s ", argv[i]);
1648
1649 log_event("Command line: %s", cl);
1650 MEM_FREE(cl);
1651 }
1652
1653 #if HAVE_MPI
1654 if (mpi_p > 1)
1655 log_event("- MPI: Node %u/%u running on %s",
1656 mpi_id + 1, mpi_p, mpi_name);
1657 #endif
1658 #if defined(HAVE_OPENCL)
1659 gpu_log_temp();
1660 #endif
1661
1662 if (options.target_enc != ASCII) {
1663 log_event("- %s input encoding enabled",
1664 cp_id2name(options.input_enc));
1665
1666 if (!options.secure) {
1667 if (options.report_utf8 &&
1668 options.loader.log_passwords)
1669 log_event("- Passwords in this logfile are "
1670 "UTF-8 encoded");
1671
1672 if (options.store_utf8)
1673 log_event("- Passwords will be stored UTF-8 "
1674 "encoded in .pot file");
1675 }
1676 }
1677
1678 if (!(options.flags & FLG_SHOW_CHK) && !options.loader.showuncracked)
1679 if (options.target_enc != options.input_enc &&
1680 (!database.format ||
1681 !(database.format->params.flags & FMT_UNICODE))) {
1682 log_event("- Target encoding: %s",
1683 cp_id2name(options.target_enc));
1684 }
1685
1686 if (!(options.flags & FLG_SHOW_CHK) && !options.loader.showuncracked)
1687 if (options.input_enc != options.internal_cp) {
1688 log_event("- Rules/masks using %s",
1689 cp_id2name(options.internal_cp));
1690 }
1691 }
1692
john_run(void)1693 static void john_run(void)
1694 {
1695 struct stat trigger_stat;
1696 int trigger_reset = 0;
1697
1698 if (options.flags & FLG_TEST_CHK)
1699 exit_status = benchmark_all() ? 1 : 0;
1700 #ifdef HAVE_FUZZ
1701 else
1702 if (options.flags & FLG_FUZZ_CHK || options.flags & FLG_FUZZ_DUMP_CHK) {
1703 /*
1704 * Suppress dupe hash check because fuzzed ones often result in
1705 * too many partial hash collisions.
1706 */
1707 options.loader.flags |= DB_WORDS;
1708 list_init(&single_seed); /* Required for DB_WORDS */
1709
1710 ldr_init_database(&database, &options.loader);
1711 exit_status = fuzz(&database);
1712 }
1713 #endif
1714 else
1715 if (options.flags & FLG_MAKECHR_CHK)
1716 do_makechars(&database, options.charset);
1717 else
1718 if (options.flags & FLG_CRACKING_CHK) {
1719 int remaining = database.password_count;
1720
1721 if (options.abort_file &&
1722 stat(path_expand(options.abort_file), &trigger_stat) == 0) {
1723 if (john_main_process)
1724 fprintf(stderr, "Abort file %s present, "
1725 "refusing to start\n", options.abort_file);
1726 error();
1727 }
1728
1729 if (!(options.flags & FLG_STDOUT)) {
1730 struct db_main *test_db = 0;
1731 char *where;
1732
1733 if (!(options.flags & FLG_NOTESTS))
1734 test_db = ldr_init_test_db(database.format,
1735 &database);
1736 else
1737 test_db = &database;
1738 where = fmt_self_test(database.format, test_db);
1739 if (!(options.flags & FLG_NOTESTS))
1740 ldr_free_test_db(test_db);
1741 if (where) {
1742 fprintf(stderr, "Self test failed (%s)\n",
1743 where);
1744 error();
1745 }
1746 trigger_reset = 1;
1747 log_init(LOG_NAME, options.activepot,
1748 options.session);
1749 status_init(NULL, 1);
1750 if (john_main_process) {
1751 john_log_format();
1752 if (idle_requested(database.format))
1753 log_event("- Configured to use otherwise idle "
1754 "processor cycles only");
1755 /*
1756 * flush log entries to make sure they appear
1757 * before the "Proceeding with ... mode" entries
1758 * of other processes
1759 */
1760 log_flush();
1761 }
1762 }
1763 tty_init(options.flags & (FLG_STDIN_CHK | FLG_PIPE_CHK));
1764
1765 if (john_main_process &&
1766 database.format->params.flags & FMT_NOT_EXACT) {
1767 if (options.flags & FLG_KEEP_GUESSING)
1768 fprintf(stderr, "Note: Will keep guessing even after finding a possible candidate.\n");
1769 else
1770 fprintf(stderr, "Note: This format may emit false positives, so it will keep trying even after\nfinding a possible candidate.\n");
1771 }
1772
1773 /* Format supports internal (eg. GPU-side) mask */
1774 if (database.format->params.flags & FMT_MASK &&
1775 !(options.flags & FLG_MASK_CHK) && john_main_process)
1776 fprintf(stderr, "Note: This format may be a lot faster with --mask acceleration (see doc/MASK).\n");
1777
1778 /* Some formats truncate at max. length */
1779 if (!(database.format->params.flags & FMT_TRUNC) &&
1780 !options.force_maxlength)
1781 options.force_maxlength =
1782 database.format->params.plaintext_length;
1783
1784 if (options.force_maxlength)
1785 log_event("- Will reject candidates longer than %d %s",
1786 options.force_maxlength,
1787 (options.target_enc == UTF_8) ?
1788 "bytes" : "characters");
1789
1790 options.eff_minlength =
1791 MAX(options.req_minlength,
1792 database.format->params.plaintext_min_length);
1793 options.eff_maxlength = options.req_maxlength ?
1794 MIN(options.req_maxlength,
1795 database.format->params.plaintext_length) :
1796 database.format->params.plaintext_length;
1797
1798 /* Some formats have a minimum plaintext length */
1799 if (options.eff_maxlength <
1800 database.format->params.plaintext_min_length) {
1801 if (john_main_process)
1802 fprintf(stderr, "Invalid option: "
1803 "--max-length smaller than "
1804 "minimum length for format\n");
1805 error();
1806 }
1807 if (options.req_minlength >= 0) {
1808 if (options.req_minlength <
1809 database.format->params.plaintext_min_length) {
1810 if (john_main_process)
1811 fprintf(stderr, "Invalid option: "
1812 "--min-length smaller than "
1813 "minimum length for format\n");
1814 error();
1815 }
1816 } else if (database.format->params.plaintext_min_length)
1817 if (john_main_process)
1818 fprintf(stderr,
1819 "Note: Minimum length forced to %d "
1820 "by format\n",
1821 options.eff_minlength);
1822
1823 if (options.flags & FLG_MASK_CHK)
1824 mask_init(&database, options.mask);
1825
1826 omp_autotune_run(&database);
1827
1828 if (trigger_reset)
1829 database.format->methods.reset(&database);
1830
1831 if (!(options.flags & FLG_STDOUT) && john_main_process) {
1832 john_log_format2();
1833 log_flush();
1834 }
1835
1836 if (options.flags & FLG_MASK_CHK)
1837 mask_crk_init(&database);
1838
1839 /* Placed here to disregard load time. */
1840 sig_init_late();
1841
1842 /* Start a resumed session by emitting a status line. */
1843 if (rec_restored)
1844 event_pending = event_status = 1;
1845
1846 if (options.flags & FLG_SINGLE_CHK)
1847 do_single_crack(&database);
1848 else
1849 if (options.flags & FLG_WORDLIST_CHK)
1850 do_wordlist_crack(&database, options.wordlist,
1851 (options.flags & FLG_RULES) != 0);
1852 #if HAVE_LIBGMP || HAVE_INT128 || HAVE___INT128 || HAVE___INT128_T
1853 else
1854 if (options.flags & FLG_PRINCE_CHK)
1855 do_prince_crack(&database, options.wordlist,
1856 (options.flags & FLG_RULES) != 0);
1857 #endif
1858 else
1859 if (options.flags & FLG_INC_CHK)
1860 do_incremental_crack(&database, options.charset);
1861 else
1862 if (options.flags & FLG_MKV_CHK)
1863 do_markov_crack(&database, options.mkv_param);
1864 else
1865 if (options.flags & FLG_SUBSETS_CHK)
1866 do_subsets_crack(&database, options.subset_full);
1867 else
1868 #if HAVE_REXGEN
1869 if ((options.flags & FLG_REGEX_CHK) &&
1870 !(options.flags & FLG_REGEX_STACKED))
1871 do_regex_crack(&database, options.regex);
1872 else
1873 #endif
1874 if ((options.flags & FLG_MASK_CHK) &&
1875 !(options.flags & FLG_MASK_STACKED))
1876 do_mask_crack(NULL);
1877 else
1878 if (options.flags & FLG_EXTERNAL_CHK)
1879 do_external_crack(&database);
1880 else
1881 if (options.flags & FLG_BATCH_CHK)
1882 do_batch_crack(&database);
1883
1884 if (options.flags & FLG_MASK_CHK)
1885 mask_done();
1886
1887 status_print();
1888
1889 if (options.flags & FLG_MASK_CHK)
1890 mask_destroy();
1891
1892 #if OS_FORK
1893 if (options.fork && john_main_process)
1894 john_wait();
1895 #endif
1896
1897 #if HAVE_MPI
1898 if (mpi_p > 1)
1899 john_mpi_wait();
1900 #endif
1901
1902 tty_done();
1903
1904 if (options.verbosity > 1)
1905 if (john_main_process && database.password_count < remaining) {
1906 char *might = "Warning: passwords printed above might";
1907 char *partial = " be partial";
1908 char *not_all = " not be all those cracked";
1909 switch (database.options->flags &
1910 (DB_SPLIT | DB_NODUP)) {
1911 case DB_SPLIT:
1912 fprintf(stderr, "%s%s\n", might, partial);
1913 break;
1914 case DB_NODUP:
1915 fprintf(stderr, "%s%s\n", might, not_all);
1916 break;
1917 case (DB_SPLIT | DB_NODUP):
1918 fprintf(stderr, "%s%s and%s\n",
1919 might, partial, not_all);
1920 }
1921 if (database.format->methods.prepare !=
1922 fmt_default_prepare)
1923 fprintf(stderr,
1924 "Use the \"--show --format=%s\" options"
1925 " to display all of the cracked "
1926 "passwords reliably\n",
1927 database.format->params.label);
1928 else
1929 fputs("Use the \"--show\" option to display all"
1930 " of the cracked passwords reliably\n",
1931 stderr);
1932 }
1933
1934 if (options.verbosity > 1 && single_disabled_recursion)
1935 fprintf(stderr,
1936 "Warning: Disabled SingleRetestGuessed due to deep recursion. You may now run\n"
1937 " '--loopback --rules=none' to test all guesses against other salts.\n");
1938 }
1939 }
1940
john_done(void)1941 static void john_done(void)
1942 {
1943 if ((options.flags & (FLG_CRACKING_CHK | FLG_STDOUT)) ==
1944 FLG_CRACKING_CHK) {
1945 if (!event_abort && mask_iter_warn) {
1946 log_event("Warning: Incremental mask started at length %d",
1947 mask_iter_warn);
1948 if (john_main_process)
1949 fprintf(stderr,
1950 "Warning: incremental mask started at length %d"
1951 " - try the CPU format for shorter lengths.\n",
1952 mask_iter_warn);
1953 }
1954 if (event_abort) {
1955 char *abort_msg = (aborted_by_timer) ?
1956 "Session stopped (max run-time reached)" :
1957 "Session aborted";
1958
1959 if (john_max_cands) {
1960 if (status.cands >= john_max_cands)
1961 abort_msg =
1962 "Session stopped (max candidates reached)";
1963 }
1964
1965 /* We already printed to stderr from signals.c */
1966 log_event("%s", abort_msg);
1967 } else if (children_ok) {
1968 log_event("Session completed");
1969 if (john_main_process)
1970 fprintf(stderr, "Session completed\n");
1971 } else {
1972 const char *msg =
1973 "Main process session completed, "
1974 "but some child processes failed";
1975 log_event("%s", msg);
1976 fprintf(stderr, "%s\n", msg);
1977 exit_status = 1;
1978 }
1979 fmt_done(database.format);
1980 }
1981 #if defined(HAVE_OPENCL)
1982 gpu_log_temp();
1983 #endif
1984 log_done();
1985 #if HAVE_OPENCL
1986 if (!(options.flags & FLG_FORK) || john_main_process)
1987 opencl_done();
1988 #endif
1989
1990 path_done();
1991
1992 /*
1993 * This may not be the correct place to free this, it likely
1994 * can be freed much earlier, but it works here
1995 */
1996 db_main_free(&database);
1997 cleanup_tiny_memory();
1998 check_abort(0);
1999 }
2000
2001 #ifdef HAVE_LIBFUZZER
main_dummy(int argc,char ** argv)2002 int main_dummy(int argc, char **argv)
2003 #else
2004 int main(int argc, char **argv)
2005 #endif
2006 {
2007 char *name;
2008
2009 sig_preinit(); /* Mitigate race conditions */
2010 #ifdef __DJGPP__
2011 if (--argc <= 0) return 1;
2012 if ((name = strrchr(argv[0], '/')))
2013 strcpy(name + 1, argv[1]);
2014 name = argv[1];
2015 argv[1] = argv[0];
2016 argv++;
2017 #else
2018 if (!argv[0])
2019 name = "john";
2020 else
2021 if ((name = strrchr(argv[0], '/')))
2022 name++;
2023 #if HAVE_WINDOWS_H
2024 else
2025 if ((name = strrchr(argv[0], '\\')))
2026 name++;
2027 #endif
2028 else
2029 name = argv[0];
2030 #endif
2031
2032 #if defined(__CYGWIN__) || defined (__MINGW32__) || defined (_MSC_VER)
2033 strlwr(name);
2034 if (strlen(name) > 4 && !strcmp(name + strlen(name) - 4, ".exe"))
2035 name[strlen(name) - 4] = 0;
2036 #endif
2037
2038 #ifdef _MSC_VER
2039 /*
2040 * Ok, I am making a simple way to debug external programs. in VC. Prior to
2041 * this, I would set break point below, right where the external name is, and
2042 * then would modify IP to put me into the block that calls main() from the
2043 * external. Now, in VC mode, if the first command is:
2044 * -external_command=COMMAND, then I set name == COMMAND, and pop the command
2045 * line args off, just like the first one was not there. So if the command was
2046 * "-external_command=gpg2john secring.gpg" then we will be setup in gpg2john
2047 * mode with command line arg of secring.gpg
2048 */
2049 if (argc > 2 && !strncmp(argv[1], "-external_command=", 18)) {
2050 int i;
2051 name = &argv[1][18];
2052 for (i = 1; i < argc; ++i) {
2053 argv[i] = argv[i+1];
2054 }
2055 --argc;
2056 }
2057 #endif
2058
2059 /* Needed before CPU fallback */
2060 path_init(argv);
2061
2062 if (!strcmp(name, "unshadow")) {
2063 CPU_detect_or_fallback(argv, 0);
2064 return unshadow(argc, argv);
2065 }
2066
2067 if (!strcmp(name, "unafs")) {
2068 CPU_detect_or_fallback(argv, 0);
2069 return unafs(argc, argv);
2070 }
2071
2072 if (!strcmp(name, "undrop")) {
2073 CPU_detect_or_fallback(argv, 0);
2074 return undrop(argc, argv);
2075 }
2076
2077 if (!strcmp(name, "unique")) {
2078 CPU_detect_or_fallback(argv, 0);
2079 return unique(argc, argv);
2080 }
2081
2082 if (!strcmp(name, "rar2john")) {
2083 CPU_detect_or_fallback(argv, 0);
2084 return rar2john(argc, argv);
2085 }
2086
2087 if (!strcmp(name, "gpg2john")) {
2088 CPU_detect_or_fallback(argv, 0);
2089 return gpg2john(argc, argv);
2090 }
2091
2092 if (!strcmp(name, "zip2john")) {
2093 CPU_detect_or_fallback(argv, 0);
2094 return zip2john(argc, argv);
2095 }
2096 if (!strcmp(name, "base64conv")) {
2097 CPU_detect_or_fallback(argv, 0);
2098 return base64conv(argc, argv);
2099 }
2100 john_init(name, argc, argv);
2101
2102 if (options.max_cands) {
2103 if (options.node_count) {
2104 long long orig_max_cands = options.max_cands;
2105
2106 /* Split between nodes */
2107 options.max_cands /= options.node_count;
2108 if (options.node_min == 1)
2109 options.max_cands +=
2110 orig_max_cands % options.node_count;
2111 }
2112
2113 /* Allow resuming, for another set of N candidates */
2114 john_max_cands = status.cands + llabs(options.max_cands);
2115 }
2116
2117 john_run();
2118 john_done();
2119
2120 return exit_status;
2121 }
2122
2123 #ifdef HAVE_LIBFUZZER
2124
LLVMFuzzerInitialize(int * argc,char *** argv)2125 int LLVMFuzzerInitialize(int *argc, char ***argv)
2126 {
2127 return 1;
2128 }
2129
2130 // dummy fuzzing target
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)2131 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) // size is actually the length of Data
2132 {
2133 static uint8_t buffer[8192];
2134
2135 if (size > sizeof(buffer) - 1) {
2136 fprintf(stderr, "size (-max_len) is greater than supported value, aborting!\n");
2137 exit(-1);
2138 }
2139 memcpy(buffer, data, size);
2140 buffer[size] = 0;
2141 jtr_basename((const char*)buffer);
2142
2143 return 0;
2144 }
2145 #endif
2146