summaryrefslogtreecommitdiff
path: root/readpass.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2011-01-06 22:43:44 +1100
committerDamien Miller <djm@mindrot.org>2011-01-06 22:43:44 +1100
commit106079c06d308f6fb3b582607f590b2dcb4682b0 (patch)
tree99be677ace30c4fbec794652b18bbb2a0e2f3620 /readpass.c
parent05c8997b33cf391784d6a5f9f0d85d275dcf7ce5 (diff)
- djm@cvs.openbsd.org 2010/12/15 00:49:27
[readpass.c] fix ControlMaster=ask regression reset SIGCHLD handler before fork (and restore it after) so we don't miss the the askpass child's exit status. Correct test for exit status/signal to account for waitpid() failure; with claudio@ ok claudio@ markus@
Diffstat (limited to 'readpass.c')
-rw-r--r--readpass.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/readpass.c b/readpass.c
index bd144c2e3..599c8ef9a 100644
--- a/readpass.c
+++ b/readpass.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readpass.c,v 1.47 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: readpass.c,v 1.48 2010/12/15 00:49:27 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -33,6 +33,7 @@
33#ifdef HAVE_PATHS_H 33#ifdef HAVE_PATHS_H
34# include <paths.h> 34# include <paths.h>
35#endif 35#endif
36#include <signal.h>
36#include <stdarg.h> 37#include <stdarg.h>
37#include <stdio.h> 38#include <stdio.h>
38#include <stdlib.h> 39#include <stdlib.h>
@@ -49,11 +50,12 @@
49static char * 50static char *
50ssh_askpass(char *askpass, const char *msg) 51ssh_askpass(char *askpass, const char *msg)
51{ 52{
52 pid_t pid; 53 pid_t pid, ret;
53 size_t len; 54 size_t len;
54 char *pass; 55 char *pass;
55 int p[2], status, ret; 56 int p[2], status;
56 char buf[1024]; 57 char buf[1024];
58 void (*osigchld)(int);
57 59
58 if (fflush(stdout) != 0) 60 if (fflush(stdout) != 0)
59 error("ssh_askpass: fflush: %s", strerror(errno)); 61 error("ssh_askpass: fflush: %s", strerror(errno));
@@ -63,8 +65,10 @@ ssh_askpass(char *askpass, const char *msg)
63 error("ssh_askpass: pipe: %s", strerror(errno)); 65 error("ssh_askpass: pipe: %s", strerror(errno));
64 return NULL; 66 return NULL;
65 } 67 }
68 osigchld = signal(SIGCHLD, SIG_DFL);
66 if ((pid = fork()) < 0) { 69 if ((pid = fork()) < 0) {
67 error("ssh_askpass: fork: %s", strerror(errno)); 70 error("ssh_askpass: fork: %s", strerror(errno));
71 signal(SIGCHLD, osigchld);
68 return NULL; 72 return NULL;
69 } 73 }
70 if (pid == 0) { 74 if (pid == 0) {
@@ -77,23 +81,24 @@ ssh_askpass(char *askpass, const char *msg)
77 } 81 }
78 close(p[1]); 82 close(p[1]);
79 83
80 len = ret = 0; 84 len = 0;
81 do { 85 do {
82 ret = read(p[0], buf + len, sizeof(buf) - 1 - len); 86 ssize_t r = read(p[0], buf + len, sizeof(buf) - 1 - len);
83 if (ret == -1 && errno == EINTR) 87
88 if (r == -1 && errno == EINTR)
84 continue; 89 continue;
85 if (ret <= 0) 90 if (r <= 0)
86 break; 91 break;
87 len += ret; 92 len += r;
88 } while (sizeof(buf) - 1 - len > 0); 93 } while (sizeof(buf) - 1 - len > 0);
89 buf[len] = '\0'; 94 buf[len] = '\0';
90 95
91 close(p[0]); 96 close(p[0]);
92 while (waitpid(pid, &status, 0) < 0) 97 while ((ret = waitpid(pid, &status, 0)) < 0)
93 if (errno != EINTR) 98 if (errno != EINTR)
94 break; 99 break;
95 100 signal(SIGCHLD, osigchld);
96 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 101 if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
97 memset(buf, 0, sizeof(buf)); 102 memset(buf, 0, sizeof(buf));
98 return NULL; 103 return NULL;
99 } 104 }