From 48c99b2c840180331f14e9ad6d1a13dcdac411ff Mon Sep 17 00:00:00 2001 From: djm Date: Wed, 7 Jun 2000 12:20:23 +0000 Subject: [PATCH] - (djm) Cleanup of entropy.c. Reorganised code, removed second pass through list of commands (by default). Removed verbose debugging (by default). - (djm) Increased command entropy estimates and default entropy collection timeout --- ChangeLog | 4 + configure.in | 2 +- entropy.c | 255 ++++++++++++++++++++++++----------------------- ssh_prng_cmds.in | 62 ++++++------ 4 files changed, 169 insertions(+), 154 deletions(-) diff --git a/ChangeLog b/ChangeLog index a928c8f2..8da1f822 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ 20000606 + - (djm) Cleanup of entropy.c. Reorganised code, removed second pass through + list of commands (by default). Removed verbose debugging (by default). + - (djm) Increased command entropy estimates and default entropy collection + timeout - (djm) Remove duplicate headers from loginrec.c - (djm) Don't add /usr/local/lib to library search path on Irix - (djm) Fix rsh path in RPMs. Report from Jason L Tibbitts III diff --git a/configure.in b/configure.in index a043e7f9..a886fbbd 100644 --- a/configure.in +++ b/configure.in @@ -1124,7 +1124,7 @@ fi # Change default command timeout for builtin PRNG -entropy_timeout=100 +entropy_timeout=200 AC_ARG_WITH(entropy-timeout, [ --with-entropy-timeout Specify entropy gathering command timeout (msec)], [ diff --git a/entropy.c b/entropy.c index a2d0f32d..cecf9e8d 100644 --- a/entropy.c +++ b/entropy.c @@ -37,10 +37,27 @@ RCSID("$Id$"); -#ifdef EGD_SOCKET #ifndef offsetof # define offsetof(type, member) ((size_t) &((type *)0)->member) #endif + +/* Print lots of detail */ +/* #define DEBUG_ENTROPY */ + +/* Number of times to pass through command list gathering entropy */ +#define NUM_ENTROPY_RUNS 1 + +/* Scale entropy estimates back by this amount on subsequent runs */ +#define SCALE_PER_RUN 10.0 + +/* Minimum number of commands to be considered valid */ +#define MIN_ENTROPY_SOURCES 16 + +#define WHITESPACE " \t\n" + +#if defined(EGD_SOCKET) || defined(RANDOM_POOL) + +#ifdef EGD_SOCKET /* Collect entropy from EGD */ void get_random_bytes(unsigned char *buf, int len) { @@ -57,7 +74,7 @@ void get_random_bytes(unsigned char *buf, int len) if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path)) fatal("Random pool path is too long"); - strcpy(addr.sun_path, EGD_SOCKET); + strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path)); addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET); @@ -104,7 +121,23 @@ void get_random_bytes(unsigned char *buf, int len) #endif /* RANDOM_POOL */ #endif /* EGD_SOCKET */ -#if !defined(EGD_SOCKET) && !defined(RANDOM_POOL) +/* + * Seed OpenSSL's random number pool from Kernel random number generator + * or EGD + */ +void +seed_rng(void) +{ + char buf[32]; + + debug("Seeding random number generator"); + get_random_bytes(buf, sizeof(buf)); + RAND_add(buf, sizeof(buf), sizeof(buf)); + memset(buf, '\0', sizeof(buf)); +} + +#else /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */ + /* * FIXME: proper entropy estimations. All current values are guesses * FIXME: (ATL) do estimates at compile time? @@ -144,8 +177,6 @@ double hash_output_from_command(entropy_source_t *src, char *hash); /* this is initialised from a file, by prng_read_commands() */ entropy_source_t *entropy_sources = NULL; -#define MIN_ENTROPY_SOURCES 16 - double stir_from_system(void) @@ -184,11 +215,8 @@ stir_from_programs(void) double total_entropy_estimate; char hash[SHA_DIGEST_LENGTH]; - /* - * Run through list of programs twice to catch differences - */ total_entropy_estimate = 0; - for(i = 0; i < 2; i++) { + for(i = 0; i < NUM_ENTROPY_RUNS; i++) { c = 0; while (entropy_sources[c].path != NULL) { @@ -203,14 +231,13 @@ stir_from_programs(void) if (entropy_estimate > SHA_DIGEST_LENGTH) entropy_estimate = SHA_DIGEST_LENGTH; - /* * Scale back estimates for subsequent passes through list */ - entropy_estimate /= 10.0 * (i + 1.0); + /* Scale back estimates for subsequent passes through list */ + entropy_estimate /= SCALE_PER_RUN * (i + 1.0); /* Stir it in */ RAND_add(hash, sizeof(hash), entropy_estimate); -/* FIXME: turn this off later */ -#if 1 +#ifdef DEBUG_ENTROPY debug("Got %0.2f bytes of entropy from '%s'", entropy_estimate, entropy_sources[c].cmdstring); #endif @@ -223,8 +250,7 @@ stir_from_programs(void) total_entropy_estimate += stir_rusage(RUSAGE_SELF, 0.1); total_entropy_estimate += stir_rusage(RUSAGE_CHILDREN, 0.1); } else { -/* FIXME: turn this off later */ -#if 1 +#ifdef DEBUG_ENTROPY debug("Command '%s' disabled (badness %d)", entropy_sources[c].cmdstring, entropy_sources[c].badness); #endif @@ -360,8 +386,7 @@ hash_output_from_command(entropy_source_t *src, char *hash) int msec_remaining; (void) gettimeofday(&tv_current, 0); - msec_elapsed = _get_timeval_msec_difference( - &tv_start, &tv_current); + msec_elapsed = _get_timeval_msec_difference(&tv_start, &tv_current); if (msec_elapsed >= entropy_timeout_current) { error_abort=1; continue; @@ -412,7 +437,9 @@ hash_output_from_command(entropy_source_t *src, char *hash) close(p[0]); +#ifdef DEBUG_ENTROPY debug("Time elapsed: %d msec", msec_elapsed); +#endif if (waitpid(pid, &status, 0) == -1) { debug("Couldn't wait for child '%s' completion: %s", src->cmdstring, @@ -436,12 +463,14 @@ hash_output_from_command(entropy_source_t *src, char *hash) if (WEXITSTATUS(status)==0) { return(total_bytes_read); } else { - debug("Exit status was %d", WEXITSTATUS(status)); + debug("Command '%s' exit status was %d", src->cmdstring, + WEXITSTATUS(status)); src->badness = src->sticky_badness = 128; return (0.0); } } else if (WIFSIGNALED(status)) { - debug("Returned on uncaught signal %d !", status); + debug("Command '%s' returned on uncaught signal %d !", src->cmdstring, + status); src->badness = src->sticky_badness = 128; return(0.0); } else @@ -571,20 +600,19 @@ prng_read_seedfile(void) { /* * entropy command initialisation functions */ -#define WHITESPACE " \t\n" - int prng_read_commands(char *cmdfilename) { FILE *f; - char line[1024]; - char cmd[1024], path[256]; - double est; char *cp; + char line[1024]; + char cmd[1024]; + char path[256]; int linenum; - entropy_source_t *entcmd; int num_cmds = 64; int cur_cmd = 0; + double est; + entropy_source_t *entcmd; f = fopen(cmdfilename, "r"); if (!f) { @@ -592,12 +620,15 @@ prng_read_commands(char *cmdfilename) cmdfilename, strerror(errno)); } - linenum = 0; - entcmd = (entropy_source_t *)xmalloc(num_cmds * sizeof(entropy_source_t)); memset(entcmd, '\0', num_cmds * sizeof(entropy_source_t)); + /* Read in file */ + linenum = 0; while (fgets(line, sizeof(line), f)) { + int arg; + char *argv; + linenum++; /* skip leading whitespace, test for blank line or comment */ @@ -605,88 +636,90 @@ prng_read_commands(char *cmdfilename) if ((*cp == 0) || (*cp == '#')) continue; /* done with this line */ - switch (*cp) { - int arg; - char *argv; - - case '"': - /* first token, command args (incl. argv[0]) in double quotes */ - cp = strtok(cp, "\""); - if (cp==NULL) { - error("missing or bad command string, %.100s line %d -- ignored", - cmdfilename, linenum); - continue; - } - strncpy(cmd, cp, sizeof(cmd)); - /* second token, full command path */ - if ((cp = strtok(NULL, WHITESPACE)) == NULL) { - error("missing command path, %.100s line %d -- ignored", - cmdfilename, linenum); - continue; - } - if (strncmp("undef", cp, 5)==0) /* did configure mark this as dead? */ - continue; - - strncpy(path, cp, sizeof(path)); - /* third token, entropy rate estimate for this command */ - if ( (cp = strtok(NULL, WHITESPACE)) == NULL) { - error("missing entropy estimate, %.100s line %d -- ignored", - cmdfilename, linenum); - continue; - } - est = strtod(cp, &argv);/* FIXME: (ATL) no error checking here */ + /* First non-whitespace char should be double quote delimiting */ + /* commandline */ + if (*cp != '"') { + error("bad entropy command, %.100s line %d", cmdfilename, + linenum); + continue; + } - /* end of line */ - if ((cp = strtok(NULL, WHITESPACE)) != NULL) { - error("garbage at end of line %d in %.100s -- ignored", - linenum, cmdfilename); - continue; - } + /* first token, command args (incl. argv[0]) in double quotes */ + cp = strtok(cp, "\""); + if (cp == NULL) { + error("missing or bad command string, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } + strlcpy(cmd, cp, sizeof(cmd)); + + /* second token, full command path */ + if ((cp = strtok(NULL, WHITESPACE)) == NULL) { + error("missing command path, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } - /* save the command for debug messages */ - entcmd[cur_cmd].cmdstring = (char*) xmalloc(strlen(cmd)+1); - strncpy(entcmd[cur_cmd].cmdstring, cmd, strlen(cmd)+1); - - /* split the command args */ - cp = strtok(cmd, WHITESPACE); - arg = 0; argv = NULL; - do { - char *s = (char*)xmalloc(strlen(cp)+1); - strncpy(s, cp, strlen(cp)+1); - entcmd[cur_cmd].args[arg] = s; - arg++; - } while ((arg < 5) && (cp = strtok(NULL, WHITESPACE))); - if (strtok(NULL, WHITESPACE)) - error("ignored extra command elements (max 5), %.100s line %d", - cmdfilename, linenum); - - /* copy the command path and rate estimate */ - entcmd[cur_cmd].path = (char *)xmalloc(strlen(path)+1); - strncpy(entcmd[cur_cmd].path, path, strlen(path)+1); - entcmd[cur_cmd].rate = est; - /* initialise other values */ - entcmd[cur_cmd].sticky_badness = 1; - - cur_cmd++; - - /* If we've filled the array, reallocate it twice the size */ - /* Do this now because even if this we're on the last command, - we need another slot to mark the last entry */ - if (cur_cmd == num_cmds) { - num_cmds *= 2; - entcmd = xrealloc(entcmd, num_cmds * sizeof(entropy_source_t)); - } - break; + /* did configure mark this as dead? */ + if (strncmp("undef", cp, 5) == 0) + continue; - default: - error("bad entropy command, %.100s line %d", cmdfilename, - linenum); + strlcpy(path, cp, sizeof(path)); + + /* third token, entropy rate estimate for this command */ + if ((cp = strtok(NULL, WHITESPACE)) == NULL) { + error("missing entropy estimate, %.100s line %d -- ignored", + cmdfilename, linenum); + continue; + } + est = strtod(cp, &argv); + + /* end of line */ + if ((cp = strtok(NULL, WHITESPACE)) != NULL) { + error("garbage at end of line %d in %.100s -- ignored", linenum, + cmdfilename); continue; } + + /* save the command for debug messages */ + entcmd[cur_cmd].cmdstring = xstrdup(cmd); + + /* split the command args */ + cp = strtok(cmd, WHITESPACE); + arg = 0; + argv = NULL; + do { + char *s = (char*)xmalloc(strlen(cp) + 1); + strncpy(s, cp, strlen(cp) + 1); + entcmd[cur_cmd].args[arg] = s; + arg++; + } while ((arg < 5) && (cp = strtok(NULL, WHITESPACE))); + + if (strtok(NULL, WHITESPACE)) + error("ignored extra command elements (max 5), %.100s line %d", + cmdfilename, linenum); + + /* Copy the command path and rate estimate */ + entcmd[cur_cmd].path = xstrdup(path); + entcmd[cur_cmd].rate = est; + + /* Initialise other values */ + entcmd[cur_cmd].sticky_badness = 1; + + cur_cmd++; + + /* If we've filled the array, reallocate it twice the size */ + /* Do this now because even if this we're on the last command, + we need another slot to mark the last entry */ + if (cur_cmd == num_cmds) { + num_cmds *= 2; + entcmd = xrealloc(entcmd, num_cmds * sizeof(entropy_source_t)); + } } /* zero the last entry */ memset(&entcmd[cur_cmd], '\0', sizeof(entropy_source_t)); + /* trim to size */ entropy_sources = xrealloc(entcmd, (cur_cmd+1) * sizeof(entropy_source_t)); @@ -695,28 +728,6 @@ prng_read_commands(char *cmdfilename) return (cur_cmd >= MIN_ENTROPY_SOURCES); } - -#endif /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */ - -#if defined(EGD_SOCKET) || defined(RANDOM_POOL) - -/* - * Seed OpenSSL's random number pool from Kernel random number generator - * or EGD - */ -void -seed_rng(void) -{ - char buf[32]; - - debug("Seeding random number generator"); - get_random_bytes(buf, sizeof(buf)); - RAND_add(buf, sizeof(buf), sizeof(buf)); - memset(buf, '\0', sizeof(buf)); -} - -#else /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */ - /* * Write a keyfile at exit */ diff --git a/ssh_prng_cmds.in b/ssh_prng_cmds.in index 16ecb30b..df45ed22 100644 --- a/ssh_prng_cmds.in +++ b/ssh_prng_cmds.in @@ -5,46 +5,46 @@ # The "rate" represents the number of bits of usuable entropy per # byte of command output. Be conservative. -"ls -alni /var/log" @PROG_LS@ 0.002 -"ls -alni /var/adm" @PROG_LS@ 0.002 -"ls -alni /var/mail" @PROG_LS@ 0.002 -"ls -alni /var/spool/mail" @PROG_LS@ 0.002 -"ls -alni /proc" @PROG_LS@ 0.002 -"ls -alni /tmp" @PROG_LS@ 0.002 +"ls -alni /var/log" @PROG_LS@ 0.02 +"ls -alni /var/adm" @PROG_LS@ 0.02 +"ls -alni /var/mail" @PROG_LS@ 0.02 +"ls -alni /var/spool/mail" @PROG_LS@ 0.02 +"ls -alni /proc" @PROG_LS@ 0.02 +"ls -alni /tmp" @PROG_LS@ 0.02 -"netstat -an" @PROG_NETSTAT@ 0.005 -"netstat -in" @PROG_NETSTAT@ 0.010 -"netstat -rn" @PROG_NETSTAT@ 0.002 -"netstat -s" @PROG_NETSTAT@ 0.002 +"netstat -an" @PROG_NETSTAT@ 0.05 +"netstat -in" @PROG_NETSTAT@ 0.05 +"netstat -rn" @PROG_NETSTAT@ 0.02 +"netstat -s" @PROG_NETSTAT@ 0.02 -"arp -a -n" @PROG_ARP@ 0.002 +"arp -a -n" @PROG_ARP@ 0.02 -"ifconfig -a" @PROG_IFCONFIG@ 0.002 +"ifconfig -a" @PROG_IFCONFIG@ 0.02 -"ps laxww" @PROG_PS@ 0.003 -"ps -al" @PROG_PS@ 0.003 -"ps -efl" @PROG_PS@ 0.003 +"ps laxww" @PROG_PS@ 0.03 +"ps -al" @PROG_PS@ 0.03 +"ps -efl" @PROG_PS@ 0.03 -"w" @PROG_W@ 0.005 +"w" @PROG_W@ 0.05 -"who -i" @PROG_WHO@ 0.001 +"who -i" @PROG_WHO@ 0.01 -"last" @PROG_LAST@ 0.001 +"last" @PROG_LAST@ 0.01 -"lastlog" @PROG_LASTLOG@ 0.001 +"lastlog" @PROG_LASTLOG@ 0.01 -"df" @PROG_DF@ 0.010 -"df -i" @PROG_DF@ 0.010 +"df" @PROG_DF@ 0.01 +"df -i" @PROG_DF@ 0.01 -"vmstat" @PROG_VMSTAT@ 0.010 -"uptime" @PROG_UPTIME@ 0.001 +"vmstat" @PROG_VMSTAT@ 0.01 +"uptime" @PROG_UPTIME@ 0.01 -"ipcs -a" @PROG_IPCS@ 0.001 +"ipcs -a" @PROG_IPCS@ 0.01 -"tail -200 /var/log/messages" @PROG_TAIL@ 0.001 -"tail -200 /var/log/syslog" @PROG_TAIL@ 0.001 -"tail -200 /var/adm/messages" @PROG_TAIL@ 0.001 -"tail -200 /var/adm/syslog" @PROG_TAIL@ 0.001 -"tail -200 /var/adm/syslog/syslog.log" @PROG_TAIL@ 0.001 -"tail -200 /var/log/maillog" @PROG_TAIL@ 0.001 -"tail -200 /var/adm/maillog" @PROG_TAIL@ 0.001 +"tail -200 /var/log/messages" @PROG_TAIL@ 0.01 +"tail -200 /var/log/syslog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/messages" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog/syslog.log" @PROG_TAIL@ 0.01 +"tail -200 /var/log/maillog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/maillog" @PROG_TAIL@ 0.01 -- 2.45.2