Check for vulnerable OpenSSL versions
authorAlan T. DeKok <aland@freeradius.org>
Tue, 8 Apr 2014 15:10:11 +0000 (11:10 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 8 Apr 2014 15:10:11 +0000 (11:10 -0400)
src/include/radiusd.h
src/main/mainconfig.c
src/main/radiusd.c
src/main/version.c

index d5e1c04..2bf5173 100644 (file)
@@ -532,7 +532,7 @@ int         pairlist_read(const char *file, PAIR_LIST **list, int complain);
 void           pairlist_free(PAIR_LIST **);
 
 /* version.c */
-int            ssl_check_version(void);
+int            ssl_check_version(int allow_vulnerable);
 const char     *ssl_version(void);
 void           version(void);
 
index 521b906..faf69fb 100644 (file)
@@ -971,11 +971,6 @@ int read_mainconfig(int reload)
        }
        if (mainconfig.reject_delay < 0) mainconfig.reject_delay = 0;
 
-       /*  Reload the modules.  */
-       if (setup_modules(reload, mainconfig.config) < 0) {
-               return -1;
-       }
-
        if (chroot_dir) {
                if (chdir(radlog_dir) < 0) {
                        radlog(L_ERR, "Failed to 'chdir %s' after chroot: %s",
index d8ad145..40541c8 100644 (file)
@@ -263,14 +263,6 @@ int main(int argc, char *argv[])
                }
        }
 
-       /*
-        *      Mismatch between build time OpenSSL and linked SSL,
-        *      better to die here than segfault later.
-        */
-       if (ssl_check_version() < 0) {
-               exit(1);
-       }
-
        if (flag && (flag != 0x03)) {
                fprintf(stderr, "radiusd: The options -i and -p cannot be used individually.\n");
                exit(1);
@@ -285,6 +277,19 @@ int main(int argc, char *argv[])
                exit(1);
        }
 
+       /*
+        *      Mismatch between build time OpenSSL and linked SSL,
+        *      better to die here than segfault later.
+        */
+       if (ssl_check_version(mainconfig.allow_vulnerable_openssl) < 0) {
+               exit(1);
+       }
+
+       /*  Load the modules AFTER doing SSL checks */
+       if (setup_modules(FALSE, mainconfig.config) < 0) {
+               return -1;
+       }
+
        /* Set the panic action (if required) */
        if (mainconfig.panic_action &&
 #ifndef NDEBUG
index e08ca8c..af82d41 100644 (file)
@@ -41,7 +41,7 @@ static long ssl_built = OPENSSL_VERSION_NUMBER;
  *
  * @return 0 if ok, else -1
  */
-int ssl_check_version(void)
+int ssl_check_version(int allow_vulnerable)
 {
        long ssl_linked;
 
@@ -63,6 +63,18 @@ int ssl_check_version(void)
                return -1;
        };
 
+       if (!allow_vulnerable) {
+               /* Check for bad versions */
+               /* 1.0.1 - 1.0.1f CVE-2014-0160 http://heartbleed.com */
+               if ((ssl_linked >= 0x010001000) && (ssl_linked < 0x010001070)) {
+                       radlog(L_ERR, "Refusing to start with libssl version %s (in range 1.0.1 - 1.0.1f).  "
+                             "Security advisory CVE-2014-0160 (Heartbleed)", ssl_version());
+                       radlog(L_ERR, "For more information see http://heartbleed.com");
+
+                       return -1;
+               }
+       }
+
        return 0;
 }
 
@@ -75,7 +87,8 @@ const char *ssl_version(void)
        return SSLeay_version(SSLEAY_VERSION);
 }
 #else
-int ssl_check_version(void) {
+int ssl_check_version(UNUSED int allow_vulnerable)
+{
        return 0;
 }