BUG/MEDIUM: ssl: openssl 0.9.8 doesn't open /dev/random before chroot

Openssl needs to access /dev/urandom to initialize its internal random
number generator. It does so when it needs a random for the first time,
which fails if it is a handshake performed after the chroot(), causing
all SSL incoming connections to fail.

This fix consists in calling RAND_bytes() to produce a random before
the chroot, which will in turn open /dev/urandom before it's too late,
and avoid the issue.

If the random generator fails to work while processing the config,
haproxy now fails with an error instead of causing SSL connections to
fail at runtime.
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index f814276..3aeba74 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -43,6 +43,7 @@
 #include <openssl/x509v3.h>
 #include <openssl/x509.h>
 #include <openssl/err.h>
+#include <openssl/rand.h>
 
 #include <common/buffer.h>
 #include <common/compat.h>
@@ -478,6 +479,22 @@
 	return cfgerr;
 }
 
+/* Make sure openssl opens /dev/urandom before the chroot. The work is only
+ * done once. Zero is returned if the operation fails. No error is returned
+ * if the random is said as not implemented, because we expect that openssl
+ * will use another method once needed.
+ */
+static int ssl_initialize_random()
+{
+	unsigned char random;
+	static int random_initialized = 0;
+
+	if (!random_initialized && RAND_bytes(&random, 1) != 0)
+		random_initialized = 1;
+
+	return random_initialized;
+}
+
 #ifndef SSL_OP_CIPHER_SERVER_PREFERENCE                 /* needs OpenSSL >= 0.9.7 */
 #define SSL_OP_CIPHER_SERVER_PREFERENCE 0
 #endif
@@ -526,6 +543,12 @@
 		SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
 		SSL_MODE_RELEASE_BUFFERS;
 
+	/* Make sure openssl opens /dev/urandom before the chroot */
+	if (!ssl_initialize_random()) {
+		Alert("OpenSSL random data generator initialization failed.\n");
+		cfgerr++;
+	}
+
 	if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
 		ssloptions |= SSL_OP_NO_SSLv3;
 	if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
@@ -635,6 +658,12 @@
 		SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
 		SSL_MODE_RELEASE_BUFFERS;
 
+	/* Make sure openssl opens /dev/urandom before the chroot */
+	if (!ssl_initialize_random()) {
+		Alert("OpenSSL random data generator initialization failed.\n");
+		cfgerr++;
+	}
+
 	 /* Initiate SSL context for current server */
 	srv->ssl_ctx.reused_sess = NULL;
 	if (srv->use_ssl)