]> git.ipfire.org Git - thirdparty/libbsd.git/commitdiff
Update readpassphrase() from OpenBSD
authorGuillem Jover <guillem@hadrons.org>
Sun, 20 May 2018 23:56:33 +0000 (01:56 +0200)
committerGuillem Jover <guillem@hadrons.org>
Mon, 21 May 2018 02:47:28 +0000 (04:47 +0200)
man/readpassphrase.3bsd
src/readpassphrase.c

index 9729061ff4b6ed2cea8859c572dff4bab24ef594..53ad52d1d97d3c057602112e6c42dc8e8557e29c 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $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>
 .\"
@@ -18,7 +18,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\"
-.Dd $Mdocdate: May 31 2007 $
+.Dd $Mdocdate: March 6 2014 $
 .Dt READPASSPHRASE 3bsd
 .Os
 .Sh NAME
@@ -55,9 +55,11 @@ Up to
 Any additional
 characters and the terminating newline (or return) character are discarded.
 .Pp
-.Fn readpassphrase
-takes the following optional
-.Fa flags :
+The
+.Fa flags
+argument is the bitwise
+.Tn OR
+of zero or more of the following values:
 .Bd -literal -offset indent
 RPP_ECHO_OFF           turn off echo (default behavior)
 RPP_ECHO_ON            leave echo on
@@ -65,7 +67,7 @@ RPP_REQUIRE_TTY               fail if there is no tty
 RPP_FORCELOWER         force input to lower case
 RPP_FORCEUPPER         force input to upper case
 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
 .Pp
 The calling process should zero the passphrase as soon as possible to
@@ -100,7 +102,7 @@ if (compare(transform(passbuf), epass) != 0)
 
 \&...
 
-memset(passbuf, 0, sizeof(passbuf));
+explicit_bzero(passbuf, sizeof(passbuf));
 .Ed
 .Sh ERRORS
 .Bl -tag -width Er
index 1f4fe0eb0f54c3d3654fb5e250a26dae4cc65552..f9f61950d17436f5550c2426701e5d22557eb642 100644 (file)
@@ -1,7 +1,8 @@
-/*     $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
  * purpose with or without fee is hereby granted, provided that the above
@@ -35,7 +36,7 @@
 #define TCSASOFT 0
 #endif
 
-static volatile sig_atomic_t signo;
+static volatile sig_atomic_t signo[_NSIG];
 
 static void handler(int);
 
@@ -43,7 +44,7 @@ char *
 readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
 {
        ssize_t nr;
-       int input, output, save_errno;
+       int input, output, save_errno, i, need_restart;
        char ch, *p, *end;
        struct termios term, oterm;
        struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
@@ -56,9 +57,11 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
        }
 
 restart:
-       signo = 0;
+       for (i = 0; i < _NSIG; i++)
+               signo[i] = 0;
        nr = -1;
        save_errno = 0;
+       need_restart = 0;
        /*
         * Read and write to /dev/tty if available.  If not, read from
         * stdin and write to stderr unless a tty is required.
@@ -74,24 +77,10 @@ restart:
        }
 
        /*
-        * Catch signals that would otherwise cause the user to end
-        * up with echo turned off in the shell.  Don't worry about
-        * things like SIGXCPU and SIGVTALRM for now.
+        * Turn off echo if possible.
+        * If we are using a tty but are not the foreground pgrp this will
+        * 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) {
                memcpy(&term, &oterm, sizeof(term));
                if (!(flags & RPP_ECHO_ON))
@@ -108,36 +97,55 @@ restart:
                oterm.c_lflag |= ECHO;
        }
 
-       /* No I/O if we are already backgrounded. */
-       if (signo != SIGTTOU && signo != SIGTTIN) {
-               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(ch)) {
-                                       if ((flags & RPP_FORCELOWER))
-                                               ch = (char)tolower(ch);
-                                       if ((flags & RPP_FORCEUPPER))
-                                               ch = (char)toupper(ch);
-                               }
-                               *p++ = ch;
+       /*
+        * Catch signals that would otherwise cause the user to end
+        * up with echo turned off in the shell.  Don't worry about
+        * things like SIGXCPU and SIGVTALRM for now.
+        */
+       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);
+
+       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. */
        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 &&
-                   errno == EINTR)
+                   errno == EINTR && !signo[SIGTTOU])
                        continue;
+               signo[SIGTTOU] = sigttou;
        }
        (void)sigaction(SIGALRM, &savealrm, NULL);
        (void)sigaction(SIGHUP, &savehup, NULL);
@@ -155,15 +163,19 @@ restart:
         * If we were interrupted by a signal, resend it to ourselves
         * now that we have restored the signal handlers.
         */
-       if (signo) {
-               kill(getpid(), signo);
-               switch (signo) {
-               case SIGTSTP:
-               case SIGTTIN:
-               case SIGTTOU:
-                       goto restart;
+       for (i = 0; i < _NSIG; i++) {
+               if (signo[i]) {
+                       kill(getpid(), i);
+                       switch (i) {
+                       case SIGTSTP:
+                       case SIGTTIN:
+                       case SIGTTOU:
+                               need_restart = 1;
+                       }
                }
        }
+       if (need_restart)
+               goto restart;
 
        if (save_errno)
                errno = save_errno;
@@ -183,5 +195,5 @@ getpass(const char *prompt)
 static void handler(int s)
 {
 
-       signo = s;
+       signo[s] = 1;
 }