diff options
Diffstat (limited to 'linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndegd.c')
-rw-r--r--[-rwxr-xr-x] | linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndegd.c | 512 |
1 files changed, 256 insertions, 256 deletions
diff --git a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndegd.c b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndegd.c index 2b7c6be..29b48e8 100755..100644 --- a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndegd.c +++ b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndegd.c | |||
@@ -1,256 +1,256 @@ | |||
1 | /* rndegd.c - interface to the EGD | 1 | /* rndegd.c - interface to the EGD |
2 | * Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc. | 2 | * Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc. |
3 | * | 3 | * |
4 | * This file is part of Libgcrypt. | 4 | * This file is part of Libgcrypt. |
5 | * | 5 | * |
6 | * Libgcrypt is free software; you can redistribute it and/or modify | 6 | * Libgcrypt is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU Lesser General Public License as | 7 | * it under the terms of the GNU Lesser General Public License as |
8 | * published by the Free Software Foundation; either version 2.1 of | 8 | * published by the Free Software Foundation; either version 2.1 of |
9 | * the License, or (at your option) any later version. | 9 | * the License, or (at your option) any later version. |
10 | * | 10 | * |
11 | * Libgcrypt is distributed in the hope that it will be useful, | 11 | * Libgcrypt is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU Lesser General Public License for more details. | 14 | * GNU Lesser General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU Lesser General Public | 16 | * You should have received a copy of the GNU Lesser General Public |
17 | * License along with this program; if not, write to the Free Software | 17 | * License along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <config.h> | 21 | #include <config.h> |
22 | #include <stdio.h> | 22 | #include <stdio.h> |
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | #include <assert.h> | 24 | #include <assert.h> |
25 | #include <errno.h> | 25 | #include <errno.h> |
26 | #include <sys/time.h> | 26 | #include <sys/time.h> |
27 | #include <sys/stat.h> | 27 | #include <sys/stat.h> |
28 | #include <string.h> | 28 | #include <string.h> |
29 | #include <unistd.h> | 29 | #include <unistd.h> |
30 | #include <sys/types.h> | 30 | #include <sys/types.h> |
31 | #include <sys/socket.h> | 31 | #include <sys/socket.h> |
32 | #include <sys/un.h> | 32 | #include <sys/un.h> |
33 | #include "types.h" | 33 | #include "types.h" |
34 | #include "g10lib.h" | 34 | #include "g10lib.h" |
35 | #include "cipher.h" | 35 | #include "cipher.h" |
36 | #include "rand-internal.h" | 36 | #include "rand-internal.h" |
37 | 37 | ||
38 | #ifndef offsetof | 38 | #ifndef offsetof |
39 | #define offsetof(type, member) ((size_t) &((type *)0)->member) | 39 | #define offsetof(type, member) ((size_t) &((type *)0)->member) |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | static int egd_socket = -1; | 42 | static int egd_socket = -1; |
43 | 43 | ||
44 | /* Allocate a new filename from FIRST_PART and SECOND_PART and to | 44 | /* Allocate a new filename from FIRST_PART and SECOND_PART and to |
45 | tilde expansion for first_part. SECOND_PART might be NULL. | 45 | tilde expansion for first_part. SECOND_PART might be NULL. |
46 | */ | 46 | */ |
47 | static char * | 47 | static char * |
48 | my_make_filename (const char *first_part, const char *second_part) | 48 | my_make_filename (const char *first_part, const char *second_part) |
49 | { | 49 | { |
50 | size_t n; | 50 | size_t n; |
51 | char *name, *home, *p; | 51 | char *name, *home, *p; |
52 | 52 | ||
53 | n = strlen(first_part)+1; | 53 | n = strlen(first_part)+1; |
54 | if (second_part) | 54 | if (second_part) |
55 | n += strlen (second_part) + 1; | 55 | n += strlen (second_part) + 1; |
56 | 56 | ||
57 | home = NULL; | 57 | home = NULL; |
58 | if( *first_part == '~' && first_part[1] == '/' | 58 | if( *first_part == '~' && first_part[1] == '/' |
59 | && (home = getenv("HOME")) && *home ) | 59 | && (home = getenv("HOME")) && *home ) |
60 | n += strlen(home); | 60 | n += strlen(home); |
61 | 61 | ||
62 | name = gcry_xmalloc(n); | 62 | name = gcry_xmalloc(n); |
63 | p = (home | 63 | p = (home |
64 | ? stpcpy (stpcpy (name, home), first_part+1 ) | 64 | ? stpcpy (stpcpy (name, home), first_part+1 ) |
65 | : stpcpy (name, first_part) ); | 65 | : stpcpy (name, first_part) ); |
66 | 66 | ||
67 | if (second_part) | 67 | if (second_part) |
68 | strcpy (stpcpy(p,"/"), second_part); | 68 | strcpy (stpcpy(p,"/"), second_part); |
69 | 69 | ||
70 | return name; | 70 | return name; |
71 | } | 71 | } |
72 | 72 | ||
73 | 73 | ||
74 | static int | 74 | static int |
75 | do_write( int fd, void *buf, size_t nbytes ) | 75 | do_write( int fd, void *buf, size_t nbytes ) |
76 | { | 76 | { |
77 | size_t nleft = nbytes; | 77 | size_t nleft = nbytes; |
78 | int nwritten; | 78 | int nwritten; |
79 | 79 | ||
80 | while( nleft > 0 ) | 80 | while( nleft > 0 ) |
81 | { | 81 | { |
82 | nwritten = write( fd, buf, nleft); | 82 | nwritten = write( fd, buf, nleft); |
83 | if( nwritten < 0 ) | 83 | if( nwritten < 0 ) |
84 | { | 84 | { |
85 | if( errno == EINTR ) | 85 | if( errno == EINTR ) |
86 | continue; | 86 | continue; |
87 | return -1; | 87 | return -1; |
88 | } | 88 | } |
89 | nleft -= nwritten; | 89 | nleft -= nwritten; |
90 | buf = (char*)buf + nwritten; | 90 | buf = (char*)buf + nwritten; |
91 | } | 91 | } |
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | static int | 95 | static int |
96 | do_read( int fd, void *buf, size_t nbytes ) | 96 | do_read( int fd, void *buf, size_t nbytes ) |
97 | { | 97 | { |
98 | int n, nread = 0; | 98 | int n, nread = 0; |
99 | 99 | ||
100 | do | 100 | do |
101 | { | 101 | { |
102 | do | 102 | do |
103 | { | 103 | { |
104 | n = read(fd, (char*)buf + nread, nbytes ); | 104 | n = read(fd, (char*)buf + nread, nbytes ); |
105 | } | 105 | } |
106 | while( n == -1 && errno == EINTR ); | 106 | while( n == -1 && errno == EINTR ); |
107 | if( n == -1) | 107 | if( n == -1) |
108 | return nread? nread:-1; | 108 | return nread? nread:-1; |
109 | if( n == 0) | 109 | if( n == 0) |
110 | return -1; | 110 | return -1; |
111 | nread += n; | 111 | nread += n; |
112 | nbytes -= n; | 112 | nbytes -= n; |
113 | } | 113 | } |
114 | while( nread < nbytes ); | 114 | while( nread < nbytes ); |
115 | return nread; | 115 | return nread; |
116 | } | 116 | } |
117 | 117 | ||
118 | 118 | ||
119 | /* Connect to the EGD and return the file descriptor. Return -1 on | 119 | /* Connect to the EGD and return the file descriptor. Return -1 on |
120 | error. With NOFAIL set to true, silently fail and return the | 120 | error. With NOFAIL set to true, silently fail and return the |
121 | error, otherwise print an error message and die. */ | 121 | error, otherwise print an error message and die. */ |
122 | int | 122 | int |
123 | _gcry_rndegd_connect_socket (int nofail) | 123 | _gcry_rndegd_connect_socket (int nofail) |
124 | { | 124 | { |
125 | int fd; | 125 | int fd; |
126 | const char *bname = NULL; | 126 | const char *bname = NULL; |
127 | char *name; | 127 | char *name; |
128 | struct sockaddr_un addr; | 128 | struct sockaddr_un addr; |
129 | int addr_len; | 129 | int addr_len; |
130 | 130 | ||
131 | if (egd_socket != -1) | 131 | if (egd_socket != -1) |
132 | { | 132 | { |
133 | close (egd_socket); | 133 | close (egd_socket); |
134 | egd_socket = -1; | 134 | egd_socket = -1; |
135 | } | 135 | } |
136 | 136 | ||
137 | #ifdef EGD_SOCKET_NAME | 137 | #ifdef EGD_SOCKET_NAME |
138 | bname = EGD_SOCKET_NAME; | 138 | bname = EGD_SOCKET_NAME; |
139 | #endif | 139 | #endif |
140 | if ( !bname || !*bname ) | 140 | if ( !bname || !*bname ) |
141 | name = my_make_filename ("~/.gnupg", "entropy"); | 141 | name = my_make_filename ("~/.gnupg", "entropy"); |
142 | else | 142 | else |
143 | name = my_make_filename (bname, NULL); | 143 | name = my_make_filename (bname, NULL); |
144 | 144 | ||
145 | if (strlen(name)+1 >= sizeof addr.sun_path) | 145 | if (strlen(name)+1 >= sizeof addr.sun_path) |
146 | log_fatal ("EGD socketname is too long\n"); | 146 | log_fatal ("EGD socketname is too long\n"); |
147 | 147 | ||
148 | memset( &addr, 0, sizeof addr ); | 148 | memset( &addr, 0, sizeof addr ); |
149 | addr.sun_family = AF_UNIX; | 149 | addr.sun_family = AF_UNIX; |
150 | strcpy( addr.sun_path, name ); | 150 | strcpy( addr.sun_path, name ); |
151 | addr_len = (offsetof( struct sockaddr_un, sun_path ) | 151 | addr_len = (offsetof( struct sockaddr_un, sun_path ) |
152 | + strlen( addr.sun_path )); | 152 | + strlen( addr.sun_path )); |
153 | 153 | ||
154 | fd = socket(AF_UNIX, SOCK_STREAM, 0); | 154 | fd = socket(AF_UNIX, SOCK_STREAM, 0); |
155 | if (fd == -1 && !nofail) | 155 | if (fd == -1 && !nofail) |
156 | log_fatal("can't create unix domain socket: %s\n", strerror(errno) ); | 156 | log_fatal("can't create unix domain socket: %s\n", strerror(errno) ); |
157 | else if (connect (fd, (struct sockaddr*)&addr, addr_len) == -1) | 157 | else if (connect (fd, (struct sockaddr*)&addr, addr_len) == -1) |
158 | { | 158 | { |
159 | if (!nofail) | 159 | if (!nofail) |
160 | log_fatal("can't connect to EGD socket `%s': %s\n", | 160 | log_fatal("can't connect to EGD socket `%s': %s\n", |
161 | name, strerror(errno) ); | 161 | name, strerror(errno) ); |
162 | close (fd); | 162 | close (fd); |
163 | fd = -1; | 163 | fd = -1; |
164 | } | 164 | } |
165 | gcry_free(name); | 165 | gcry_free(name); |
166 | if (fd != -1) | 166 | if (fd != -1) |
167 | egd_socket = fd; | 167 | egd_socket = fd; |
168 | return fd; | 168 | return fd; |
169 | } | 169 | } |
170 | 170 | ||
171 | /**************** | 171 | /**************** |
172 | * Note: We always use the highest level. | 172 | * Note: We always use the highest level. |
173 | * To boost the performance we may want to add some | 173 | * To boost the performance we may want to add some |
174 | * additional code for level 1 | 174 | * additional code for level 1 |
175 | * | 175 | * |
176 | * Using a level of 0 should never block and better add nothing | 176 | * Using a level of 0 should never block and better add nothing |
177 | * to the pool. So this is just a dummy for EGD. | 177 | * to the pool. So this is just a dummy for EGD. |
178 | */ | 178 | */ |
179 | int | 179 | int |
180 | _gcry_rndegd_gather_random (void (*add)(const void*, size_t, int), | 180 | _gcry_rndegd_gather_random (void (*add)(const void*, size_t, int), |
181 | int requester, | 181 | int requester, |
182 | size_t length, int level ) | 182 | size_t length, int level ) |
183 | { | 183 | { |
184 | int fd = egd_socket; | 184 | int fd = egd_socket; |
185 | int n; | 185 | int n; |
186 | byte buffer[256+2]; | 186 | byte buffer[256+2]; |
187 | int nbytes; | 187 | int nbytes; |
188 | int do_restart = 0; | 188 | int do_restart = 0; |
189 | 189 | ||
190 | if( !length ) | 190 | if( !length ) |
191 | return 0; | 191 | return 0; |
192 | if( !level ) | 192 | if( !level ) |
193 | return 0; | 193 | return 0; |
194 | 194 | ||
195 | restart: | 195 | restart: |
196 | if (fd == -1 || do_restart) | 196 | if (fd == -1 || do_restart) |
197 | fd = _gcry_rndegd_connect_socket (0); | 197 | fd = _gcry_rndegd_connect_socket (0); |
198 | 198 | ||
199 | do_restart = 0; | 199 | do_restart = 0; |
200 | 200 | ||
201 | nbytes = length < 255? length : 255; | 201 | nbytes = length < 255? length : 255; |
202 | /* First time we do it with a non blocking request */ | 202 | /* First time we do it with a non blocking request */ |
203 | buffer[0] = 1; /* non blocking */ | 203 | buffer[0] = 1; /* non blocking */ |
204 | buffer[1] = nbytes; | 204 | buffer[1] = nbytes; |
205 | if( do_write( fd, buffer, 2 ) == -1 ) | 205 | if( do_write( fd, buffer, 2 ) == -1 ) |
206 | log_fatal("can't write to the EGD: %s\n", strerror(errno) ); | 206 | log_fatal("can't write to the EGD: %s\n", strerror(errno) ); |
207 | n = do_read( fd, buffer, 1 ); | 207 | n = do_read( fd, buffer, 1 ); |
208 | if( n == -1 ) | 208 | if( n == -1 ) |
209 | { | 209 | { |
210 | log_error("read error on EGD: %s\n", strerror(errno)); | 210 | log_error("read error on EGD: %s\n", strerror(errno)); |
211 | do_restart = 1; | 211 | do_restart = 1; |
212 | goto restart; | 212 | goto restart; |
213 | } | 213 | } |
214 | n = buffer[0]; | 214 | n = buffer[0]; |
215 | if( n ) | 215 | if( n ) |
216 | { | 216 | { |
217 | n = do_read( fd, buffer, n ); | 217 | n = do_read( fd, buffer, n ); |
218 | if( n == -1 ) | 218 | if( n == -1 ) |
219 | { | 219 | { |
220 | log_error("read error on EGD: %s\n", strerror(errno)); | 220 | log_error("read error on EGD: %s\n", strerror(errno)); |
221 | do_restart = 1; | 221 | do_restart = 1; |
222 | goto restart; | 222 | goto restart; |
223 | } | 223 | } |
224 | (*add)( buffer, n, requester ); | 224 | (*add)( buffer, n, requester ); |
225 | length -= n; | 225 | length -= n; |
226 | } | 226 | } |
227 | 227 | ||
228 | if( length ) | 228 | if( length ) |
229 | { | 229 | { |
230 | log_info ( | 230 | log_info ( |
231 | _("Please wait, entropy is being gathered. Do some work if it would\n" | 231 | _("Please wait, entropy is being gathered. Do some work if it would\n" |
232 | "keep you from getting bored, because it will improve the quality\n" | 232 | "keep you from getting bored, because it will improve the quality\n" |
233 | "of the entropy.\n") ); | 233 | "of the entropy.\n") ); |
234 | } | 234 | } |
235 | while( length ) | 235 | while( length ) |
236 | { | 236 | { |
237 | nbytes = length < 255? length : 255; | 237 | nbytes = length < 255? length : 255; |
238 | 238 | ||
239 | buffer[0] = 2; /* blocking */ | 239 | buffer[0] = 2; /* blocking */ |
240 | buffer[1] = nbytes; | 240 | buffer[1] = nbytes; |
241 | if( do_write( fd, buffer, 2 ) == -1 ) | 241 | if( do_write( fd, buffer, 2 ) == -1 ) |
242 | log_fatal("can't write to the EGD: %s\n", strerror(errno) ); | 242 | log_fatal("can't write to the EGD: %s\n", strerror(errno) ); |
243 | n = do_read( fd, buffer, nbytes ); | 243 | n = do_read( fd, buffer, nbytes ); |
244 | if( n == -1 ) | 244 | if( n == -1 ) |
245 | { | 245 | { |
246 | log_error("read error on EGD: %s\n", strerror(errno)); | 246 | log_error("read error on EGD: %s\n", strerror(errno)); |
247 | do_restart = 1; | 247 | do_restart = 1; |
248 | goto restart; | 248 | goto restart; |
249 | } | 249 | } |
250 | (*add)( buffer, n, requester ); | 250 | (*add)( buffer, n, requester ); |
251 | length -= n; | 251 | length -= n; |
252 | } | 252 | } |
253 | memset(buffer, 0, sizeof(buffer) ); | 253 | memset(buffer, 0, sizeof(buffer) ); |
254 | 254 | ||
255 | return 0; /* success */ | 255 | return 0; /* success */ |
256 | } | 256 | } |