27#ifndef HAVE_READPASSPHRASE
33#include "ext/tor_readpassphrase.h"
39# define _PATH_TTY "/dev/tty"
43# define _T_FLUSH (TCSAFLUSH|TCSASOFT)
45# define _T_FLUSH (TCSAFLUSH)
49#if !defined(_POSIX_VDISABLE) && defined(VDISABLE)
50# define _POSIX_VDISABLE VDISABLE
61static volatile sig_atomic_t signo[_NSIG];
63static void handler(
int);
66readpassphrase(
const char *prompt,
char *buf,
size_t bufsiz,
int flags)
68 ssize_t bytes_written = 0;
70 int input, output, save_errno, i, need_restart;
72 struct termios term, oterm;
73 struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
74 struct sigaction savetstp, savettin, savettou, savepipe;
83 for (i = 0; i < _NSIG; i++)
92 if ((flags & RPP_STDIN) ||
93 (input = output = open(_PATH_TTY, O_RDWR)) == -1) {
94 if (flags & RPP_REQUIRE_TTY) {
99 output = STDERR_FILENO;
107 sigemptyset(&sa.sa_mask);
109 sa.sa_handler = handler;
110 (void)sigaction(SIGALRM, &sa, &savealrm);
111 (void)sigaction(SIGHUP, &sa, &savehup);
112 (void)sigaction(SIGINT, &sa, &saveint);
113 (void)sigaction(SIGPIPE, &sa, &savepipe);
114 (void)sigaction(SIGQUIT, &sa, &savequit);
115 (void)sigaction(SIGTERM, &sa, &saveterm);
116 (void)sigaction(SIGTSTP, &sa, &savetstp);
117 (void)sigaction(SIGTTIN, &sa, &savettin);
118 (void)sigaction(SIGTTOU, &sa, &savettou);
121 if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
122 memcpy(&term, &oterm,
sizeof(term));
123 if (!(flags & RPP_ECHO_ON))
124 term.c_lflag &= ~(ECHO | ECHONL);
126 if (term.c_cc[VSTATUS] != _POSIX_VDISABLE)
127 term.c_cc[VSTATUS] = _POSIX_VDISABLE;
129 (void)tcsetattr(input, _T_FLUSH, &term);
131 memset(&term, 0,
sizeof(term));
132 term.c_lflag |= ECHO;
133 memset(&oterm, 0,
sizeof(oterm));
134 oterm.c_lflag |= ECHO;
138 if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) {
139 if (!(flags & RPP_STDIN))
140 bytes_written = write(output, prompt, strlen(prompt));
141 end = buf + bufsiz - 1;
143 while ((nr = read(input, &ch, 1)) == 1 && ch !=
'\n' && ch !=
'\r') {
146 if ((flags & RPP_SEVENBIT))
149 if ((flags & RPP_FORCELOWER))
150 ch = (char)tolower(ch);
151 if ((flags & RPP_FORCEUPPER))
152 ch = (
char)toupper(ch);
160 if (!(term.c_lflag & ECHO))
161 bytes_written = write(output,
"\n", 1);
164 (void) bytes_written;
167 if (memcmp(&term, &oterm,
sizeof(term)) != 0) {
168 while (tcsetattr(input, _T_FLUSH, &oterm) == -1 &&
172 (void)sigaction(SIGALRM, &savealrm, NULL);
173 (void)sigaction(SIGHUP, &savehup, NULL);
174 (void)sigaction(SIGINT, &saveint, NULL);
175 (void)sigaction(SIGQUIT, &savequit, NULL);
176 (void)sigaction(SIGPIPE, &savepipe, NULL);
177 (void)sigaction(SIGTERM, &saveterm, NULL);
178 (void)sigaction(SIGTSTP, &savetstp, NULL);
179 (void)sigaction(SIGTTIN, &savettin, NULL);
180 (void)sigaction(SIGTTOU, &savettou, NULL);
181 if (input != STDIN_FILENO)
188 for (i = 0; i < _NSIG; i++) {
204 return(nr == -1 ? NULL : buf);
209getpass(
const char *prompt)
211 static char buf[_PASSWORD_LEN + 1];
213 return(readpassphrase(prompt, buf,
sizeof(buf), RPP_ECHO_OFF));
217static void handler(
int s)