xref: /freebsd/contrib/libarchive/libarchive_fe/passphrase.c (revision 13d826ff947d9026f98e317e7385b22abfc0eace)
1cdf63a70SMartin Matuska /*-
2cdf63a70SMartin Matuska  * Copyright (c) 2014 Michihiro NAKAJIMA
3cdf63a70SMartin Matuska  * All rights reserved.
4cdf63a70SMartin Matuska  *
5cdf63a70SMartin Matuska  * Redistribution and use in source and binary forms, with or without
6cdf63a70SMartin Matuska  * modification, are permitted provided that the following conditions
7cdf63a70SMartin Matuska  * are met:
8cdf63a70SMartin Matuska  * 1. Redistributions of source code must retain the above copyright
9cdf63a70SMartin Matuska  *    notice, this list of conditions and the following disclaimer
10cdf63a70SMartin Matuska  *    in this position and unchanged.
11cdf63a70SMartin Matuska  * 2. Redistributions in binary form must reproduce the above copyright
12cdf63a70SMartin Matuska  *    notice, this list of conditions and the following disclaimer in the
13cdf63a70SMartin Matuska  *    documentation and/or other materials provided with the distribution.
14cdf63a70SMartin Matuska  *
15cdf63a70SMartin Matuska  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16cdf63a70SMartin Matuska  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17cdf63a70SMartin Matuska  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18cdf63a70SMartin Matuska  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19cdf63a70SMartin Matuska  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20cdf63a70SMartin Matuska  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21cdf63a70SMartin Matuska  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22cdf63a70SMartin Matuska  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23cdf63a70SMartin Matuska  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24cdf63a70SMartin Matuska  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25cdf63a70SMartin Matuska  */
26fae5c36eSMartin Matuska /*	$OpenBSD: readpassphrase.c,v 1.27 2019/01/25 00:19:25 millert Exp $	*/
27fae5c36eSMartin Matuska 
28cdf63a70SMartin Matuska /*
29fae5c36eSMartin Matuska  * Copyright (c) 2000-2002, 2007, 2010
30fae5c36eSMartin Matuska  * 	Todd C. Miller <millert@openbsd.org>
31cdf63a70SMartin Matuska  *
32cdf63a70SMartin Matuska  * Permission to use, copy, modify, and distribute this software for any
33cdf63a70SMartin Matuska  * purpose with or without fee is hereby granted, provided that the above
34cdf63a70SMartin Matuska  * copyright notice and this permission notice appear in all copies.
35cdf63a70SMartin Matuska  *
36cdf63a70SMartin Matuska  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
37cdf63a70SMartin Matuska  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
38cdf63a70SMartin Matuska  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
39cdf63a70SMartin Matuska  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40cdf63a70SMartin Matuska  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
41cdf63a70SMartin Matuska  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
42cdf63a70SMartin Matuska  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
43cdf63a70SMartin Matuska  *
44cdf63a70SMartin Matuska  * Sponsored in part by the Defense Advanced Research Projects
45cdf63a70SMartin Matuska  * Agency (DARPA) and Air Force Research Laboratory, Air Force
46cdf63a70SMartin Matuska  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
47cdf63a70SMartin Matuska  */
48cdf63a70SMartin Matuska 
49cdf63a70SMartin Matuska /* OPENBSD ORIGINAL: lib/libc/gen/readpassphrase.c */
50cdf63a70SMartin Matuska 
51cdf63a70SMartin Matuska 
52cdf63a70SMartin Matuska #include "lafe_platform.h"
53cdf63a70SMartin Matuska #include <errno.h>
54cdf63a70SMartin Matuska #ifdef HAVE_STDLIB_H
55cdf63a70SMartin Matuska #include <stdlib.h>
56cdf63a70SMartin Matuska #endif
57cdf63a70SMartin Matuska #ifdef HAVE_UNISTD_H
58cdf63a70SMartin Matuska #include <unistd.h>
59cdf63a70SMartin Matuska #endif
60cdf63a70SMartin Matuska #ifdef HAVE_READPASSPHRASE_H
61cdf63a70SMartin Matuska #include <readpassphrase.h>
62cdf63a70SMartin Matuska #endif
63cdf63a70SMartin Matuska 
64cdf63a70SMartin Matuska #include "err.h"
65cdf63a70SMartin Matuska #include "passphrase.h"
66cdf63a70SMartin Matuska 
67cdf63a70SMartin Matuska #ifndef HAVE_READPASSPHRASE
68cdf63a70SMartin Matuska 
69cdf63a70SMartin Matuska #define RPP_ECHO_OFF    0x00		/* Turn off echo (default). */
70cdf63a70SMartin Matuska #define RPP_ECHO_ON     0x01		/* Leave echo on. */
71cdf63a70SMartin Matuska #define RPP_REQUIRE_TTY 0x02		/* Fail if there is no tty. */
72cdf63a70SMartin Matuska #define RPP_FORCELOWER  0x04		/* Force input to lower case. */
73cdf63a70SMartin Matuska #define RPP_FORCEUPPER  0x08		/* Force input to upper case. */
74cdf63a70SMartin Matuska #define RPP_SEVENBIT    0x10		/* Strip the high bit from input. */
75cdf63a70SMartin Matuska #define RPP_STDIN       0x20		/* Read from stdin, not /dev/tty */
76cdf63a70SMartin Matuska 
77cdf63a70SMartin Matuska 
78cdf63a70SMartin Matuska #if defined(_WIN32) && !defined(__CYGWIN__)
79*13d826ffSMartin Matuska #include <string.h>
80cdf63a70SMartin Matuska #include <windows.h>
81cdf63a70SMartin Matuska 
82cdf63a70SMartin Matuska static char *
83cdf63a70SMartin Matuska readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
84cdf63a70SMartin Matuska {
85cdf63a70SMartin Matuska 	HANDLE hStdin, hStdout;
86cdf63a70SMartin Matuska 	DWORD mode, rbytes;
87cdf63a70SMartin Matuska 	BOOL success;
88cdf63a70SMartin Matuska 
89cdf63a70SMartin Matuska 	(void)flags;
90cdf63a70SMartin Matuska 
91cdf63a70SMartin Matuska 	hStdin = GetStdHandle(STD_INPUT_HANDLE);
92cdf63a70SMartin Matuska 	if (hStdin == INVALID_HANDLE_VALUE)
93cdf63a70SMartin Matuska 		return (NULL);
94cdf63a70SMartin Matuska 	hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
95cdf63a70SMartin Matuska 	if (hStdout == INVALID_HANDLE_VALUE)
96cdf63a70SMartin Matuska 		return (NULL);
97cdf63a70SMartin Matuska 
98cdf63a70SMartin Matuska 	success = GetConsoleMode(hStdin, &mode);
99cdf63a70SMartin Matuska 	if (!success)
100cdf63a70SMartin Matuska 		return (NULL);
101cdf63a70SMartin Matuska 	mode &= ~ENABLE_ECHO_INPUT;
102cdf63a70SMartin Matuska 	mode |= ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
103cdf63a70SMartin Matuska 	success = SetConsoleMode(hStdin, mode);
104cdf63a70SMartin Matuska 	if (!success)
105cdf63a70SMartin Matuska 		return (NULL);
106cdf63a70SMartin Matuska 
107cdf63a70SMartin Matuska 	success = WriteFile(hStdout, prompt, (DWORD)strlen(prompt),
108cdf63a70SMartin Matuska 		NULL, NULL);
109cdf63a70SMartin Matuska 	if (!success)
110cdf63a70SMartin Matuska 		return (NULL);
111cdf63a70SMartin Matuska 	success = ReadFile(hStdin, buf, (DWORD)bufsiz - 1, &rbytes, NULL);
112cdf63a70SMartin Matuska 	if (!success)
113cdf63a70SMartin Matuska 		return (NULL);
114cdf63a70SMartin Matuska 	WriteFile(hStdout, "\r\n", 2, NULL, NULL);
115cdf63a70SMartin Matuska 	buf[rbytes] = '\0';
116cdf63a70SMartin Matuska 	/* Remove trailing carriage return(s). */
117*13d826ffSMartin Matuska 	buf[strcspn(buf, "\r\n")] = '\0';
118cdf63a70SMartin Matuska 
119cdf63a70SMartin Matuska 	return (buf);
120cdf63a70SMartin Matuska }
121cdf63a70SMartin Matuska 
122cdf63a70SMartin Matuska #else /* _WIN32 && !__CYGWIN__ */
123cdf63a70SMartin Matuska 
124f061a221SMartin Matuska #include <assert.h>
125cdf63a70SMartin Matuska #include <ctype.h>
126cdf63a70SMartin Matuska #include <fcntl.h>
127cdf63a70SMartin Matuska #ifdef HAVE_PATHS_H
128cdf63a70SMartin Matuska #include <paths.h>
129cdf63a70SMartin Matuska #endif
130f061a221SMartin Matuska #include <signal.h>
131cdf63a70SMartin Matuska #include <string.h>
132f061a221SMartin Matuska #include <termios.h>
133cdf63a70SMartin Matuska #include <unistd.h>
134cdf63a70SMartin Matuska 
135ae5876eaSMartin Matuska #ifndef _PATH_TTY
136ae5876eaSMartin Matuska #define _PATH_TTY "/dev/tty"
137ae5876eaSMartin Matuska #endif
138ae5876eaSMartin Matuska 
139cdf63a70SMartin Matuska #ifdef TCSASOFT
140cdf63a70SMartin Matuska # define _T_FLUSH	(TCSAFLUSH|TCSASOFT)
141cdf63a70SMartin Matuska #else
142cdf63a70SMartin Matuska # define _T_FLUSH	(TCSAFLUSH)
143cdf63a70SMartin Matuska #endif
144cdf63a70SMartin Matuska 
145cdf63a70SMartin Matuska /* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */
146cdf63a70SMartin Matuska #if !defined(_POSIX_VDISABLE) && defined(VDISABLE)
147cdf63a70SMartin Matuska #  define _POSIX_VDISABLE       VDISABLE
148cdf63a70SMartin Matuska #endif
149cdf63a70SMartin Matuska 
150f061a221SMartin Matuska #define M(a,b) (a > b ? a : b)
151f061a221SMartin Matuska #define MAX_SIGNO M(M(M(SIGALRM, SIGHUP), \
152f061a221SMartin Matuska                       M(SIGINT, SIGPIPE)), \
153f061a221SMartin Matuska                     M(M(SIGQUIT, SIGTERM), \
154f061a221SMartin Matuska                       M(M(SIGTSTP, SIGTTIN), SIGTTOU)))
155f061a221SMartin Matuska 
156f061a221SMartin Matuska static volatile sig_atomic_t signo[MAX_SIGNO + 1];
157cdf63a70SMartin Matuska 
158cdf63a70SMartin Matuska static void
159cdf63a70SMartin Matuska handler(int s)
160cdf63a70SMartin Matuska {
161f061a221SMartin Matuska 	assert(s <= MAX_SIGNO);
162cdf63a70SMartin Matuska 	signo[s] = 1;
163cdf63a70SMartin Matuska }
164cdf63a70SMartin Matuska 
165cdf63a70SMartin Matuska static char *
166cdf63a70SMartin Matuska readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
167cdf63a70SMartin Matuska {
168cdf63a70SMartin Matuska 	ssize_t nr;
169cdf63a70SMartin Matuska 	int input, output, save_errno, i, need_restart;
170cdf63a70SMartin Matuska 	char ch, *p, *end;
171cdf63a70SMartin Matuska 	struct termios term, oterm;
172e64fe029SMartin Matuska #ifdef HAVE_SIGACTION
173cdf63a70SMartin Matuska 	struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
174cdf63a70SMartin Matuska 	struct sigaction savetstp, savettin, savettou, savepipe;
175e64fe029SMartin Matuska #endif
176cdf63a70SMartin Matuska 
177cdf63a70SMartin Matuska 	/* I suppose we could alloc on demand in this case (XXX). */
178cdf63a70SMartin Matuska 	if (bufsiz == 0) {
179cdf63a70SMartin Matuska 		errno = EINVAL;
180cdf63a70SMartin Matuska 		return(NULL);
181cdf63a70SMartin Matuska 	}
182cdf63a70SMartin Matuska 
183cdf63a70SMartin Matuska restart:
184f061a221SMartin Matuska 	for (i = 0; i <= MAX_SIGNO; i++)
185cdf63a70SMartin Matuska 		signo[i] = 0;
186cdf63a70SMartin Matuska 	nr = -1;
187cdf63a70SMartin Matuska 	save_errno = 0;
188cdf63a70SMartin Matuska 	need_restart = 0;
189cdf63a70SMartin Matuska 	/*
190cdf63a70SMartin Matuska 	 * Read and write to /dev/tty if available.  If not, read from
191cdf63a70SMartin Matuska 	 * stdin and write to stderr unless a tty is required.
192cdf63a70SMartin Matuska 	 */
193cdf63a70SMartin Matuska 	if ((flags & RPP_STDIN) ||
194cdf63a70SMartin Matuska 	    (input = output = open(_PATH_TTY, O_RDWR)) == -1) {
195cdf63a70SMartin Matuska 		if (flags & RPP_REQUIRE_TTY) {
196cdf63a70SMartin Matuska 			errno = ENOTTY;
197cdf63a70SMartin Matuska 			return(NULL);
198cdf63a70SMartin Matuska 		}
199cdf63a70SMartin Matuska 		input = STDIN_FILENO;
200cdf63a70SMartin Matuska 		output = STDERR_FILENO;
201cdf63a70SMartin Matuska 	}
202cdf63a70SMartin Matuska 
203cdf63a70SMartin Matuska 	/*
204fae5c36eSMartin Matuska 	 * Turn off echo if possible.
205fae5c36eSMartin Matuska 	 * If we are using a tty but are not the foreground pgrp this will
206fae5c36eSMartin Matuska 	 * generate SIGTTOU, so do it *before* installing the signal handlers.
207fae5c36eSMartin Matuska 	 */
208fae5c36eSMartin Matuska 	if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
209fae5c36eSMartin Matuska 		memcpy(&term, &oterm, sizeof(term));
210fae5c36eSMartin Matuska 		if (!(flags & RPP_ECHO_ON))
211fae5c36eSMartin Matuska 			term.c_lflag &= ~(ECHO | ECHONL);
212fae5c36eSMartin Matuska #ifdef VSTATUS
213fae5c36eSMartin Matuska 		if (term.c_cc[VSTATUS] != _POSIX_VDISABLE)
214fae5c36eSMartin Matuska 			term.c_cc[VSTATUS] = _POSIX_VDISABLE;
215fae5c36eSMartin Matuska #endif
216fae5c36eSMartin Matuska 		(void)tcsetattr(input, _T_FLUSH, &term);
217fae5c36eSMartin Matuska 	} else {
218fae5c36eSMartin Matuska 		memset(&term, 0, sizeof(term));
219fae5c36eSMartin Matuska 		term.c_lflag |= ECHO;
220fae5c36eSMartin Matuska 		memset(&oterm, 0, sizeof(oterm));
221fae5c36eSMartin Matuska 		oterm.c_lflag |= ECHO;
222fae5c36eSMartin Matuska 	}
223fae5c36eSMartin Matuska 
224e64fe029SMartin Matuska #ifdef HAVE_SIGACTION
225fae5c36eSMartin Matuska 	/*
226cdf63a70SMartin Matuska 	 * Catch signals that would otherwise cause the user to end
227cdf63a70SMartin Matuska 	 * up with echo turned off in the shell.  Don't worry about
228cdf63a70SMartin Matuska 	 * things like SIGXCPU and SIGVTALRM for now.
229cdf63a70SMartin Matuska 	 */
230cdf63a70SMartin Matuska 	sigemptyset(&sa.sa_mask);
231cdf63a70SMartin Matuska 	sa.sa_flags = 0;		/* don't restart system calls */
232cdf63a70SMartin Matuska 	sa.sa_handler = handler;
233f061a221SMartin Matuska 	/* Keep this list in sync with MAX_SIGNO! */
234cdf63a70SMartin Matuska 	(void)sigaction(SIGALRM, &sa, &savealrm);
235cdf63a70SMartin Matuska 	(void)sigaction(SIGHUP, &sa, &savehup);
236cdf63a70SMartin Matuska 	(void)sigaction(SIGINT, &sa, &saveint);
237cdf63a70SMartin Matuska 	(void)sigaction(SIGPIPE, &sa, &savepipe);
238cdf63a70SMartin Matuska 	(void)sigaction(SIGQUIT, &sa, &savequit);
239cdf63a70SMartin Matuska 	(void)sigaction(SIGTERM, &sa, &saveterm);
240cdf63a70SMartin Matuska 	(void)sigaction(SIGTSTP, &sa, &savetstp);
241cdf63a70SMartin Matuska 	(void)sigaction(SIGTTIN, &sa, &savettin);
242cdf63a70SMartin Matuska 	(void)sigaction(SIGTTOU, &sa, &savettou);
243e64fe029SMartin Matuska #endif
244cdf63a70SMartin Matuska 
245cdf63a70SMartin Matuska 	if (!(flags & RPP_STDIN)) {
246cdf63a70SMartin Matuska 		int r = write(output, prompt, strlen(prompt));
247cdf63a70SMartin Matuska 		(void)r;
248cdf63a70SMartin Matuska 	}
249cdf63a70SMartin Matuska 	end = buf + bufsiz - 1;
250cdf63a70SMartin Matuska 	p = buf;
251cdf63a70SMartin Matuska 	while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') {
252cdf63a70SMartin Matuska 		if (p < end) {
253cdf63a70SMartin Matuska 			if ((flags & RPP_SEVENBIT))
254cdf63a70SMartin Matuska 				ch &= 0x7f;
255f061a221SMartin Matuska 			if (isalpha((unsigned char)ch)) {
256cdf63a70SMartin Matuska 				if ((flags & RPP_FORCELOWER))
257f061a221SMartin Matuska 					ch = (char)tolower((unsigned char)ch);
258cdf63a70SMartin Matuska 				if ((flags & RPP_FORCEUPPER))
259f061a221SMartin Matuska 					ch = (char)toupper((unsigned char)ch);
260cdf63a70SMartin Matuska 			}
261cdf63a70SMartin Matuska 			*p++ = ch;
262cdf63a70SMartin Matuska 		}
263cdf63a70SMartin Matuska 	}
264cdf63a70SMartin Matuska 	*p = '\0';
265cdf63a70SMartin Matuska 	save_errno = errno;
266cdf63a70SMartin Matuska 	if (!(term.c_lflag & ECHO)) {
267cdf63a70SMartin Matuska 		int r = write(output, "\n", 1);
268cdf63a70SMartin Matuska 		(void)r;
269cdf63a70SMartin Matuska 	}
270cdf63a70SMartin Matuska 
271cdf63a70SMartin Matuska 	/* Restore old terminal settings and signals. */
272cdf63a70SMartin Matuska 	if (memcmp(&term, &oterm, sizeof(term)) != 0) {
273fae5c36eSMartin Matuska 		const int sigttou = signo[SIGTTOU];
274fae5c36eSMartin Matuska 
275fae5c36eSMartin Matuska 		/* Ignore SIGTTOU generated when we are not the fg pgrp. */
276cdf63a70SMartin Matuska 		while (tcsetattr(input, _T_FLUSH, &oterm) == -1 &&
277fae5c36eSMartin Matuska 		    errno == EINTR && !signo[SIGTTOU])
278cdf63a70SMartin Matuska 			continue;
279fae5c36eSMartin Matuska 		signo[SIGTTOU] = sigttou;
280cdf63a70SMartin Matuska 	}
281e64fe029SMartin Matuska #ifdef HAVE_SIGACTION
282cdf63a70SMartin Matuska 	(void)sigaction(SIGALRM, &savealrm, NULL);
283cdf63a70SMartin Matuska 	(void)sigaction(SIGHUP, &savehup, NULL);
284cdf63a70SMartin Matuska 	(void)sigaction(SIGINT, &saveint, NULL);
285cdf63a70SMartin Matuska 	(void)sigaction(SIGQUIT, &savequit, NULL);
286cdf63a70SMartin Matuska 	(void)sigaction(SIGPIPE, &savepipe, NULL);
287cdf63a70SMartin Matuska 	(void)sigaction(SIGTERM, &saveterm, NULL);
288cdf63a70SMartin Matuska 	(void)sigaction(SIGTSTP, &savetstp, NULL);
289cdf63a70SMartin Matuska 	(void)sigaction(SIGTTIN, &savettin, NULL);
290cdf63a70SMartin Matuska 	(void)sigaction(SIGTTOU, &savettou, NULL);
291e64fe029SMartin Matuska #endif
292cdf63a70SMartin Matuska 	if (input != STDIN_FILENO)
293cdf63a70SMartin Matuska 		(void)close(input);
294cdf63a70SMartin Matuska 
295cdf63a70SMartin Matuska 	/*
296cdf63a70SMartin Matuska 	 * If we were interrupted by a signal, resend it to ourselves
297cdf63a70SMartin Matuska 	 * now that we have restored the signal handlers.
298cdf63a70SMartin Matuska 	 */
299f061a221SMartin Matuska 	for (i = 0; i <= MAX_SIGNO; i++) {
300cdf63a70SMartin Matuska 		if (signo[i]) {
301cdf63a70SMartin Matuska 			kill(getpid(), i);
302cdf63a70SMartin Matuska 			switch (i) {
303cdf63a70SMartin Matuska 			case SIGTSTP:
304cdf63a70SMartin Matuska 			case SIGTTIN:
305cdf63a70SMartin Matuska 			case SIGTTOU:
306cdf63a70SMartin Matuska 				need_restart = 1;
307cdf63a70SMartin Matuska 			}
308cdf63a70SMartin Matuska 		}
309cdf63a70SMartin Matuska 	}
310cdf63a70SMartin Matuska 	if (need_restart)
311cdf63a70SMartin Matuska 		goto restart;
312cdf63a70SMartin Matuska 
313cdf63a70SMartin Matuska 	if (save_errno)
314cdf63a70SMartin Matuska 		errno = save_errno;
315cdf63a70SMartin Matuska 	return(nr == -1 ? NULL : buf);
316cdf63a70SMartin Matuska }
317cdf63a70SMartin Matuska #endif /* _WIN32 && !__CYGWIN__ */
318cdf63a70SMartin Matuska #endif /* HAVE_READPASSPHRASE */
319cdf63a70SMartin Matuska 
320cdf63a70SMartin Matuska char *
321cdf63a70SMartin Matuska lafe_readpassphrase(const char *prompt, char *buf, size_t bufsiz)
322cdf63a70SMartin Matuska {
323cdf63a70SMartin Matuska 	char *p;
324cdf63a70SMartin Matuska 
325cdf63a70SMartin Matuska 	p = readpassphrase(prompt, buf, bufsiz, RPP_ECHO_OFF);
326cdf63a70SMartin Matuska 	if (p == NULL) {
327cdf63a70SMartin Matuska 		switch (errno) {
328cdf63a70SMartin Matuska 		case EINTR:
329cdf63a70SMartin Matuska 			break;
330cdf63a70SMartin Matuska 		default:
331cdf63a70SMartin Matuska 			lafe_errc(1, errno, "Couldn't read passphrase");
332b9128a37SMartin Matuska 			/* NOTREACHED */
333cdf63a70SMartin Matuska 		}
334cdf63a70SMartin Matuska 	}
335cdf63a70SMartin Matuska 	return (p);
336cdf63a70SMartin Matuska }
337cdf63a70SMartin Matuska 
338