Commit 3efad641 authored by Guillem Jover's avatar Guillem Jover

Update readpassphrase() from OpenBSD

parent a6f407ab
.\" $OpenBSD: readpassphrase.3,v 1.16 2005/07/22 03:16:58 jaredy Exp $ .\" $OpenBSD: readpassphrase.3,v 1.20 2014/03/06 23:03:18 millert Exp $
.\" .\"
.\" Copyright (c) 2000, 2002 Todd C. Miller <Todd.Miller@courtesan.com> .\" Copyright (c) 2000, 2002 Todd C. Miller <Todd.Miller@courtesan.com>
.\" .\"
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
.\" .\"
.Dd $Mdocdate: May 31 2007 $ .Dd $Mdocdate: March 6 2014 $
.Dt READPASSPHRASE 3bsd .Dt READPASSPHRASE 3bsd
.Os .Os
.Sh NAME .Sh NAME
...@@ -55,9 +55,11 @@ Up to ...@@ -55,9 +55,11 @@ Up to
Any additional Any additional
characters and the terminating newline (or return) character are discarded. characters and the terminating newline (or return) character are discarded.
.Pp .Pp
.Fn readpassphrase The
takes the following optional .Fa flags
.Fa flags : argument is the bitwise
.Tn OR
of zero or more of the following values:
.Bd -literal -offset indent .Bd -literal -offset indent
RPP_ECHO_OFF turn off echo (default behavior) RPP_ECHO_OFF turn off echo (default behavior)
RPP_ECHO_ON leave echo on RPP_ECHO_ON leave echo on
...@@ -65,7 +67,7 @@ RPP_REQUIRE_TTY fail if there is no tty ...@@ -65,7 +67,7 @@ RPP_REQUIRE_TTY fail if there is no tty
RPP_FORCELOWER force input to lower case RPP_FORCELOWER force input to lower case
RPP_FORCEUPPER force input to upper case RPP_FORCEUPPER force input to upper case
RPP_SEVENBIT strip the high bit from input RPP_SEVENBIT strip the high bit from input
RPP_STDIN force read of passphrase from stdin RPP_STDIN read passphrase from stdin; ignore prompt
.Ed .Ed
.Pp .Pp
The calling process should zero the passphrase as soon as possible to The calling process should zero the passphrase as soon as possible to
...@@ -100,7 +102,7 @@ if (compare(transform(passbuf), epass) != 0) ...@@ -100,7 +102,7 @@ if (compare(transform(passbuf), epass) != 0)
\&... \&...
memset(passbuf, 0, sizeof(passbuf)); explicit_bzero(passbuf, sizeof(passbuf));
.Ed .Ed
.Sh ERRORS .Sh ERRORS
.Bl -tag -width Er .Bl -tag -width Er
......
/* $OpenBSD: readpassphrase.c,v 1.20 2007/10/30 12:03:48 millert Exp $ */ /* $OpenBSD: readpassphrase.c,v 1.26 2016/10/18 12:47:18 millert Exp $ */
/* /*
* Copyright (c) 2000-2002, 2007 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 2000-2002, 2007, 2010
* Todd C. Miller <Todd.Miller@courtesan.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
...@@ -35,7 +36,7 @@ ...@@ -35,7 +36,7 @@
#define TCSASOFT 0 #define TCSASOFT 0
#endif #endif
static volatile sig_atomic_t signo; static volatile sig_atomic_t signo[_NSIG];
static void handler(int); static void handler(int);
...@@ -43,7 +44,7 @@ char * ...@@ -43,7 +44,7 @@ char *
readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
{ {
ssize_t nr; ssize_t nr;
int input, output, save_errno; int input, output, save_errno, i, need_restart;
char ch, *p, *end; char ch, *p, *end;
struct termios term, oterm; struct termios term, oterm;
struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
...@@ -56,9 +57,11 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) ...@@ -56,9 +57,11 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
} }
restart: restart:
signo = 0; for (i = 0; i < _NSIG; i++)
signo[i] = 0;
nr = -1; nr = -1;
save_errno = 0; save_errno = 0;
need_restart = 0;
/* /*
* Read and write to /dev/tty if available. If not, read from * Read and write to /dev/tty if available. If not, read from
* stdin and write to stderr unless a tty is required. * stdin and write to stderr unless a tty is required.
...@@ -74,24 +77,10 @@ restart: ...@@ -74,24 +77,10 @@ restart:
} }
/* /*
* Catch signals that would otherwise cause the user to end * Turn off echo if possible.
* up with echo turned off in the shell. Don't worry about * If we are using a tty but are not the foreground pgrp this will
* things like SIGXCPU and SIGVTALRM for now. * generate SIGTTOU, so do it *before* installing the signal handlers.
*/ */
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0; /* don't restart system calls */
sa.sa_handler = handler;
(void)sigaction(SIGALRM, &sa, &savealrm);
(void)sigaction(SIGHUP, &sa, &savehup);
(void)sigaction(SIGINT, &sa, &saveint);
(void)sigaction(SIGPIPE, &sa, &savepipe);
(void)sigaction(SIGQUIT, &sa, &savequit);
(void)sigaction(SIGTERM, &sa, &saveterm);
(void)sigaction(SIGTSTP, &sa, &savetstp);
(void)sigaction(SIGTTIN, &sa, &savettin);
(void)sigaction(SIGTTOU, &sa, &savettou);
/* Turn off echo if possible. */
if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
memcpy(&term, &oterm, sizeof(term)); memcpy(&term, &oterm, sizeof(term));
if (!(flags & RPP_ECHO_ON)) if (!(flags & RPP_ECHO_ON))
...@@ -108,36 +97,55 @@ restart: ...@@ -108,36 +97,55 @@ restart:
oterm.c_lflag |= ECHO; oterm.c_lflag |= ECHO;
} }
/* No I/O if we are already backgrounded. */ /*
if (signo != SIGTTOU && signo != SIGTTIN) { * Catch signals that would otherwise cause the user to end
if (!(flags & RPP_STDIN)) * up with echo turned off in the shell. Don't worry about
(void)write(output, prompt, strlen(prompt)); * things like SIGXCPU and SIGVTALRM for now.
end = buf + bufsiz - 1; */
p = buf; sigemptyset(&sa.sa_mask);
while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { sa.sa_flags = 0; /* don't restart system calls */
if (p < end) { sa.sa_handler = handler;
if ((flags & RPP_SEVENBIT)) (void)sigaction(SIGALRM, &sa, &savealrm);
ch &= 0x7f; (void)sigaction(SIGHUP, &sa, &savehup);
if (isalpha(ch)) { (void)sigaction(SIGINT, &sa, &saveint);
if ((flags & RPP_FORCELOWER)) (void)sigaction(SIGPIPE, &sa, &savepipe);
ch = (char)tolower(ch); (void)sigaction(SIGQUIT, &sa, &savequit);
if ((flags & RPP_FORCEUPPER)) (void)sigaction(SIGTERM, &sa, &saveterm);
ch = (char)toupper(ch); (void)sigaction(SIGTSTP, &sa, &savetstp);
} (void)sigaction(SIGTTIN, &sa, &savettin);
*p++ = ch; (void)sigaction(SIGTTOU, &sa, &savettou);
if (!(flags & RPP_STDIN))
(void)write(output, prompt, strlen(prompt));
end = buf + bufsiz - 1;
p = buf;
while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') {
if (p < end) {
if ((flags & RPP_SEVENBIT))
ch &= 0x7f;
if (isalpha((unsigned char)ch)) {
if ((flags & RPP_FORCELOWER))
ch = (char)tolower((unsigned char)ch);
if ((flags & RPP_FORCEUPPER))
ch = (char)toupper((unsigned char)ch);
} }
*p++ = ch;
} }
*p = '\0';
save_errno = errno;
if (!(term.c_lflag & ECHO))
(void)write(output, "\n", 1);
} }
*p = '\0';
save_errno = errno;
if (!(term.c_lflag & ECHO))
(void)write(output, "\n", 1);
/* Restore old terminal settings and signals. */ /* Restore old terminal settings and signals. */
if (memcmp(&term, &oterm, sizeof(term)) != 0) { if (memcmp(&term, &oterm, sizeof(term)) != 0) {
const int sigttou = signo[SIGTTOU];
/* Ignore SIGTTOU generated when we are not the fg pgrp. */
while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 && while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 &&
errno == EINTR) errno == EINTR && !signo[SIGTTOU])
continue; continue;
signo[SIGTTOU] = sigttou;
} }
(void)sigaction(SIGALRM, &savealrm, NULL); (void)sigaction(SIGALRM, &savealrm, NULL);
(void)sigaction(SIGHUP, &savehup, NULL); (void)sigaction(SIGHUP, &savehup, NULL);
...@@ -155,15 +163,19 @@ restart: ...@@ -155,15 +163,19 @@ restart:
* If we were interrupted by a signal, resend it to ourselves * If we were interrupted by a signal, resend it to ourselves
* now that we have restored the signal handlers. * now that we have restored the signal handlers.
*/ */
if (signo) { for (i = 0; i < _NSIG; i++) {
kill(getpid(), signo); if (signo[i]) {
switch (signo) { kill(getpid(), i);
case SIGTSTP: switch (i) {
case SIGTTIN: case SIGTSTP:
case SIGTTOU: case SIGTTIN:
goto restart; case SIGTTOU:
need_restart = 1;
}
} }
} }
if (need_restart)
goto restart;
if (save_errno) if (save_errno)
errno = save_errno; errno = save_errno;
...@@ -183,5 +195,5 @@ getpass(const char *prompt) ...@@ -183,5 +195,5 @@ getpass(const char *prompt)
static void handler(int s) static void handler(int s)
{ {
signo = s; signo[s] = 1;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment