1 /****************************************************************************
2  *									    *
3  *									    *
4  *   Unix Randomness-Gathering Code					    *
5  *									    *
6  *   Copyright Peter Gutmann, Paul Kendall, and Chris Wedgwood 1996-1999.   *
7  *   Heavily modified for GnuPG by Werner Koch				    *
8  *									    *
9  *									    *
10  ****************************************************************************/
11 
12 /* This module is part of the cryptlib continuously seeded pseudorandom
13    number generator.  For usage conditions, see lib_rand.c
14 
15    [Here is the notice from lib_rand.c:]
16 
17    This module and the misc/rnd*.c modules represent the cryptlib
18    continuously seeded pseudorandom number generator (CSPRNG) as described in
19    my 1998 Usenix Security Symposium paper "The generation of random numbers
20    for cryptographic purposes".
21 
22    The CSPRNG code is copyright Peter Gutmann (and various others) 1996,
23    1997, 1998, 1999, all rights reserved.  Redistribution of the CSPRNG
24    modules and use in source and binary forms, with or without modification,
25    are permitted provided that the following conditions are met:
26 
27    1. Redistributions of source code must retain the above copyright notice
28       and this permission notice in its entirety.
29 
30    2. Redistributions in binary form must reproduce the copyright notice in
31       the documentation and/or other materials provided with the distribution.
32 
33    3. A copy of any bugfixes or enhancements made must be provided to the
34       author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the
35       baseline version of the code.
36 
37   ALTERNATIVELY, the code may be distributed under the terms of the
38   GNU Lesser General Public License, version 2.1 or any later version
39   published by the Free Software Foundation, in which case the
40   provisions of the GNU LGPL are required INSTEAD OF the above
41   restrictions.
42 
43   Although not required under the terms of the LGPL, it would still be
44   nice if you could make any changes available to the author to allow
45   a consistent code base to be maintained.  */
46 /*************************************************************************
47  The above alternative was changed from GPL to LGPL on 2007-08-22 with
48  permission from Peter Gutmann:
49  ==========
50  From: pgut001 <pgut001@cs.auckland.ac.nz>
51  Subject: Re: LGPL for the windows entropy gatherer
52  To: wk@gnupg.org
53  Date: Wed, 22 Aug 2007 03:05:42 +1200
54 
55  Hi,
56 
57  >As of now libgcrypt is GPL under Windows due to that module and some people
58  >would really like to see it under LGPL too.  Can you do such a license change
59  >to LGPL version 2?  Note that LGPL give the user the option to relicense it
60  >under GPL, so the change would be pretty easy and backwar compatible.
61 
62  Sure.  I assumed that since GPG was GPLd, you'd prefer the GPL for the entropy
63  code as well, but Ian asked for LGPL as an option so as of the next release
64  I'll have LGPL in there.  You can consider it to be retroactive, so your
65  current version will be LGPLd as well.
66 
67  Peter.
68  ==========
69  From: pgut001 <pgut001@cs.auckland.ac.nz>
70  Subject: Re: LGPL for the windows entropy gatherer
71  To: wk@gnupg.org
72  Date: Wed, 22 Aug 2007 20:50:08 +1200
73 
74  >Would you mind to extend this also to the Unix entropy gatherer which is
75  >still used on systems without /dev/random and when EGD is not installed? That
76  >would be the last GPLed piece in Libgcrypt.
77 
78  Sure, it covers the entire entropy-gathering subsystem.
79 
80  Peter.
81  =========
82 */
83 
84 /* General includes */
85 
86 #include <config.h>
87 #include <stdlib.h>
88 #include <stdio.h>
89 #ifdef HAVE_STDINT_H
90 # include <stdint.h>
91 #endif
92 #include <string.h>
93 
94 /* OS-specific includes */
95 
96 #ifdef __osf__
97   /* Somewhere in the morass of system-specific cruft which OSF/1 pulls in
98    * via the following includes are various endianness defines, so we
99    * undefine the cryptlib ones, which aren't really needed for this module
100    * anyway */
101 #undef BIG_ENDIAN
102 #undef LITTLE_ENDIAN
103 #endif				/* __osf__ */
104 
105 #include <unistd.h>
106 #include <fcntl.h>
107 #include <pwd.h>
108 #ifndef __QNX__
109 #include <sys/errno.h>
110 #include <sys/ipc.h>
111 #endif				/* __QNX__ */
112 #include <sys/time.h>		/* SCO and SunOS need this before resource.h */
113 #ifndef __QNX__
114 #include <sys/resource.h>
115 #endif				/* __QNX__ */
116 #if defined( _AIX ) || defined( __QNX__ )
117 #include <sys/select.h>
118 #endif				/* _AIX */
119 #ifndef __QNX__
120 #include <sys/shm.h>
121 #include <signal.h>
122 #include <sys/signal.h>
123 #endif				/* __QNX__ */
124 #include <sys/stat.h>
125 #include <sys/types.h>		/* Verschiedene komische Typen */
126 #if defined( __hpux ) && ( OS_VERSION == 9 )
127 #include <vfork.h>
128 #endif				/* __hpux 9.x, after that it's in unistd.h */
129 #include <sys/wait.h>
130 /* #include <kitchensink.h> */
131 #ifdef __QNX__
132 #include <signal.h>
133 #include <process.h>
134 #endif		      /* __QNX__ */
135 #include <errno.h>
136 
137 #include "types.h"  /* for byte and u32 typedefs */
138 #include "g10lib.h"
139 #include "rand-internal.h"
140 
141 #ifndef EAGAIN
142 #define EAGAIN	EWOULDBLOCK
143 #endif
144 #ifndef STDIN_FILENO
145 #define STDIN_FILENO 0
146 #endif
147 #ifndef STDOUT_FILENO
148 #define STDOUT_FILENO 1
149 #endif
150 #ifndef STDERR_FILENO
151 #define STDERR_FILENO 2
152 #endif
153 
154 #define GATHER_BUFSIZE		49152	/* Usually about 25K are filled */
155 
156 /* The structure containing information on random-data sources.  Each
157  * record contains the source and a relative estimate of its usefulness
158  * (weighting) which is used to scale the number of kB of output from the
159  * source (total = data_bytes / usefulness).  Usually the weighting is in the
160  * range 1-3 (or 0 for especially useless sources), resulting in a usefulness
161  * rating of 1...3 for each kB of source output (or 0 for the useless
162  * sources).
163  *
164  * If the source is constantly changing (certain types of network statistics
165  * have this characteristic) but the amount of output is small, the weighting
166  * is given as a negative value to indicate that the output should be treated
167  * as if a minimum of 1K of output had been obtained.  If the source produces
168  * a lot of output then the scale factor is fractional, resulting in a
169  * usefulness rating of < 1 for each kB of source output.
170  *
171  * In order to provide enough randomness to satisfy the requirements for a
172  * slow poll, we need to accumulate at least 20 points of usefulness (a
173  * typical system should get about 30 points).
174  *
175  * Some potential options are missed out because of special considerations.
176  * pstat -i and pstat -f can produce amazing amounts of output (the record
177  * is 600K on an Oracle server) which floods the buffer and doesn't yield
178  * anything useful (apart from perhaps increasing the entropy of the vmstat
179  * output a bit), so we don't bother with this.  pstat in general produces
180  * quite a bit of output, but it doesn't change much over time, so it gets
181  * very low weightings.  netstat -s produces constantly-changing output but
182  * also produces quite a bit of it, so it only gets a weighting of 2 rather
183  * than 3.  The same holds for netstat -in, which gets 1 rather than 2.
184  *
185  * Some binaries are stored in different locations on different systems so
186  * alternative paths are given for them.  The code sorts out which one to
187  * run by itself, once it finds an exectable somewhere it moves on to the
188  * next source.  The sources are arranged roughly in their order of
189  * usefulness, occasionally sources which provide a tiny amount of
190  * relatively useless data are placed ahead of ones which provide a large
191  * amount of possibly useful data because another 100 bytes can't hurt, and
192  * it means the buffer won't be swamped by one or two high-output sources.
193  * All the high-output sources are clustered towards the end of the list
194  * for this reason.  Some binaries are checked for in a certain order, for
195  * example under Slowaris /usr/ucb/ps understands aux as an arg, but the
196  * others don't.  Some systems have conditional defines enabling alternatives
197  * to commands which don't understand the usual options but will provide
198  * enough output (in the form of error messages) to look like they're the
199  * real thing, causing alternative options to be skipped (we can't check the
200  * return either because some commands return peculiar, non-zero status even
201  * when they're working correctly).
202  *
203  * In order to maximise use of the buffer, the code performs a form of run-
204  * length compression on its input where a repeated sequence of bytes is
205  * replaced by the occurrence count mod 256.  Some commands output an awful
206  * lot of whitespace, this measure greatly increases the amount of data we
207  * can fit in the buffer.
208  *
209  * When we scale the weighting using the SC() macro, some preprocessors may
210  * give a division by zero warning for the most obvious expression
211  * 'weight ? 1024 / weight : 0' (and gcc 2.7.2.2 dies with a division by zero
212  * trap), so we define a value SC_0 which evaluates to zero when fed to
213  * '1024 / SC_0' */
214 
215 #define SC( weight )	( 1024 / weight )	/* Scale factor */
216 #define SC_0			16384	/* SC( SC_0 ) evaluates to 0 */
217 
218 static struct RI {
219     const char *path;		/* Path to check for existence of source */
220     const char *arg;		/* Args for source */
221     const int usefulness;	/* Usefulness of source */
222     FILE *pipe; 		/* Pipe to source as FILE * */
223     int pipeFD; 		/* Pipe to source as FD */
224     pid_t pid;			/* pid of child for waitpid() */
225     int length; 		/* Quantity of output produced */
226     const int hasAlternative;	    /* Whether source has alt.location */
227 } dataSources[] = {
228 
229     {	"/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 1    },
230     {	"/usr/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 0},
231     {	"/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 1     },
232     {	"/usr/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 0},
233     {	"/usr/bin/pfstat", NULL, SC(-2), NULL, 0, 0, 0, 0},
234     {	"/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 1     },
235     {	"/usr/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 0},
236     {	"/usr/ucb/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
237     {	"/usr/bin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
238     {	"/usr/sbin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1},
239     {	"/usr/etc/netstat", "-s", SC(2), NULL, 0, 0, 0, 0},
240     {	"/usr/bin/nfsstat", NULL, SC(2), NULL, 0, 0, 0, 0},
241     {	"/usr/ucb/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1  },
242     {	"/usr/bin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1  },
243     {	"/usr/sbin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
244     {	"/usr/etc/netstat", "-m", SC(-1), NULL, 0, 0, 0, 0 },
245     {	"/bin/netstat",     "-in", SC(-1), NULL, 0, 0, 0, 1 },
246     {	"/usr/ucb/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
247     {	"/usr/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
248     {	"/usr/sbin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1},
249     {	"/usr/etc/netstat", "-in", SC(-1), NULL, 0, 0, 0, 0},
250     {	"/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.1.0",
251 				    SC(-1), NULL, 0, 0, 0, 0 }, /* UDP in */
252     {	"/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.4.0",
253 				    SC(-1), NULL, 0, 0, 0, 0 },  /* UDP out */
254     {	"/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.4.3.0",
255 				    SC(-1), NULL, 0, 0, 0, 0 }, /* IP ? */
256     {	"/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.10.0",
257 				    SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
258     {	"/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.11.0",
259 				    SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
260     {	"/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.13.0",
261 				    SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
262     {	"/usr/bin/mpstat", NULL, SC(1), NULL, 0, 0, 0, 0     },
263     {	"/usr/bin/w", NULL, SC(1), NULL, 0, 0, 0, 1           },
264     {	"/usr/bsd/w", NULL, SC(1), NULL, 0, 0, 0, 0          },
265     {	"/usr/bin/df", NULL, SC(1), NULL, 0, 0, 0, 1          },
266     {	"/bin/df", NULL, SC(1), NULL, 0, 0, 0, 0             },
267     {	"/usr/sbin/portstat", NULL, SC(1), NULL, 0, 0, 0, 0  },
268     {	"/usr/bin/iostat", NULL, SC(SC_0), NULL, 0, 0, 0, 0  },
269     {	"/usr/bin/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 1   },
270     {	"/usr/bsd/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 0  },
271     {	"/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 1       },
272     {	"/usr/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 0  },
273     {	"/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 1       },
274     {	"/usr/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 0  },
275     {	"/usr/ucb/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1   },
276     {	"/usr/bin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1   },
277     {	"/usr/sbin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1  },
278     {	"/usr/etc/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 0  },
279 #if defined( __sgi ) || defined( __hpux )
280     {	"/bin/ps", "-el", SC(0.3), NULL, 0, 0, 0, 1           },
281 #endif				/* __sgi || __hpux */
282     {	"/usr/ucb/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1       },
283     {	"/usr/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1       },
284     {	"/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 0          },
285     {   "/bin/ps", "-A", SC(0.3), NULL, 0, 0, 0, 0           }, /*QNX*/
286     {	"/usr/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 1      },
287     {	"/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 0         },
288     /* Unreliable source, depends on system usage */
289     {	"/etc/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 1         },
290     {	"/bin/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 0        },
291     {	"/etc/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 1         },
292     {	"/bin/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 0        },
293     {	"/etc/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 1         },
294     {	"/bin/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 0        },
295     {	"/etc/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 1         },
296     {	"/bin/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 0        },
297     {	"/etc/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 1         },
298     {	"/bin/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 0        },
299     /* pstat is your friend */
300     {	"/usr/bin/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 1   },
301 #ifdef __sgi
302     {	"/usr/bsd/last", "-50", SC(0.3), NULL, 0, 0, 0, 0    },
303 #endif				/* __sgi */
304 #ifdef __hpux
305     {	"/etc/last", "-50", SC(0.3), NULL, 0, 0, 0, 0        },
306 #endif				/* __hpux */
307     {	"/usr/bsd/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 0  },
308     {	"/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.1.0",
309 				SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
310     {	"/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.3.0",
311 				SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
312     {	"/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1  },
313     {	"/usr/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1  },
314     {	"/usr/bin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1  },
315     {	"/usr/sbin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 0 },
316     {	"/usr/sbin/ripquery", "-nw 1 127.0.0.1",
317 				SC(0.1), NULL, 0, 0, 0, 0 },
318     {	"/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1     },
319     {	"/usr/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
320     {	"/usr/ucb/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 0 },
321     {	"/usr/bin/tcpdump", "-c 5 -efvvx", SC(1), NULL, 0, 0, 0, 0 },
322     /* This is very environment-dependent.  If network traffic is low, it'll
323      * probably time out before delivering 5 packets, which is OK because
324      * it'll probably be fixed stuff like ARP anyway */
325     {	"/usr/sbin/advfsstat", "-b usr_domain",
326 				SC(SC_0), NULL, 0, 0, 0, 0},
327     {	"/usr/sbin/advfsstat", "-l 2 usr_domain",
328 				SC(0.5), NULL, 0, 0, 0, 0},
329     {	"/usr/sbin/advfsstat", "-p usr_domain",
330 				SC(SC_0), NULL, 0, 0, 0, 0},
331     /* This is a complex and screwball program.  Some systems have things
332      * like rX_dmn, x = integer, for RAID systems, but the statistics are
333      * pretty dodgy */
334 #ifdef __QNXNTO__
335     { "/bin/pidin", "-F%A%B%c%d%E%I%J%K%m%M%n%N%p%P%S%s%T", SC(0.3),
336              NULL, 0, 0, 0, 0       },
337 #endif
338 #if 0
339     /* The following aren't enabled since they're somewhat slow and not very
340      * unpredictable, however they give an indication of the sort of sources
341      * you can use (for example the finger might be more useful on a
342      * firewalled internal network) */
343     {	"/usr/bin/finger", "@ml.media.mit.edu", SC(0.9), NULL, 0, 0, 0, 0 },
344     {	"/usr/local/bin/wget", "-O - http://lavarand.sgi.com/block.html",
345 				SC(0.9), NULL, 0, 0, 0, 0 },
346     {	"/bin/cat", "/usr/spool/mqueue/syslog", SC(0.9), NULL, 0, 0, 0, 0 },
347 #endif				/* 0 */
348     {	NULL, NULL, 0, NULL, 0, 0, 0, 0 }
349 };
350 
351 static byte *gather_buffer;	    /* buffer for gathering random noise */
352 static int gather_buffer_size;	    /* size of the memory buffer */
353 static uid_t gatherer_uid;
354 
355 /* The message structure used to communicate with the parent */
356 typedef struct {
357     int  usefulness;	/* usefulness of data */
358     int  ndata; 	/* valid bytes in data */
359     char data[500];	/* gathered data */
360 } GATHER_MSG;
361 
362 #ifndef HAVE_WAITPID
363 static pid_t
waitpid(pid_t pid,int * statptr,int options)364 waitpid(pid_t pid, int *statptr, int options)
365 {
366 #ifdef HAVE_WAIT4
367 	return wait4(pid, statptr, options, NULL);
368 #else
369 	/* If wait4 is also not available, try wait3 for SVR3 variants */
370 	/* Less ideal because can't actually request a specific pid */
371 	/* For that reason, first check to see if pid is for an */
372 	/*   existing process. */
373 	int tmp_pid, dummystat;;
374 	if (kill(pid, 0) == -1) {
375 		errno = ECHILD;
376 		return -1;
377 	}
378 	if (statptr == NULL)
379 		statptr = &dummystat;
380 	while (((tmp_pid = wait3(statptr, options, 0)) != pid) &&
381 		    (tmp_pid != -1) && (tmp_pid != 0) && (pid != -1))
382 	    ;
383 	return tmp_pid;
384 #endif
385 }
386 #endif
387 
388 /* Under SunOS popen() doesn't record the pid of the child process.  When
389  * pclose() is called, instead of calling waitpid() for the correct child, it
390  * calls wait() repeatedly until the right child is reaped.  The problem is
391  * that this reaps any other children that happen to have died at that
392  * moment, and when their pclose() comes along, the process hangs forever.
393  * The fix is to use a wrapper for popen()/pclose() which saves the pid in
394  * the dataSources structure (code adapted from GNU-libc's popen() call).
395  *
396  * Aut viam inveniam aut faciam */
397 
398 static FILE *
my_popen(struct RI * entry)399 my_popen(struct RI *entry)
400 {
401     int pipedes[2];
402     FILE *stream;
403 
404     /* Create the pipe */
405     if (pipe(pipedes) < 0)
406 	return (NULL);
407 
408     /* Fork off the child ("vfork() is like an OS orgasm.  All OS's want to
409      * do it, but most just end up faking it" - Chris Wedgwood).  If your OS
410      * supports it, you should try to use vfork() here because it's somewhat
411      * more efficient */
412 #if defined( sun ) || defined( __ultrix__ ) || defined( __osf__ ) || \
413 	defined(__hpux)
414     entry->pid = vfork();
415 #else				/*  */
416     entry->pid = fork();
417 #endif				/* Unixen which have vfork() */
418     if (entry->pid == (pid_t) - 1) {
419 	/* The fork failed */
420 	close(pipedes[0]);
421 	close(pipedes[1]);
422 	return (NULL);
423     }
424 
425     if (entry->pid == (pid_t) 0) {
426 	struct passwd *passwd;
427 
428 	/* We are the child.  Make the read side of the pipe be stdout */
429 	if (dup2(pipedes[STDOUT_FILENO], STDOUT_FILENO) < 0)
430 	    exit(127);
431 
432 	/* Now that everything is set up, give up our permissions to make
433 	 * sure we don't read anything sensitive.  If the getpwnam() fails,
434 	 * we default to -1, which is usually nobody */
435 	if (gatherer_uid == (uid_t)-1 && \
436 	    (passwd = getpwnam("nobody")) != NULL)
437 	    gatherer_uid = passwd->pw_uid;
438 
439 	setuid(gatherer_uid);
440 
441 	/* Close the pipe descriptors */
442 	close(pipedes[STDIN_FILENO]);
443 	close(pipedes[STDOUT_FILENO]);
444 
445 	/* Try and exec the program */
446 	execl(entry->path, entry->path, entry->arg, NULL);
447 
448 	/* Die if the exec failed */
449 	exit(127);
450     }
451 
452     /* We are the parent.  Close the irrelevant side of the pipe and open
453      * the relevant side as a new stream.  Mark our side of the pipe to
454      * close on exec, so new children won't see it */
455     close(pipedes[STDOUT_FILENO]);
456 
457 #ifdef FD_CLOEXEC
458     fcntl(pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC);
459 #endif
460 
461     stream = fdopen(pipedes[STDIN_FILENO], "r");
462 
463     if (stream == NULL) {
464 	int savedErrno = errno;
465 
466 	/* The stream couldn't be opened or the child structure couldn't be
467 	 * allocated.  Kill the child and close the other side of the pipe */
468 	kill(entry->pid, SIGKILL);
469 	if (stream == NULL)
470 	    close(pipedes[STDOUT_FILENO]);
471 	else
472 	    fclose(stream);
473 
474 	waitpid(entry->pid, NULL, 0);
475 
476 	entry->pid = 0;
477 	errno = savedErrno;
478 	return (NULL);
479     }
480 
481     return (stream);
482 }
483 
484 static int
my_pclose(struct RI * entry)485 my_pclose(struct RI *entry)
486 {
487     int status = 0;
488 
489     if (fclose(entry->pipe))
490 	return (-1);
491 
492     /* We ignore the return value from the process because some
493        programs return funny values which would result in the input
494        being discarded even if they executed successfully.  This isn't
495        a problem because the result data size threshold will filter
496        out any programs which exit with a usage message without
497        producing useful output.  */
498     if (waitpid(entry->pid, NULL, 0) != entry->pid)
499 	status = -1;
500 
501     entry->pipe = NULL;
502     entry->pid = 0;
503     return (status);
504 }
505 
506 
507 /* Unix slow poll (without special support for Linux)
508  *
509  * If a few of the randomness sources create a large amount of output then
510  * the slowPoll() stops once the buffer has been filled (but before all the
511  * randomness sources have been sucked dry) so that the 'usefulness' factor
512  * remains below the threshold.  For this reason the gatherer buffer has to
513  * be fairly sizeable on moderately loaded systems.  This is something of a
514  * bug since the usefulness should be influenced by the amount of output as
515  * well as the source type */
516 
517 
518 static int
slow_poll(FILE * dbgfp,int dbgall,size_t * nbytes)519 slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes )
520 {
521     int moreSources;
522     struct timeval tv;
523     fd_set fds;
524 #if defined( __hpux )
525     size_t maxFD = 0;
526 #else
527     int maxFD = 0;
528 #endif /* OS-specific brokenness */
529     int bufPos, i, usefulness = 0;
530     int last_so_far = 0;
531     int any_need_entropy = 0;
532     int delay;
533     int rc;
534 
535     /* Fire up each randomness source */
536     FD_ZERO(&fds);
537     for (i = 0; dataSources[i].path != NULL; i++) {
538 	/* Since popen() is a fairly heavy function, we check to see whether
539 	 * the executable exists before we try to run it */
540 	if (access(dataSources[i].path, X_OK)) {
541 	    if( dbgfp && dbgall )
542 		fprintf(dbgfp, "%s not present%s\n", dataSources[i].path,
543 			       dataSources[i].hasAlternative ?
544 					", has alternatives" : "");
545 	    dataSources[i].pipe = NULL;
546 	}
547 	else
548 	    dataSources[i].pipe = my_popen(&dataSources[i]);
549 
550 	if (dataSources[i].pipe != NULL) {
551 	    dataSources[i].pipeFD = fileno(dataSources[i].pipe);
552 	    if (dataSources[i].pipeFD > maxFD)
553 		maxFD = dataSources[i].pipeFD;
554 
555 #ifdef O_NONBLOCK /* Ohhh what a hack (used for Atari) */
556 	    fcntl(dataSources[i].pipeFD, F_SETFL, O_NONBLOCK);
557 #else
558 #error O_NONBLOCK is missing
559 #endif
560             /* FIXME: We need to make sure that the fd is less than
561                FD_SETSIZE.  */
562 	    FD_SET(dataSources[i].pipeFD, &fds);
563 	    dataSources[i].length = 0;
564 
565 	    /* If there are alternatives for this command, don't try and
566 	     * execute them */
567 	    while (dataSources[i].hasAlternative) {
568 		if( dbgfp && dbgall )
569 		    fprintf(dbgfp, "Skipping %s\n", dataSources[i + 1].path);
570 		i++;
571 	    }
572 	}
573     }
574 
575 
576     /* Suck all the data we can get from each of the sources */
577     bufPos = 0;
578     moreSources = 1;
579     delay = 0; /* Return immediately (well, after 100ms) the first time.  */
580     while (moreSources && bufPos <= gather_buffer_size) {
581 	/* Wait for data to become available from any of the sources, with a
582 	 * timeout of 10 seconds.  This adds even more randomness since data
583 	 * becomes available in a nondeterministic fashion.  Kudos to HP's QA
584 	 * department for managing to ship a select() which breaks its own
585 	 * prototype */
586 	tv.tv_sec = delay;
587 	tv.tv_usec = delay? 0 : 100000;
588 
589 #if defined( __hpux ) && ( OS_VERSION == 9 )
590 	rc = select(maxFD + 1, (int *)&fds, NULL, NULL, &tv);
591 #else  /*  */
592 	rc = select(maxFD + 1, &fds, NULL, NULL, &tv);
593 #endif /* __hpux */
594         if (rc == -1)
595           break; /* Ooops; select failed. */
596 
597         if (!rc)
598           {
599             /* FIXME: Because we run several tools at once it is
600                unlikely that we will see a block in select at all. */
601             if (!any_need_entropy
602                 || last_so_far != (gather_buffer_size - bufPos) )
603               {
604                 last_so_far = gather_buffer_size - bufPos;
605                 _gcry_random_progress ("need_entropy", 'X',
606                                        last_so_far,
607                                        gather_buffer_size);
608                 any_need_entropy = 1;
609               }
610             delay = 10; /* Use 10 seconds henceforth.  */
611             /* Note that the fd_set is setup again at the end of this loop.  */
612           }
613 
614 	/* One of the sources has data available, read it into the buffer */
615 	for (i = 0; dataSources[i].path != NULL; i++) {
616 	    if( dataSources[i].pipe && FD_ISSET(dataSources[i].pipeFD, &fds)) {
617 		size_t noBytes;
618 
619 		if ((noBytes = fread(gather_buffer + bufPos, 1,
620 				     gather_buffer_size - bufPos,
621 				     dataSources[i].pipe)) == 0) {
622 		    if (my_pclose(&dataSources[i]) == 0) {
623 			int total = 0;
624 
625 			/* Try and estimate how much entropy we're getting
626 			 * from a data source */
627 			if (dataSources[i].usefulness) {
628 			    if (dataSources[i].usefulness < 0)
629 				total = (dataSources[i].length + 999)
630 					/ -dataSources[i].usefulness;
631 			    else
632 				total = dataSources[i].length
633 					/ dataSources[i].usefulness;
634 			}
635 			if( dbgfp )
636 			    fprintf(dbgfp,
637 			       "%s %s contributed %d bytes, "
638 			       "usefulness = %d\n", dataSources[i].path,
639 			       (dataSources[i].arg != NULL) ?
640 				       dataSources[i].arg : "",
641 				      dataSources[i].length, total);
642 			if( dataSources[i].length )
643 			    usefulness += total;
644 		    }
645 		    dataSources[i].pipe = NULL;
646 		}
647 		else {
648 		    int currPos = bufPos;
649 		    int endPos = bufPos + noBytes;
650 
651 		    /* Run-length compress the input byte sequence */
652 		    while (currPos < endPos) {
653 			int ch = gather_buffer[currPos];
654 
655 			/* If it's a single byte, just copy it over */
656 			if (ch != gather_buffer[currPos + 1]) {
657 			    gather_buffer[bufPos++] = ch;
658 			    currPos++;
659 			}
660 			else {
661 			    int count = 0;
662 
663 			    /* It's a run of repeated bytes, replace them
664 			     * with the byte count mod 256 */
665 			    while ((ch == gather_buffer[currPos])
666 				    && currPos < endPos) {
667 				count++;
668 				currPos++;
669 			    }
670 			    gather_buffer[bufPos++] = count;
671 			    noBytes -= count - 1;
672 			}
673 		    }
674 
675 		    /* Remember the number of (compressed) bytes of input we
676 		     * obtained */
677 		    dataSources[i].length += noBytes;
678 		}
679 	    }
680 	}
681 
682 	/* Check if there is more input available on any of the sources */
683 	moreSources = 0;
684 	FD_ZERO(&fds);
685 	for (i = 0; dataSources[i].path != NULL; i++) {
686 	    if (dataSources[i].pipe != NULL) {
687 		FD_SET(dataSources[i].pipeFD, &fds);
688 		moreSources = 1;
689 	    }
690 	}
691     }
692 
693     if (any_need_entropy)
694         _gcry_random_progress ("need_entropy", 'X',
695                                gather_buffer_size,
696                                gather_buffer_size);
697 
698     if( dbgfp ) {
699 	fprintf(dbgfp, "Got %d bytes, usefulness = %d\n", bufPos, usefulness);
700 	fflush(dbgfp);
701     }
702     *nbytes = bufPos;
703     return usefulness;
704 }
705 
706 /****************
707  * Start the gatherer process which writes messages of
708  * type GATHERER_MSG to pipedes
709  */
710 static void
start_gatherer(int pipefd)711 start_gatherer( int pipefd )
712 {
713     FILE *dbgfp = NULL;
714     int dbgall;
715 
716     {
717 	const char *s = getenv("GCRYPT_RNDUNIX_DBG");
718 	if( s ) {
719 	    dbgfp = (*s=='-' && !s[1])? stdout : fopen(s, "a");
720 	    if( !dbgfp )
721 		log_info("can't open debug file `%s': %s\n",
722 			     s, strerror(errno) );
723 	    else
724 		fprintf(dbgfp,"\nSTART RNDUNIX DEBUG pid=%d\n", (int)getpid());
725 	}
726 	dbgall = !!getenv("GCRYPT_RNDUNIX_DBGALL");
727     }
728     /* close all files but the ones we need */
729     {	int nmax, n1, n2, i;
730 #ifdef _SC_OPEN_MAX
731 	if( (nmax=sysconf( _SC_OPEN_MAX )) < 0 ) {
732 # ifdef _POSIX_OPEN_MAX
733 	    nmax = _POSIX_OPEN_MAX;
734 # else
735 	    nmax = 20; /* assume a reasonable value */
736 # endif
737 	}
738         /* AIX returns INT32_MAX instead of a proper value.  We assume that
739          * this is always an error and use a reasonable value.  */
740 # ifdef INT32_MAX
741         if (nmax == INT32_MAX)
742           nmax = 20;
743 # endif
744 #else /*!_SC_OPEN_MAX*/
745 	nmax = 20; /* assume a reasonable value */
746 #endif /*!_SC_OPEN_MAX*/
747 	n1 = fileno( stderr );
748 	n2 = dbgfp? fileno( dbgfp ) : -1;
749 	for(i=0; i < nmax; i++ ) {
750 	    if( i != n1 && i != n2 && i != pipefd )
751 		close(i);
752 	}
753 	errno = 0;
754     }
755 
756 
757     /* Set up the buffer.  Not ethat we use a plain standard malloc here. */
758     gather_buffer_size = GATHER_BUFSIZE;
759     gather_buffer = malloc( gather_buffer_size );
760     if( !gather_buffer ) {
761 	log_error("out of core while allocating the gatherer buffer\n");
762 	exit(2);
763     }
764 
765     /* Reset the SIGC(H)LD handler to the system default.  This is necessary
766      * because if the program which cryptlib is a part of installs its own
767      * SIGC(H)LD handler, it will end up reaping the cryptlib children before
768      * cryptlib can.  As a result, my_pclose() will call waitpid() on a
769      * process which has already been reaped by the installed handler and
770      * return an error, so the read data won't be added to the randomness
771      * pool.  There are two types of SIGC(H)LD naming, the SysV SIGCLD and
772      * the BSD/Posix SIGCHLD, so we need to handle either possibility */
773 #ifdef SIGCLD
774     signal(SIGCLD, SIG_DFL);
775 #else
776     signal(SIGCHLD, SIG_DFL);
777 #endif
778 
779     fclose(stderr);		/* Arrghh!!  It's Stuart code!! */
780 
781     /* Mary goes to Berkeley: NetBSD emits warnings if the standard
782        descriptors are not open when running setuid program.  Thus we
783        connect them to the bitbucket if they are not already open.  */
784     {
785       struct stat statbuf;
786 
787       if (fstat (STDIN_FILENO, &statbuf) == -1 && errno == EBADF)
788         open ("/dev/null",O_RDONLY);
789       if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
790         open ("/dev/null",O_WRONLY);
791       if (fstat (STDERR_FILENO, &statbuf) == -1 && errno == EBADF)
792         open ("/dev/null",O_WRONLY);
793     }
794 
795     for(;;) {
796 	GATHER_MSG msg;
797 	size_t nbytes;
798 	const char *p;
799 
800 	msg.usefulness = slow_poll( dbgfp, dbgall, &nbytes );
801 	p = (const char*)gather_buffer;
802 	while( nbytes ) {
803 	    msg.ndata = nbytes > sizeof(msg.data)? sizeof(msg.data) : nbytes;
804 	    memcpy( msg.data, p, msg.ndata );
805 	    nbytes -= msg.ndata;
806 	    p += msg.ndata;
807 
808 	    while( write( pipefd, &msg, sizeof(msg) ) != sizeof(msg) ) {
809 		if( errno == EINTR )
810 		    continue;
811 		if( errno == EAGAIN ) {
812 		    struct timeval tv;
813 		    tv.tv_sec = 0;
814 		    tv.tv_usec = 50000;
815 		    select(0, NULL, NULL, NULL, &tv);
816 		    continue;
817 		}
818 		if( errno == EPIPE ) /* parent has exited, so give up */
819 		   exit(0);
820 
821 		/* we can't do very much here because stderr is closed */
822 		if( dbgfp )
823 		    fprintf(dbgfp, "gatherer can't write to pipe: %s\n",
824 				    strerror(errno) );
825 		/* we start a new poll to give the system some time */
826 		nbytes = 0;
827 		break;
828 	    }
829 	}
830     }
831     /* we are killed when the parent dies */
832 }
833 
834 
835 static int
read_a_msg(int fd,GATHER_MSG * msg)836 read_a_msg( int fd, GATHER_MSG *msg )
837 {
838     char *buffer = (char*)msg;
839     size_t length = sizeof( *msg );
840     int n;
841 
842     do {
843 	do {
844 	    n = read(fd, buffer, length );
845 	} while( n == -1 && errno == EINTR );
846 	if( n == -1 )
847 	    return -1;
848 	buffer += n;
849 	length -= n;
850     } while( length );
851     return 0;
852 }
853 
854 
855 /****************
856  * Using a level of 0 should never block and better add nothing
857  * to the pool.  So this is just a dummy for this gatherer.
858  */
859 int
_gcry_rndunix_gather_random(void (* add)(const void *,size_t,enum random_origins),enum random_origins origin,size_t length,int level)860 _gcry_rndunix_gather_random (void (*add)(const void*, size_t,
861                                          enum random_origins),
862                              enum random_origins origin,
863                              size_t length, int level )
864 {
865     static pid_t gatherer_pid = 0;
866     static int pipedes[2];
867     GATHER_MSG msg;
868     size_t n;
869 
870     if( !level )
871 	return 0;
872 
873     if( !gatherer_pid ) {
874 	/* Make sure we are not setuid. */
875 	if ( getuid() != geteuid() )
876 	    BUG();
877 	/* time to start the gatherer process */
878 	if( pipe( pipedes ) ) {
879 	    log_error("pipe() failed: %s\n", strerror(errno));
880 	    return -1;
881 	}
882 	gatherer_pid = fork();
883 	if( gatherer_pid == -1 ) {
884 	    log_error("can't for gatherer process: %s\n", strerror(errno));
885 	    return -1;
886 	}
887 	if( !gatherer_pid ) {
888 	    start_gatherer( pipedes[1] );
889 	    /* oops, can't happen */
890 	    return -1;
891 	}
892     }
893 
894     /* now read from the gatherer */
895     while( length ) {
896 	int goodness;
897 	unsigned long subtract;
898 
899 	if( read_a_msg( pipedes[0], &msg ) ) {
900 	    log_error("reading from gatherer pipe failed: %s\n",
901 							    strerror(errno));
902 	    return -1;
903 	}
904 
905 
906 	if( level > 1 ) {
907 	    if( msg.usefulness > 30 )
908 		goodness = 100;
909 	    else if ( msg.usefulness )
910 		goodness = msg.usefulness * 100 / 30;
911 	    else
912 		goodness = 0;
913 	}
914 	else if( level ) {
915 	    if( msg.usefulness > 15 )
916 		goodness = 100;
917 	    else if ( msg.usefulness )
918 		goodness = msg.usefulness * 100 / 15;
919 	    else
920 		goodness = 0;
921 	}
922 	else
923 	    goodness = 100; /* goodness of level 0 is always 100 % */
924 
925 	n = msg.ndata;
926 	if( n > length )
927 	    n = length;
928 	(*add)( msg.data, n, origin );
929 
930 	/* this is the trick how we cope with the goodness */
931 	subtract = (unsigned long)n * goodness / 100;
932 	/* subtract at least 1 byte to avoid infinite loops */
933 	length -= subtract ? subtract : 1;
934     }
935 
936     return 0;
937 }
938