]> git.proxmox.com Git - libgit2.git/commitdiff
ssl: init everything all the time
authorCarlos Martín Nieto <cmn@dwim.me>
Thu, 12 Jun 2014 14:20:52 +0000 (16:20 +0200)
committerCarlos Martín Nieto <cmn@dwim.me>
Thu, 12 Jun 2014 14:58:25 +0000 (16:58 +0200)
Bring together all of the OpenSSL initialization to
git_threads_init() so it's together and doesn't need locks.

Moving it here also gives us libssh2 thread safety (when built against
openssl).

src/global.c
src/global.h
src/netops.c

index 41428ec42419ce8fb5be3310fb90d9e584bc289d..b144b050a8faf39272df64eccdf1556a34ef2692 100644 (file)
@@ -19,11 +19,9 @@ git_mutex git__mwindow_mutex;
 #ifdef GIT_SSL
 # include <openssl/ssl.h>
 SSL_CTX *git__ssl_ctx;
+static git_mutex *openssl_locks;
 #endif
 
-git_mutex git__ssl_mutex;
-git_atomic git__ssl_init;
-
 static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB];
 static git_atomic git__n_shutdown_callbacks;
 static git_atomic git__n_inits;
@@ -47,12 +45,59 @@ static void git__shutdown(void)
 
 }
 
+#if defined(GIT_THREADS) && defined(GIT_SSL)
+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]);
+       }
+}
+#endif
+
+
 static void init_ssl(void)
 {
 #ifdef GIT_SSL
        SSL_load_error_strings();
        OpenSSL_add_ssl_algorithms();
        git__ssl_ctx = SSL_CTX_new(SSLv23_method());
+       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;
+       }
+
+# 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;
+               }
+
+               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;
+                       }
+               }
+
+               CRYPTO_set_locking_callback(openssl_locking_function);
+       }
+# endif
 #endif
 }
 
@@ -183,8 +228,6 @@ static void init_once(void)
 {
        if ((init_error = git_mutex_init(&git__mwindow_mutex)) != 0)
                return;
-       if ((init_error = git_mutex_init(&git__ssl_mutex)) != 0)
-               return;
        pthread_key_create(&_tls_key, &cb__free_status);
 
 
index 8904e2de5b9039330dd36bf94e801ae74cab9a94..745df3e4a22ab02d2459fe8f23aee47266cf1e18 100644 (file)
@@ -23,8 +23,6 @@ extern SSL_CTX *git__ssl_ctx;
 git_global_st *git__global_state(void);
 
 extern git_mutex git__mwindow_mutex;
-extern git_mutex git__ssl_mutex;
-extern git_atomic git__ssl_init;
 
 #define GIT_GLOBAL (git__global_state())
 
index 54804d4182b44cf526a96b45bc4a0fbf11e4c2f8..965e4775d309d4c964f6b01ecc826a4b0cd68341 100644 (file)
 #include "http_parser.h"
 #include "global.h"
 
-#if defined(GIT_SSL) && defined(GIT_THREADS)
-/* OpenSSL wants us to keep an array of locks */
-static git_mutex *openssl_locks;
-#endif
-
 #ifdef GIT_WIN32
 static void net_set_error(const char *str)
 {
@@ -391,86 +386,14 @@ cert_fail_name:
        return -1;
 }
 
-#ifdef GIT_THREADS
-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]);
-       }
-}
-#endif
-
-/**
- * The OpenSSL init functions are not reentrant so we need to init
- * them under lock.
- */
-static int init_ssl(void)
-{
-       if (git__ssl_init.val)
-               return 0;
-
-       if (git_mutex_lock(&git__ssl_mutex) < 0) {
-               giterr_set(GITERR_OS, "failed to acquire ssl init lock");
-               return -1;
-       }
-
-       /* if we had to wait for the lock, someone else did it, we can return */
-       if (git__ssl_init.val)
-               return 0;
-
-       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)) {
-               unsigned long err = ERR_get_error();
-               giterr_set(GITERR_SSL, "failed to set verify paths: %s\n", ERR_error_string(err, NULL));
-               return -1;
-       }
-
-#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) {
-                       git_mutex_unlock(&git__ssl_mutex);
-                       return -1;
-               }
-               GITERR_CHECK_ALLOC(openssl_locks);
-
-               for (i = 0; i < num_locks; i++) {
-                       if (git_mutex_init(&openssl_locks[i]) != 0) {
-                               git_mutex_unlock(&git__ssl_mutex);
-                               giterr_set(GITERR_SSL, "failed to init lock %d", i);
-                               return -1;
-                       }
-               }
-       }
-
-       CRYPTO_set_locking_callback(openssl_locking_function);
-#endif
-
-       git_atomic_inc(&git__ssl_init);
-       git_mutex_unlock(&git__ssl_mutex);
-
-       return 0;
-}
-
 static int ssl_setup(gitno_socket *socket, const char *host, int flags)
 {
        int ret;
 
-       if (init_ssl() < 0)
+       if (git__ssl_ctx == NULL) {
+               giterr_set(GITERR_NET, "OpenSSL initialization failed");
                return -1;
+       }
 
        socket->ssl.ssl = SSL_new(git__ssl_ctx);
        if (socket->ssl.ssl == NULL)