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