From d0ccb989c2ccb190bf81819c4b6418d63c682538 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 4 Mar 2001 00:29:20 +1100 Subject: [PATCH] - Allow PRNGd entropy collection from localhost TCP socket. Replace "--with-egd-pool" configure option with "--with-prngd-socket" and "--with-prngd-port" options. Debugged and improved by Lutz Jaenicke --- ChangeLog | 6 ++++- INSTALL | 11 +++++--- acconfig.h | 9 ++++--- configure.in | 43 +++++++++++++++++++----------- entropy.c | 75 ++++++++++++++++++++++++++++++++++++---------------- 5 files changed, 99 insertions(+), 45 deletions(-) diff --git a/ChangeLog b/ChangeLog index 71da4c457..7313e0a47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,10 @@ - Remove make-ssh-known-hosts.pl, ssh-keyscan is better. - Document PAM ChallengeResponseAuthentication in sshd.8 - Disable and comment ChallengeResponseAuthentication in sshd_config + - Allow PRNGd entropy collection from localhost TCP socket. Replace + "--with-egd-pool" configure option with "--with-prngd-socket" and + "--with-prngd-port" options. Debugged and improved by Lutz Jaenicke + 20010301 - (djm) Properly add -lcrypt if needed. @@ -4180,4 +4184,4 @@ - Wrote replacements for strlcpy and mkdtemp - Released 1.0pre1 -$Id: ChangeLog,v 1.847 2001/03/03 13:16:20 djm Exp $ +$Id: ChangeLog,v 1.848 2001/03/03 13:29:20 djm Exp $ diff --git a/INSTALL b/INSTALL index 47b071e1a..6778a2881 100644 --- a/INSTALL +++ b/INSTALL @@ -119,8 +119,13 @@ headers, for this to work. random numbers (the default is /dev/urandom). Unless you are absolutely sure of what you are doing, it is best to leave this alone. ---with-egd-pool=/some/file allows you to enable EGD or PRNGD support -and to specify a EGD pool socket. Use this if your Unix lacks +--with-prngd-socket=/some/file allows you to enable EGD or PRNGD +support and to specify a PRNGd socket. Use this if your Unix lacks +/dev/random and you don't want to use OpenSSH's builtin entropy +collection support. + +--with-prngd-port=portnum allows you to enable EGD or PRNGD support +and to specify a EGD localhost TCP port. Use this if your Unix lacks /dev/random and you don't want to use OpenSSH's builtin entropy collection support. @@ -217,4 +222,4 @@ Please refer to the "reporting bugs" section of the webpage at http://www.openssh.com/ -$Id: INSTALL,v 1.41 2001/02/18 01:58:24 djm Exp $ +$Id: INSTALL,v 1.42 2001/03/03 13:29:21 djm Exp $ diff --git a/acconfig.h b/acconfig.h index a43435868..db53d1696 100644 --- a/acconfig.h +++ b/acconfig.h @@ -1,4 +1,4 @@ -/* $Id: acconfig.h,v 1.105 2001/02/26 21:39:07 djm Exp $ */ +/* $Id: acconfig.h,v 1.106 2001/03/03 13:29:21 djm Exp $ */ #ifndef _CONFIG_H #define _CONFIG_H @@ -89,8 +89,11 @@ /* Location of random number pool */ #undef RANDOM_POOL -/* Location of EGD random number socket */ -#undef EGD_SOCKET +/* Location of PRNGD/EGD random number socket */ +#undef PRNGD_SOCKET + +/* Port number of PRNGD/EGD random number socket */ +#undef PRNGD_PORT /* Builtin PRNG command timeout */ #undef ENTROPY_TIMEOUT_MSEC diff --git a/configure.in b/configure.in index 69db290c4..de3a2fb8f 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -# $Id: configure.in,v 1.260 2001/02/28 22:16:12 djm Exp $ +# $Id: configure.in,v 1.261 2001/03/03 13:29:21 djm Exp $ AC_INIT(ssh.c) @@ -1266,13 +1266,24 @@ AC_ARG_WITH(random, ] ) -# Check for EGD pool file -AC_ARG_WITH(egd-pool, - [ --with-egd-pool=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool)], +# Check for PRNGD/EGD pool file +AC_ARG_WITH(prngd-port, + [ --with-prngd-port=PORT read entropy from PRNGD/EGD localhost:PORT], + [ + if test ! -z "$withval" -a "x$withval" != "xno" ; then + PRNGD_PORT="$withval" + AC_DEFINE_UNQUOTED(PRNGD_PORT, $PRNGD_PORT) + fi + ] +) + +# Check for PRNGD/EGD pool file +AC_ARG_WITH(prngd-socket, + [ --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool)], [ if test "x$withval" != "xno" ; then - EGD_SOCKET="$withval"; - AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET") + PRNGD_SOCKET="$withval" + AC_DEFINE_UNQUOTED(PRNGD_SOCKET, "$PRNGD_SOCKET") fi ], [ @@ -1280,15 +1291,15 @@ AC_ARG_WITH(egd-pool, if test -z "$RANDOM_POOL" ; then AC_MSG_CHECKING(for PRNGD/EGD socket) # Insert other locations here - for egdsock in /var/run/egd-pool /etc/entropy; do - if test -r $egdsock && $TEST_MINUS_S_SH -c "test -S $egdsock -o -p $egdsock" ; then - EGD_SOCKET="$egdsock" - AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET") + for sock in /var/run/egd-pool /etc/entropy; do + if test -r $sock && $TEST_MINUS_S_SH -c "test -S $sock -o -p $sock" ; then + PRNGD_SOCKET="$sock" + AC_DEFINE_UNQUOTED(PRNGD_SOCKET, "$PRNGD_SOCKET") break; fi done - if test ! -z "$EGD_SOCKET" ; then - AC_MSG_RESULT($EGD_SOCKET) + if test ! -z "$PRNGD_SOCKET" ; then + AC_MSG_RESULT($PRNGD_SOCKET) else AC_MSG_RESULT(not found) fi @@ -1300,7 +1311,7 @@ AC_ARG_WITH(egd-pool, # detect pathnames for entropy gathering commands, if we need them INSTALL_SSH_PRNG_CMDS="" rm -f prng_commands -if (test -z "$RANDOM_POOL" && test -z "$EGD_SOCKET") ; then +if (test -z "$RANDOM_POOL" && test -z "$PRNGD") ; then # Use these commands to collect entropy OSSH_PATH_ENTROPY_PROG(PROG_LS, ls) OSSH_PATH_ENTROPY_PROG(PROG_NETSTAT, netstat) @@ -1749,8 +1760,10 @@ fi if test ! -z "$RANDOM_POOL" ; then RAND_MSG="Device ($RANDOM_POOL)" else - if test ! -z "$EGD_SOCKET" ; then - RAND_MSG="EGD/PRNGD ($EGD_SOCKET)" + if test ! -z "$PRNGD_PORT" ; then + RAND_MSG="PRNGD/EGD (port localhost:$PRNGD_PORT)" + elif test ! -z "$PRNGD_SOCKET" ; then + RAND_MSG="PRNGD/EGD (socket $PRNGD_SOCKET)" else RAND_MSG="Builtin (timeout $entropy_timeout)" BUILTIN_RNG=1 diff --git a/entropy.c b/entropy.c index 3b0893b3e..665f77324 100644 --- a/entropy.c +++ b/entropy.c @@ -40,7 +40,7 @@ #include "pathnames.h" #include "log.h" -RCSID("$Id: entropy.c,v 1.34 2001/02/27 00:00:52 djm Exp $"); +RCSID("$Id: entropy.c,v 1.35 2001/03/03 13:29:21 djm Exp $"); #ifndef offsetof # define offsetof(type, member) ((size_t) &((type *)0)->member) @@ -75,47 +75,76 @@ void check_openssl_version(void) "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 */ +#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 +154,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 +165,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,7 +177,7 @@ 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) @@ -174,16 +203,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"); @@ -202,7 +231,7 @@ 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 @@ -877,4 +906,4 @@ void init_rng(void) prng_initialised = 1; } -#endif /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */ +#endif /* defined(USE_PRNGD) || defined(RANDOM_POOL) */