summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--NEWS5
-rw-r--r--THANKS2
-rw-r--r--TODO15
-rw-r--r--acconfig.h1
-rw-r--r--cipher/ChangeLog7
-rw-r--r--cipher/dynload.c18
-rw-r--r--cipher/random.c2
-rw-r--r--cipher/rndlinux.c2
-rw-r--r--cipher/rndunix.c523
-rw-r--r--configure.in42
-rw-r--r--util/ChangeLog4
-rw-r--r--util/argparse.c4
13 files changed, 373 insertions, 258 deletions
diff --git a/ChangeLog b/ChangeLog
index 1498fc57e..f1ab556db 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sat Dec 12 18:40:32 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Add check for dlopen in libc (Greg Troxel)
+ and a new define
+ * acconfig.h (DLSYM_NEEDS_UNDERSCORE): New.
+
Thu Dec 10 20:15:36 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* acinclude.m (GNUPG_CHECK_PIC): New
diff --git a/NEWS b/NEWS
index 8c069ba6a..1e7d9300f 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,11 @@
* Fixed the uncompress bug.
+ * Rewrote the rndunix module. There are two environment variables
+ used for debugging now: GNUPG_RNDUNIX_DBG give the file to write
+ debugging information (use "-" for stdout) and if GNUPG_RNDUNIX_DBGALL
+ is set, all programs which are only tried are also printed.
+
Noteworthy changes in version 0.4.5
-----------------------------------
diff --git a/THANKS b/THANKS
index 8d5ab857c..61116a64a 100644
--- a/THANKS
+++ b/THANKS
@@ -20,9 +20,11 @@ Dirk Lattermann dlatt@t-online.de
Ed Boraas ecxjo@esperanto.org
Ernst Molitor ernst.molitor@uni-bonn.de
Fabio Coatti cova@felix.unife.it
+Felix von Leitner leitner@amdiv.de
Frank Heckenbach heckenb@mi.uni-erlangen.de
Gaël Quéri gqueri@mail.dotcom.fr
Greg Louis glouis@dynamicro.on.ca
+Greg Troxel gdt@ir.bbn.com
Gregory Steuck steuck@iname.com
Geoff Keating geoffk@ozemail.com.au
Hendrik Buschkamp buschkamp@rheumanet.org
diff --git a/TODO b/TODO
index 454384600..caa080c67 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,8 @@
- * Check revocation and expire stuff.
+ * Check revocation and expire stuff. PLEASE: THIS MUST BE TESTED!
- * Check calculation of key validity.
+ * Check calculation of key validity. PLEASE: IT IS IMPORTED THAT
+ THIS GET TESTED.
* preferences of hash algorithms are not yet used.
@@ -14,9 +15,6 @@
* clearsig: keep lineendings as they are. Remember that trailings
blanks are not hashed.
- * OpenBSD: dynamic loading with dlopen works on OpenBSD, but:
- OpenBSD binaries are a.out, so every symbol begins with "_"
-
* should we flush the getkey.c caches while doing an import?
* The critical bit of signature subpackets is not yet supported; i.e.
@@ -32,6 +30,7 @@
* new menu to delete signatures and list signature in menu
* Replace the SIGUSR1 stuff by semaphores to avoid loss of a signal.
+ or use POSIX.4 realtime signals.
* add test cases for invalid data (scrambled armor or other random data)
@@ -51,13 +50,7 @@
* change the fake_data stuff to mpi_set_opaque
- * Add some stuff for DU cc
-
* Use "user ID", "trustdb", "NOTE" and "WARNING".
* Replace Blowfish by Twofish
- * Print a warning when a experimental algorithm is used.
-
- * Remove ElGamal signatures.
-
diff --git a/acconfig.h b/acconfig.h
index 44af60073..de2fa3e0e 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -81,6 +81,7 @@
#undef USE_DYNAMIC_LINKING
#undef HAVE_DL_DLOPEN
#undef HAVE_DLD_DLD_LINK
+#undef DLSYM_NEEDS_UNDERSCORE
#undef USE_SHM_COPROCESSING
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index 1df5a1500..2874426f7 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -1,3 +1,10 @@
+Sat Dec 12 18:40:32 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (SYMBOL_VERSION): New to cope with system which needs
+ underscores.
+
+ * rndunix.c: Rewrote large parts
+
Thu Dec 10 20:15:36 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* dynload.c (load_extension): increased needed verbosity level.
diff --git a/cipher/dynload.c b/cipher/dynload.c
index 204f186b0..563f791f2 100644
--- a/cipher/dynload.c
+++ b/cipher/dynload.c
@@ -32,6 +32,14 @@
#include "cipher.h"
#include "dynload.h"
+#ifdef DLSYM_NEEDS_UNDERSCORE
+ #define SYMBOL_VERSION "_gnupgext_version"
+ #define SYMBOL_ENUM "_gnupgext_enum_func"
+#else
+ #define SYMBOL_VERSION "gnupgext_version"
+ #define SYMBOL_ENUM "gnupgext_enum_func"
+#endif
+
#ifndef RTLD_NOW
#define RTLD_NOW 1
@@ -193,7 +201,7 @@ load_extension( EXTLIST el )
log_error("%s: error loading extension: %s\n", el->name, dlerror() );
goto failure;
}
- name = (char**)dlsym(el->handle, "gnupgext_version");
+ name = (char**)dlsym(el->handle, SYMBOL_VERSION);
if( (err=dlerror()) ) {
log_error("%s: not a gnupg extension: %s\n", el->name, err );
goto failure;
@@ -222,7 +230,7 @@ load_extension( EXTLIST el )
el->name, dld_strerror(rc) );
goto failure;
}
- addr = dld_get_symbol("gnupgext_version");
+ addr = dld_get_symbol(SYMBOL_VERSION);
if( !addr ) {
log_error("%s: not a gnupg extension: %s\n",
el->name, dld_strerror(dld_errno) );
@@ -238,20 +246,20 @@ load_extension( EXTLIST el )
el->hintstr? ")":"");
#ifdef HAVE_DL_DLOPEN
- sym = dlsym(el->handle, "gnupgext_enum_func");
+ sym = dlsym(el->handle, SYMBOL_ENUM);
if( (err=dlerror()) ) {
log_error("%s: invalid gnupg extension: %s\n", el->name, err );
goto failure;
}
el->enumfunc = (void *(*)(int,int*,int*,int*))sym;
#else /* dld */
- addr = dld_get_func("gnupgext_enum_func");
+ addr = dld_get_func(SYMBOL_ENUM);
if( !addr ) {
log_error("%s: invalid gnupg extension: %s\n",
el->name, dld_strerror(dld_errno) );
goto failure;
}
- rc = dld_function_executable_p("gnupgext_enum_func");
+ rc = dld_function_executable_p(SYMBOL_ENUM);
if( rc ) {
log_error("%s: extension function is not executable: %s\n",
el->name, dld_strerror(rc) );
diff --git a/cipher/random.c b/cipher/random.c
index 32415bd0b..699f76994 100644
--- a/cipher/random.c
+++ b/cipher/random.c
@@ -395,6 +395,8 @@ read_random_source( byte *buffer, size_t length, int level )
while( length ) {
nbytes = length;
goodness = (*fnc)( buffer, &nbytes, level );
+ if( goodness < 0 )
+ log_fatal("No way to gather entropy for the RNG\n");
buffer +=nbytes;
length -= nbytes;
/* FIXME: how can we handle the goodness */
diff --git a/cipher/rndlinux.c b/cipher/rndlinux.c
index 3d0ac1b58..b9376e8fe 100644
--- a/cipher/rndlinux.c
+++ b/cipher/rndlinux.c
@@ -138,7 +138,7 @@ gather_random( byte *buffer, size_t *r_length, int level )
length -= n;
} while( length );
- return 100; /* 100% useful at the requested level */
+ return 100; /* always 100% useful at the requested level */
}
diff --git a/cipher/rndunix.c b/cipher/rndunix.c
index 3eca9df81..92e735689 100644
--- a/cipher/rndunix.c
+++ b/cipher/rndunix.c
@@ -12,15 +12,6 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
-#ifdef HAVE_GETHRTIME
- #include <sys/times.h>
-#endif
-#ifdef HAVE_GETTIMEOFDAY
- #include <sys/times.h>
-#endif
-#ifdef HAVE_GETRUSAGE
- #include <sys/resource.h>
-#endif
/* OS-specific includes */
@@ -66,11 +57,8 @@
#include "dynload.h"
#endif
-typedef enum { FALSE=0, TRUE } BOOLEAN;
-typedef unsigned char BYTE;
-#define DEBUG_RANDOM 1
-#define DEBUG_RANDOM_VERBOSE 1
+#define GATHER_BUFSIZE 49152 /* Usually about 25K are filled */
/* The structure containing information on random-data sources. Each
* record contains the source and a relative estimate of its usefulness
@@ -142,110 +130,110 @@ static struct RI {
int pipeFD; /* Pipe to source as FD */
pid_t pid; /* pid of child for waitpid() */
int length; /* Quantity of output produced */
- const BOOLEAN hasAlternative; /* Whether source has alt.location */
+ const int hasAlternative; /* Whether source has alt.location */
} dataSources[] = {
- { "/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, FALSE},
- { "/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, FALSE},
- { "/usr/bin/pfstat", NULL, SC(-2), NULL, 0, 0, 0, FALSE},
- { "/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, FALSE},
- { "/usr/ucb/netstat", "-s", SC(2), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/netstat", "-s", SC(2), NULL, 0, 0, 0, TRUE },
- { "/usr/sbin/netstat", "-s", SC(2), NULL, 0, 0, 0, TRUE},
- { "/usr/etc/netstat", "-s", SC(2), NULL, 0, 0, 0, FALSE},
- { "/usr/bin/nfsstat", NULL, SC(2), NULL, 0, 0, 0, FALSE},
- { "/usr/ucb/netstat", "-m", SC(-1), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/netstat", "-m", SC(-1), NULL, 0, 0, 0, TRUE },
- { "/usr/sbin/netstat", "-m", SC(-1), NULL, 0, 0, 0, TRUE },
- { "/usr/etc/netstat", "-m", SC(-1), NULL, 0, 0, 0, FALSE },
- { "/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, TRUE },
- { "/usr/ucb/netstat", "-in", SC(-1), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, TRUE },
- { "/usr/sbin/netstat", "-in", SC(-1), NULL, 0, 0, 0, TRUE},
- { "/usr/etc/netstat", "-in", SC(-1), NULL, 0, 0, 0, FALSE},
+ { "/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 0},
+ { "/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 0},
+ { "/usr/bin/pfstat", NULL, SC(-2), NULL, 0, 0, 0, 0},
+ { "/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 0},
+ { "/usr/ucb/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1},
+ { "/usr/etc/netstat", "-s", SC(2), NULL, 0, 0, 0, 0},
+ { "/usr/bin/nfsstat", NULL, SC(2), NULL, 0, 0, 0, 0},
+ { "/usr/ucb/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/etc/netstat", "-m", SC(-1), NULL, 0, 0, 0, 0 },
+ { "/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/ucb/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1},
+ { "/usr/etc/netstat", "-in", SC(-1), NULL, 0, 0, 0, 0},
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.1.0",
- SC(-1), NULL, 0, 0, 0, FALSE }, /* UDP in */
+ SC(-1), NULL, 0, 0, 0, 0 }, /* UDP in */
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.4.0",
- SC(-1), NULL, 0, 0, 0, FALSE }, /* UDP out */
+ SC(-1), NULL, 0, 0, 0, 0 }, /* UDP out */
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.4.3.0",
- SC(-1), NULL, 0, 0, 0, FALSE }, /* IP ? */
+ SC(-1), NULL, 0, 0, 0, 0 }, /* IP ? */
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.10.0",
- SC(-1), NULL, 0, 0, 0, FALSE }, /* TCP ? */
+ SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.11.0",
- SC(-1), NULL, 0, 0, 0, FALSE }, /* TCP ? */
+ SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.13.0",
- SC(-1), NULL, 0, 0, 0, FALSE }, /* TCP ? */
- { "/usr/bin/mpstat", NULL, SC(1), NULL, 0, 0, 0, FALSE },
- { "/usr/bin/w", NULL, SC(1), NULL, 0, 0, 0, TRUE },
- { "/usr/bsd/w", NULL, SC(1), NULL, 0, 0, 0, FALSE },
- { "/usr/bin/df", NULL, SC(1), NULL, 0, 0, 0, TRUE },
- { "/bin/df", NULL, SC(1), NULL, 0, 0, 0, FALSE },
- { "/usr/sbin/portstat", NULL, SC(1), NULL, 0, 0, 0, FALSE },
- { "/usr/bin/iostat", NULL, SC(SC_0), NULL, 0, 0, 0, FALSE },
- { "/usr/bin/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, TRUE },
- { "/usr/bsd/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, FALSE },
- { "/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, FALSE },
- { "/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, FALSE },
- { "/usr/ucb/netstat", "-n", SC(0.5), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, TRUE },
- { "/usr/sbin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, TRUE },
- { "/usr/etc/netstat", "-n", SC(0.5), NULL, 0, 0, 0, FALSE },
+ SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
+ { "/usr/bin/mpstat", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/w", NULL, SC(1), NULL, 0, 0, 0, 1 },
+ { "/usr/bsd/w", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/df", NULL, SC(1), NULL, 0, 0, 0, 1 },
+ { "/bin/df", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/sbin/portstat", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/iostat", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 1 },
+ { "/usr/bsd/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/usr/ucb/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/usr/etc/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 0 },
#if defined( __sgi ) || defined( __hpux )
- { "/bin/ps", "-el", SC(0.3), NULL, 0, 0, 0, TRUE },
+ { "/bin/ps", "-el", SC(0.3), NULL, 0, 0, 0, 1 },
#endif /* __sgi || __hpux */
- { "/usr/ucb/ps", "aux", SC(0.3), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, TRUE },
- { "/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, FALSE },
- { "/usr/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, TRUE },
- { "/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, FALSE },
+ { "/usr/ucb/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
+ { "/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 0 },
/* Unreliable source, depends on system usage */
- { "/etc/pstat", "-p", SC(0.5), NULL, 0, 0, 0, TRUE },
- { "/bin/pstat", "-p", SC(0.5), NULL, 0, 0, 0, FALSE },
- { "/etc/pstat", "-S", SC(0.2), NULL, 0, 0, 0, TRUE },
- { "/bin/pstat", "-S", SC(0.2), NULL, 0, 0, 0, FALSE },
- { "/etc/pstat", "-v", SC(0.2), NULL, 0, 0, 0, TRUE },
- { "/bin/pstat", "-v", SC(0.2), NULL, 0, 0, 0, FALSE },
- { "/etc/pstat", "-x", SC(0.2), NULL, 0, 0, 0, TRUE },
- { "/bin/pstat", "-x", SC(0.2), NULL, 0, 0, 0, FALSE },
- { "/etc/pstat", "-t", SC(0.1), NULL, 0, 0, 0, TRUE },
- { "/bin/pstat", "-t", SC(0.1), NULL, 0, 0, 0, FALSE },
+ { "/etc/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 0 },
/* pstat is your friend */
- { "/usr/bin/last", "-n 50", SC(0.3), NULL, 0, 0, 0, TRUE },
+ { "/usr/bin/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 1 },
#ifdef __sgi
- { "/usr/bsd/last", "-50", SC(0.3), NULL, 0, 0, 0, FALSE },
+ { "/usr/bsd/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 },
#endif /* __sgi */
#ifdef __hpux
- { "/etc/last", "-50", SC(0.3), NULL, 0, 0, 0, FALSE },
+ { "/etc/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 },
#endif /* __hpux */
- { "/usr/bsd/last", "-n 50", SC(0.3), NULL, 0, 0, 0, FALSE },
+ { "/usr/bsd/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 0 },
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.1.0",
- SC(0.1), NULL, 0, 0, 0, FALSE }, /* ICMP ? */
+ SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
{ "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.3.0",
- SC(0.1), NULL, 0, 0, 0, FALSE }, /* ICMP ? */
- { "/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, TRUE },
- { "/usr/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/arp", "-a", SC(0.1), NULL, 0, 0, 0, TRUE },
- { "/usr/sbin/arp", "-a", SC(0.1), NULL, 0, 0, 0, FALSE },
+ SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
+ { "/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 0 },
{ "/usr/sbin/ripquery", "-nw 1 127.0.0.1",
- SC(0.1), NULL, 0, 0, 0, FALSE },
- { "/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, TRUE },
- { "/usr/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, TRUE },
- { "/usr/ucb/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, FALSE },
- { "/usr/bin/tcpdump", "-c 5 -efvvx", SC(1), NULL, 0, 0, 0, FALSE },
+ SC(0.1), NULL, 0, 0, 0, 0 },
+ { "/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/ucb/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/tcpdump", "-c 5 -efvvx", SC(1), NULL, 0, 0, 0, 0 },
/* This is very environment-dependant. If network traffic is low, it'll
* probably time out before delivering 5 packets, which is OK because
* it'll probably be fixed stuff like ARP anyway */
{ "/usr/sbin/advfsstat", "-b usr_domain",
- SC(SC_0), NULL, 0, 0, 0, FALSE},
+ SC(SC_0), NULL, 0, 0, 0, 0},
{ "/usr/sbin/advfsstat", "-l 2 usr_domain",
- SC(0.5), NULL, 0, 0, 0, FALSE},
+ SC(0.5), NULL, 0, 0, 0, 0},
{ "/usr/sbin/advfsstat", "-p usr_domain",
- SC(SC_0), NULL, 0, 0, 0, FALSE},
+ SC(SC_0), NULL, 0, 0, 0, 0},
/* This is a complex and screwball program. Some systems have things
* like rX_dmn, x = integer, for RAID systems, but the statistics are
* pretty dodgy */
@@ -254,30 +242,24 @@ static struct RI {
* unpredictable, however they give an indication of the sort of sources
* you can use (for example the finger might be more useful on a
* firewalled internal network) */
- { "/usr/bin/finger", "@ml.media.mit.edu", SC(0.9), NULL, 0, 0, 0, FALSE },
+ { "/usr/bin/finger", "@ml.media.mit.edu", SC(0.9), NULL, 0, 0, 0, 0 },
{ "/usr/local/bin/wget", "-O - http://lavarand.sgi.com/block.html",
- SC(0.9), NULL, 0, 0, 0, FALSE },
- { "/bin/cat", "/usr/spool/mqueue/syslog", SC(0.9), NULL, 0, 0, 0, FALSE },
+ SC(0.9), NULL, 0, 0, 0, 0 },
+ { "/bin/cat", "/usr/spool/mqueue/syslog", SC(0.9), NULL, 0, 0, 0, 0 },
#endif /* 0 */
- { NULL, NULL, 0, NULL, 0, 0, 0, FALSE }
+ { NULL, NULL, 0, NULL, 0, 0, 0, 0 }
};
-/* Variables to manage the child process which fills the buffer */
-
-static pid_t gathererProcess = 0; /* The child process which fills the
- * buffer */
-static BYTE *gathererBuffer; /* Shared buffer for gathering random noise */
-static int gathererMemID; /* ID for shared memory */
-static int gathererBufSize; /* Size of the shared memory buffer */
-static uid_t gathererID = (uid_t) - 1; /* Gatherers user ID */
-
-/* The struct at the start of the shared memory buffer used to communicate
- * information from the child to the parent */
+static byte *gather_buffer; /* buffer for gathering random noise */
+static int gather_buffer_size; /* size of the memory buffer */
+static uid_t gatherer_uid;
+/* The message structure used to communicate with the parent */
typedef struct {
- int usefulness; /* Usefulness of data in buffer */
- int noBytes; /* No.of bytes in buffer */
-} GATHERER_INFO;
+ int usefulness; /* usefulness of data */
+ int ndata; /* valid bytes in data */
+ char data[500]; /* gathered data */
+} GATHER_MSG;
/* Under SunOS popen() doesn't record the pid of the child process. When
* pclose() is called, instead of calling waitpid() for the correct child, it
@@ -327,11 +309,11 @@ my_popen(struct RI *entry)
/* Now that everything is set up, give up our permissions to make
* sure we don't read anything sensitive. If the getpwnam() fails,
* we default to -1, which is usually nobody */
- if (gathererID == (uid_t) - 1 && \
+ if (gatherer_uid == (uid_t)-1 && \
(passwd = getpwnam("nobody")) != NULL)
- gathererID = passwd->pw_uid;
+ gatherer_uid = passwd->pw_uid;
- setuid(gathererID);
+ setuid(gatherer_uid);
/* Close the pipe descriptors */
close(pipedes[STDIN_FILENO]);
@@ -406,70 +388,23 @@ my_pclose(struct RI *entry)
* bug since the usefulness should be influenced by the amount of output as
* well as the source type */
-#define DEVRANDOM_BITS 1024
-#define SHARED_BUFSIZE 49152 /* Usually about 25K are filled */
-static void
-slowPoll(void)
+static int
+slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes )
{
- GATHERER_INFO *gathererInfo;
- BOOLEAN moreSources;
+ int moreSources;
struct timeval tv;
fd_set fds;
-#if defined( __hpux )
+ #if defined( __hpux )
size_t maxFD = 0;
int pageSize = 4096; /* PHUX doesn't have getpagesize() */
-#elif defined( _M_XENIX ) || defined( __aux )
- int maxFD = 0, pageSize = 4096; /* Nor do others, but they
- * get fd right */
-#else /* */
+ #elif defined( _M_XENIX ) || defined( __aux )
+ int maxFD = 0, pageSize = 4096;/* Nor do others, but they get fd right */
+ #else
int maxFD = 0, pageSize = getpagesize();
-#endif /* OS-specific brokenness */
+ #endif /* OS-specific brokenness */
int bufPos, i, usefulness = 0;
- /* Make sure we don't start more than one slow poll at a time */
- if (gathererProcess) {
- g10_log_debug( "already in slowPoll\n");
- return;
- }
-
- /* Set up the shared memory */
- gathererBufSize = (SHARED_BUFSIZE / pageSize) * (pageSize + 1);
-
- if ((gathererMemID = shmget(IPC_PRIVATE, gathererBufSize,
- IPC_CREAT | 0600)) == -1) {
- g10_log_debug("shmget failed: %s\n", strerror(errno) );
- return; /* Something broke */
- }
-
- if ((gathererBuffer = (BYTE *) shmat(gathererMemID, NULL, 0)) == (BYTE *) - 1) {
- g10_log_debug("shmat failed: %s\n", strerror(errno) );
- return; /* Something broke */
- }
-
- /* Fork off the gatherer, the parent process returns to the caller */
- if ((gathererProcess = fork()) || (gathererProcess == -1)) {
- g10_log_debug("gatherer pid = %d\n", gathererProcess );
- return; /* Error/parent process returns */
- }
-
-
- fclose(stderr); /* Arrghh!! It's Stuart code!! */
-
- /* Reset the SIGC(H)LD handler to the system default. This is necessary
- * because if the program which cryptlib is a part of installs its own
- * SIGC(H)LD handler, it will end up reaping the cryptlib children before
- * cryptlib can. As a result, my_pclose() will call waitpid() on a
- * process which has already been reaped by the installed handler and
- * return an error, so the read data won't be added to the randomness
- * pool. There are two types of SIGC(H)LD naming, the SysV SIGCLD and
- * the BSD/Posix SIGCHLD, so we need to handle either possibility */
-#ifdef SIGCLD
- signal(SIGCLD, SIG_DFL);
-#else /* */
- signal(SIGCHLD, SIG_DFL);
-
-#endif /* SIGCLD */
/* Fire up each randomness source */
FD_ZERO(&fds);
@@ -477,10 +412,10 @@ slowPoll(void)
/* Since popen() is a fairly heavy function, we check to see whether
* the executable exists before we try to run it */
if (access(dataSources[i].path, X_OK)) {
-#ifdef DEBUG_RANDOM_VERBOSE
- printf("%s not present%s\n", dataSources[i].path,
- dataSources[i].hasAlternative ? ", has alternatives" : "");
-#endif /* DEBUG_RANDOM */
+ if( dbgfp && dbgall )
+ fprintf(dbgfp, "%s not present%s\n", dataSources[i].path,
+ dataSources[i].hasAlternative ?
+ ", has alternatives" : "");
dataSources[i].pipe = NULL;
}
else
@@ -497,21 +432,18 @@ slowPoll(void)
/* If there are alternatives for this command, don't try and
* execute them */
while (dataSources[i].hasAlternative) {
-#ifdef DEBUG_RANDOM_VERBOSE
- printf("Skipping %s\n", dataSources[i + 1].path);
-#endif /* DEBUG_RANDOM */
+ if( dbgfp && dbgall )
+ fprintf(dbgfp, "Skipping %s\n", dataSources[i + 1].path);
i++;
}
}
}
- gathererInfo = (GATHERER_INFO *) gathererBuffer;
- bufPos = sizeof(GATHERER_INFO); /* Start of buf.has status
- * info */
/* Suck all the data we can get from each of the sources */
- moreSources = TRUE;
- while (moreSources && bufPos <= gathererBufSize) {
+ bufPos = 0;
+ moreSources = 1;
+ while (moreSources && bufPos <= gather_buffer_size) {
/* Wait for data to become available from any of the sources, with a
* timeout of 10 seconds. This adds even more randomness since data
* becomes available in a nondeterministic fashion. Kudos to HP's QA
@@ -520,11 +452,11 @@ slowPoll(void)
tv.tv_sec = 10;
tv.tv_usec = 0;
-#if defined( __hpux ) && ( OS_VERSION == 9 )
+ #if defined( __hpux ) && ( OS_VERSION == 9 )
if (select(maxFD + 1, (int *)&fds, NULL, NULL, &tv) == -1)
-#else /* */
+ #else /* */
if (select(maxFD + 1, &fds, NULL, NULL, &tv) == -1)
-#endif /* __hpux */
+ #endif /* __hpux */
break;
/* One of the sources has data available, read it into the buffer */
@@ -532,8 +464,8 @@ slowPoll(void)
if( dataSources[i].pipe && FD_ISSET(dataSources[i].pipeFD, &fds)) {
size_t noBytes;
- if ((noBytes = fread(gathererBuffer + bufPos, 1,
- gathererBufSize - bufPos,
+ if ((noBytes = fread(gather_buffer + bufPos, 1,
+ gather_buffer_size - bufPos,
dataSources[i].pipe)) == 0) {
if (my_pclose(&dataSources[i]) == 0) {
int total = 0;
@@ -547,13 +479,13 @@ slowPoll(void)
else
total = dataSources[i].length
/ dataSources[i].usefulness;
-#ifdef DEBUG_RANDOM
- printf("%s %s contributed %d bytes (compressed), "
+ if( dbgfp )
+ fprintf(dbgfp,
+ "%s %s contributed %d bytes, "
"usefulness = %d\n", dataSources[i].path,
(dataSources[i].arg != NULL) ?
dataSources[i].arg : "",
dataSources[i].length, total);
-#endif /* DEBUG_RANDOM */
if( dataSources[i].length )
usefulness += total;
}
@@ -565,11 +497,11 @@ slowPoll(void)
/* Run-length compress the input byte sequence */
while (currPos < endPos) {
- int ch = gathererBuffer[currPos];
+ int ch = gather_buffer[currPos];
/* If it's a single byte, just copy it over */
- if (ch != gathererBuffer[currPos + 1]) {
- gathererBuffer[bufPos++] = ch;
+ if (ch != gather_buffer[currPos + 1]) {
+ gather_buffer[bufPos++] = ch;
currPos++;
}
else {
@@ -577,12 +509,12 @@ slowPoll(void)
/* It's a run of repeated bytes, replace them
* with the byte count mod 256 */
- while ((ch == gathererBuffer[currPos])
+ while ((ch == gather_buffer[currPos])
&& currPos < endPos) {
count++;
currPos++;
}
- gathererBuffer[bufPos++] = count;
+ gather_buffer[bufPos++] = count;
noBytes -= count - 1;
}
}
@@ -595,61 +527,206 @@ slowPoll(void)
}
/* Check if there is more input available on any of the sources */
- moreSources = FALSE;
+ moreSources = 0;
FD_ZERO(&fds);
for (i = 0; dataSources[i].path != NULL; i++) {
if (dataSources[i].pipe != NULL) {
FD_SET(dataSources[i].pipeFD, &fds);
- moreSources = TRUE;
+ moreSources = 1;
}
}
}
- gathererInfo->usefulness = usefulness;
- gathererInfo->noBytes = bufPos;
+ if( dbgfp ) {
+ fprintf(dbgfp, "Got %d bytes, usefulness = %d\n", bufPos, usefulness);
+ fflush(dbgfp);
+ }
+ *nbytes = bufPos;
+ return usefulness;
+}
-#ifdef DEBUG_RANDOM
- printf("Got %d bytes, usefulness = %d\n", bufPos, usefulness);
-#endif /* DEBUG_RANDOM */
+/****************
+ * Start the gatherer process which writes messages of
+ * type GATHERER_MSG to pipedes
+ */
+static void
+start_gatherer( int pipefd )
+{
+ FILE *dbgfp = NULL;
+ int dbgall;
+
+ {
+ const char *s = getenv("GNUPG_RNDUNIX_DBG");
+ if( s ) {
+ dbgfp = (*s=='-' && !s[1])? stdout : fopen(s, "a");
+ if( !dbgfp )
+ g10_log_info("can't open debug file '%s': %s\n",
+ s, strerror(errno) );
+ else
+ fprintf(dbgfp,"\nSTART RNDUNIX DEBUG pid=%d\n", (int)getpid());
+ }
+ dbgall = !!getenv("GNUPG_RNDUNIX_DBGALL");
+ }
+ /* close all files but the ones we need */
+ { int nmax, n1, n2, i;
+ if( (nmax=sysconf( _SC_OPEN_MAX )) < 0 ) {
+ #ifdef _POSIX_OPEN_MAX
+ nmax = _POSIX_OPEN_MAX;
+ #else
+ nmax = 20; /* assume a reasonable value */
+ #endif
+ }
+ n1 = fileno( stderr );
+ n2 = dbgfp? fileno( dbgfp ) : -1;
+ for(i=0; i < nmax; i++ ) {
+ if( i != n1 && i != n2 && i != pipefd )
+ close(i);
+ }
+ errno = 0;
+ }
- /* Child MUST exit here */
- exit(0);
+
+
+ /* Set up the buffer */
+ gather_buffer_size = GATHER_BUFSIZE;
+ gather_buffer = malloc( gather_buffer_size );
+ if( !gather_buffer ) {
+ g10_log_error("out of core while allocating the gatherer buffer\n");
+ exit(2);
+ }
+
+ /* Reset the SIGC(H)LD handler to the system default. This is necessary
+ * because if the program which cryptlib is a part of installs its own
+ * SIGC(H)LD handler, it will end up reaping the cryptlib children before
+ * cryptlib can. As a result, my_pclose() will call waitpid() on a
+ * process which has already been reaped by the installed handler and
+ * return an error, so the read data won't be added to the randomness
+ * pool. There are two types of SIGC(H)LD naming, the SysV SIGCLD and
+ * the BSD/Posix SIGCHLD, so we need to handle either possibility */
+ #ifdef SIGCLD
+ signal(SIGCLD, SIG_DFL);
+ #else
+ signal(SIGCHLD, SIG_DFL);
+ #endif
+
+ fclose(stderr); /* Arrghh!! It's Stuart code!! */
+
+ for(;;) {
+ GATHER_MSG msg;
+ size_t nbytes;
+ const char *p;
+
+ msg.usefulness = slow_poll( dbgfp, dbgall, &nbytes );
+ p = gather_buffer;
+ while( nbytes ) {
+ msg.ndata = nbytes > sizeof(msg.data)? sizeof(msg.data) : nbytes;
+ memcpy( msg.data, p, msg.ndata );
+ nbytes -= msg.ndata;
+ p += msg.ndata;
+
+ while( write( pipefd, &msg, sizeof(msg) ) != sizeof(msg) ) {
+ if( errno == EINTR )
+ continue;
+ if( errno = EAGAIN ) {
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = 50000;
+ select(0, NULL, NULL, NULL, &tv);
+ continue;
+ }
+ /* we can't do very much here because stderr is closed */
+ if( dbgfp )
+ fprintf(dbgfp, "gatherer can't write to pipe: %s\n",
+ strerror(errno) );
+ /* we start a new poll to give the system some time */
+ nbytes = 0;
+ break;
+ }
+ }
+ }
+ /* we are killed when the parent dies */
}
+static int
+read_a_msg( int fd, GATHER_MSG *msg )
+{
+ char *buffer = (char*)msg;
+ size_t length = sizeof( *msg );
+ int n;
+
+ do {
+ do {
+ n = read(fd, buffer, length );
+ } while( n == -1 && errno == EINTR );
+ if( n == -1 )
+ return -1;
+ buffer += n;
+ length -= n;
+ } while( length );
+ return 0;
+}
+
static int
-gather_random( byte *buffer, size_t *r_length, int level )
+gather_random( char *buffer, size_t *r_length, int level )
{
- GATHERER_INFO gathererInfo;
- int status;
+ static pid_t gatherer_pid = 0;
+ static int pipedes[2];
+ GATHER_MSG msg;
size_t n;
size_t length = *r_length;
- slowPoll();
- assert( gathererProcess );
- /* Wait for the gathering process to finish, add the randomness it's
- * gathered, and detach the shared memory */
- waitpid(gathererProcess, &status, 0); /* Should prob.check status */
+ if( !gatherer_pid ) {
+ /* time to start the gatherer process */
+ if( pipe( pipedes ) ) {
+ g10_log_error("pipe() failed: %s\n", strerror(errno));
+ return -1;
+ }
+ gatherer_pid = fork();
+ if( gatherer_pid == -1 ) {
+ g10_log_error("can't for gatherer process: %s\n", strerror(errno));
+ return -1;
+ }
+ if( !gatherer_pid ) {
+ start_gatherer( pipedes[1] );
+ /* oops, can't happen */
+ return -1;
+ }
+ }
- gathererInfo = *(GATHERER_INFO *)gathererBuffer;
- n = gathererInfo.noBytes;
+ /* now read from the gatherer */
+ if( read_a_msg( pipedes[0], &msg ) ) {
+ g10_log_error("reading from gatherer pipe failed: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+ n = msg.ndata;
if( n > length )
n = length;
- memcpy( buffer, gathererBuffer, n );
-
- memset(gathererBuffer, 0, gathererBufSize);
- shmdt(gathererBuffer);
- shmctl(gathererMemID, IPC_RMID, NULL);
- gathererProcess = 0;
+ memcpy( buffer, msg.data, n );
*r_length = n;
- if( gathererInfo.usefulness > 30 )
- return 100;
- else if ( gathererInfo.usefulness )
- return gathererInfo.usefulness * 100 / 30;
+
+ if( level > 1 ) {
+ if( msg.usefulness > 30 )
+ return 100;
+ else if ( msg.usefulness )
+ return msg.usefulness * 100 / 30;
+ else
+ return 0;
+ }
+ else if( level ) {
+ if( msg.usefulness > 15 )
+ return 100;
+ else if ( msg.usefulness )
+ return msg.usefulness * 100 / 15;
+ else
+ return 0;
+ }
else
- return 0;
+ return 100; /* goodness of level 0 is always 100 % */
}
diff --git a/configure.in b/configure.in
index 374e57102..acadc9e26 100644
--- a/configure.in
+++ b/configure.in
@@ -105,7 +105,6 @@ case "${target}" in
if test -z "$GCC" ; then
CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
fi
- AC_DEFINE(USE_RNDUNIX)
;;
*)
;;
@@ -156,21 +155,32 @@ AC_CHECK_LIB(gdbm,gdbm_firstkey)
if test "$try_dynload" = yes ; then
-AC_CHECK_LIB(dl,dlopen)
-if test "$ac_cv_lib_dl_dlopen" = "yes"; then
- AC_DEFINE(USE_DYNAMIC_LINKING)
- AC_DEFINE(HAVE_DL_DLOPEN)
- DYNLINK_LDFLAGS="-Wl,-export-dynamic"
- use_gnupg_extensions=yes
-else
-AC_CHECK_LIB(dld,dld_link)
-if test "$ac_cv_lib_dld_dld_link" = "yes"; then
- AC_DEFINE(USE_DYNAMIC_LINKING)
- AC_DEFINE(HAVE_DLD_DLD_LINK)
- DYNLINK_LDFLAGS="-Wl,-export-dynamic"
- use_gnupg_extensions=yes
-fi
-fi
+ AC_CHECK_LIB(dl,dlopen)
+ if test "$ac_cv_lib_dl_dlopen" = "yes"; then
+ AC_DEFINE(USE_DYNAMIC_LINKING)
+ AC_DEFINE(HAVE_DL_DLOPEN)
+ DYNLINK_LDFLAGS="-Wl,-export-dynamic"
+ use_gnupg_extensions=yes
+ else
+ AC_CHECK_LIB(c,dlopen)
+ if test "$ac_cv_lib_c_dlopen" = "yes"; then
+ AC_DEFINE(USE_DYNAMIC_LINKING)
+ AC_DEFINE(HAVE_DL_DLOPEN)
+ DYNLINK_LDFLAGS="-Wl,-export-dynamic"
+ dnl fixme: this is probably false but it should
+ dnl work for freebsd
+ AC_DEFINE(DLSYM_NEEDS_UNDERSCORE)
+ use_gnupg_extensions=yes
+ else
+ AC_CHECK_LIB(dld,dld_link)
+ if test "$ac_cv_lib_dld_dld_link" = "yes"; then
+ AC_DEFINE(USE_DYNAMIC_LINKING)
+ AC_DEFINE(HAVE_DLD_DLD_LINK)
+ DYNLINK_LDFLAGS="-Wl,-export-dynamic"
+ use_gnupg_extensions=yes
+ fi
+ fi
+ fi
else
AC_MSG_CHECKING(for dynamic loading)
DYNLINK_LDFLAGS=
diff --git a/util/ChangeLog b/util/ChangeLog
index dc24d3851..2311a3ade 100644
--- a/util/ChangeLog
+++ b/util/ChangeLog
@@ -1,3 +1,7 @@
+Sat Dec 12 18:40:32 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * argparse.c (arg_pars): fixed opts[i] with negative index.
+
Fri Nov 27 21:37:41 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* dotlock.c: Implemented
diff --git a/util/argparse.c b/util/argparse.c
index ffda57238..4810d8700 100644
--- a/util/argparse.c
+++ b/util/argparse.c
@@ -516,9 +516,9 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
}
if( i == -2 ) /* ambiguous option */
- arg->r_opt = (opts[i].flags & 256)? -9:-8;
+ arg->r_opt = -8;
else if( i == -1 ) {
- arg->r_opt = (opts[i].flags & 256)? -7:-2;
+ arg->r_opt = -2;
arg->r.ret_str = s+2;
}
else