Hi, dovecot tries to use OpenSSL's PRNG to generate random numbers if there is no /dev/urandom found. Unfortunately, it is flawed in its present form, since the PRNG is not seeded before RAND_bytes() is called in src/lib/randgen.c (on systems which have /dev/urandom, OpenSSL automatically seeds its PRNG from the urandom device). Here's a patch to address this issue: it tries to seed the PRNG if there is no /dev/urandom present (which is likely the case if dovecot uses OpenSSL's RAND API). It can also be fetched from http://innoidea.com/~vili/dovecot_rng_init.diff -Vilmos Nebehaj Index: configure.in =================================================================== RCS file: /home/cvs/dovecot/configure.in,v retrieving revision 1.266 diff -u -r1.266 configure.in --- configure.in 28 Feb 2006 08:36:41 -0000 1.266 +++ configure.in 10 Mar 2006 17:15:01 -0000 @@ -358,7 +358,8 @@ AC_CHECK_FUNCS(fcntl flock lockf inet_aton sigaction getpagesize madvise \ strcasecmp stricmp vsnprintf vsyslog writev pread \ setrlimit setproctitle seteuid setreuid setegid setresgid \ - strtoull strtouq setpriority quotactl getmntent kqueue kevent) + strtoull strtouq setpriority quotactl getmntent kqueue kevent \ + getrusage) dnl * I/O loop function have_ioloop=no Index: src/lib/lib.h =================================================================== RCS file: /home/cvs/dovecot/src/lib/lib.h,v retrieving revision 1.20 diff -u -r1.20 lib.h --- src/lib/lib.h 25 Sep 2005 10:44:04 -0000 1.20 +++ src/lib/lib.h 10 Mar 2006 17:15:02 -0000 @@ -20,6 +20,13 @@ # include <stdint.h> /* C99 int types, we mostly need uintmax_t */ #endif +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif +#ifdef HAVE_SYS_TIME_H +# include <sys/resource.h> +#endif + #include "compat.h" #include "macros.h" #include "failures.h" Index: src/lib/randgen.c =================================================================== RCS file: /home/cvs/dovecot/src/lib/randgen.c,v retrieving revision 1.13 diff -u -r1.13 randgen.c --- src/lib/randgen.c 6 Jan 2005 19:08:19 -0000 1.13 +++ src/lib/randgen.c 10 Mar 2006 17:15:03 -0000 @@ -81,6 +81,42 @@ return buf; } +static void random_init_rng(void) +{ + int counter = 0; + struct timeval tv; +#ifdef HAVE_GETRUSAGE + struct rusage ru; +#endif + + /* + * If the RNG is already seeded, we can return + * immediately. + */ + if (RAND_status() == 1) + return; + + /* + * Else, try to seed it. Unfortunately we don't have + * /dev/urandom, so we can only use weak random sources. + */ + while (RAND_status() != 1) { + if (gettimeofday(&tv, NULL) < 0) + i_fatal("gettimeofday() failed: %m"); + RAND_add((const void *)&tv, sizeof(tv), + (double)sizeof(tv) / 2); +#ifdef HAVE_GETRUSAGE + if (getrusage(RUSAGE_SELF, &ru) < 0) + i_fatal("getrusage() failed: %m"); + RAND_add((const void *)&ru, sizeof(ru), + (double)sizeof(ru) / 2); +#endif + + if (counter++ > 100) + i_fatal("could not get enough entropy"); + } +} + void random_fill(void *buf, size_t size) { if (RAND_bytes(buf, size) != 1) @@ -91,6 +127,8 @@ { unsigned int seed; + random_init_rng(); + random_fill(&seed, sizeof(seed)); srand(seed); }