X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/32e0cb42c43d036d846128d3788e4061a3c0df69..27c47c0ad07c3e63270ef33b5f3f7226d4d58582:/entropy.c diff --git a/entropy.c b/entropy.c index 55df6c9f..9588f792 100644 --- a/entropy.c +++ b/entropy.c @@ -68,54 +68,85 @@ RCSID("$Id$"); # define SAVED_IDS_WORK_WITH_SETEUID #endif -void check_openssl_version(void) +static void +check_openssl_version(void) { if (SSLeay() != OPENSSL_VERSION_NUMBER) fatal("OpenSSL version mismatch. Built against %lx, you " "have %lx", OPENSSL_VERSION_NUMBER, SSLeay()); } +#if defined(PRNGD_SOCKET) || defined(PRNGD_PORT) +# define USE_PRNGD +#endif -#if defined(EGD_SOCKET) || defined(RANDOM_POOL) +#if defined(USE_PRNGD) || defined(RANDOM_POOL) -#ifdef EGD_SOCKET -/* Collect entropy from EGD */ -int get_random_bytes(unsigned char *buf, int len) +#ifdef USE_PRNGD +/* Collect entropy from PRNGD/EGD */ +int +get_random_bytes(unsigned char *buf, int len) { int fd; char msg[2]; +#ifdef PRNGD_PORT + struct sockaddr_in addr; +#else struct sockaddr_un addr; +#endif int addr_len, rval, errors; mysig_t old_sigpipe; + memset(&addr, '\0', sizeof(addr)); + +#ifdef PRNGD_PORT + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = htons(PRNGD_PORT); + addr_len = sizeof(struct sockaddr_in); +#else /* use IP socket PRNGD_SOCKET instead */ /* Sanity checks */ - if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path)) + if (sizeof(PRNGD_SOCKET) > sizeof(addr.sun_path)) fatal("Random pool path is too long"); if (len > 255) - fatal("Too many bytes to read from EGD"); + fatal("Too many bytes to read from PRNGD"); - memset(&addr, '\0', sizeof(addr)); addr.sun_family = AF_UNIX; - strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path)); - addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET); + strlcpy(addr.sun_path, PRNGD_SOCKET, sizeof(addr.sun_path)); + addr_len = offsetof(struct sockaddr_un, sun_path) + + sizeof(PRNGD_SOCKET); +#endif old_sigpipe = mysignal(SIGPIPE, SIG_IGN); errors = rval = 0; reopen: - fd = socket(AF_UNIX, SOCK_STREAM, 0); +#ifdef PRNGD_PORT + fd = socket(addr.sin_family, SOCK_STREAM, 0); + if (fd == -1) { + error("Couldn't create AF_INET socket: %s", strerror(errno)); + goto done; + } +#else + fd = socket(addr.sun_family, SOCK_STREAM, 0); if (fd == -1) { error("Couldn't create AF_UNIX socket: %s", strerror(errno)); goto done; } +#endif if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) { - error("Couldn't connect to EGD socket \"%s\": %s", - addr.sun_path, strerror(errno)); +#ifdef PRNGD_PORT + error("Couldn't connect to PRNGD port %d: %s", + PRNGD_PORT, strerror(errno)); +#else + error("Couldn't connect to PRNGD socket \"%s\": %s", + addr.sun_path, strerror(errno)); +#endif goto done; } - /* Send blocking read request to EGD */ + /* Send blocking read request to PRNGD */ msg[0] = 0x02; msg[1] = len; @@ -125,8 +156,8 @@ reopen: errors++; goto reopen; } - error("Couldn't write to EGD socket \"%s\": %s", - EGD_SOCKET, strerror(errno)); + error("Couldn't write to PRNGD socket: %s", + strerror(errno)); goto done; } @@ -136,8 +167,8 @@ reopen: errors++; goto reopen; } - error("Couldn't read from EGD socket \"%s\": %s", - EGD_SOCKET, strerror(errno)); + error("Couldn't read from PRNGD socket: %s", + strerror(errno)); goto done; } @@ -148,10 +179,11 @@ done: close(fd); return(rval); } -#else /* !EGD_SOCKET */ +#else /* !USE_PRNGD */ #ifdef RANDOM_POOL /* Collect entropy from /dev/urandom or pipe */ -int get_random_bytes(unsigned char *buf, int len) +static int +get_random_bytes(unsigned char *buf, int len) { int random_pool; @@ -174,16 +206,16 @@ int get_random_bytes(unsigned char *buf, int len) return(1); } #endif /* RANDOM_POOL */ -#endif /* EGD_SOCKET */ +#endif /* USE_PRNGD */ /* * Seed OpenSSL's random number pool from Kernel random number generator - * or EGD + * or PRNGD/EGD */ void seed_rng(void) { - char buf[32]; + unsigned char buf[32]; debug("Seeding random number generator"); @@ -197,12 +229,13 @@ seed_rng(void) memset(buf, '\0', sizeof(buf)); } -void init_rng(void) +void +init_rng(void) { check_openssl_version(); } -#else /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */ +#else /* defined(USE_PRNGD) || defined(RANDOM_POOL) */ /* * FIXME: proper entropy estimations. All current values are guesses @@ -374,8 +407,7 @@ stir_rusage(int who, double entropy_estimate) } -static -int +static int _get_timeval_msec_difference(struct timeval *t1, struct timeval *t2) { int secdiff, usecdiff; @@ -473,7 +505,9 @@ hash_output_from_command(entropy_source_t *src, char *hash) break; case 1: /* command input */ - bytes_read = read(p[0], buf, sizeof(buf)); + do { + bytes_read = read(p[0], buf, sizeof(buf)); + } while (bytes_read == -1 && errno == EINTR); RAND_add(&bytes_read, sizeof(&bytes_read), 0.0); if (bytes_read == -1) { error_abort = 1; @@ -813,8 +847,10 @@ seed_rng(void) /* commands */ old_sigchld_handler = mysignal(SIGCHLD, SIG_DFL); - debug("Seeded RNG with %i bytes from programs", (int)stir_from_programs()); - debug("Seeded RNG with %i bytes from system calls", (int)stir_from_system()); + debug("Seeded RNG with %i bytes from programs", + (int)stir_from_programs()); + debug("Seeded RNG with %i bytes from system calls", + (int)stir_from_system()); if (!RAND_status()) fatal("Not enough entropy in RNG"); @@ -825,7 +861,8 @@ seed_rng(void) fatal("Couldn't initialise builtin random number generator -- exiting."); } -void init_rng(void) +void +init_rng(void) { int original_euid; @@ -877,4 +914,4 @@ void init_rng(void) prng_initialised = 1; } -#endif /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */ +#endif /* defined(USE_PRNGD) || defined(RANDOM_POOL) */