]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: ssl: openssl 0.9.8 doesn't open /dev/random before chroot
authorThierry Fournier <tfournier@exceliance.fr>
Thu, 24 Jan 2013 13:15:43 +0000 (14:15 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 24 Jan 2013 20:16:41 +0000 (21:16 +0100)
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.

src/ssl_sock.c

index f814276064fbb29cb5e4566091e8d00de39b3665..3aeba744a7c322a1cc5f09fe7e74b0887bf7e959 100644 (file)
@@ -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 @@ int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *cu
        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 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy
                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 @@ int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
                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)