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