diff options
author | Linus Nordberg <linus@nordberg.se> | 2013-12-20 18:38:48 +0100 |
---|---|---|
committer | Linus Nordberg <linus@nordberg.se> | 2013-12-20 19:00:12 +0100 |
commit | c9b4a492cfe93fc9563d9b2b30bcdceefee1d4bb (patch) | |
tree | f8278f0fca0f17f02228e8f1a8d0e07cbc9b73dd /lib/tls.c | |
parent | 5871418432e1b127c760cd42a50f781d95d245fd (diff) |
Detect POSIX threads at configure time and use them for OpenSSL.
Diffstat (limited to 'lib/tls.c')
-rw-r--r-- | lib/tls.c | 57 |
1 files changed, 56 insertions, 1 deletions
@@ -10,11 +10,15 @@ #include <assert.h> #include <fcntl.h> #include <limits.h> +#if defined HAVE_PTHREAD_H +#include <pthread.h> +#endif #include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/bn.h> #include <openssl/x509v3.h> #include <openssl/rand.h> +#include <openssl/crypto.h> #include <radsec/radsec.h> #include <radsec/radsec-impl.h> @@ -182,11 +186,62 @@ init_openssl_rand_ (void) return 0; } +#if defined HAVE_PTHREADS +/** Array of pthread_mutex_t for OpenSSL. Allocated and initialised in + \a init_locking_ and never freed. */ +static pthread_mutex_t *s_openssl_mutexes = NULL; +/** Number of pthread_mutex_t's allocated at s_openssl_mutexes. */ +static int s_openssl_mutexes_count = 0; + +/** Callback for OpenSSL when a lock is to be held or released. */ +static void +openssl_locking_cb_ (int mode, int i, const char *file, int line) +{ + if (s_openssl_mutexes == NULL || i >= s_openssl_mutexes_count) + return; + if (mode & CRYPTO_LOCK) + pthread_mutex_lock (&s_openssl_mutexes[i]); + else + pthread_mutex_unlock (&s_openssl_mutexes[i]); +} + +/** Initialise any locking needed for being thread safe. Libradsec has + all its own state in one or more struct rs_context and doesn't + need locks but libraries used by libradsec may need protection. */ +static int +init_locking_ () +{ + int i, n; + n = CRYPTO_num_locks (); + + s_openssl_mutexes = calloc (n, sizeof(pthread_mutex_t)); + if (s_openssl_mutexes == NULL) + return -RSE_NOMEM; + for (i = 0; i < n; i++) + pthread_mutex_init (&s_openssl_mutexes[i], NULL); + s_openssl_mutexes_count = n; + + return 0; +} +#endif /* HAVE_PTHREADS */ + /** Initialise the TLS library. Return 0 on success, -1 on failure. */ int -tls_init (void) +tls_init () { SSL_load_error_strings (); +#if defined HAVE_PTHREADS + if (CRYPTO_get_locking_callback () == NULL) + { + assert (s_openssl_mutexes_count == 0); + /* Allocate and initialise mutexes. We will never free + these. FIXME: Is there a portable way of having a function + invoked when a solib is unloaded? -ln */ + if (init_locking_ ()) + return -1; + CRYPTO_set_locking_callback (openssl_locking_cb_); + } +#endif /* HAVE_PTHREADS */ SSL_library_init (); return init_openssl_rand_ (); } |