diff options
author | markm <markm@FreeBSD.org> | 2000-02-24 14:29:47 +0000 |
---|---|---|
committer | markm <markm@FreeBSD.org> | 2000-02-24 14:29:47 +0000 |
commit | fc557ff7d97438559e69347575f5aa8ef03a5f50 (patch) | |
tree | c90ea5392aa03e7619696143bde781f2bf5c0dff /crypto/openssh/readpass.c | |
download | FreeBSD-src-fc557ff7d97438559e69347575f5aa8ef03a5f50.zip FreeBSD-src-fc557ff7d97438559e69347575f5aa8ef03a5f50.tar.gz |
Vendor import of OpenSSH.
Diffstat (limited to 'crypto/openssh/readpass.c')
-rw-r--r-- | crypto/openssh/readpass.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/crypto/openssh/readpass.c b/crypto/openssh/readpass.c new file mode 100644 index 0000000..deb37cab6 --- /dev/null +++ b/crypto/openssh/readpass.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#include "includes.h" +RCSID("$Id: readpass.c,v 1.9 2000/01/21 21:16:00 deraadt Exp $"); + +#include "xmalloc.h" +#include "ssh.h" + +volatile int intr; + +void +intcatch() +{ + intr = 1; +} + +/* + * Reads a passphrase from /dev/tty with echo turned off. Returns the + * passphrase (allocated with xmalloc), being very careful to ensure that + * no other userland buffer is storing the password. + */ +char * +read_passphrase(const char *prompt, int from_stdin) +{ + char buf[1024], *p, ch; + struct termios tio, saved_tio; + sigset_t oset, nset; + struct sigaction sa, osa; + int input, output, echo = 0; + + if (from_stdin) { + input = STDIN_FILENO; + output = STDERR_FILENO; + } else + input = output = open("/dev/tty", O_RDWR); + + if (input == -1) + fatal("You have no controlling tty. Cannot read passphrase.\n"); + + /* block signals, get terminal modes and turn off echo */ + sigemptyset(&nset); + sigaddset(&nset, SIGTSTP); + (void) sigprocmask(SIG_BLOCK, &nset, &oset); + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = intcatch; + (void) sigaction(SIGINT, &sa, &osa); + + intr = 0; + + if (tcgetattr(input, &saved_tio) == 0 && (saved_tio.c_lflag & ECHO)) { + echo = 1; + tio = saved_tio; + tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); + (void) tcsetattr(input, TCSANOW, &tio); + } + + fflush(stdout); + + (void)write(output, prompt, strlen(prompt)); + for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';) { + if (intr) + break; + if (p < buf + sizeof(buf) - 1) + *p++ = ch; + } + *p = '\0'; + if (!intr) + (void)write(output, "\n", 1); + + /* restore terminal modes and allow signals */ + if (echo) + tcsetattr(input, TCSANOW, &saved_tio); + (void) sigprocmask(SIG_SETMASK, &oset, NULL); + (void) sigaction(SIGINT, &osa, NULL); + + if (intr) { + kill(getpid(), SIGINT); + sigemptyset(&nset); + /* XXX tty has not neccessarily drained by now? */ + sigsuspend(&nset); + } + + if (!from_stdin) + (void)close(input); + p = xstrdup(buf); + memset(buf, 0, sizeof(buf)); + return (p); +} |