Commit 8a6d667763eb04ad872693ca76352821d1dee78c

Edward Thomson 2016-02-08T16:14:03

global: make openssl registration like the rest

diff --git a/src/global.c b/src/global.c
index 35595fb..4a61a06 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 54dd761..0705d90 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 9ca0648..82b5110 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