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