Commit e93206e0 by Vicent Marti

Merge pull request #2421 from libgit2/cmn/init-ssl-once

netops: init OpenSSL once under lock
parents 9c3e4e97 081e76ba
...@@ -16,6 +16,12 @@ git_mutex git__mwindow_mutex; ...@@ -16,6 +16,12 @@ git_mutex git__mwindow_mutex;
#define MAX_SHUTDOWN_CB 8 #define MAX_SHUTDOWN_CB 8
#ifdef GIT_SSL
# include <openssl/ssl.h>
SSL_CTX *git__ssl_ctx;
static git_mutex *openssl_locks;
#endif
static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB]; static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB];
static git_atomic git__n_shutdown_callbacks; static git_atomic git__n_shutdown_callbacks;
static git_atomic git__n_inits; static git_atomic git__n_inits;
...@@ -39,6 +45,62 @@ static void git__shutdown(void) ...@@ -39,6 +45,62 @@ 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
}
/** /**
* Handle the global state with TLS * Handle the global state with TLS
* *
...@@ -168,10 +230,14 @@ static void init_once(void) ...@@ -168,10 +230,14 @@ static void init_once(void)
return; return;
pthread_key_create(&_tls_key, &cb__free_status); pthread_key_create(&_tls_key, &cb__free_status);
/* Initialize any other subsystems that have global state */ /* Initialize any other subsystems that have global state */
if ((init_error = git_hash_global_init()) >= 0) if ((init_error = git_hash_global_init()) >= 0)
init_error = git_sysdir_global_init(); init_error = git_sysdir_global_init();
/* OpenSSL needs to be initialized from the main thread */
init_ssl();
GIT_MEMORY_BARRIER; GIT_MEMORY_BARRIER;
} }
...@@ -225,6 +291,7 @@ static git_global_st __state; ...@@ -225,6 +291,7 @@ static git_global_st __state;
int git_threads_init(void) int git_threads_init(void)
{ {
init_ssl();
git_atomic_inc(&git__n_inits); git_atomic_inc(&git__n_inits);
return 0; return 0;
} }
......
...@@ -15,6 +15,11 @@ typedef struct { ...@@ -15,6 +15,11 @@ typedef struct {
git_error error_t; git_error error_t;
} git_global_st; } git_global_st;
#ifdef GIT_SSL
# include <openssl/ssl.h>
extern SSL_CTX *git__ssl_ctx;
#endif
git_global_st *git__global_state(void); git_global_st *git__global_state(void);
extern git_mutex git__mwindow_mutex; extern git_mutex git__mwindow_mutex;
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "posix.h" #include "posix.h"
#include "buffer.h" #include "buffer.h"
#include "http_parser.h" #include "http_parser.h"
#include "global.h"
#ifdef GIT_WIN32 #ifdef GIT_WIN32
static void net_set_error(const char *str) static void net_set_error(const char *str)
...@@ -157,7 +158,7 @@ void gitno_buffer_setup_callback( ...@@ -157,7 +158,7 @@ void gitno_buffer_setup_callback(
void gitno_buffer_setup(gitno_socket *socket, gitno_buffer *buf, char *data, size_t len) void gitno_buffer_setup(gitno_socket *socket, gitno_buffer *buf, char *data, size_t len)
{ {
#ifdef GIT_SSL #ifdef GIT_SSL
if (socket->ssl.ctx) { if (socket->ssl.ssl) {
gitno_buffer_setup_callback(socket, buf, data, len, gitno__recv_ssl, NULL); gitno_buffer_setup_callback(socket, buf, data, len, gitno__recv_ssl, NULL);
return; return;
} }
...@@ -202,7 +203,6 @@ static int gitno_ssl_teardown(gitno_ssl *ssl) ...@@ -202,7 +203,6 @@ static int gitno_ssl_teardown(gitno_ssl *ssl)
ret = 0; ret = 0;
SSL_free(ssl->ssl); SSL_free(ssl->ssl);
SSL_CTX_free(ssl->ctx);
return ret; return ret;
} }
...@@ -390,18 +390,12 @@ static int ssl_setup(gitno_socket *socket, const char *host, int flags) ...@@ -390,18 +390,12 @@ static int ssl_setup(gitno_socket *socket, const char *host, int flags)
{ {
int ret; int ret;
SSL_library_init(); if (git__ssl_ctx == NULL) {
SSL_load_error_strings(); giterr_set(GITERR_NET, "OpenSSL initialization failed");
socket->ssl.ctx = SSL_CTX_new(SSLv23_method()); return -1;
if (socket->ssl.ctx == NULL) }
return ssl_set_error(&socket->ssl, 0);
SSL_CTX_set_mode(socket->ssl.ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_verify(socket->ssl.ctx, SSL_VERIFY_NONE, NULL);
if (!SSL_CTX_set_default_verify_paths(socket->ssl.ctx))
return ssl_set_error(&socket->ssl, 0);
socket->ssl.ssl = SSL_new(socket->ssl.ctx); socket->ssl.ssl = SSL_new(git__ssl_ctx);
if (socket->ssl.ssl == NULL) if (socket->ssl.ssl == NULL)
return ssl_set_error(&socket->ssl, 0); return ssl_set_error(&socket->ssl, 0);
...@@ -538,7 +532,7 @@ int gitno_send(gitno_socket *socket, const char *msg, size_t len, int flags) ...@@ -538,7 +532,7 @@ int gitno_send(gitno_socket *socket, const char *msg, size_t len, int flags)
size_t off = 0; size_t off = 0;
#ifdef GIT_SSL #ifdef GIT_SSL
if (socket->ssl.ctx) if (socket->ssl.ssl)
return gitno_send_ssl(&socket->ssl, msg, len, flags); return gitno_send_ssl(&socket->ssl, msg, len, flags);
#endif #endif
...@@ -559,7 +553,7 @@ int gitno_send(gitno_socket *socket, const char *msg, size_t len, int flags) ...@@ -559,7 +553,7 @@ int gitno_send(gitno_socket *socket, const char *msg, size_t len, int flags)
int gitno_close(gitno_socket *s) int gitno_close(gitno_socket *s)
{ {
#ifdef GIT_SSL #ifdef GIT_SSL
if (s->ssl.ctx && if (s->ssl.ssl &&
gitno_ssl_teardown(&s->ssl) < 0) gitno_ssl_teardown(&s->ssl) < 0)
return -1; return -1;
#endif #endif
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
struct gitno_ssl { struct gitno_ssl {
#ifdef GIT_SSL #ifdef GIT_SSL
SSL_CTX *ctx;
SSL *ssl; SSL *ssl;
#else #else
size_t dummy; size_t dummy;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment