From fe6b51ae40313036436f81d4e87d232691cdacac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 1 Nov 2014 10:45:33 +0100 Subject: ssl: separate locking init from general init Extract the lock-setting functions into their own, as we cannot assume that it's ok for us to set this unconditionally. --- include/git2/threads.h | 16 ++++++++++++++++ src/global.c | 41 +++++++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/include/git2/threads.h b/include/git2/threads.h index 11f89729a..6b4287033 100644 --- a/include/git2/threads.h +++ b/include/git2/threads.h @@ -44,6 +44,22 @@ GIT_EXTERN(int) git_threads_init(void); */ GIT_EXTERN(void) git_threads_shutdown(void); +/** + * Initialize the OpenSSL locks + * + * OpenSSL requires the application to determine how it performs + * locking. This is a convenience function which libgit2 provides for + * allocating and initializing the locks as well as setting the + * locking function to use the system's native locking functions. + * + * The locking function will be cleared and the memory will be freed + * when you call git_threads_sutdown(). + * + * @return 0 on success, -1 if there are errors or if libgit2 was not + * built with OpenSSL and threading support. + */ +GIT_EXTERN(int) git_openssl_set_locking(void); + /** @} */ GIT_END_DECL #endif diff --git a/src/global.c b/src/global.c index 2435b5673..3e721ee3a 100644 --- a/src/global.c +++ b/src/global.c @@ -64,7 +64,7 @@ void openssl_locking_function(int mode, int n, const char *file, int line) } } -static void shutdown_ssl(void) +static void shutdown_ssl_locking(void) { CRYPTO_set_locking_callback(NULL); git__free(openssl_locks); @@ -96,30 +96,35 @@ static void init_ssl(void) SSL_CTX_free(git__ssl_ctx); git__ssl_ctx = NULL; } +#endif +} +int git_openssl_set_locking(void) +{ +#ifdef GIT_SSL # ifdef GIT_THREADS - { - int num_locks, i; - - num_locks = CRYPTO_num_locks(); - openssl_locks = git__calloc(num_locks, sizeof(git_mutex)); - if (openssl_locks == NULL) { - SSL_CTX_free(git__ssl_ctx); - git__ssl_ctx = NULL; - } + int num_locks, i; - for (i = 0; i < num_locks; i++) { - if (git_mutex_init(&openssl_locks[i]) != 0) { - SSL_CTX_free(git__ssl_ctx); - git__ssl_ctx = NULL; - } - } + num_locks = CRYPTO_num_locks(); + openssl_locks = git__calloc(num_locks, sizeof(git_mutex)); + GITERR_CHECK_ALLOC(openssl_locks); - CRYPTO_set_locking_callback(openssl_locking_function); + for (i = 0; i < num_locks; i++) { + if (git_mutex_init(&openssl_locks[i]) != 0) { + giterr_set(GITERR_SSL, "failed to initialize openssl locks"); + return -1; + } } - git__on_shutdown(shutdown_ssl); + CRYPTO_set_locking_callback(openssl_locking_function); + git__on_shutdown(shutdown_ssl_locking); + return 0; +# else + giterr_set(GITERR_THREAD, "libgit2 as not built with threads"); + return -1; # endif + giterr_set(GITERR_SSL, "libgit2 was not built with OpenSSL support"); + return -1; #endif } -- cgit v1.2.1