Skip to content

Commit

Permalink
Improve "stdin vs. keyboard vs. message"
Browse files Browse the repository at this point in the history
Add option --force-keys for enabling it even if we're not the
foreground process, for use with pipes and inside frontend scripts.
Ensure the "Press 'q' to abort (...)" message really reflects whether
we have the terminal set up for reading keystrokes or not.

Closes openwall#4403
  • Loading branch information
magnumripper committed Nov 11, 2020
1 parent d595de9 commit 965426d
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 15 deletions.
5 changes: 5 additions & 0 deletions doc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ Major changes from 1.9.0-jumbo-1 (May 2019) in this bleeding-edge version:
a legacy internal codepage, convert them to that codepage. Mask mode already
had the corresponding feature. [magnum; 2020]

- Improve handling of using stdin or pipe vs. reading keystrokes. This
includes a new option --force-keys that will set the terminal up for
reading status/quit keystrokes even if we're not the foreground process.
[magnum; 2020]


Major changes from 1.8.0-jumbo-1 (December 2014) to 1.9.0-jumbo-1 (May 2019):

Expand Down
6 changes: 6 additions & 0 deletions doc/OPTIONS
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ very large, sorting it will speed up loading.
These are used to enable the wordlist mode. If FILE is not specified,
the one defined in john.conf will be used.

--force-keys

Set the terminal up for reading status/quit keystrokes even if we're not
the foreground process. The downside is we might get race conditions so
you may end up with strange problems hard to reproduce.

--dupe-suppression suppress all duplicates from wordlist

Normally, consecutive duplicates are ignored when reading a wordlist file.
Expand Down
17 changes: 11 additions & 6 deletions src/cracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "gpu_common.h"
#endif
#include "rules.h"
#include "tty.h"

#ifdef index
#undef index
Expand Down Expand Up @@ -125,9 +126,13 @@ static void crk_init_salt(void)
static void crk_help(void)
{
static int printed = 0;
if (!john_main_process || printed ||
((options.flags & FLG_STDOUT) && isatty(fileno(stdout))))

if (!john_main_process || printed)
return;

if ((options.flags & FLG_STDOUT) && isatty(fileno(stdout)))
return;

#ifdef HAVE_MPI
if (mpi_p > 1 || getenv("OMPI_COMM_WORLD_SIZE"))
#ifdef SIGUSR1
Expand All @@ -137,16 +142,16 @@ static void crk_help(void)
#endif
else
#endif
if ((options.flags & FLG_STDIN_CHK) || (options.flags & FLG_PIPE_CHK))
if (tty_has_keyboard())
fprintf(stderr, "Press 'q' or Ctrl-C to abort, almost any other key for status\n");
else
fprintf(stderr, "Press Ctrl-C to abort, "
#ifdef SIGUSR1
"or send SIGUSR1 to john process for status\n");
#else
"or send SIGHUP to john process for status\n");
#endif
else
fprintf(stderr, "Press 'q' or Ctrl-C to abort, "
"almost any other key for status\n");

printed = 1;
}

Expand Down
5 changes: 4 additions & 1 deletion src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ static struct opt_entry opt_list[] = {
~FLG_MASK_CHK & ~OPT_REQ_PARAM, "%d", &benchmark_time},
{"tune", FLG_ZERO, 0, 0, OPT_REQ_PARAM,
OPT_FMT_STR_ALLOC, &options.tune},
{"force-keys", FLG_FORCE_KEYS},
{NULL}
};

Expand Down Expand Up @@ -441,7 +442,9 @@ JOHN_USAGE_FORK \
"--input-encoding=NAME input encoding (alias for --encoding)\n" \
"--internal-codepage=NAME codepage used in rules/masks (see doc/ENCODINGS)\n" \
"--target-encoding=NAME output encoding (used by format, see doc/ENCODINGS)\n" \
"--tune=HOW tuning options (auto/report/N)\n"
"--tune=HOW tuning options (auto/report/N)\n" \
"--force-keys set up terminal for reading keystrokes even if we're\n" \
" not the foreground process\n"

#define JOHN_USAGE_FORMAT \
"--format=[NAME|CLASS][,..] force hash of type NAME. The supported formats can\n" \
Expand Down
2 changes: 2 additions & 0 deletions src/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@
/* Ignore NOP rules */
#define FLG_RULE_SKIP_NOP 0x0800000000000000ULL
#define FLG_NO_MASK_BENCH 0x1000000000000000ULL
/* Configure terminal for reading keystrokes even if we're not the foreground process */
#define FLG_FORCE_KEYS 0x2000000000000000ULL

/*
* Macro for getting correct node number regardless of if MPI or not
Expand Down
45 changes: 37 additions & 8 deletions src/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,33 +44,53 @@
#if !defined(__DJGPP__) && !defined(__MINGW32__) && !defined (_MSC_VER)
static int tty_fd = -1;
static struct termios saved_ti;
#else
static int in_stdin_mode;
#endif

int tty_has_keyboard(void)
{
#if !defined(__DJGPP__) && !defined(__MINGW32__) && !defined (_MSC_VER)
return (tty_fd >= 0);
#else
return !(in_stdin_mode && isatty(fileno(stdin)));
#endif
}

void tty_init(opt_flags stdin_mode)
{
#if !defined(__DJGPP__) && !defined(__MINGW32__) && !defined (_MSC_VER)
int fd;
struct termios ti;

if (tty_fd >= 0) return;

if (tty_fd >= 0)
return;
/*
* If we're in "--stdin" mode (reading candidate passwords from stdin), then
* only initialize the tty if stdin is not a tty. Otherwise it could be the
* same tty, in which case we'd interfere with the user's ability to type
* candidate passwords directly to John.
*/
if (stdin_mode && !tcgetattr(0, &ti))
if (stdin_mode && isatty(fileno(stdin)))
return;

if ((fd = open("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0) return;
if ((fd = open("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0)
return;

if (tcgetpgrp(fd) != getpid()) {
close(fd); return;
/*
* Give up the keyboard if we're not the foreground process. This can be
* overridden with --force-keys option.
*/
if (!(options.flags & FLG_FORCE_KEYS) && tcgetpgrp(fd) != getpid()) {
close(fd);
return;
}

tcgetattr(fd, &ti);
saved_ti = ti;
/*
* Set up terminal for reading keystrokes, and no echo.
*/
ti.c_lflag &= ~(ICANON | ECHO);
ti.c_cc[VMIN] = 1;
ti.c_cc[VTIME] = 0;
Expand All @@ -79,6 +99,8 @@ void tty_init(opt_flags stdin_mode)
tty_fd = fd;

atexit(tty_done);
#else
in_stdin_mode = stdin_mode;
#endif
}

Expand All @@ -101,7 +123,8 @@ int tty_getchar(void)
return -1;
#endif
c = 0;
if (read(tty_fd, &c, 1) > 0) return c;
if (read(tty_fd, &c, 1) > 0)
return c;
}
#elif defined(__DJGPP__)
if (_bios_keybrd(_KEYBRD_READY))
Expand All @@ -119,9 +142,15 @@ void tty_done(void)
#if !defined(__DJGPP__) && !defined(__MINGW32__) && !defined (_MSC_VER)
int fd;

if (tty_fd < 0) return;
if (tty_fd < 0)
return;

fd = tty_fd; tty_fd = -1;

/* Do the usually-best-thing in the race condition sometimes caused by --force-keys */
if (options.flags & FLG_FORCE_KEYS)
saved_ti.c_lflag |= (ICANON | ECHO);

tcsetattr(fd, TCSANOW, &saved_ti);

close(fd);
Expand Down
5 changes: 5 additions & 0 deletions src/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
#define _JOHN_TTY_H
#include "options.h"

/*
* Returns true if we set up terminal for reading keystrokes
*/
extern int tty_has_keyboard(void);

/*
* Initializes the terminal for unbuffered non-blocking input. Also registers
* tty_done() via atexit().
Expand Down

0 comments on commit 965426d

Please sign in to comment.