Merge branch 'tr-upgrade' into debian-upgrade
[freeradius.git] / src / main / version.c
index ffa37de..61d52a5 100644 (file)
@@ -17,7 +17,7 @@
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 1999-2012  The FreeRADIUS server project
+ * Copyright 1999-2014  The FreeRADIUS server project
  * Copyright 2012  Alan DeKok <aland@ox.org>
  * Copyright 2000  Chris Parker <cparker@starnetusa.com>
  */
@@ -27,10 +27,11 @@ RCSID("$Id$")
 #include <freeradius-devel/radiusd.h>
 USES_APPLE_DEPRECATED_API      /* OpenSSL API has been deprecated by Apple */
 
-#ifdef HAVE_OPENSSL_CRYPTO_H
+static uint64_t libmagic = RADIUSD_MAGIC_NUMBER;
 
-#include <openssl/crypto.h>
-#include <openssl/opensslv.h>
+#ifdef HAVE_OPENSSL_CRYPTO_H
+#  include <openssl/crypto.h>
+#  include <openssl/opensslv.h>
 
 static long ssl_built = OPENSSL_VERSION_NUMBER;
 
@@ -41,21 +42,81 @@ static long ssl_built = OPENSSL_VERSION_NUMBER;
  *
  * @return 0 if ok, else -1
  */
-int ssl_check_version(void)
+int ssl_check_consistency(void)
 {
        return 0;
 }
 
+/** Convert a version number to a text string
+ *
+ * @note Not thread safe.
+ *
+ * @param v version to convert.
+ * @return pointer to a static buffer containing the version string.
+ */
+char const *ssl_version_by_num(uint64_t v)
+{
+       /* 2 (%s) + 1 (.) + 2 (%i) + 1 (.) + 2 (%i) + 1 (c) + 1 (-) + 2 (%i) + \0 */
+       static char buffer[13];
+       char *p = buffer;
+
+       p += sprintf(p, "%i.%i.%i",
+                    (int) ((0xff0000000 & v) >> 28),
+                    (int) ((0x00ff00000 & v) >> 20),
+                    (int) ((0x0000ff000 & v) >> 12));
+
+       if ((0x000000ff0 & v) >> 4) {
+               *p++ =  (char) (0x60 + ((0x000000ff0 & v) >> 4));
+       }
+
+       sprintf(p, "-%i", (int) (0x00000000f & v));
+
+       return buffer;
+}
+
+/** Convert two openssl version numbers into a range string
+ *
+ * @note Not thread safe.
+ *
+ * @param low version to convert.
+ * @param high version to convert.
+ * @return pointer to a static buffer containing the version range string.
+ */
+char const *ssl_version_range(uint64_t low, uint64_t high)
+{
+       /* 12 (version) + 3 ( - ) + 12 (version) */
+       static char buffer[28];
+       char *p = buffer;
+
+       p += strlcpy(p, ssl_version_by_num(low), sizeof(buffer));
+       p += strlcpy(p, " - ", sizeof(buffer) - (p - buffer));
+       strlcpy(p, ssl_version_by_num(high), sizeof(buffer) - (p - buffer));
+
+       return buffer;
+}
+
 /** Print the current linked version of Openssl
  *
  * Print the currently linked version of the OpenSSL library.
+ *
+ * @note Not thread safe.
+ * @return pointer to a static buffer containing libssl version information.
  */
 char const *ssl_version(void)
 {
-       return SSLeay_version(SSLEAY_VERSION);
+       static char buffer[256];
+
+       uint64_t v = (uint64_t) SSLeay();
+
+       snprintf(buffer, sizeof(buffer), "%s 0x%.9" PRIx64 " (%s)",
+                SSLeay_version(SSLEAY_VERSION),                /* Not all builds include a useful version number */
+                v,
+                ssl_version_by_num((uint64_t) v));
+
+       return buffer;
 }
-#else
-int ssl_check_version(void) {
+#  else
+int ssl_check_consistency(void) {
        return 0;
 }
 
@@ -63,7 +124,39 @@ char const *ssl_version()
 {
        return "not linked";
 }
-#endif
+#endif /* ifdef HAVE_OPENSSL_CRYPTO_H */
+
+
+/** Check if the application linking to the library has the correct magic number
+ *
+ * @param magic number as defined by RADIUSD_MAGIC_NUMBER
+ * @returns 0 on success, -1 on prefix mismatch, -2 on version mismatch -3 on commit mismatch.
+ */
+int rad_check_lib_magic(uint64_t magic)
+{
+       if (MAGIC_PREFIX(magic) != MAGIC_PREFIX(libmagic)) {
+               ERROR("Application and libfreeradius-server magic number (prefix) mismatch."
+                     "  application: %x library: %x",
+                     MAGIC_PREFIX(magic), MAGIC_PREFIX(libmagic));
+               return -1;
+       }
+
+       if (MAGIC_VERSION(magic) != MAGIC_VERSION(libmagic)) {
+               ERROR("Application and libfreeradius-server magic number (version) mismatch."
+                     "  application: %lx library: %lx",
+                     (unsigned long) MAGIC_VERSION(magic), (unsigned long) MAGIC_VERSION(libmagic));
+               return -2;
+       }
+
+       if (MAGIC_COMMIT(magic) != MAGIC_COMMIT(libmagic)) {
+               ERROR("Application and libfreeradius-server magic number (commit) mismatch."
+                     "  application: %lx library: %lx",
+                     (unsigned long) MAGIC_COMMIT(magic), (unsigned long) MAGIC_COMMIT(libmagic));
+               return -3;
+       }
+
+       return 0;
+}
 
 /*
  *     Display the revision number for this program
@@ -132,12 +225,26 @@ void version(void)
 #ifdef WITH_VMPS
        DEBUG3("  vmps");
 #endif
+#ifndef NDEBUG
+       DEBUG3("  developer");
+#endif
 
        DEBUG3("Server core libs:");
-       DEBUG3("  talloc : %i.%i.*", talloc_version_major(),
-              talloc_version_minor());
+       DEBUG3("  talloc : %i.%i.*", talloc_version_major(), talloc_version_minor());
        DEBUG3("  ssl    : %s", ssl_version());
 
+       DEBUG3("Library magic number:");
+       DEBUG3("  0x%llx", (unsigned long long) libmagic);
+
+       DEBUG3("Endianess:");
+#if defined(LITTLE_ENDIAN)
+       DEBUG3("  little");
+#elif defined(BIG_ENDIAN)
+       DEBUG3("  big");
+#else
+       DEBUG3("  unknown");
+#endif
+
        INFO("Copyright (C) 1999-2014 The FreeRADIUS server project and contributors");
        INFO("There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A");
        INFO("PARTICULAR PURPOSE");