summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2001-02-18 12:44:29 +1100
committerDamien Miller <djm@mindrot.org>2001-02-18 12:44:29 +1100
commitb3ffc5f1d4f630521e5ad4787db1f691942b8592 (patch)
treed8cbdaf9d62d1311985294b9075d140a9b318f22
parent0a4e27d5832a6a2d0fdaff4a169d0c216b37eeee (diff)
- (djm) Robustify EGD/PRNGd code in face of socket closures. Patch from
Todd C. Miller <Todd.Miller@courtesan.com>
-rw-r--r--ChangeLog4
-rw-r--r--entropy.c41
2 files changed, 32 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 4450f48ac..b0da442c9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,8 @@
7 <vinschen@redhat.com> and myself. 7 <vinschen@redhat.com> and myself.
8 - (djm) Close listen_sock on bind() failures. Patch from Arkadiusz 8 - (djm) Close listen_sock on bind() failures. Patch from Arkadiusz
9 Miskiewicz <misiek@pld.ORG.PL> 9 Miskiewicz <misiek@pld.ORG.PL>
10 - (djm) Robustify EGD/PRNGd code in face of socket closures. Patch from
11 Todd C. Miller <Todd.Miller@courtesan.com>
10 12
1120010217 1320010217
12 - (bal) OpenBSD Sync: 14 - (bal) OpenBSD Sync:
@@ -4014,4 +4016,4 @@
4014 - Wrote replacements for strlcpy and mkdtemp 4016 - Wrote replacements for strlcpy and mkdtemp
4015 - Released 1.0pre1 4017 - Released 1.0pre1
4016 4018
4017$Id: ChangeLog,v 1.786 2001/02/18 01:36:39 djm Exp $ 4019$Id: ChangeLog,v 1.787 2001/02/18 01:44:29 djm Exp $
diff --git a/entropy.c b/entropy.c
index 2e71f5f5a..fb81d7822 100644
--- a/entropy.c
+++ b/entropy.c
@@ -38,7 +38,7 @@
38#include "pathnames.h" 38#include "pathnames.h"
39#include "log.h" 39#include "log.h"
40 40
41RCSID("$Id: entropy.c,v 1.26 2001/02/05 12:42:17 stevesk Exp $"); 41RCSID("$Id: entropy.c,v 1.27 2001/02/18 01:44:29 djm Exp $");
42 42
43#ifndef offsetof 43#ifndef offsetof
44# define offsetof(type, member) ((size_t) &((type *)0)->member) 44# define offsetof(type, member) ((size_t) &((type *)0)->member)
@@ -71,7 +71,8 @@ int get_random_bytes(unsigned char *buf, int len)
71 int fd; 71 int fd;
72 char msg[2]; 72 char msg[2];
73 struct sockaddr_un addr; 73 struct sockaddr_un addr;
74 int addr_len; 74 int addr_len, rval, errors;
75 struct sigaction nsa, osa;
75 76
76 /* Sanity checks */ 77 /* Sanity checks */
77 if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path)) 78 if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path))
@@ -84,17 +85,22 @@ int get_random_bytes(unsigned char *buf, int len)
84 strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path)); 85 strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path));
85 addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET); 86 addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET);
86 87
88 memset(&nsa, 0, sizeof(nsa));
89 nsa.sa_handler = SIG_IGN;
90 (void) sigaction(SIGPIPE, &nsa, &osa);
91
92 errors = rval = 0;
93reopen:
87 fd = socket(AF_UNIX, SOCK_STREAM, 0); 94 fd = socket(AF_UNIX, SOCK_STREAM, 0);
88 if (fd == -1) { 95 if (fd == -1) {
89 error("Couldn't create AF_UNIX socket: %s", strerror(errno)); 96 error("Couldn't create AF_UNIX socket: %s", strerror(errno));
90 return(0); 97 goto done;
91 } 98 }
92 99
93 if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) { 100 if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) {
94 error("Couldn't connect to EGD socket \"%s\": %s", 101 error("Couldn't connect to EGD socket \"%s\": %s",
95 addr.sun_path, strerror(errno)); 102 addr.sun_path, strerror(errno));
96 close(fd); 103 goto done;
97 return(0);
98 } 104 }
99 105
100 /* Send blocking read request to EGD */ 106 /* Send blocking read request to EGD */
@@ -102,22 +108,33 @@ int get_random_bytes(unsigned char *buf, int len)
102 msg[1] = len; 108 msg[1] = len;
103 109
104 if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) { 110 if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) {
111 if (errno == EPIPE && errors < 10) {
112 close(fd);
113 errors++;
114 goto reopen;
115 }
105 error("Couldn't write to EGD socket \"%s\": %s", 116 error("Couldn't write to EGD socket \"%s\": %s",
106 EGD_SOCKET, strerror(errno)); 117 EGD_SOCKET, strerror(errno));
107 close(fd); 118 goto done;
108 return(0);
109 } 119 }
110 120
111 if (atomicio(read, fd, buf, len) != len) { 121 if (atomicio(read, fd, buf, len) != len) {
122 if (errno == EPIPE && errors < 10) {
123 close(fd);
124 errors++;
125 goto reopen;
126 }
112 error("Couldn't read from EGD socket \"%s\": %s", 127 error("Couldn't read from EGD socket \"%s\": %s",
113 EGD_SOCKET, strerror(errno)); 128 EGD_SOCKET, strerror(errno));
114 close(fd); 129 goto done;
115 return(0);
116 } 130 }
117 131
118 close(fd); 132 rval = 1;
119 133done:
120 return(1); 134 (void) sigaction(SIGPIPE, &osa, NULL);
135 if (fd != -1)
136 close(fd);
137 return(rval);
121} 138}
122#else /* !EGD_SOCKET */ 139#else /* !EGD_SOCKET */
123#ifdef RANDOM_POOL 140#ifdef RANDOM_POOL