From be0b9bb72147c9ea8bfb2fac41d4c3feff1ca312 Mon Sep 17 00:00:00 2001 From: djm Date: Mon, 26 Jun 2000 03:01:33 +0000 Subject: [PATCH] - (djm) Make EGD failures non-fatal if OpenSSL's entropy pool is still OK based on patch from Lutz Jaenicke --- ChangeLog | 2 ++ README | 9 +++++- entropy.c | 97 ++++++++++++++++++++++++++++++++++--------------------- 3 files changed, 70 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index a4189801..9fd1c786 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,8 @@ - (djm) Better fix to aclocal tests from Garrick James - (djm) Account expiry support from Andreas Steinmetz - (djm) Added password expiry checking (no password change support) + - (djm) Make EGD failures non-fatal if OpenSSL's entropy pool is still OK + based on patch from Lutz Jaenicke - OpenBSD CVS update - provos@cvs.openbsd.org 2000/06/25 14:17:58 [channels.c] diff --git a/README b/README index c5142884..54adb10e 100644 --- a/README +++ b/README @@ -37,9 +37,15 @@ There is now several mailing lists for this port of OpenSSH. Please refer to http://www.openssh.com/list.html for details on how to join. Please send bug reports and patches to the mailing list -openssh-unix-dev@mindrot.org. The list is currently open to posting by +openssh-unix-dev@mindrot.org. The list is open to posting by unsubscribed users. +If you are a citizen of the USA or another country which restricts +export of cryptographic products, then please refrain from sending +crypto-related code or patches to the list. We cannot accept them. +Other code contribution are accepted, but please follow the OpenBSD +style guidelines[5]. + Please refer to the INSTALL document for information on how to install OpenSSH on your system. The UPGRADING document details differences between this port of OpenSSH and F-Secure SSH 1.x. @@ -59,4 +65,5 @@ References - [2] ftp://ftp.freesoftware.com/pub/infozip/zlib/ [3] http://www.openssl.org/ [4] http://www.kernel.org/pub/linux/libs/pam/ (PAM is standard on Solaris) +[5] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9&apropos=0&manpath=OpenBSD+Current diff --git a/entropy.c b/entropy.c index 0b86fdf0..96e6e85f 100644 --- a/entropy.c +++ b/entropy.c @@ -66,64 +66,83 @@ RCSID("$Id$"); #ifdef EGD_SOCKET /* Collect entropy from EGD */ -void get_random_bytes(unsigned char *buf, int len) +int get_random_bytes(unsigned char *buf, int len) { - static int egd_socket = -1; - int c; - char egd_message[2] = { 0x02, 0x00 }; + int fd; + char msg[2]; struct sockaddr_un addr; int addr_len; - memset(&addr, '\0', sizeof(addr)); - addr.sun_family = AF_UNIX; - - /* FIXME: compile time check? */ + /* Sanity checks */ if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path)) fatal("Random pool path is too long"); - + if (len > 255) + fatal("Too many bytes to read from EGD"); + + 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); - if (egd_socket == -1) { - egd_socket = socket(AF_UNIX, SOCK_STREAM, 0); - if (egd_socket == -1) - fatal("Couldn't create AF_UNIX socket: %s", strerror(errno)); - if (connect(egd_socket, (struct sockaddr*)&addr, addr_len) == -1) - fatal("Couldn't connect to EGD socket \"%s\": %s", addr.sun_path, strerror(errno)); - } + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { + error("Couldn't create AF_UNIX socket: %s", strerror(errno)); + return(0); + } + + if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) { + error("Couldn't connect to EGD socket \"%s\": %s", + addr.sun_path, strerror(errno)); + close(fd); + return(0); + } - if (len > 255) - fatal("Too many bytes to read from EGD"); - /* Send blocking read request to EGD */ - egd_message[1] = len; + msg[0] = 0x02; + msg[1] = len; - c = atomicio(write, egd_socket, egd_message, sizeof(egd_message)); - if (c == -1) - fatal("Couldn't write to EGD socket \"%s\": %s", EGD_SOCKET, strerror(errno)); + if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) { + error("Couldn't write to EGD socket \"%s\": %s", + EGD_SOCKET, strerror(errno)); + close(fd); + return(0); + } - c = atomicio(read, egd_socket, buf, len); - if (c <= 0) - fatal("Couldn't read from EGD socket \"%s\": %s", EGD_SOCKET, strerror(errno)); + if (atomicio(read, fd, buf, len) != len) { + error("Couldn't read from EGD socket \"%s\": %s", + EGD_SOCKET, strerror(errno)); + close(fd); + return(0); + } + + close(fd); + + return(1); } #else /* !EGD_SOCKET */ #ifdef RANDOM_POOL /* Collect entropy from /dev/urandom or pipe */ -void get_random_bytes(unsigned char *buf, int len) +int get_random_bytes(unsigned char *buf, int len) { - static int random_pool = -1; - int c; + int random_pool; + random_pool = open(RANDOM_POOL, O_RDONLY); if (random_pool == -1) { - random_pool = open(RANDOM_POOL, O_RDONLY); - if (random_pool == -1) - fatal("Couldn't open random pool \"%s\": %s", RANDOM_POOL, strerror(errno)); + error("Couldn't open random pool \"%s\": %s", + RANDOM_POOL, strerror(errno)); + return(0); } - c = atomicio(read, random_pool, buf, len); - if (c <= 0) - fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno)); + if (atomicio(read, random_pool, buf, len) != len) { + error("Couldn't read from random pool \"%s\": %s", + RANDOM_POOL, strerror(errno)); + close(random_pool); + return(0); + } + + close(random_pool); + + return(1); } #endif /* RANDOM_POOL */ #endif /* EGD_SOCKET */ @@ -138,8 +157,12 @@ seed_rng(void) char buf[32]; debug("Seeding random number generator"); - get_random_bytes(buf, sizeof(buf)); + + if (!get_random_bytes(buf, sizeof(buf)) && !RAND_status()) + fatal("Entropy collection failed and entropy exhausted"); + RAND_add(buf, sizeof(buf), sizeof(buf)); + memset(buf, '\0', sizeof(buf)); } -- 2.45.1