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