summaryrefslogtreecommitdiff
path: root/openbsd-compat
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2010-03-31 00:48:57 +0100
committerColin Watson <cjwatson@debian.org>2010-03-31 00:48:57 +0100
commitd1a87e462e1db89f19cd960588d0c6b287cb5ccc (patch)
treef0d13e1687800f36a3c4322b94ac5230ad17bdbf /openbsd-compat
parent964476f91b66c475d5b8fa1e8b28d39a97a1b56e (diff)
parent004a7fb9c6a00b13dc98f56599918a54a3506d10 (diff)
merge 5.4p1
Diffstat (limited to 'openbsd-compat')
-rw-r--r--openbsd-compat/Makefile.in4
-rw-r--r--openbsd-compat/bsd-cygwin_util.c9
-rw-r--r--openbsd-compat/openbsd-compat.h10
-rw-r--r--openbsd-compat/openssl-compat.c3
-rw-r--r--openbsd-compat/port-aix.c25
-rw-r--r--openbsd-compat/port-aix.h6
-rw-r--r--openbsd-compat/port-linux.c98
-rw-r--r--openbsd-compat/port-linux.h8
-rw-r--r--openbsd-compat/pwcache.c114
-rw-r--r--openbsd-compat/readpassphrase.c78
10 files changed, 306 insertions, 49 deletions
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index a60e5a68d..d65b77b5b 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.43 2008/06/08 17:32:29 dtucker Exp $ 1# $Id: Makefile.in,v 1.44 2010/01/15 01:38:30 dtucker Exp $
2 2
3sysconfdir=@sysconfdir@ 3sysconfdir=@sysconfdir@
4piddir=@piddir@ 4piddir=@piddir@
@@ -16,7 +16,7 @@ RANLIB=@RANLIB@
16INSTALL=@INSTALL@ 16INSTALL=@INSTALL@
17LDFLAGS=-L. @LDFLAGS@ 17LDFLAGS=-L. @LDFLAGS@
18 18
19OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o 19OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o
20 20
21COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o 21COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
22 22
diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c
index e90c1597f..e9fa3a0e2 100644
--- a/openbsd-compat/bsd-cygwin_util.c
+++ b/openbsd-compat/bsd-cygwin_util.c
@@ -85,23 +85,14 @@ static struct wenv {
85 size_t namelen; 85 size_t namelen;
86} wenv_arr[] = { 86} wenv_arr[] = {
87 { NL("ALLUSERSPROFILE=") }, 87 { NL("ALLUSERSPROFILE=") },
88 { NL("COMMONPROGRAMFILES=") },
89 { NL("COMPUTERNAME=") }, 88 { NL("COMPUTERNAME=") },
90 { NL("COMSPEC=") }, 89 { NL("COMSPEC=") },
91 { NL("CYGWIN=") }, 90 { NL("CYGWIN=") },
92 { NL("NUMBER_OF_PROCESSORS=") },
93 { NL("OS=") }, 91 { NL("OS=") },
94 { NL("PATH=") }, 92 { NL("PATH=") },
95 { NL("PATHEXT=") }, 93 { NL("PATHEXT=") },
96 { NL("PROCESSOR_ARCHITECTURE=") },
97 { NL("PROCESSOR_IDENTIFIER=") },
98 { NL("PROCESSOR_LEVEL=") },
99 { NL("PROCESSOR_REVISION=") },
100 { NL("PROGRAMFILES=") },
101 { NL("SYSTEMDRIVE=") }, 94 { NL("SYSTEMDRIVE=") },
102 { NL("SYSTEMROOT=") }, 95 { NL("SYSTEMROOT=") },
103 { NL("TMP=") },
104 { NL("TEMP=") },
105 { NL("WINDIR=") } 96 { NL("WINDIR=") }
106}; 97};
107 98
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
index 50c6d990b..cad2408d6 100644
--- a/openbsd-compat/openbsd-compat.h
+++ b/openbsd-compat/openbsd-compat.h
@@ -1,4 +1,4 @@
1/* $Id: openbsd-compat.h,v 1.46 2008/06/08 17:32:29 dtucker Exp $ */ 1/* $Id: openbsd-compat.h,v 1.49 2010/01/16 12:58:37 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999-2003 Damien Miller. All rights reserved. 4 * Copyright (c) 1999-2003 Damien Miller. All rights reserved.
@@ -200,6 +200,14 @@ int vasprintf(char **, const char *, va_list);
200int vsnprintf(char *, size_t, const char *, va_list); 200int vsnprintf(char *, size_t, const char *, va_list);
201#endif 201#endif
202 202
203#ifndef HAVE_USER_FROM_UID
204char *user_from_uid(uid_t, int);
205#endif
206
207#ifndef HAVE_GROUP_FROM_GID
208char *group_from_gid(gid_t, int);
209#endif
210
203void *xmmap(size_t size); 211void *xmmap(size_t size);
204char *xcrypt(const char *password, const char *salt); 212char *xcrypt(const char *password, const char *salt);
205char *shadow_pw(struct passwd *pw); 213char *shadow_pw(struct passwd *pw);
diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c
index dd326c00f..420496caa 100644
--- a/openbsd-compat/openssl-compat.c
+++ b/openbsd-compat/openssl-compat.c
@@ -1,4 +1,4 @@
1/* $Id: openssl-compat.c,v 1.8 2009/03/07 11:22:35 dtucker Exp $ */ 1/* $Id: openssl-compat.c,v 1.9 2010/01/28 23:54:11 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> 4 * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
@@ -67,5 +67,6 @@ ssh_SSLeay_add_all_algorithms(void)
67 /* Enable use of crypto hardware */ 67 /* Enable use of crypto hardware */
68 ENGINE_load_builtin_engines(); 68 ENGINE_load_builtin_engines();
69 ENGINE_register_all_complete(); 69 ENGINE_register_all_complete();
70 OPENSSL_config(NULL);
70} 71}
71#endif 72#endif
diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c
index d9c0876f3..0bdefbf6d 100644
--- a/openbsd-compat/port-aix.c
+++ b/openbsd-compat/port-aix.c
@@ -374,6 +374,31 @@ aix_restoreauthdb(void)
374 374
375# endif /* WITH_AIXAUTHENTICATE */ 375# endif /* WITH_AIXAUTHENTICATE */
376 376
377# ifdef USE_AIX_KRB_NAME
378/*
379 * aix_krb5_get_principal_name: returns the user's kerberos client principal name if
380 * configured, otherwise NULL. Caller must free returned string.
381 */
382char *
383aix_krb5_get_principal_name(char *pw_name)
384{
385 char *authname = NULL, *authdomain = NULL, *principal = NULL;
386
387 setuserdb(S_READ);
388 if (getuserattr(pw_name, S_AUTHDOMAIN, &authdomain, SEC_CHAR) != 0)
389 debug("AIX getuserattr S_AUTHDOMAIN: %s", strerror(errno));
390 if (getuserattr(pw_name, S_AUTHNAME, &authname, SEC_CHAR) != 0)
391 debug("AIX getuserattr S_AUTHNAME: %s", strerror(errno));
392
393 if (authdomain != NULL)
394 xasprintf(&principal, "%s@%s", authname ? authname : pw_name, authdomain);
395 else if (authname != NULL)
396 principal = xstrdup(authname);
397 enduserdb();
398 return principal;
399}
400# endif /* USE_AIX_KRB_NAME */
401
377# if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO) 402# if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO)
378# undef getnameinfo 403# undef getnameinfo
379/* 404/*
diff --git a/openbsd-compat/port-aix.h b/openbsd-compat/port-aix.h
index 3ac76ae15..53e4e88a0 100644
--- a/openbsd-compat/port-aix.h
+++ b/openbsd-compat/port-aix.h
@@ -1,4 +1,4 @@
1/* $Id: port-aix.h,v 1.31 2009/08/20 06:20:50 dtucker Exp $ */ 1/* $Id: port-aix.h,v 1.32 2009/12/20 23:49:22 dtucker Exp $ */
2 2
3/* 3/*
4 * 4 *
@@ -95,6 +95,10 @@ int sys_auth_record_login(const char *, const char *, const char *, Buffer *);
95# define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG 95# define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
96char *sys_auth_get_lastlogin_msg(const char *, uid_t); 96char *sys_auth_get_lastlogin_msg(const char *, uid_t);
97# define CUSTOM_FAILED_LOGIN 1 97# define CUSTOM_FAILED_LOGIN 1
98# if defined(S_AUTHDOMAIN) && defined (S_AUTHNAME)
99# define USE_AIX_KRB_NAME
100char *aix_krb5_get_principal_name(char *);
101# endif
98#endif 102#endif
99 103
100void aix_setauthdb(const char *); 104void aix_setauthdb(const char *);
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index ad262758e..89b9a7340 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux.c
@@ -1,4 +1,4 @@
1/* $Id: port-linux.c,v 1.5 2008/03/26 20:27:21 dtucker Exp $ */ 1/* $Id: port-linux.c,v 1.8 2010/03/01 04:52:50 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com> 4 * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
@@ -23,14 +23,17 @@
23 23
24#include "includes.h" 24#include "includes.h"
25 25
26#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)
26#include <errno.h> 27#include <errno.h>
27#include <stdarg.h> 28#include <stdarg.h>
28#include <string.h> 29#include <string.h>
30#include <stdio.h>
29 31
30#ifdef WITH_SELINUX
31#include "log.h" 32#include "log.h"
33#include "xmalloc.h"
32#include "port-linux.h" 34#include "port-linux.h"
33 35
36#ifdef WITH_SELINUX
34#include <selinux/selinux.h> 37#include <selinux/selinux.h>
35#include <selinux/flask.h> 38#include <selinux/flask.h>
36#include <selinux/get_context_list.h> 39#include <selinux/get_context_list.h>
@@ -168,4 +171,95 @@ ssh_selinux_setup_pty(char *pwname, const char *tty)
168 freecon(user_ctx); 171 freecon(user_ctx);
169 debug3("%s: done", __func__); 172 debug3("%s: done", __func__);
170} 173}
174
175void
176ssh_selinux_change_context(const char *newname)
177{
178 int len, newlen;
179 char *oldctx, *newctx, *cx;
180
181 if (!ssh_selinux_enabled())
182 return;
183
184 if (getcon((security_context_t *)&oldctx) < 0) {
185 logit("%s: getcon failed with %s", __func__, strerror (errno));
186 return;
187 }
188 if ((cx = index(oldctx, ':')) == NULL || (cx = index(cx + 1, ':')) ==
189 NULL) {
190 logit ("%s: unparseable context %s", __func__, oldctx);
191 return;
192 }
193
194 newlen = strlen(oldctx) + strlen(newname) + 1;
195 newctx = xmalloc(newlen);
196 len = cx - oldctx + 1;
197 memcpy(newctx, oldctx, len);
198 strlcpy(newctx + len, newname, newlen - len);
199 if ((cx = index(cx + 1, ':')))
200 strlcat(newctx, cx, newlen);
201 debug3("%s: setting context from '%s' to '%s'", __func__, oldctx,
202 newctx);
203 if (setcon(newctx) < 0)
204 logit("%s: setcon failed with %s", __func__, strerror (errno));
205 xfree(oldctx);
206 xfree(newctx);
207}
171#endif /* WITH_SELINUX */ 208#endif /* WITH_SELINUX */
209
210#ifdef LINUX_OOM_ADJUST
211#define OOM_ADJ_PATH "/proc/self/oom_adj"
212/*
213 * The magic "don't kill me", as documented in eg:
214 * http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt
215 */
216#define OOM_ADJ_NOKILL -17
217
218static int oom_adj_save = INT_MIN;
219
220/*
221 * Tell the kernel's out-of-memory killer to avoid sshd.
222 * Returns the previous oom_adj value or zero.
223 */
224void
225oom_adjust_setup(void)
226{
227 FILE *fp;
228
229 debug3("%s", __func__);
230 if ((fp = fopen(OOM_ADJ_PATH, "r+")) != NULL) {
231 if (fscanf(fp, "%d", &oom_adj_save) != 1)
232 verbose("error reading %s: %s", OOM_ADJ_PATH, strerror(errno));
233 else {
234 rewind(fp);
235 if (fprintf(fp, "%d\n", OOM_ADJ_NOKILL) <= 0)
236 verbose("error writing %s: %s",
237 OOM_ADJ_PATH, strerror(errno));
238 else
239 verbose("Set %s from %d to %d",
240 OOM_ADJ_PATH, oom_adj_save, OOM_ADJ_NOKILL);
241 }
242 fclose(fp);
243 }
244}
245
246/* Restore the saved OOM adjustment */
247void
248oom_adjust_restore(void)
249{
250 FILE *fp;
251
252 debug3("%s", __func__);
253 if (oom_adj_save == INT_MIN || (fp = fopen(OOM_ADJ_PATH, "w")) == NULL)
254 return;
255
256 if (fprintf(fp, "%d\n", oom_adj_save) <= 0)
257 verbose("error writing %s: %s", OOM_ADJ_PATH, strerror(errno));
258 else
259 verbose("Set %s to %d", OOM_ADJ_PATH, oom_adj_save);
260
261 fclose(fp);
262 return;
263}
264#endif /* LINUX_OOM_ADJUST */
265#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index 5cd39bf83..209d9a7a2 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -1,4 +1,4 @@
1/* $Id: port-linux.h,v 1.2 2008/03/26 20:27:21 dtucker Exp $ */ 1/* $Id: port-linux.h,v 1.4 2009/12/08 02:39:48 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006 Damien Miller <djm@openbsd.org> 4 * Copyright (c) 2006 Damien Miller <djm@openbsd.org>
@@ -23,6 +23,12 @@
23int ssh_selinux_enabled(void); 23int ssh_selinux_enabled(void);
24void ssh_selinux_setup_pty(char *, const char *); 24void ssh_selinux_setup_pty(char *, const char *);
25void ssh_selinux_setup_exec_context(char *); 25void ssh_selinux_setup_exec_context(char *);
26void ssh_selinux_change_context(const char *);
27#endif
28
29#ifdef LINUX_OOM_ADJUST
30void oom_adjust_restore(void);
31void oom_adjust_setup(void);
26#endif 32#endif
27 33
28#endif /* ! _PORT_LINUX_H */ 34#endif /* ! _PORT_LINUX_H */
diff --git a/openbsd-compat/pwcache.c b/openbsd-compat/pwcache.c
new file mode 100644
index 000000000..5a8b78801
--- /dev/null
+++ b/openbsd-compat/pwcache.c
@@ -0,0 +1,114 @@
1/* $OpenBSD: pwcache.c,v 1.9 2005/08/08 08:05:34 espie Exp $ */
2/*
3 * Copyright (c) 1989, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31/* OPENBSD ORIGINAL: lib/libc/gen/pwcache.c */
32
33#include "includes.h"
34
35#include <sys/types.h>
36
37#include <grp.h>
38#include <pwd.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42
43#define NCACHE 64 /* power of 2 */
44#define MASK (NCACHE - 1) /* bits to store with */
45
46#ifndef HAVE_USER_FROM_UID
47char *
48user_from_uid(uid_t uid, int nouser)
49{
50 static struct ncache {
51 uid_t uid;
52 char *name;
53 } c_uid[NCACHE];
54 static int pwopen;
55 static char nbuf[15]; /* 32 bits == 10 digits */
56 struct passwd *pw;
57 struct ncache *cp;
58
59 cp = c_uid + (uid & MASK);
60 if (cp->uid != uid || cp->name == NULL) {
61 if (pwopen == 0) {
62#ifdef HAVE_SETPASSENT
63 setpassent(1);
64#endif
65 pwopen = 1;
66 }
67 if ((pw = getpwuid(uid)) == NULL) {
68 if (nouser)
69 return (NULL);
70 (void)snprintf(nbuf, sizeof(nbuf), "%u", uid);
71 }
72 cp->uid = uid;
73 if (cp->name != NULL)
74 free(cp->name);
75 cp->name = strdup(pw ? pw->pw_name : nbuf);
76 }
77 return (cp->name);
78}
79#endif
80
81#ifndef HAVE_GROUP_FROM_GID
82char *
83group_from_gid(gid_t gid, int nogroup)
84{
85 static struct ncache {
86 gid_t gid;
87 char *name;
88 } c_gid[NCACHE];
89 static int gropen;
90 static char nbuf[15]; /* 32 bits == 10 digits */
91 struct group *gr;
92 struct ncache *cp;
93
94 cp = c_gid + (gid & MASK);
95 if (cp->gid != gid || cp->name == NULL) {
96 if (gropen == 0) {
97#ifdef HAVE_SETGROUPENT
98 setgroupent(1);
99#endif
100 gropen = 1;
101 }
102 if ((gr = getgrgid(gid)) == NULL) {
103 if (nogroup)
104 return (NULL);
105 (void)snprintf(nbuf, sizeof(nbuf), "%u", gid);
106 }
107 cp->gid = gid;
108 if (cp->name != NULL)
109 free(cp->name);
110 cp->name = strdup(gr ? gr->gr_name : nbuf);
111 }
112 return (cp->name);
113}
114#endif
diff --git a/openbsd-compat/readpassphrase.c b/openbsd-compat/readpassphrase.c
index 11bd8f646..62b6d0d84 100644
--- a/openbsd-compat/readpassphrase.c
+++ b/openbsd-compat/readpassphrase.c
@@ -1,7 +1,7 @@
1/* $OpenBSD: readpassphrase.c,v 1.18 2005/08/08 08:05:34 espie Exp $ */ 1/* $OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000-2002 Todd C. Miller <Todd.Miller@courtesan.com> 4 * Copyright (c) 2000-2002, 2007 Todd C. Miller <Todd.Miller@courtesan.com>
5 * 5 *
6 * Permission to use, copy, modify, and distribute this software for any 6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -46,7 +46,7 @@
46# define _POSIX_VDISABLE VDISABLE 46# define _POSIX_VDISABLE VDISABLE
47#endif 47#endif
48 48
49static volatile sig_atomic_t signo; 49static volatile sig_atomic_t signo[_NSIG];
50 50
51static void handler(int); 51static void handler(int);
52 52
@@ -54,7 +54,7 @@ char *
54readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) 54readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
55{ 55{
56 ssize_t nr; 56 ssize_t nr;
57 int input, output, save_errno; 57 int input, output, save_errno, i, need_restart;
58 char ch, *p, *end; 58 char ch, *p, *end;
59 struct termios term, oterm; 59 struct termios term, oterm;
60 struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; 60 struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
@@ -67,7 +67,11 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
67 } 67 }
68 68
69restart: 69restart:
70 signo = 0; 70 for (i = 0; i < _NSIG; i++)
71 signo[i] = 0;
72 nr = -1;
73 save_errno = 0;
74 need_restart = 0;
71 /* 75 /*
72 * Read and write to /dev/tty if available. If not, read from 76 * Read and write to /dev/tty if available. If not, read from
73 * stdin and write to stderr unless a tty is required. 77 * stdin and write to stderr unless a tty is required.
@@ -117,26 +121,30 @@ restart:
117 oterm.c_lflag |= ECHO; 121 oterm.c_lflag |= ECHO;
118 } 122 }
119 123
120 if (!(flags & RPP_STDIN)) 124 /* No I/O if we are already backgrounded. */
121 (void)write(output, prompt, strlen(prompt)); 125 if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) {
122 end = buf + bufsiz - 1; 126 if (!(flags & RPP_STDIN))
123 for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { 127 (void)write(output, prompt, strlen(prompt));
124 if (p < end) { 128 end = buf + bufsiz - 1;
125 if ((flags & RPP_SEVENBIT)) 129 p = buf;
126 ch &= 0x7f; 130 while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') {
127 if (isalpha(ch)) { 131 if (p < end) {
128 if ((flags & RPP_FORCELOWER)) 132 if ((flags & RPP_SEVENBIT))
129 ch = tolower(ch); 133 ch &= 0x7f;
130 if ((flags & RPP_FORCEUPPER)) 134 if (isalpha(ch)) {
131 ch = toupper(ch); 135 if ((flags & RPP_FORCELOWER))
136 ch = (char)tolower(ch);
137 if ((flags & RPP_FORCEUPPER))
138 ch = (char)toupper(ch);
139 }
140 *p++ = ch;
132 } 141 }
133 *p++ = ch;
134 } 142 }
143 *p = '\0';
144 save_errno = errno;
145 if (!(term.c_lflag & ECHO))
146 (void)write(output, "\n", 1);
135 } 147 }
136 *p = '\0';
137 save_errno = errno;
138 if (!(term.c_lflag & ECHO))
139 (void)write(output, "\n", 1);
140 148
141 /* Restore old terminal settings and signals. */ 149 /* Restore old terminal settings and signals. */
142 if (memcmp(&term, &oterm, sizeof(term)) != 0) { 150 if (memcmp(&term, &oterm, sizeof(term)) != 0) {
@@ -152,6 +160,7 @@ restart:
152 (void)sigaction(SIGTERM, &saveterm, NULL); 160 (void)sigaction(SIGTERM, &saveterm, NULL);
153 (void)sigaction(SIGTSTP, &savetstp, NULL); 161 (void)sigaction(SIGTSTP, &savetstp, NULL);
154 (void)sigaction(SIGTTIN, &savettin, NULL); 162 (void)sigaction(SIGTTIN, &savettin, NULL);
163 (void)sigaction(SIGTTOU, &savettou, NULL);
155 if (input != STDIN_FILENO) 164 if (input != STDIN_FILENO)
156 (void)close(input); 165 (void)close(input);
157 166
@@ -159,20 +168,25 @@ restart:
159 * If we were interrupted by a signal, resend it to ourselves 168 * If we were interrupted by a signal, resend it to ourselves
160 * now that we have restored the signal handlers. 169 * now that we have restored the signal handlers.
161 */ 170 */
162 if (signo) { 171 for (i = 0; i < _NSIG; i++) {
163 kill(getpid(), signo); 172 if (signo[i]) {
164 switch (signo) { 173 kill(getpid(), i);
165 case SIGTSTP: 174 switch (i) {
166 case SIGTTIN: 175 case SIGTSTP:
167 case SIGTTOU: 176 case SIGTTIN:
168 goto restart; 177 case SIGTTOU:
178 need_restart = 1;
179 }
169 } 180 }
170 } 181 }
182 if (need_restart)
183 goto restart;
171 184
172 errno = save_errno; 185 if (save_errno)
186 errno = save_errno;
173 return(nr == -1 ? NULL : buf); 187 return(nr == -1 ? NULL : buf);
174} 188}
175 189
176#if 0 190#if 0
177char * 191char *
178getpass(const char *prompt) 192getpass(const char *prompt)
@@ -186,6 +200,6 @@ getpass(const char *prompt)
186static void handler(int s) 200static void handler(int s)
187{ 201{
188 202
189 signo = s; 203 signo[s] = 1;
190} 204}
191#endif /* HAVE_READPASSPHRASE */ 205#endif /* HAVE_READPASSPHRASE */