~ubuntu-branches/ubuntu/karmic/gnupg2/karmic-security

« back to all changes in this revision

Viewing changes to cipher/rndunix.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

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 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*/