]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/openssl.c
Restore win32 dir from Branch-5.2 and update it
[bacula/bacula] / bacula / src / lib / openssl.c
index 647f38eff12ab51d332a40e5554a23b7121a8b3b..558868b5205a0c23bafa2be501ab8e5ca3af990d 100644 (file)
@@ -1,25 +1,26 @@
 /*
-   Bacula® - The Network Backup Solution
+   Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2005-2014 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2016 Kern Sibbald
 
-   The main author of Bacula is Kern Sibbald, with contributions from many
-   others, a complete list can be found in the file AUTHORS.
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
 
    You may use this file and others of this release according to the
    license defined in the LICENSE file, which includes the Affero General
    Public License, v3.0 ("AGPLv3") and some additional permissions and
    terms pursuant to its AGPLv3 Section 7.
 
-   Bacula® is a registered trademark of Kern Sibbald.
+   This notice must be preserved when any source code is 
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
 */
 /*
  * openssl.c OpenSSL support functions
  *
  * Author: Landon Fuller <landonf@opendarwin.org>
  *
- * Version $Id$
- *
  * This file was contributed to the Bacula project by Landon Fuller.
  *
  * Landon Fuller has been granted a perpetual, worldwide, non-exclusive,
 
 #ifdef HAVE_OPENSSL
 
-/* Array of mutexes for use with OpenSSL static locking */
-static pthread_mutex_t *mutexes;
-
-/* OpenSSL dynamic locking structure */
-struct CRYPTO_dynlock_value {
-   pthread_mutex_t mutex;
-};
-
+/* Are we initialized? */
+static int crypto_initialized = false;
 /*
  * ***FIXME*** this is a sort of dummy to avoid having to
  *   change all the existing code to pass either a jcr or
@@ -57,7 +52,6 @@ void openssl_post_errors(int code, const char *errstring)
    openssl_post_errors(NULL, code, errstring);
 }
 
-
 /*
  * Post all per-thread openssl errors
  */
@@ -75,6 +69,15 @@ void openssl_post_errors(JCR *jcr, int code, const char *errstring)
    }
 }
 
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+/* Array of mutexes for use with OpenSSL static locking */
+static pthread_mutex_t *mutexes;
+
+/* OpenSSL dynamic locking structure */
+struct CRYPTO_dynlock_value {
+   pthread_mutex_t mutex;
+};
+
 /*
  * Return an OpenSSL thread ID
  *  Returns: thread ID
@@ -83,7 +86,7 @@ void openssl_post_errors(JCR *jcr, int code, const char *errstring)
 static unsigned long get_openssl_thread_id(void)
 {
 #ifdef HAVE_WIN32
-   return (unsigned long)getpid();
+   return (unsigned long)GetCurrentThreadId();
 #else
    /*
     * Comparison without use of pthread_equal() is mandated by the OpenSSL API
@@ -151,12 +154,11 @@ static void openssl_update_static_mutex (int mode, int i, const char *file, int
  *  Returns: 0 on success
  *           errno on failure
  */
-int openssl_init_threads (void)
+static int openssl_init_threads (void)
 {
    int i, numlocks;
    int stat;
 
-
    /* Set thread ID callback */
    CRYPTO_set_id_callback(get_openssl_thread_id);
 
@@ -185,7 +187,7 @@ int openssl_init_threads (void)
 /*
  * Clean up OpenSSL threading support
  */
-void openssl_cleanup_threads(void)
+static void openssl_cleanup_threads(void)
 {
    int i, numlocks;
    int stat;
@@ -216,13 +218,14 @@ void openssl_cleanup_threads(void)
    CRYPTO_set_dynlock_destroy_callback(NULL);
 }
 
+#endif
 
 /*
  * Seed OpenSSL PRNG
  *  Returns: 1 on success
  *           0 on failure
  */
-int openssl_seed_prng (void)
+static int openssl_seed_prng (void)
 {
    const char *names[]  = { "/dev/urandom", "/dev/random", NULL };
    int i;
@@ -247,11 +250,92 @@ int openssl_seed_prng (void)
  *  Returns: 1 on success
  *           0 on failure
  */
-int openssl_save_prng (void)
+static int openssl_save_prng (void)
 {
    // ***FIXME***
    // Implement PRNG state save
    return 1;
 }
 
+/*
+ * Perform global initialization of OpenSSL
+ * This function is not thread safe.
+ *  Returns: 0 on success
+ *           errno on failure
+ */
+int init_crypto (void)
+{
+   int stat = 0;
+
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+   if ((stat = openssl_init_threads()) != 0) {
+      berrno be;
+      Jmsg1(NULL, M_ABORT, 0,
+        _("Unable to init OpenSSL threading: ERR=%s\n"), be.bstrerror(stat));
+   }
+
+   /* Load libssl and libcrypto human-readable error strings */
+   SSL_load_error_strings();
+
+   /* Initialize OpenSSL SSL  library */
+   SSL_library_init();
+
+   /* Register OpenSSL ciphers and digests */
+   OpenSSL_add_all_algorithms();
+#endif
+
+   if (!openssl_seed_prng()) {
+      Jmsg0(NULL, M_ERROR_TERM, 0, _("Failed to seed OpenSSL PRNG\n"));
+   }
+
+   crypto_initialized = true;
+
+   return stat;
+}
+
+/*
+ * Perform global cleanup of OpenSSL
+ * All cryptographic operations must be completed before calling this function.
+ * This function is not thread safe.
+ *  Returns: 0 on success
+ *           errno on failure
+ */
+int cleanup_crypto (void)
+{
+   /*
+    * Ensure that we've actually been initialized; Doing this here decreases the
+    * complexity of client's termination/cleanup code.
+    */
+   if (!crypto_initialized) {
+      return 0;
+   }
+
+   if (!openssl_save_prng()) {
+      Jmsg0(NULL, M_ERROR, 0, _("Failed to save OpenSSL PRNG\n"));
+   }
+
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+   openssl_cleanup_threads();
+
+   /* Free libssl and libcrypto error strings */
+   ERR_free_strings();
+
+   /* Free all ciphers and digests */
+   EVP_cleanup();
+
+   /* Free memory used by PRNG */
+   RAND_cleanup();
+#endif
+
+   crypto_initialized = false;
+
+   return 0;
+}
+
+#else
+
+/* Dummy routines */
+int init_crypto (void) { return 0; }
+int cleanup_crypto (void) { return 0; }
+
 #endif /* HAVE_OPENSSL */