diff options
author | Edward Thomson <ethomson@github.com> | 2016-02-08 16:14:03 -0800 |
---|---|---|
committer | Edward Thomson <ethomson@github.com> | 2016-02-08 16:30:39 -0800 |
commit | 8a6d667763eb04ad872693ca76352821d1dee78c (patch) | |
tree | 85135e09629417ea6ef905060c8cfe615b6c8ff8 | |
parent | bad2702c433227fcab1690303993e5861c6861b5 (diff) | |
download | libgit2-8a6d667763eb04ad872693ca76352821d1dee78c.tar.gz |
global: make openssl registration like the rest
-rw-r--r-- | src/global.c | 121 | ||||
-rw-r--r-- | src/openssl_stream.c | 120 | ||||
-rw-r--r-- | src/openssl_stream.h | 2 |
3 files changed, 128 insertions, 115 deletions
diff --git a/src/global.c b/src/global.c index 35595fbb4..4a61a062c 100644 --- a/src/global.c +++ b/src/global.c @@ -8,9 +8,11 @@ #include "global.h" #include "hash.h" #include "sysdir.h" -#include "git2/global.h" -#include "git2/sys/openssl.h" +#include "filter.h" +#include "openssl_stream.h" #include "thread-utils.h" +#include "git2/global.h" + #if defined(GIT_MSVC_CRTDBG) #include "win32/w32_stack.h" #include "win32/w32_crtdbg_stacktrace.h" @@ -33,9 +35,6 @@ static git_atomic git__n_shutdown_callbacks; static git_atomic git__n_inits; char *git__user_agent; -static int init_ssl(void); -static void shutdown_ssl(void); - void git__on_shutdown(git_global_shutdown_fn callback) { int count = git_atomic_inc(&git__n_shutdown_callbacks); @@ -65,8 +64,8 @@ static int init_common(void) /* Initialize any other subsystems that have global state */ if ((ret = git_hash_global_init()) == 0 && (ret = git_sysdir_global_init()) == 0 && - (ret = init_ssl()) == 0) { - } + (ret = git_filter_global_init()) == 0) + ret = git_openssl_stream_global_init(); GIT_MEMORY_BARRIER; @@ -89,8 +88,6 @@ static void shutdown_common(void) cb(); } - shutdown_ssl(); - git__free(git__user_agent); #if defined(GIT_MSVC_CRTDBG) @@ -99,112 +96,6 @@ static void shutdown_common(void) #endif } -#if defined(GIT_THREADS) && defined(GIT_OPENSSL) -void openssl_locking_function(int mode, int n, const char *file, int line) -{ - int lock; - - GIT_UNUSED(file); - GIT_UNUSED(line); - - lock = mode & CRYPTO_LOCK; - - if (lock) { - git_mutex_lock(&openssl_locks[n]); - } else { - git_mutex_unlock(&openssl_locks[n]); - } -} - -static void shutdown_ssl_locking(void) -{ - int num_locks, i; - - num_locks = CRYPTO_num_locks(); - CRYPTO_set_locking_callback(NULL); - - for (i = 0; i < num_locks; ++i) - git_mutex_free(openssl_locks); - git__free(openssl_locks); -} -#endif - -static int init_ssl(void) -{ -#ifdef GIT_OPENSSL - long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; - - /* Older OpenSSL and MacOS OpenSSL doesn't have this */ -#ifdef SSL_OP_NO_COMPRESSION - ssl_opts |= SSL_OP_NO_COMPRESSION; -#endif - - SSL_load_error_strings(); - OpenSSL_add_ssl_algorithms(); - /* - * Load SSLv{2,3} and TLSv1 so that we can talk with servers - * which use the SSL hellos, which are often used for - * compatibility. We then disable SSL so we only allow OpenSSL - * to speak TLSv1 to perform the encryption itself. - */ - git__ssl_ctx = SSL_CTX_new(SSLv23_method()); - SSL_CTX_set_options(git__ssl_ctx, ssl_opts); - SSL_CTX_set_mode(git__ssl_ctx, SSL_MODE_AUTO_RETRY); - SSL_CTX_set_verify(git__ssl_ctx, SSL_VERIFY_NONE, NULL); - if (!SSL_CTX_set_default_verify_paths(git__ssl_ctx)) { - SSL_CTX_free(git__ssl_ctx); - git__ssl_ctx = NULL; - return -1; - } -#endif - - return 0; -} - -/** - * This function aims to clean-up the SSL context which - * we allocated. - */ -static void shutdown_ssl(void) -{ -#ifdef GIT_OPENSSL - if (git__ssl_ctx) { - SSL_CTX_free(git__ssl_ctx); - git__ssl_ctx = NULL; - } -#endif -} - -int git_openssl_set_locking(void) -{ -#ifdef GIT_OPENSSL -# ifdef GIT_THREADS - int num_locks, i; - - num_locks = CRYPTO_num_locks(); - openssl_locks = git__calloc(num_locks, sizeof(git_mutex)); - GITERR_CHECK_ALLOC(openssl_locks); - - 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; - } - } - - 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 -#else - giterr_set(GITERR_SSL, "libgit2 was not built with OpenSSL support"); - return -1; -#endif -} - /** * Handle the global state with TLS * diff --git a/src/openssl_stream.c b/src/openssl_stream.c index 54dd761ca..0705d90e7 100644 --- a/src/openssl_stream.c +++ b/src/openssl_stream.c @@ -31,6 +31,115 @@ #include <openssl/x509v3.h> #include <openssl/bio.h> +SSL_CTX *git__ssl_ctx; + +#ifdef GIT_THREADS + +static git_mutex *openssl_locks; + +static void openssl_locking_function( + int mode, int n, const char *file, int line) +{ + int lock; + + GIT_UNUSED(file); + GIT_UNUSED(line); + + lock = mode & CRYPTO_LOCK; + + if (lock) { + git_mutex_lock(&openssl_locks[n]); + } else { + git_mutex_unlock(&openssl_locks[n]); + } +} + +static void shutdown_ssl_locking(void) +{ + int num_locks, i; + + num_locks = CRYPTO_num_locks(); + CRYPTO_set_locking_callback(NULL); + + for (i = 0; i < num_locks; ++i) + git_mutex_free(openssl_locks); + git__free(openssl_locks); +} + +#endif /* GIT_THREADS */ + +/** + * This function aims to clean-up the SSL context which + * we allocated. + */ +static void shutdown_ssl(void) +{ + if (git__ssl_ctx) { + SSL_CTX_free(git__ssl_ctx); + git__ssl_ctx = NULL; + } +} + +int git_openssl_stream_global_init(void) +{ +#ifdef GIT_OPENSSL + long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; + + /* Older OpenSSL and MacOS OpenSSL doesn't have this */ +#ifdef SSL_OP_NO_COMPRESSION + ssl_opts |= SSL_OP_NO_COMPRESSION; +#endif + + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); + /* + * Load SSLv{2,3} and TLSv1 so that we can talk with servers + * which use the SSL hellos, which are often used for + * compatibility. We then disable SSL so we only allow OpenSSL + * to speak TLSv1 to perform the encryption itself. + */ + git__ssl_ctx = SSL_CTX_new(SSLv23_method()); + SSL_CTX_set_options(git__ssl_ctx, ssl_opts); + SSL_CTX_set_mode(git__ssl_ctx, SSL_MODE_AUTO_RETRY); + SSL_CTX_set_verify(git__ssl_ctx, SSL_VERIFY_NONE, NULL); + if (!SSL_CTX_set_default_verify_paths(git__ssl_ctx)) { + SSL_CTX_free(git__ssl_ctx); + git__ssl_ctx = NULL; + return -1; + } +#endif + + git__on_shutdown(shutdown_ssl); + + return 0; +} + +int git_openssl_set_locking(void) +{ +#ifdef GIT_THREADS + int num_locks, i; + + num_locks = CRYPTO_num_locks(); + openssl_locks = git__calloc(num_locks, sizeof(git_mutex)); + GITERR_CHECK_ALLOC(openssl_locks); + + 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; + } + } + + 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 +} + + static int bio_create(BIO *b) { b->init = 1; @@ -472,6 +581,17 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port) #include "stream.h" +int git_openssl_stream_global_init(void) +{ + return 0; +} + +int git_openssl_set_locking(void) +{ + giterr_set(GITERR_SSL, "libgit2 was not built with OpenSSL support"); + return -1; +} + int git_openssl_stream_new(git_stream **out, const char *host, const char *port) { GIT_UNUSED(out); diff --git a/src/openssl_stream.h b/src/openssl_stream.h index 9ca06489e..82b5110c4 100644 --- a/src/openssl_stream.h +++ b/src/openssl_stream.h @@ -9,6 +9,8 @@ #include "git2/sys/stream.h" +extern int git_openssl_stream_global_init(void); + extern int git_openssl_stream_new(git_stream **out, const char *host, const char *port); #endif |