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