Annotation of src/usr.bin/ssh/readpass.c, Revision 1.10
1.1 deraadt 1: /*
1.8 deraadt 2: * Copyright (c) 1988, 1993
3: * The Regents of the University of California. All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
1.6 deraadt 32: */
1.1 deraadt 33:
34: #include "includes.h"
1.10 ! markus 35: RCSID("$Id: readpass.c,v 1.9 2000/01/21 21:16:00 deraadt Exp $");
1.1 deraadt 36:
37: #include "xmalloc.h"
38: #include "ssh.h"
39:
1.9 deraadt 40: volatile int intr;
41:
42: void
43: intcatch()
44: {
45: intr = 1;
46: }
47:
1.7 markus 48: /*
49: * Reads a passphrase from /dev/tty with echo turned off. Returns the
1.8 deraadt 50: * passphrase (allocated with xmalloc), being very careful to ensure that
51: * no other userland buffer is storing the password.
1.7 markus 52: */
1.5 markus 53: char *
54: read_passphrase(const char *prompt, int from_stdin)
1.1 deraadt 55: {
1.8 deraadt 56: char buf[1024], *p, ch;
57: struct termios tio, saved_tio;
58: sigset_t oset, nset;
1.9 deraadt 59: struct sigaction sa, osa;
1.8 deraadt 60: int input, output, echo = 0;
1.10 ! markus 61:
1.8 deraadt 62: if (from_stdin) {
63: input = STDIN_FILENO;
64: output = STDERR_FILENO;
65: } else
66: input = output = open("/dev/tty", O_RDWR);
67:
68: if (input == -1)
69: fatal("You have no controlling tty. Cannot read passphrase.\n");
70:
71: /* block signals, get terminal modes and turn off echo */
72: sigemptyset(&nset);
73: sigaddset(&nset, SIGTSTP);
74: (void) sigprocmask(SIG_BLOCK, &nset, &oset);
1.9 deraadt 75: memset(&sa, 0, sizeof(sa));
76: sa.sa_handler = intcatch;
77: (void) sigaction(SIGINT, &sa, &osa);
78:
79: intr = 0;
1.8 deraadt 80:
1.9 deraadt 81: if (tcgetattr(input, &saved_tio) == 0 && (saved_tio.c_lflag & ECHO)) {
1.8 deraadt 82: echo = 1;
1.9 deraadt 83: tio = saved_tio;
1.8 deraadt 84: tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
85: (void) tcsetattr(input, TCSANOW, &tio);
1.1 deraadt 86: }
87:
1.5 markus 88: fflush(stdout);
89:
1.8 deraadt 90: (void)write(output, prompt, strlen(prompt));
1.9 deraadt 91: for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';) {
92: if (intr)
93: break;
1.8 deraadt 94: if (p < buf + sizeof(buf) - 1)
95: *p++ = ch;
1.9 deraadt 96: }
1.8 deraadt 97: *p = '\0';
1.9 deraadt 98: if (!intr)
99: (void)write(output, "\n", 1);
1.8 deraadt 100:
101: /* restore terminal modes and allow signals */
102: if (echo)
103: tcsetattr(input, TCSANOW, &saved_tio);
104: (void) sigprocmask(SIG_SETMASK, &oset, NULL);
1.9 deraadt 105: (void) sigaction(SIGINT, &osa, NULL);
106:
107: if (intr) {
108: kill(getpid(), SIGINT);
109: sigemptyset(&nset);
110: /* XXX tty has not neccessarily drained by now? */
111: sigsuspend(&nset);
112: }
1.8 deraadt 113:
114: if (!from_stdin)
115: (void)close(input);
116: p = xstrdup(buf);
1.5 markus 117: memset(buf, 0, sizeof(buf));
1.8 deraadt 118: return (p);
1.1 deraadt 119: }