Refuse to start with OpenSSL 1.0.1 - 1.0.1f
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 8 Apr 2014 07:29:19 +0000 (08:29 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 8 Apr 2014 10:11:46 +0000 (11:11 +0100)
src/include/tls-h
src/main/radiusd.c
src/main/tls.c
src/main/version.c

index cc2413f..dcf8301 100644 (file)
@@ -293,7 +293,7 @@ void                cbtls_msg(int write_p, int msg_version, int content_type, void const *buf
 int            cbtls_verify(int ok, X509_STORE_CTX *ctx);
 
 /* TLS */
-void           tls_global_init(void);
+int            tls_global_init(void);
 tls_session_t  *tls_new_session(fr_tls_server_conf_t *conf, REQUEST *request,
                               int client_cert);
 tls_session_t  *tls_new_client_session(fr_tls_server_conf_t *conf, int fd);
index 8018b4a..c17e190 100644 (file)
@@ -313,7 +313,9 @@ int main(int argc, char *argv[])
         *      Initialising OpenSSL once, here, is safer than having individual
         *      modules do it.
         */
-       tls_global_init();
+       if (tls_global_init() < 0) {
+               exit(EXIT_FAILURE);
+       }
 #endif
 
        if (flag && (flag != 0x03)) {
index aa8b10f..09d208b 100644 (file)
@@ -1913,13 +1913,29 @@ static void sess_free_vps(UNUSED void *parent, void *data_ptr,
  *
  *     This should be called exactly once from main.
  */
-void tls_global_init(void)
+int tls_global_init(void)
 {
+       long v;
+
        SSL_load_error_strings();       /* readable error messages (examples show call before library_init) */
        SSL_library_init();             /* initialize library */
 #ifdef HAVE_OPENSSL_EVP_H
        OpenSSL_add_all_algorithms();   /* required for SHA2 in OpenSSL < 0.9.8o and 1.0.0.a */
 #endif
+
+       /* Check for bad versions */
+       v = SSLeay();
+
+       /* 1.0.1 - 1.0.1f CVE-2014-0160 http://heartbleed.com */
+       if ((v >= 0x010001000) && (v < 0x010001070)) {
+               ERROR("Refusing to start with libssl version %s (in range 1.0.1 - 1.0.1f).  "
+                     "Security advisory CVE-2014-0160 (Heartbleed)", ssl_version());
+               ERROR("For more information see http://heartbleed.com");
+
+               return -1;
+       }
+
+       return 0;
 }
 
 /*
index cb959b3..9015220 100644 (file)
@@ -65,7 +65,22 @@ int ssl_check_version(void)
  */
 char const *ssl_version(void)
 {
-       return SSLeay_version(SSLEAY_VERSION);
+       static char buffer[1024];
+       uint64_t v;
+
+       /* OpenSSL represents the version as a 36bit unsigned integer */
+       v = (uint64_t) SSLeay();
+
+       snprintf(buffer, sizeof(buffer), "%s 0x%.9" PRIx64 " (%i.%i.%i%c %i)",
+                SSLeay_version(SSLEAY_VERSION),                /* Not all builds include a useful version number */
+                v,
+                (int) ((0x0000000ff0000000 & v) >> 28),
+                (int) ((0x000000000ff00000 & v) >> 20),
+                (int) ((0x00000000000ff000 & v) >> 12),
+                (char)((0x0000000000000ff0 & v) >> 4 ? (0x60 + ((0x000000000000ff0 & v) >> 4)) : ' '),
+                (int) ((0x000000000000000f & v)));
+
+       return buffer;
 }
 #  else
 int ssl_check_version(void) {