summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--configure.in2
-rw-r--r--entropy.c257
-rw-r--r--ssh_prng_cmds.in62
4 files changed, 170 insertions, 155 deletions
diff --git a/ChangeLog b/ChangeLog
index a928c8f28..8da1f8226 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,8 @@
120000606 120000606
2 - (djm) Cleanup of entropy.c. Reorganised code, removed second pass through
3 list of commands (by default). Removed verbose debugging (by default).
4 - (djm) Increased command entropy estimates and default entropy collection
5 timeout
2 - (djm) Remove duplicate headers from loginrec.c 6 - (djm) Remove duplicate headers from loginrec.c
3 - (djm) Don't add /usr/local/lib to library search path on Irix 7 - (djm) Don't add /usr/local/lib to library search path on Irix
4 - (djm) Fix rsh path in RPMs. Report from Jason L Tibbitts III 8 - (djm) Fix rsh path in RPMs. Report from Jason L Tibbitts III
diff --git a/configure.in b/configure.in
index a043e7f92..a886fbbd6 100644
--- a/configure.in
+++ b/configure.in
@@ -1124,7 +1124,7 @@ fi
1124 1124
1125 1125
1126# Change default command timeout for builtin PRNG 1126# Change default command timeout for builtin PRNG
1127entropy_timeout=100 1127entropy_timeout=200
1128AC_ARG_WITH(entropy-timeout, 1128AC_ARG_WITH(entropy-timeout,
1129 [ --with-entropy-timeout Specify entropy gathering command timeout (msec)], 1129 [ --with-entropy-timeout Specify entropy gathering command timeout (msec)],
1130 [ 1130 [
diff --git a/entropy.c b/entropy.c
index ffadd32c7..cbb36fd29 100644
--- a/entropy.c
+++ b/entropy.c
@@ -35,12 +35,29 @@
35#include <openssl/rand.h> 35#include <openssl/rand.h>
36#include <openssl/sha.h> 36#include <openssl/sha.h>
37 37
38RCSID("$Id: entropy.c,v 1.12 2000/05/31 01:24:34 damien Exp $"); 38RCSID("$Id: entropy.c,v 1.13 2000/06/07 12:20:23 djm Exp $");
39 39
40#ifdef EGD_SOCKET
41#ifndef offsetof 40#ifndef offsetof
42# define offsetof(type, member) ((size_t) &((type *)0)->member) 41# define offsetof(type, member) ((size_t) &((type *)0)->member)
43#endif 42#endif
43
44/* Print lots of detail */
45/* #define DEBUG_ENTROPY */
46
47/* Number of times to pass through command list gathering entropy */
48#define NUM_ENTROPY_RUNS 1
49
50/* Scale entropy estimates back by this amount on subsequent runs */
51#define SCALE_PER_RUN 10.0
52
53/* Minimum number of commands to be considered valid */
54#define MIN_ENTROPY_SOURCES 16
55
56#define WHITESPACE " \t\n"
57
58#if defined(EGD_SOCKET) || defined(RANDOM_POOL)
59
60#ifdef EGD_SOCKET
44/* Collect entropy from EGD */ 61/* Collect entropy from EGD */
45void get_random_bytes(unsigned char *buf, int len) 62void get_random_bytes(unsigned char *buf, int len)
46{ 63{
@@ -57,7 +74,7 @@ void get_random_bytes(unsigned char *buf, int len)
57 if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path)) 74 if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path))
58 fatal("Random pool path is too long"); 75 fatal("Random pool path is too long");
59 76
60 strcpy(addr.sun_path, EGD_SOCKET); 77 strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path));
61 78
62 addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET); 79 addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET);
63 80
@@ -104,7 +121,23 @@ void get_random_bytes(unsigned char *buf, int len)
104#endif /* RANDOM_POOL */ 121#endif /* RANDOM_POOL */
105#endif /* EGD_SOCKET */ 122#endif /* EGD_SOCKET */
106 123
107#if !defined(EGD_SOCKET) && !defined(RANDOM_POOL) 124/*
125 * Seed OpenSSL's random number pool from Kernel random number generator
126 * or EGD
127 */
128void
129seed_rng(void)
130{
131 char buf[32];
132
133 debug("Seeding random number generator");
134 get_random_bytes(buf, sizeof(buf));
135 RAND_add(buf, sizeof(buf), sizeof(buf));
136 memset(buf, '\0', sizeof(buf));
137}
138
139#else /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */
140
108/* 141/*
109 * FIXME: proper entropy estimations. All current values are guesses 142 * FIXME: proper entropy estimations. All current values are guesses
110 * FIXME: (ATL) do estimates at compile time? 143 * FIXME: (ATL) do estimates at compile time?
@@ -144,8 +177,6 @@ double hash_output_from_command(entropy_source_t *src, char *hash);
144 177
145/* this is initialised from a file, by prng_read_commands() */ 178/* this is initialised from a file, by prng_read_commands() */
146entropy_source_t *entropy_sources = NULL; 179entropy_source_t *entropy_sources = NULL;
147#define MIN_ENTROPY_SOURCES 16
148
149 180
150double 181double
151stir_from_system(void) 182stir_from_system(void)
@@ -184,11 +215,8 @@ stir_from_programs(void)
184 double total_entropy_estimate; 215 double total_entropy_estimate;
185 char hash[SHA_DIGEST_LENGTH]; 216 char hash[SHA_DIGEST_LENGTH];
186 217
187 /*
188 * Run through list of programs twice to catch differences
189 */
190 total_entropy_estimate = 0; 218 total_entropy_estimate = 0;
191 for(i = 0; i < 2; i++) { 219 for(i = 0; i < NUM_ENTROPY_RUNS; i++) {
192 c = 0; 220 c = 0;
193 while (entropy_sources[c].path != NULL) { 221 while (entropy_sources[c].path != NULL) {
194 222
@@ -203,14 +231,13 @@ stir_from_programs(void)
203 if (entropy_estimate > SHA_DIGEST_LENGTH) 231 if (entropy_estimate > SHA_DIGEST_LENGTH)
204 entropy_estimate = SHA_DIGEST_LENGTH; 232 entropy_estimate = SHA_DIGEST_LENGTH;
205 233
206 /* * Scale back estimates for subsequent passes through list */ 234 /* Scale back estimates for subsequent passes through list */
207 entropy_estimate /= 10.0 * (i + 1.0); 235 entropy_estimate /= SCALE_PER_RUN * (i + 1.0);
208 236
209 /* Stir it in */ 237 /* Stir it in */
210 RAND_add(hash, sizeof(hash), entropy_estimate); 238 RAND_add(hash, sizeof(hash), entropy_estimate);
211 239
212/* FIXME: turn this off later */ 240#ifdef DEBUG_ENTROPY
213#if 1
214 debug("Got %0.2f bytes of entropy from '%s'", entropy_estimate, 241 debug("Got %0.2f bytes of entropy from '%s'", entropy_estimate,
215 entropy_sources[c].cmdstring); 242 entropy_sources[c].cmdstring);
216#endif 243#endif
@@ -223,8 +250,7 @@ stir_from_programs(void)
223 total_entropy_estimate += stir_rusage(RUSAGE_SELF, 0.1); 250 total_entropy_estimate += stir_rusage(RUSAGE_SELF, 0.1);
224 total_entropy_estimate += stir_rusage(RUSAGE_CHILDREN, 0.1); 251 total_entropy_estimate += stir_rusage(RUSAGE_CHILDREN, 0.1);
225 } else { 252 } else {
226/* FIXME: turn this off later */ 253#ifdef DEBUG_ENTROPY
227#if 1
228 debug("Command '%s' disabled (badness %d)", 254 debug("Command '%s' disabled (badness %d)",
229 entropy_sources[c].cmdstring, entropy_sources[c].badness); 255 entropy_sources[c].cmdstring, entropy_sources[c].badness);
230#endif 256#endif
@@ -360,8 +386,7 @@ hash_output_from_command(entropy_source_t *src, char *hash)
360 int msec_remaining; 386 int msec_remaining;
361 387
362 (void) gettimeofday(&tv_current, 0); 388 (void) gettimeofday(&tv_current, 0);
363 msec_elapsed = _get_timeval_msec_difference( 389 msec_elapsed = _get_timeval_msec_difference(&tv_start, &tv_current);
364 &tv_start, &tv_current);
365 if (msec_elapsed >= entropy_timeout_current) { 390 if (msec_elapsed >= entropy_timeout_current) {
366 error_abort=1; 391 error_abort=1;
367 continue; 392 continue;
@@ -412,7 +437,9 @@ hash_output_from_command(entropy_source_t *src, char *hash)
412 437
413 close(p[0]); 438 close(p[0]);
414 439
440#ifdef DEBUG_ENTROPY
415 debug("Time elapsed: %d msec", msec_elapsed); 441 debug("Time elapsed: %d msec", msec_elapsed);
442#endif
416 443
417 if (waitpid(pid, &status, 0) == -1) { 444 if (waitpid(pid, &status, 0) == -1) {
418 debug("Couldn't wait for child '%s' completion: %s", src->cmdstring, 445 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)
436 if (WEXITSTATUS(status)==0) { 463 if (WEXITSTATUS(status)==0) {
437 return(total_bytes_read); 464 return(total_bytes_read);
438 } else { 465 } else {
439 debug("Exit status was %d", WEXITSTATUS(status)); 466 debug("Command '%s' exit status was %d", src->cmdstring,
467 WEXITSTATUS(status));
440 src->badness = src->sticky_badness = 128; 468 src->badness = src->sticky_badness = 128;
441 return (0.0); 469 return (0.0);
442 } 470 }
443 } else if (WIFSIGNALED(status)) { 471 } else if (WIFSIGNALED(status)) {
444 debug("Returned on uncaught signal %d !", status); 472 debug("Command '%s' returned on uncaught signal %d !", src->cmdstring,
473 status);
445 src->badness = src->sticky_badness = 128; 474 src->badness = src->sticky_badness = 128;
446 return(0.0); 475 return(0.0);
447 } else 476 } else
@@ -571,20 +600,19 @@ prng_read_seedfile(void) {
571/* 600/*
572 * entropy command initialisation functions 601 * entropy command initialisation functions
573 */ 602 */
574#define WHITESPACE " \t\n"
575
576int 603int
577prng_read_commands(char *cmdfilename) 604prng_read_commands(char *cmdfilename)
578{ 605{
579 FILE *f; 606 FILE *f;
580 char line[1024];
581 char cmd[1024], path[256];
582 double est;
583 char *cp; 607 char *cp;
608 char line[1024];
609 char cmd[1024];
610 char path[256];
584 int linenum; 611 int linenum;
585 entropy_source_t *entcmd;
586 int num_cmds = 64; 612 int num_cmds = 64;
587 int cur_cmd = 0; 613 int cur_cmd = 0;
614 double est;
615 entropy_source_t *entcmd;
588 616
589 f = fopen(cmdfilename, "r"); 617 f = fopen(cmdfilename, "r");
590 if (!f) { 618 if (!f) {
@@ -592,12 +620,15 @@ prng_read_commands(char *cmdfilename)
592 cmdfilename, strerror(errno)); 620 cmdfilename, strerror(errno));
593 } 621 }
594 622
595 linenum = 0;
596
597 entcmd = (entropy_source_t *)xmalloc(num_cmds * sizeof(entropy_source_t)); 623 entcmd = (entropy_source_t *)xmalloc(num_cmds * sizeof(entropy_source_t));
598 memset(entcmd, '\0', num_cmds * sizeof(entropy_source_t)); 624 memset(entcmd, '\0', num_cmds * sizeof(entropy_source_t));
599 625
626 /* Read in file */
627 linenum = 0;
600 while (fgets(line, sizeof(line), f)) { 628 while (fgets(line, sizeof(line), f)) {
629 int arg;
630 char *argv;
631
601 linenum++; 632 linenum++;
602 633
603 /* skip leading whitespace, test for blank line or comment */ 634 /* skip leading whitespace, test for blank line or comment */
@@ -605,88 +636,90 @@ prng_read_commands(char *cmdfilename)
605 if ((*cp == 0) || (*cp == '#')) 636 if ((*cp == 0) || (*cp == '#'))
606 continue; /* done with this line */ 637 continue; /* done with this line */
607 638
608 switch (*cp) { 639 /* First non-whitespace char should be double quote delimiting */
609 int arg; 640 /* commandline */
610 char *argv; 641 if (*cp != '"') {
611 642 error("bad entropy command, %.100s line %d", cmdfilename,
612 case '"': 643 linenum);
613 /* first token, command args (incl. argv[0]) in double quotes */ 644 continue;
614 cp = strtok(cp, "\""); 645 }
615 if (cp==NULL) {
616 error("missing or bad command string, %.100s line %d -- ignored",
617 cmdfilename, linenum);
618 continue;
619 }
620 strncpy(cmd, cp, sizeof(cmd));
621 /* second token, full command path */
622 if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
623 error("missing command path, %.100s line %d -- ignored",
624 cmdfilename, linenum);
625 continue;
626 }
627 if (strncmp("undef", cp, 5)==0) /* did configure mark this as dead? */
628 continue;
629
630 strncpy(path, cp, sizeof(path));
631 /* third token, entropy rate estimate for this command */
632 if ( (cp = strtok(NULL, WHITESPACE)) == NULL) {
633 error("missing entropy estimate, %.100s line %d -- ignored",
634 cmdfilename, linenum);
635 continue;
636 }
637 est = strtod(cp, &argv);/* FIXME: (ATL) no error checking here */
638 646
639 /* end of line */ 647 /* first token, command args (incl. argv[0]) in double quotes */
640 if ((cp = strtok(NULL, WHITESPACE)) != NULL) { 648 cp = strtok(cp, "\"");
641 error("garbage at end of line %d in %.100s -- ignored", 649 if (cp == NULL) {
642 linenum, cmdfilename); 650 error("missing or bad command string, %.100s line %d -- ignored",
643 continue; 651 cmdfilename, linenum);
644 } 652 continue;
653 }
654 strlcpy(cmd, cp, sizeof(cmd));
655
656 /* second token, full command path */
657 if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
658 error("missing command path, %.100s line %d -- ignored",
659 cmdfilename, linenum);
660 continue;
661 }
645 662
646 /* save the command for debug messages */ 663 /* did configure mark this as dead? */
647 entcmd[cur_cmd].cmdstring = (char*) xmalloc(strlen(cmd)+1); 664 if (strncmp("undef", cp, 5) == 0)
648 strncpy(entcmd[cur_cmd].cmdstring, cmd, strlen(cmd)+1); 665 continue;
649
650 /* split the command args */
651 cp = strtok(cmd, WHITESPACE);
652 arg = 0; argv = NULL;
653 do {
654 char *s = (char*)xmalloc(strlen(cp)+1);
655 strncpy(s, cp, strlen(cp)+1);
656 entcmd[cur_cmd].args[arg] = s;
657 arg++;
658 } while ((arg < 5) && (cp = strtok(NULL, WHITESPACE)));
659 if (strtok(NULL, WHITESPACE))
660 error("ignored extra command elements (max 5), %.100s line %d",
661 cmdfilename, linenum);
662
663 /* copy the command path and rate estimate */
664 entcmd[cur_cmd].path = (char *)xmalloc(strlen(path)+1);
665 strncpy(entcmd[cur_cmd].path, path, strlen(path)+1);
666 entcmd[cur_cmd].rate = est;
667 /* initialise other values */
668 entcmd[cur_cmd].sticky_badness = 1;
669
670 cur_cmd++;
671
672 /* If we've filled the array, reallocate it twice the size */
673 /* Do this now because even if this we're on the last command,
674 we need another slot to mark the last entry */
675 if (cur_cmd == num_cmds) {
676 num_cmds *= 2;
677 entcmd = xrealloc(entcmd, num_cmds * sizeof(entropy_source_t));
678 }
679 break;
680 666
681 default: 667 strlcpy(path, cp, sizeof(path));
682 error("bad entropy command, %.100s line %d", cmdfilename, 668
683 linenum); 669 /* third token, entropy rate estimate for this command */
670 if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
671 error("missing entropy estimate, %.100s line %d -- ignored",
672 cmdfilename, linenum);
673 continue;
674 }
675 est = strtod(cp, &argv);
676
677 /* end of line */
678 if ((cp = strtok(NULL, WHITESPACE)) != NULL) {
679 error("garbage at end of line %d in %.100s -- ignored", linenum,
680 cmdfilename);
684 continue; 681 continue;
685 } 682 }
683
684 /* save the command for debug messages */
685 entcmd[cur_cmd].cmdstring = xstrdup(cmd);
686
687 /* split the command args */
688 cp = strtok(cmd, WHITESPACE);
689 arg = 0;
690 argv = NULL;
691 do {
692 char *s = (char*)xmalloc(strlen(cp) + 1);
693 strncpy(s, cp, strlen(cp) + 1);
694 entcmd[cur_cmd].args[arg] = s;
695 arg++;
696 } while ((arg < 5) && (cp = strtok(NULL, WHITESPACE)));
697
698 if (strtok(NULL, WHITESPACE))
699 error("ignored extra command elements (max 5), %.100s line %d",
700 cmdfilename, linenum);
701
702 /* Copy the command path and rate estimate */
703 entcmd[cur_cmd].path = xstrdup(path);
704 entcmd[cur_cmd].rate = est;
705
706 /* Initialise other values */
707 entcmd[cur_cmd].sticky_badness = 1;
708
709 cur_cmd++;
710
711 /* If we've filled the array, reallocate it twice the size */
712 /* Do this now because even if this we're on the last command,
713 we need another slot to mark the last entry */
714 if (cur_cmd == num_cmds) {
715 num_cmds *= 2;
716 entcmd = xrealloc(entcmd, num_cmds * sizeof(entropy_source_t));
717 }
686 } 718 }
687 719
688 /* zero the last entry */ 720 /* zero the last entry */
689 memset(&entcmd[cur_cmd], '\0', sizeof(entropy_source_t)); 721 memset(&entcmd[cur_cmd], '\0', sizeof(entropy_source_t));
722
690 /* trim to size */ 723 /* trim to size */
691 entropy_sources = xrealloc(entcmd, (cur_cmd+1) * sizeof(entropy_source_t)); 724 entropy_sources = xrealloc(entcmd, (cur_cmd+1) * sizeof(entropy_source_t));
692 725
@@ -695,28 +728,6 @@ prng_read_commands(char *cmdfilename)
695 return (cur_cmd >= MIN_ENTROPY_SOURCES); 728 return (cur_cmd >= MIN_ENTROPY_SOURCES);
696} 729}
697 730
698
699#endif /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */
700
701#if defined(EGD_SOCKET) || defined(RANDOM_POOL)
702
703/*
704 * Seed OpenSSL's random number pool from Kernel random number generator
705 * or EGD
706 */
707void
708seed_rng(void)
709{
710 char buf[32];
711
712 debug("Seeding random number generator");
713 get_random_bytes(buf, sizeof(buf));
714 RAND_add(buf, sizeof(buf), sizeof(buf));
715 memset(buf, '\0', sizeof(buf));
716}
717
718#else /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */
719
720/* 731/*
721 * Write a keyfile at exit 732 * Write a keyfile at exit
722 */ 733 */
diff --git a/ssh_prng_cmds.in b/ssh_prng_cmds.in
index 16ecb30bb..df45ed22e 100644
--- a/ssh_prng_cmds.in
+++ b/ssh_prng_cmds.in
@@ -5,46 +5,46 @@
5# The "rate" represents the number of bits of usuable entropy per 5# The "rate" represents the number of bits of usuable entropy per
6# byte of command output. Be conservative. 6# byte of command output. Be conservative.
7 7
8"ls -alni /var/log" @PROG_LS@ 0.002 8"ls -alni /var/log" @PROG_LS@ 0.02
9"ls -alni /var/adm" @PROG_LS@ 0.002 9"ls -alni /var/adm" @PROG_LS@ 0.02
10"ls -alni /var/mail" @PROG_LS@ 0.002 10"ls -alni /var/mail" @PROG_LS@ 0.02
11"ls -alni /var/spool/mail" @PROG_LS@ 0.002 11"ls -alni /var/spool/mail" @PROG_LS@ 0.02
12"ls -alni /proc" @PROG_LS@ 0.002 12"ls -alni /proc" @PROG_LS@ 0.02
13"ls -alni /tmp" @PROG_LS@ 0.002 13"ls -alni /tmp" @PROG_LS@ 0.02
14 14
15"netstat -an" @PROG_NETSTAT@ 0.005 15"netstat -an" @PROG_NETSTAT@ 0.05
16"netstat -in" @PROG_NETSTAT@ 0.010 16"netstat -in" @PROG_NETSTAT@ 0.05
17"netstat -rn" @PROG_NETSTAT@ 0.002 17"netstat -rn" @PROG_NETSTAT@ 0.02
18"netstat -s" @PROG_NETSTAT@ 0.002 18"netstat -s" @PROG_NETSTAT@ 0.02
19 19
20"arp -a -n" @PROG_ARP@ 0.002 20"arp -a -n" @PROG_ARP@ 0.02
21 21
22"ifconfig -a" @PROG_IFCONFIG@ 0.002 22"ifconfig -a" @PROG_IFCONFIG@ 0.02
23 23
24"ps laxww" @PROG_PS@ 0.003 24"ps laxww" @PROG_PS@ 0.03
25"ps -al" @PROG_PS@ 0.003 25"ps -al" @PROG_PS@ 0.03
26"ps -efl" @PROG_PS@ 0.003 26"ps -efl" @PROG_PS@ 0.03
27 27
28"w" @PROG_W@ 0.005 28"w" @PROG_W@ 0.05
29 29
30"who -i" @PROG_WHO@ 0.001 30"who -i" @PROG_WHO@ 0.01
31 31
32"last" @PROG_LAST@ 0.001 32"last" @PROG_LAST@ 0.01
33 33
34"lastlog" @PROG_LASTLOG@ 0.001 34"lastlog" @PROG_LASTLOG@ 0.01
35 35
36"df" @PROG_DF@ 0.010 36"df" @PROG_DF@ 0.01
37"df -i" @PROG_DF@ 0.010 37"df -i" @PROG_DF@ 0.01
38 38
39"vmstat" @PROG_VMSTAT@ 0.010 39"vmstat" @PROG_VMSTAT@ 0.01
40"uptime" @PROG_UPTIME@ 0.001 40"uptime" @PROG_UPTIME@ 0.01
41 41
42"ipcs -a" @PROG_IPCS@ 0.001 42"ipcs -a" @PROG_IPCS@ 0.01
43 43
44"tail -200 /var/log/messages" @PROG_TAIL@ 0.001 44"tail -200 /var/log/messages" @PROG_TAIL@ 0.01
45"tail -200 /var/log/syslog" @PROG_TAIL@ 0.001 45"tail -200 /var/log/syslog" @PROG_TAIL@ 0.01
46"tail -200 /var/adm/messages" @PROG_TAIL@ 0.001 46"tail -200 /var/adm/messages" @PROG_TAIL@ 0.01
47"tail -200 /var/adm/syslog" @PROG_TAIL@ 0.001 47"tail -200 /var/adm/syslog" @PROG_TAIL@ 0.01
48"tail -200 /var/adm/syslog/syslog.log" @PROG_TAIL@ 0.001 48"tail -200 /var/adm/syslog/syslog.log" @PROG_TAIL@ 0.01
49"tail -200 /var/log/maillog" @PROG_TAIL@ 0.001 49"tail -200 /var/log/maillog" @PROG_TAIL@ 0.01
50"tail -200 /var/adm/maillog" @PROG_TAIL@ 0.001 50"tail -200 /var/adm/maillog" @PROG_TAIL@ 0.01