diff options
| -rw-r--r-- | common/userpref.c | 4 | ||||
| -rw-r--r-- | src/idevice.c | 89 | 
2 files changed, 80 insertions, 13 deletions
diff --git a/common/userpref.c b/common/userpref.c index 808c55c..5fb8458 100644 --- a/common/userpref.c +++ b/common/userpref.c @@ -609,8 +609,6 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da  	gnutls_x509_privkey_t host_privkey;  	gnutls_x509_crt_t host_cert; -	gnutls_global_init(); -  	/* use less secure random to speed up key generation */  	gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM); @@ -770,8 +768,6 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da  	gnutls_free(exponent.data);  	gnutls_free(der_pub_key.data); - -	gnutls_global_deinit();  #endif  	if (NULL != root_cert_pem.data && 0 != root_cert_pem.size &&  		NULL != host_cert_pem.data && 0 != host_cert_pem.size) diff --git a/src/idevice.c b/src/idevice.c index 3d20069..28a62b0 100644 --- a/src/idevice.c +++ b/src/idevice.c @@ -36,10 +36,89 @@  #endif  #include "idevice.h"  #include "common/userpref.h" +#include "common/thread.h"  #include "common/debug.h"  #ifdef HAVE_OPENSSL -static int openssl_init_done = 0; +static mutex_t *mutex_buf = NULL; +static void locking_function(int mode, int n, const char* file, int line) +{ +	if (mode & CRYPTO_LOCK) +		mutex_lock(&mutex_buf[n]); +	else +		mutex_unlock(&mutex_buf[n]); +} + +static unsigned long id_function(void) +{ +	return ((unsigned long)THREAD_ID); +} +#endif + +static void internal_idevice_init(void) +{ +#ifdef HAVE_OPENSSL +	int i; +	SSL_library_init(); + +	mutex_buf = malloc(CRYPTO_num_locks() * sizeof(mutex_t)); +	if (!mutex_buf) +		return; +	for (i = 0; i < CRYPTO_num_locks(); i++) +		mutex_init(&mutex_buf[i]); + +	CRYPTO_set_id_callback(id_function); +	CRYPTO_set_locking_callback(locking_function); +#else +	gnutls_global_init(); +#endif +} + +static void internal_idevice_deinit(void) +{ +#ifdef HAVE_OPENSSL +	int i; +	if (!mutex_buf) +		return; +	CRYPTO_set_id_callback(NULL); +	CRYPTO_set_locking_callback(NULL); +	for (i = 0; i < CRYPTO_num_locks(); i++) +		mutex_destroy(&mutex_buf[i]); +	free(mutex_buf); +	mutex_buf = NULL; +#else +	gnutls_global_deinit(); +#endif +} + +static thread_once_t init_once = THREAD_ONCE_INIT; +static thread_once_t deinit_once = THREAD_ONCE_INIT; + +#ifdef WIN32 +int APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) +{ +	switch (dwReason) { +	case DLL_PROCESS_ATTACH: +		thread_once(&init_once,	internal_idevice_init); +		break; +	case DLL_PROCESS_DETACH: +		thread_once(&deinit_once, internal_idevice_deinit); +		break; +	default: +		break; +	} +	return 1; +} +#else +static void __attribute__((constructor)) libimobiledevice_initialize(void) +{ +	thread_once(&init_once, internal_idevice_init); +} + +static void __attribute__((destructor)) libimobiledevice_deinitialize(void) +{ +	thread_once(&deinit_once, internal_idevice_deinit); +}  #endif  static idevice_event_cb_t event_cb = NULL; @@ -575,7 +654,6 @@ static void internal_ssl_cleanup(ssl_data_t ssl_data)  	if (ssl_data->ctx) {  		SSL_CTX_free(ssl_data->ctx);  	} -	openssl_init_done = 0;  #else  	if (ssl_data->session) {  		gnutls_deinit(ssl_data->session); @@ -691,12 +769,6 @@ idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection)  	if (pair_record)  		plist_free(pair_record); -	/* Set up OpenSSL */ -	if (openssl_init_done == 0) { -		SSL_library_init(); -		openssl_init_done = 1; -	} -  	BIO *ssl_bio = BIO_new(BIO_s_socket());  	if (!ssl_bio) {  		debug_info("ERROR: Could not create SSL bio."); @@ -761,7 +833,6 @@ idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection)  	/* Set up GnuTLS... */  	debug_info("enabling SSL mode"); -	gnutls_global_init();  	errno = 0;  	gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate);  	gnutls_certificate_client_set_retrieve_function(ssl_data_loc->certificate, internal_cert_callback);  | 
