~ubuntu-branches/ubuntu/natty/libgcrypt11/natty-proposed

« back to all changes in this revision

Viewing changes to random/rndunix.c

  • Committer: Bazaar Package Importer
  • Author(s): Bhavani Shankar
  • Date: 2009-05-16 20:13:32 UTC
  • mfrom: (1.1.6 upstream) (2.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090516201332-czkobpu32w318i16
Tags: 1.4.4-2ubuntu1
* Merge from Debian unstable (LP: #364535), remaining changes:
  - Add libgcrypt11-udeb for use by cryptsetup-udeb.
  - Add clean-la.mk, and add a symlink for the .la
  - Install to /lib.

Show diffs side-by-side

added added

removed removed

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