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