diff --git a/encfs/readpassphrase.cpp b/encfs/readpassphrase.cpp index 7e1a334..df85dfb 100644 --- a/encfs/readpassphrase.cpp +++ b/encfs/readpassphrase.cpp @@ -1,59 +1,47 @@ -/* $OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $ +/* $OpenBSD: readpassphrase.c,v 1.26 2016/10/18 12:47:18 millert Exp $ */ /* - * Copyright (c) 2000 Todd C. Miller - * All rights reserved. + * Copyright (c) 2000-2002, 2007, 2010 + * Todd C. Miller * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = - "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ +/* OPENBSD ORIGINAL: lib/libc/gen/readpassphrase.c */ -//#include "includes.h" +// #include "includes.h" +#include "readpassphrase.h" #ifndef HAVE_READPASSPHRASE -#include "readpassphrase.h" - -#include -#include -#include -#include -#include +#include +#include #include +// #include #include -#include +#include +#include #include #include -#ifdef TCSASOFT -#define _T_FLUSH (TCSAFLUSH | TCSASOFT) -#else -#define _T_FLUSH (TCSAFLUSH) +#ifndef TCSASOFT +/* If we don't have TCSASOFT define it so that ORing it it below is a no-op. */ +#define TCSASOFT 0 #endif /* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ @@ -61,131 +49,147 @@ static const char rcsid[] = #define _POSIX_VDISABLE VDISABLE #endif -static volatile sig_atomic_t signo; +#ifndef _NSIG +#ifdef NSIG +#define _NSIG NSIG +#else +#define _NSIG 128 +#endif +#endif + +static volatile sig_atomic_t signo[_NSIG]; static void handler(int); 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, saveint, savehup, savequit, saveterm; - struct sigaction savetstp, savettin, savettou; + struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; + struct sigaction savetstp, savettin, savettou, savepipe; /* I suppose we could alloc on demand in this case (XXX). */ if (bufsiz == 0) { errno = EINVAL; - return (nullptr); + return nullptr; } restart: + 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. */ - if ((input = output = open(_PATH_TTY, O_RDWR)) == -1) { - if ((flags & RPP_REQUIRE_TTY) != 0) { + if ((flags & RPP_STDIN) || (input = output = open(_PATH_TTY, O_RDWR)) == -1) { + if (flags & RPP_REQUIRE_TTY) { errno = ENOTTY; - return (nullptr); + return nullptr; } input = STDIN_FILENO; output = STDERR_FILENO; } + /* + * 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. + */ + if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { + memcpy(&term, &oterm, sizeof(term)); + if (!(flags & RPP_ECHO_ON)) term.c_lflag &= ~(ECHO | ECHONL); +#ifdef VSTATUS + if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) + term.c_cc[VSTATUS] = _POSIX_VDISABLE; +#endif + (void)tcsetattr(input, TCSAFLUSH | TCSASOFT, &term); + } else { + memset(&term, 0, sizeof(term)); + term.c_lflag |= ECHO; + memset(&oterm, 0, sizeof(oterm)); + oterm.c_lflag |= ECHO; + } + /* * Catch signals that would otherwise cause the user to end * up with echo turned off in the shell. Don't worry about - * things like SIGALRM and SIGPIPE for now. + * 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(SIGINT, &sa, &saveint); + (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 (tcgetattr(input, &oterm) == 0) { - memcpy(&term, &oterm, sizeof(term)); - if ((flags & RPP_ECHO_ON) == 0) { - term.c_lflag &= ~(ECHO | ECHONL); - } -#ifdef VSTATUS - if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) - term.c_cc[VSTATUS] = _POSIX_VDISABLE; -#endif - (void)tcsetattr(input, _T_FLUSH, &term); - } else { - memset(&term, 0, sizeof(term)); - memset(&oterm, 0, sizeof(oterm)); - } - - if (write(output, prompt, strlen(prompt)) != -1) { - end = buf + bufsiz - 1; - for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { - if (p < end) { - if ((flags & RPP_SEVENBIT) != 0) { - ch &= 0x7f; - } - if (isalpha(ch) != 0) { - if ((flags & RPP_FORCELOWER) != 0) { - ch = tolower(ch); - } - if ((flags & RPP_FORCEUPPER) != 0) { - ch = toupper(ch); - } - } - *p++ = ch; + 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'; } + *p = '\0'; save_errno = errno; - if ((term.c_lflag & ECHO) == 0u) { - if(write(output, "\n", 1) != -1) { - //dummy test to get rid of warn_unused_result compilation warning - } - } + if (!(term.c_lflag & ECHO)) (void)write(output, "\n", 1); /* Restore old terminal settings and signals. */ if (memcmp(&term, &oterm, sizeof(term)) != 0) { - (void)tcsetattr(input, _T_FLUSH, &oterm); - } - (void)sigaction(SIGINT, &saveint, nullptr); - (void)sigaction(SIGHUP, &savehup, nullptr); - (void)sigaction(SIGQUIT, &savequit, nullptr); - (void)sigaction(SIGTERM, &saveterm, nullptr); - (void)sigaction(SIGTSTP, &savetstp, nullptr); - (void)sigaction(SIGTTIN, &savettin, nullptr); - (void)sigaction(SIGTTOU, &savettou, nullptr); - if (input != STDIN_FILENO) { - (void)close(input); + const int sigttou = signo[SIGTTOU]; + + /* Ignore SIGTTOU generated when we are not the fg pgrp. */ + while (tcsetattr(input, TCSAFLUSH | TCSASOFT, &oterm) == -1 && + errno == EINTR && !signo[SIGTTOU]) + continue; + signo[SIGTTOU] = sigttou; } + (void)sigaction(SIGALRM, &savealrm, NULL); + (void)sigaction(SIGHUP, &savehup, NULL); + (void)sigaction(SIGINT, &saveint, NULL); + (void)sigaction(SIGQUIT, &savequit, NULL); + (void)sigaction(SIGPIPE, &savepipe, NULL); + (void)sigaction(SIGTERM, &saveterm, NULL); + (void)sigaction(SIGTSTP, &savetstp, NULL); + (void)sigaction(SIGTTIN, &savettin, NULL); + (void)sigaction(SIGTTOU, &savettou, NULL); + if (input != STDIN_FILENO) (void)close(input); /* * If we were interrupted by a signal, resend it to ourselves * now that we have restored the signal handlers. */ - if (signo != 0) { - kill(getpid(), signo); - switch (signo) { - case SIGTSTP: - case SIGTTIN: - case SIGTTOU: - signo = 0; - 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; - errno = save_errno; - return (nr == -1 ? nullptr : buf); + if (save_errno) errno = save_errno; + return (nr == -1 ? NULL : buf); } -#endif /* HAVE_READPASSPHRASE */ +// DEF_WEAK(readpassphrase); #if 0 char * @@ -197,4 +201,5 @@ getpass(const char *prompt) } #endif -static void handler(int s) { signo = s; } +static void handler(int s) { signo[s] = 1; } +#endif /* HAVE_READPASSPHRASE */ diff --git a/encfs/readpassphrase.h b/encfs/readpassphrase.h index 1c4f993..3adbde6 100644 --- a/encfs/readpassphrase.h +++ b/encfs/readpassphrase.h @@ -1,37 +1,32 @@ -/* $OpenBSD: readpassphrase.h,v 1.1 2000/11/21 00:48:38 millert Exp $ +/* $OpenBSD: readpassphrase.h,v 1.5 2003/06/17 21:56:23 millert Exp $ */ /* - * Copyright (c) 2000 Todd C. Miller - * All rights reserved. + * Copyright (c) 2000, 2002 Todd C. Miller * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ +/* OPENBSD ORIGINAL: include/readpassphrase.h */ + #ifndef _READPASSPHRASE_H_ #define _READPASSPHRASE_H_ -//#include "includes.h" +// #include "includes.h" #include #ifndef HAVE_READPASSPHRASE @@ -42,6 +37,7 @@ #define RPP_FORCELOWER 0x04 /* Force input to lower case. */ #define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ #define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ +#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */ #ifdef __cplusplus extern "C"