X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Flib%2Fopenssl.c;h=23ac946cfaeeffcbc12535f0fbb274e44e448edf;hb=4582761e377a2e1e4cbbbefd26e127b9488f3a48;hp=57fea7cacf09ac33d051f3fe7b7262e504738c51;hpb=4aaa0052c810d4d8e72a23449a308bab4c6b606f;p=bacula%2Fbacula diff --git a/bacula/src/lib/openssl.c b/bacula/src/lib/openssl.c index 57fea7cacf..23ac946cfa 100644 --- a/bacula/src/lib/openssl.c +++ b/bacula/src/lib/openssl.c @@ -1,37 +1,26 @@ /* - Bacula® - The Network Backup Solution - - Copyright (C) 2005-2011 Free Software Foundation Europe e.V. - - The main author of Bacula is Kern Sibbald, with contributions from - many others, a complete list can be found in the file AUTHORS. - This program is Free Software; you can redistribute it and/or - modify it under the terms of version three of the GNU Affero General Public - License as published by the Free Software Foundation and included - in the file LICENSE. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - - Bacula® is a registered trademark of Kern Sibbald. - The licensor of Bacula is the Free Software Foundation Europe - (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, - Switzerland, email:ftf@fsfeurope.org. + Bacula(R) - The Network Backup Solution + + Copyright (C) 2000-2016 Kern Sibbald + + 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. + + 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 * - * Version $Id$ - * * This file was contributed to the Bacula project by Landon Fuller. * * Landon Fuller has been granted a perpetual, worldwide, non-exclusive, @@ -50,14 +39,8 @@ #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 @@ -69,7 +52,6 @@ void openssl_post_errors(int code, const char *errstring) openssl_post_errors(NULL, code, errstring); } - /* * Post all per-thread openssl errors */ @@ -87,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 @@ -94,17 +85,13 @@ 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(); -#else /* - * Comparison without use of pthread_equal() is mandated by the OpenSSL API + * Comparison without use of pthread_equal() is mandated by the OpenSSL API * * Note: this creates problems with the new Win32 pthreads * emulation code, which defines pthread_t as a structure. */ return ((unsigned long)pthread_self()); -#endif } /* @@ -163,12 +150,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); @@ -197,21 +183,21 @@ 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; /* Unset thread ID callback */ CRYPTO_set_id_callback(NULL); - + /* Deallocate static lock mutexes */ numlocks = CRYPTO_num_locks(); for (i = 0; i < numlocks; i++) { if ((stat = pthread_mutex_destroy(&mutexes[i])) != 0) { berrno be; /* We don't halt execution, reporting the error should be sufficient */ - Jmsg1(NULL, M_ERROR, 0, _("Unable to destroy mutex: ERR=%s\n"), + Jmsg1(NULL, M_ERROR, 0, _("Unable to destroy mutex: ERR=%s\n"), be.bstrerror(stat)); } } @@ -228,13 +214,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; @@ -259,11 +246,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 */