]> andersk Git - openssh.git/commitdiff
- Wrote entropy collection routines for systems that lack /dev/random
authordamien <damien>
Mon, 3 Apr 2000 04:50:43 +0000 (04:50 +0000)
committerdamien <damien>
Mon, 3 Apr 2000 04:50:43 +0000 (04:50 +0000)
   and EGD

12 files changed:
ChangeLog
Makefile.in
README
acconfig.h
bsd-misc.c
bsd-misc.h
configure.in
entropy.c [new file with mode: 0644]
entropy.h [new file with mode: 0644]
random.c [deleted file]
random.h [deleted file]
rsa.c

index 585686e2af11a64a9986c0148c0b8b59e3950dbe..978c40828f1fcf2167c525e82c846446d7e57bd9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+20000403
+ - Wrote entropy collection routines for systems that lack /dev/random
+   and EGD
+
 20000401
  - Big OpenBSD CVS update (mainly beginnings of SSH2 infrastructure)
    - [auth.c session.c sshd.c auth.h]
index 43870d5f94e89d4ffae3e9069f56c90a8d9bdc2f..89b408487defca3e601820d3e551aa3429361e9d 100644 (file)
@@ -31,7 +31,7 @@ LDFLAGS=-L. @LDFLAGS@
 
 TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS)
 
-LIBOBJS= atomicio.o authfd.o authfile.o bsd-bindresvport.o bsd-daemon.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o fake-getaddrinfo.o fake-getnameinfo.o fingerprint.o hostfile.o key.o log.o match.o mpaux.o nchan.o packet.o radix.o random.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o 
+LIBOBJS= atomicio.o authfd.o authfile.o bsd-bindresvport.o bsd-daemon.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o fake-getaddrinfo.o fake-getnameinfo.o fingerprint.o hostfile.o key.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o 
 
 SSHOBJS= ssh.o sshconnect.o log-client.o readconf.o clientloop.o
 
diff --git a/README b/README
index ecd82c4d8c97160283f45ead9632bb117b05ef5e..450d81c5cce445d183470477a6c456d7bb8fe4fa 100644 (file)
--- a/README
+++ b/README
@@ -32,11 +32,6 @@ The PAM support is now more functional than the popular packages of
 commercial ssh-1.2.x. It checks "account" and "session" modules for
 all logins, not just when using password authentication.
 
-All new code is released under a XFree style license, which is very
-liberal. Please refer to the source files for details. The code in
-bsd-*.[ch] is from the OpenBSD project and has its own license (again,
-see the source files for details).
-
 OpenSSH depends on Zlib[2], OpenSSL[3] and optionally PAM[4] and
 Dante[6]. To build the GNOME[5] pass-phrase requester
 (--with-gnome-askpass), you will need the GNOME libraries installed.
@@ -64,10 +59,6 @@ This version of SSH is based upon code retrieved from the OpenBSD CVS
 repository which in turn was based on the last free 
 version of SSH released by Tatu Ylonen.
 
-Code in bsd-misc.[ch] and gnome-ssh-askpass.c is Copyright 1999 Damien
-Miller & Internet Business Solutions and is released under a X11-style
-license (see source files for details).
-
 References -
 
 [1] http://www.lothar.com/tech/crypto/
index 32764f0926c51b196dd8627d18e360aa16bf92a2..cbb3a97cd9a4fc079b68a3b21ba5e06ff1071c96 100644 (file)
 /* Location of random number pool  */
 #undef RANDOM_POOL
 
-/* Are we using the Entropy gathering daemon */
-#undef HAVE_EGD
-
-/* Define if using the Dante SOCKS library. */
-#undef HAVE_DANTE
-
-/* Define if using the Socks4 SOCKS library. */
-#undef HAVE_SOCKS4
-
-/* Define if using the Socks5 SOCKS library. */
-#undef HAVE_SOCKS5
+/* Location of EGD random number socket */
+#undef EGD_SOCKET
 
 /* Define if you want to install preformatted manpages.*/
 #undef MANTYPE
 /* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */
 #undef IPV4_IN_IPV6
 
+/* Programs used in entropy collection */
+#undef PROG_LS
+#undef PROG_NETSTAT
+#undef PROG_ARP
+#undef PROG_IFCONFIG
+#undef PROG_PS
+#undef PROG_W
+#undef PROG_WHO
+#undef PROG_LAST
+#undef PROG_LASTLOG
+#undef PROG_DF
+#undef PROG_VMSTAT
+#undef PROG_UPTIME
+#undef PROG_IPCS
+#undef PROG_TAIL
+
+
 @BOTTOM@
 
 /* ******************* Shouldn't need to edit below this line ************** */
index dd1f6a4764be6201cec9ee5d35fe0aceb91948f4..3186c86d869db17c3db9507292ef496813fe0124 100644 (file)
@@ -1,38 +1,31 @@
 /*
-**
-** OpenBSD replacement routines
-**
-** Damien Miller <djm@ibs.com.au>
-** 
-** Copyright 1999 Damien Miller
-** Copyright 1999 Internet Business Solutions
-**
-** Permission is hereby granted, free of charge, to any person
-** obtaining a copy of this software and associated documentation
-** files (the "Software"), to deal in the Software without
-** restriction, including without limitation the rights to use, copy,
-** modify, merge, publish, distribute, sublicense, and/or sell copies
-** of the Software, and to permit persons to whom the Software is
-** furnished to do so, subject to the following conditions:
-**
-** The above copyright notice and this permission notice shall be
-** included in all copies or substantial portions of the Software.
-**
-** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-** KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-** WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
-** AND NONINFRINGEMENT.  IN NO EVENT SHALL DAMIEN MILLER OR INTERNET
-** BUSINESS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
-** OR OTHER DEALINGS IN THE SOFTWARE.
-**
-** Except as contained in this notice, the name of Internet Business
-** Solutions shall not be used in advertising or otherwise to promote
-** the sale, use or other dealings in this Software without prior
-** written authorization from Internet Business Solutions.
-**
-*/
+ * Copyright (c) 1999-2000 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Markus Friedl.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #include "config.h"
 
@@ -52,7 +45,7 @@
 #include "xmalloc.h"
 #include "ssh.h"
 #include "bsd-misc.h"
-#include "random.h"
+#include "entropy.h"
 
 #ifndef HAVE_ARC4RANDOM
 
@@ -125,8 +118,11 @@ void arc4random_stir(void)
        
        if (rc4 == NULL)
                rc4 = xmalloc(sizeof(*rc4));
+
+       seed_rng();
+       RAND_bytes(rand_buf, sizeof(rand_buf));
+       seed_rng();
        
-       get_random_bytes(rand_buf, sizeof(rand_buf));
        rc4_key(rc4, rand_buf, sizeof(rand_buf));
        memset(rand_buf, 0, sizeof(rand_buf));
 }
index 9d499c805085f7369a93ba31bc8c67f4b26fade2..cdf8e2b6782f2f7d2c4792be85ddb76708bf20e9 100644 (file)
@@ -1,38 +1,31 @@
 /*
-**
-** OpenBSD replacement routines
-**
-** Damien Miller <djm@ibs.com.au>
-** 
-** Copyright 1999 Damien Miller
-** Copyright 1999 Internet Business Solutions
-**
-** Permission is hereby granted, free of charge, to any person
-** obtaining a copy of this software and associated documentation
-** files (the "Software"), to deal in the Software without
-** restriction, including without limitation the rights to use, copy,
-** modify, merge, publish, distribute, sublicense, and/or sell copies
-** of the Software, and to permit persons to whom the Software is
-** furnished to do so, subject to the following conditions:
-**
-** The above copyright notice and this permission notice shall be
-** included in all copies or substantial portions of the Software.
-**
-** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-** KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-** WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
-** AND NONINFRINGEMENT.  IN NO EVENT SHALL DAMIEN MILLER OR INTERNET
-** BUSINESS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
-** OR OTHER DEALINGS IN THE SOFTWARE.
-**
-** Except as contained in this notice, the name of Internet Business
-** Solutions shall not be used in advertising or otherwise to promote
-** the sale, use or other dealings in this Software without prior
-** written authorization from Internet Business Solutions.
-**
-*/
+ * Copyright (c) 1999-2000 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Markus Friedl.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #ifndef _BSD_MISC_H
 #define _BSD_MISC_H
index 2d2fbe1ac780edb6f1ce7905c4a53f5d4c1fb8b4..6c9ea3129af48aec8fe7ad5a1f3c51df858acd01 100644 (file)
@@ -12,6 +12,36 @@ AC_CHECK_PROG(AR, ar, ar)
 AC_PATH_PROG(PERL, perl)
 AC_SUBST(PERL)
 
+# We may need these for entropy collection
+AC_PATH_PROG(PROG_LS, ls)
+AC_DEFINE_UNQUOTED(PROG_LS, "$PROG_LS")
+AC_PATH_PROG(PROG_NETSTAT, netstat)
+AC_DEFINE_UNQUOTED(PROG_NETSTAT, "$PROG_NETSTAT")
+AC_PATH_PROG(PROG_ARP, arp)
+AC_DEFINE_UNQUOTED(PROG_ARP, "$PROG_ARP")
+AC_PATH_PROG(PROG_IFCONFIG, ifconfig)
+AC_DEFINE_UNQUOTED(PROG_IFCONFIG, "$PROG_IFCONFIG")
+AC_PATH_PROG(PROG_PS, ps)
+AC_DEFINE_UNQUOTED(PROG_PS, "$PROG_PS")
+AC_PATH_PROG(PROG_W, w)
+AC_DEFINE_UNQUOTED(PROG_W, "$PROG_W")
+AC_PATH_PROG(PROG_WHO, who)
+AC_DEFINE_UNQUOTED(PROG_WHO, "$PROG_WHO")
+AC_PATH_PROG(PROG_LAST, last)
+AC_DEFINE_UNQUOTED(PROG_LAST, "$PROG_LAST")
+AC_PATH_PROG(PROG_LASTLOG, lastlog)
+AC_DEFINE_UNQUOTED(PROG_LASTLOG, "$PROG_LASTLOG")
+AC_PATH_PROG(PROG_DF, df)
+AC_DEFINE_UNQUOTED(PROG_DF, "$PROG_DF")
+AC_PATH_PROG(PROG_VMSTAT, vmstat)
+AC_DEFINE_UNQUOTED(PROG_VMSTAT, "$PROG_VMSTAT")
+AC_PATH_PROG(PROG_UPTIME, uptime)
+AC_DEFINE_UNQUOTED(PROG_UPTIME, "$PROG_UPTIME")
+AC_PATH_PROG(PROG_IPCS, ipcs)
+AC_DEFINE_UNQUOTED(PROG_UPTIME, "$PROG_UPTIME")
+AC_PATH_PROG(PROG_TAIL, tail)
+AC_DEFINE_UNQUOTED(PROG_TAIL, "$PROG_TAIL")
+
 if test -z "$LD" ; then
        LD=$CC
 fi
@@ -110,7 +140,7 @@ fi
 AC_CHECK_HEADERS(bstring.h endian.h lastlog.h login.h maillock.h netdb.h netgroup.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h util.h utmp.h utmpx.h)
 
 # Checks for library functions.
-AC_CHECK_FUNCS(arc4random bindresvport_af freeaddrinfo gai_strerror getaddrinfo getnameinfo innetgr md5_crypt mkdtemp openpty rresvport_af setenv seteuid setlogin setproctitle setreuid snprintf strlcat strlcpy updwtmpx vsnprintf _getpty)
+AC_CHECK_FUNCS(arc4random bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage innetgr md5_crypt mkdtemp openpty rresvport_af setenv seteuid setlogin setproctitle setreuid snprintf strlcat strlcpy updwtmpx vsnprintf _getpty)
 
 AC_CHECK_FUNC(login, 
        [AC_DEFINE(HAVE_LOGIN)],
@@ -604,8 +634,10 @@ AC_CHECK_FILE("/dev/ptc",
 AC_ARG_WITH(random,
        [  --with-random=FILE      read randomness from FILE (default=/dev/urandom)],
        [
-               RANDOM_POOL="$withval";
-               AC_DEFINE_UNQUOTED(RANDOM_POOL, "$RANDOM_POOL")
+               if test "x$withval" != "xno" ; then
+                       RANDOM_POOL="$withval";
+                       AC_DEFINE_UNQUOTED(RANDOM_POOL, "$RANDOM_POOL")
+               fi
        ],
        [
                # Check for random device
@@ -623,18 +655,13 @@ AC_ARG_WITH(random,
 AC_ARG_WITH(egd-pool,
        [  --with-egd-pool=FILE    read randomness from EGD pool FILE (default none)],
        [
-               RANDOM_POOL="$withval";
-               AC_DEFINE(HAVE_EGD)
-               AC_SUBST(RANDOM_POOL)
-               AC_DEFINE_UNQUOTED(RANDOM_POOL, "$RANDOM_POOL")
+               if test "x$withval" != "xno" ; then
+                       EGD_SOCKET="$withval";
+                       AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET")
+               fi
        ]
 )
 
-# Make sure we have some random number support
-if test -z "$RANDOM_POOL" -a -z "$EGD_POOL"; then
-       AC_MSG_ERROR([No random device found, and no EGD random pool specified])
-fi
-
 AC_ARG_WITH(catman,
        [  --with-catman=man|cat   Install preformatted manpages[no]],
        [
diff --git a/entropy.c b/entropy.c
new file mode 100644 (file)
index 0000000..a1fe80c
--- /dev/null
+++ b/entropy.c
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 2000 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Markus Friedl.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+
+#include "ssh.h"
+#include "xmalloc.h"
+
+#ifdef HAVE_OPENSSL
+# include <openssl/rand.h>
+# include <openssl/sha.h>
+#endif
+#ifdef HAVE_SSL
+# include <ssl/rand.h>
+# include <ssl/sha.h>
+#endif
+
+RCSID("$Id$");
+
+#ifdef EGD_SOCKET
+#ifndef offsetof
+# define offsetof(type, member) ((size_t) &((type *)0)->member)
+#endif
+/* Collect entropy from EGD */
+void get_random_bytes(unsigned char *buf, int len)
+{
+       static int egd_socket = -1;
+       int c;
+       char egd_message[2] = { 0x02, 0x00 };
+       struct sockaddr_un addr;
+       int addr_len;
+
+       memset(&addr, '\0', sizeof(addr));
+       addr.sun_family = AF_UNIX;
+       
+       /* FIXME: compile time check? */
+       if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path))
+               fatal("Random pool path is too long");
+       
+       strcpy(addr.sun_path, EGD_SOCKET);
+       
+       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));
+       }       
+
+       if (len > 255)
+               fatal("Too many bytes to read from EGD");
+       
+       /* Send blocking read request to EGD */
+       egd_message[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));
+
+       c = atomicio(read, egd_socket, buf, len);
+       if (c <= 0)
+               fatal("Couldn't read from EGD socket \"%s\": %s", EGD_SOCKET, strerror(errno));
+       
+       close(EGD_SOCKET);
+}
+#else /* !EGD_SOCKET */
+#ifdef RANDOM_POOL
+/* Collect entropy from /dev/urandom or pipe */
+void get_random_bytes(unsigned char *buf, int len)
+{
+       static int random_pool = -1;
+       int c;
+
+       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));
+       }
+       
+       verbose("randfd: %i", random_pool);
+
+       c = atomicio(read, random_pool, buf, len);
+       if (c <= 0)
+               fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
+}
+#endif /* RANDOM_POOL */
+#endif /* EGD_SOCKET */
+
+#if !defined(EGD_SOCKET) && !defined(RANDOM_POOL)
+/* 
+ * FIXME: proper entropy estimations. All current values are guesses
+ * FIXME: Need timeout for slow moving programs
+ * FIXME: More entropy sources
+ */
+
+double stir_from_system(void);
+double stir_from_programs(void);
+double stir_gettimeofday(double entropy_estimate);
+double stir_clock(double entropy_estimate);
+double stir_rusage(int who, double entropy_estimate);
+double hash_output_from_command(const char *path, const char **args, char *hash);
+
+typedef struct
+{
+       /* Proportion of data that is entropy */
+       double rate;
+       /* Path to executable */
+       const char *path;
+       /* argv to pass to executable */
+       const char *args[5];
+} entropy_source_t;
+
+entropy_source_t entropy_sources[] = {
+#ifdef PROG_LS
+       { 0.002, PROG_LS,       { "ls", "-alni", "/var/log", NULL } },
+       { 0.002, PROG_LS,       { "ls", "-alni", "/var/adm", NULL } },
+       { 0.002, PROG_LS,       { "ls", "-alni", "/var/mail", NULL } },
+       { 0.002, PROG_LS,       { "ls", "-alni", "/var/spool/mail", NULL } },
+       { 0.002, PROG_LS,       { "ls", "-alni", "/proc", NULL } },
+       { 0.002, PROG_LS,       { "ls", "-alni", "/tmp", NULL } },
+#endif
+#ifdef PROG_NETSTAT
+       { 0.005, PROG_NETSTAT,  { "netstat","-an", NULL, NULL } },
+       { 0.010, PROG_NETSTAT,  { "netstat","-in", NULL, NULL } },
+       { 0.002, PROG_NETSTAT,  { "netstat","-rn", NULL, NULL } },
+       { 0.002, PROG_NETSTAT,  { "netstat","-s", NULL, NULL } },
+#endif
+#ifdef PROG_ARP
+       { 0.002, PROG_ARP,      { "arp","-a","-n", NULL } },
+#endif
+#ifdef PROG_IFCONFIG
+       { 0.002, PROG_IFCONFIG, { "ifconfig", "-a", NULL, NULL } },
+#endif
+#ifdef PROG_PS
+       { 0.003, PROG_PS,       { "ps", "laxww", NULL, NULL } },
+       { 0.003, PROG_PS,       { "ps", "-al", NULL, NULL } },
+       { 0.003, PROG_PS,       { "ps", "-efl", NULL, NULL } },
+#endif
+#ifdef PROG_W
+       { 0.005, PROG_W,        { "w", NULL, NULL, NULL } },
+#endif
+#ifdef PROG_WHO
+       { 0.001, PROG_WHO,      { "who","-i", NULL, NULL } },
+#endif
+#ifdef PROG_LAST
+       { 0.001, PROG_LAST,     { "last", NULL, NULL, NULL } },
+#endif
+#ifdef PROG_LASTLOG
+       { 0.001, PROG_LASTLOG,  { "lastlog", NULL, NULL, NULL } },
+#endif
+#ifdef PROG_DF
+       { 0.010, PROG_DF,       { "df", NULL, NULL, NULL } },
+       { 0.010, PROG_DF,       { "df", "-i", NULL, NULL } },
+#endif
+#ifdef PROG_VMSTAT
+       { 0.010, PROG_VMSTAT,   { "vmstat", NULL, NULL, NULL } },
+#endif
+#ifdef PROG_UPTIME
+       { 0.001, PROG_UPTIME,   { "uptime", NULL, NULL, NULL } },
+#endif
+#ifdef PROG_IPCS
+       { 0.001, PROG_IPCS,     { "-a", NULL, NULL, NULL } },
+#endif
+#ifdef PROG_TAIL
+       { 0.001, PROG_TAIL,     { "tail", "-200", "/var/log/messages", NULL, NULL } },
+       { 0.001, PROG_TAIL,     { "tail", "-200", "/var/log/syslog", NULL, NULL } },
+       { 0.001, PROG_TAIL,     { "tail", "-200", "/var/adm/messages", NULL, NULL } },
+       { 0.001, PROG_TAIL,     { "tail", "-200", "/var/adm/syslog", NULL, NULL } },
+       { 0.001, PROG_TAIL,     { "tail", "-200", "/var/log/maillog", NULL, NULL } },
+       { 0.001, PROG_TAIL,     { "tail", "-200", "/var/adm/maillog", NULL, NULL } },
+#endif
+       { 0.000, NULL,          { NULL, NULL, NULL, NULL, NULL } },
+};
+
+
+double 
+stir_from_system(void)
+{
+       double total_entropy_estimate;
+       long int i;
+       
+       total_entropy_estimate = 0;
+       
+       i = getpid();
+       RAND_add(&i, sizeof(i), 0.1);
+       total_entropy_estimate += 0.1;
+       
+       i = getppid();
+       RAND_add(&i, sizeof(i), 0.1);
+       total_entropy_estimate += 0.1;
+
+       i = getuid();
+       RAND_add(&i, sizeof(i), 0.0);
+       i = getgid();
+       RAND_add(&i, sizeof(i), 0.0);
+
+       total_entropy_estimate += stir_gettimeofday(1.0);
+       total_entropy_estimate += stir_clock(0.2);
+       total_entropy_estimate += stir_rusage(RUSAGE_SELF, 2.0);
+
+       return(total_entropy_estimate);
+}
+
+double 
+stir_from_programs(void)
+{
+       int i;
+       int c;
+       double entropy_estimate;
+       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++) {
+               c = 0;
+               while (entropy_sources[c].path != NULL) {
+                       /* Hash output from command */
+                       entropy_estimate = hash_output_from_command(entropy_sources[c].path,
+                               entropy_sources[c].args, hash);
+
+                       /* Scale back entropy estimate according to command's rate */
+                       entropy_estimate *= entropy_sources[c].rate;
+                       /* Upper bound of entropy estimate is SHA_DIGEST_LENGTH */
+                       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);
+                       
+                       /* Stir it in */
+                       RAND_add(hash, sizeof(hash), entropy_estimate);
+
+/* FIXME: turn this off later */
+#if 1
+                       debug("Got %0.2f bytes of entropy from %s", entropy_estimate, 
+                               entropy_sources[c].path);
+#endif
+
+                       total_entropy_estimate += entropy_estimate;
+
+                       /* Execution times should be a little unpredictable */
+                       total_entropy_estimate += stir_gettimeofday(0.05);
+                       total_entropy_estimate += stir_clock(0.05);
+                       total_entropy_estimate += stir_rusage(RUSAGE_SELF, 0.1);
+                       total_entropy_estimate += stir_rusage(RUSAGE_CHILDREN, 0.1);
+                       
+                       c++;
+               }
+       }
+       
+       return(total_entropy_estimate);
+}
+
+double
+stir_gettimeofday(double entropy_estimate)
+{
+       struct timeval tv;
+       
+       if (gettimeofday(&tv, NULL) == -1)
+               fatal("Couldn't gettimeofday: %s", strerror(errno));
+
+       RAND_add(&tv, sizeof(tv), entropy_estimate);
+       
+       return(entropy_estimate);
+}
+
+double
+stir_clock(double entropy_estimate)
+{
+#ifdef HAVE_CLOCK
+       clock_t c;
+       
+       c = clock();
+       RAND_add(&c, sizeof(c), entropy_estimate);
+       
+       return(entropy_estimate);
+#else /* _HAVE_CLOCK */
+       return(0);
+#endif /* _HAVE_CLOCK */
+}
+
+double
+stir_rusage(int who, double entropy_estimate)
+{
+#ifdef HAVE_GETRUSAGE
+       struct rusage ru;
+       
+   if (getrusage(who, &ru) == -1)
+               fatal("Couldn't getrusage: %s", strerror(errno));
+
+       RAND_add(&ru, sizeof(ru), 0.1);
+
+       return(entropy_estimate);
+#else /* _HAVE_GETRUSAGE */
+       return(0);
+#endif /* _HAVE_GETRUSAGE */
+}
+
+double
+hash_output_from_command(const char *path, const char **args, char *hash)
+{
+       static int devnull = -1;
+       int p[2];
+       pid_t pid;
+       int status;
+       char buf[2048];
+       int bytes_read;
+       int total_bytes_read;
+       SHA_CTX sha;
+       
+       if (devnull == -1) {
+               devnull = open("/dev/null", O_RDWR);
+               if (devnull == -1)
+                       fatal("Couldn't open /dev/null: %s", strerror(errno));
+       }
+       
+       if (pipe(p) == -1)
+               fatal("Couldn't open pipe: %s", strerror(errno));
+
+       switch (pid = fork()) {
+               case -1: /* Error */
+                       close(p[0]);
+                       close(p[1]);
+                       fatal("Couldn't fork: %s", strerror(errno));
+                       /* NOTREACHED */
+               case 0: /* Child */
+                       close(0);
+                       close(1);
+                       close(2);
+                       dup2(devnull, 0);
+                       dup2(p[1], 1);
+                       dup2(p[1], 2);
+                       close(p[0]);
+                       close(p[1]);
+                       close(devnull);
+
+                       execv(path, (char**)args);
+                       debug("(child) Couldn't exec '%s': %s", path, strerror(errno));
+                       _exit(-1);
+               default: /* Parent */
+                       break;
+       }
+
+       RAND_add(&pid, sizeof(&pid), 0.0);
+
+       close(p[1]);
+
+       /* Hash output from child */
+       SHA1_Init(&sha);
+       total_bytes_read = 0;
+       while ((bytes_read = read(p[0], buf, sizeof(buf)))      > 0) {
+               SHA1_Update(&sha, buf, bytes_read);
+               total_bytes_read += bytes_read;
+               RAND_add(&bytes_read, sizeof(&bytes_read), 0.0);
+       }
+       SHA1_Final(hash, &sha);
+
+       close(p[0]);
+       
+       if (waitpid(pid, &status, 0) == -1) {
+               error("Couldn't wait for child '%s' completion: %s", path, 
+                       strerror(errno));
+               return(-1);
+       }
+
+       RAND_add(&status, sizeof(&status), 0.0);
+
+       if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
+               return(0.0);
+       else
+               return(total_bytes_read);
+}
+#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) */
+/*
+ * Conditionally Seed OpenSSL's random number pool syscalls and program output
+ */
+void
+seed_rng(void)
+{
+       if (!RAND_status()) {
+               debug("Seeding random number generator.");
+               debug("%i bytes from system calls", (int)stir_from_system());
+               debug("%i bytes from programs", (int)stir_from_programs());
+               debug("OpenSSL random status is now %i\n", RAND_status());
+       }
+}
+#endif /* defined(EGD_SOCKET) || defined(RANDOM_POOL) */
diff --git a/entropy.h b/entropy.h
new file mode 100644 (file)
index 0000000..ec425a0
--- /dev/null
+++ b/entropy.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 1999-2000 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Markus Friedl.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RANDOMS_H
+#define _RANDOMS_H
+
+void seed_rng(void);
+
+#endif /* _RANDOMS_H */
diff --git a/random.c b/random.c
deleted file mode 100644 (file)
index 06c8d2b..0000000
--- a/random.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-**
-** Random number collection
-**
-** Damien Miller <djm@ibs.com.au>
-** 
-** Copyright 1999 Damien Miller
-**
-** Permission is hereby granted, free of charge, to any person
-** obtaining a copy of this software and associated documentation
-** files (the "Software"), to deal in the Software without
-** restriction, including without limitation the rights to use, copy,
-** modify, merge, publish, distribute, sublicense, and/or sell copies
-** of the Software, and to permit persons to whom the Software is
-** furnished to do so, subject to the following conditions:
-**
-** The above copyright notice and this permission notice shall be
-** included in all copies or substantial portions of the Software.
-**
-** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-** KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-** WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
-** AND NONINFRINGEMENT.  IN NO EVENT SHALL DAMIEN MILLER OR INTERNET
-** BUSINESS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
-** OR OTHER DEALINGS IN THE SOFTWARE.
-**
-** Except as contained in this notice, the name of Internet Business
-** Solutions shall not be used in advertising or otherwise to promote
-** the sale, use or other dealings in this Software without prior
-** written authorization from Internet Business Solutions.
-**
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <fcntl.h>
-#ifdef HAVE_STDDEF_H
-#include <stddef.h>
-#endif
-
-#include "ssh.h"
-#include "xmalloc.h"
-#include "random.h"
-
-#ifndef offsetof
-# define offsetof(type, member) ((size_t) &((type *)0)->member)
-#endif
-
-#ifdef HAVE_EGD
-
-/* Collect entropy from EGD */
-void get_random_bytes(unsigned char *buf, int len)
-{
-       static int random_pool;
-       int c;
-       char egd_message[2] = { 0x02, 0x00 };
-       struct sockaddr_un addr;
-       int addr_len;
-
-       memset(&addr, '\0', sizeof(addr));
-       addr.sun_family = AF_UNIX;
-       
-       /* FIXME: compile time check? */
-       if (sizeof(RANDOM_POOL) > sizeof(addr.sun_path))
-               fatal("Random pool path is too long");
-       
-       strcpy(addr.sun_path, RANDOM_POOL);
-       
-       addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(RANDOM_POOL);
-       
-       random_pool = socket(AF_UNIX, SOCK_STREAM, 0);
-       
-       if (random_pool == -1)
-               fatal("Couldn't create AF_UNIX socket: %s", strerror(errno));
-       
-       if (connect(random_pool, (struct sockaddr*)&addr, addr_len) == -1)
-               fatal("Couldn't connect to EGD socket \"%s\": %s", addr.sun_path, strerror(errno));
-
-       if (len > 255)
-               fatal("Too many bytes to read from EGD");
-       
-       /* Send blocking read request to EGD */
-       egd_message[1] = len;
-
-       c = atomicio(write, random_pool, egd_message, sizeof(egd_message));
-       if (c == -1)
-               fatal("Couldn't write to EGD socket \"%s\": %s", RANDOM_POOL, strerror(errno));
-
-       c = atomicio(read, random_pool, buf, len);
-       if (c <= 0)
-               fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
-       
-       close(random_pool);
-}
-#else /* HAVE_EGD */
-
-/* Collect entropy from /dev/urandom or pipe */
-void get_random_bytes(unsigned char *buf, int len)
-{
-       static int random_pool;
-       int c;
-
-       random_pool = open(RANDOM_POOL, O_RDONLY);
-       if (random_pool == -1)
-               fatal("Couldn't open random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
-
-       c = atomicio(read, random_pool, buf, len);
-       if (c <= 0)
-               fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
-       
-       close(random_pool);
-}
-
-#endif /* HAVE_EGD */
diff --git a/random.h b/random.h
deleted file mode 100644 (file)
index 6eb9f3a..0000000
--- a/random.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-**
-** Random number collection
-**
-** Damien Miller <djm@ibs.com.au>
-** 
-** Copyright 1999 Damien Miller
-**
-** Permission is hereby granted, free of charge, to any person
-** obtaining a copy of this software and associated documentation
-** files (the "Software"), to deal in the Software without
-** restriction, including without limitation the rights to use, copy,
-** modify, merge, publish, distribute, sublicense, and/or sell copies
-** of the Software, and to permit persons to whom the Software is
-** furnished to do so, subject to the following conditions:
-**
-** The above copyright notice and this permission notice shall be
-** included in all copies or substantial portions of the Software.
-**
-** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-** KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-** WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
-** AND NONINFRINGEMENT.  IN NO EVENT SHALL DAMIEN MILLER OR INTERNET
-** BUSINESS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
-** OR OTHER DEALINGS IN THE SOFTWARE.
-**
-** Except as contained in this notice, the name of Internet Business
-** Solutions shall not be used in advertising or otherwise to promote
-** the sale, use or other dealings in this Software without prior
-** written authorization from Internet Business Solutions.
-**
-*/
-
-#ifndef _RANDOM_H
-#define _RANDOM_H
-
-void get_random_bytes(unsigned char *buf, int len);
-
-#endif /* _RANDOM_H */
diff --git a/rsa.c b/rsa.c
index 5cc987df9116991cd10b14d81c5266da33e0d470..4d52251c3e67892c1016d3788ca371a6d64c80d8 100644 (file)
--- a/rsa.c
+++ b/rsa.c
@@ -40,23 +40,10 @@ RCSID("$Id$");
 #include "rsa.h"
 #include "ssh.h"
 #include "xmalloc.h"
-#include "random.h"
+#include "entropy.h"
 
 int rsa_verbose = 1;
 
-/*
- * Seed OpenSSL's random number generator
- */
-void
-seed_rng()
-{
-       char buf[64];
-
-       get_random_bytes(buf, sizeof(buf));
-       RAND_seed(buf, sizeof(buf));
-       memset(buf, 0, sizeof(buf));
-}
-
 int
 rsa_alive()
 {
@@ -109,6 +96,8 @@ rsa_generate_key(RSA *prv, RSA *pub, unsigned int bits)
        if (key == NULL)
                fatal("rsa_generate_key: key generation failed.");
 
+       seed_rng();
+
        /* Copy public key parameters */
        pub->n = BN_new();
        BN_copy(pub->n, key->n);
This page took 0.71865 seconds and 5 git commands to generate.