diff options
| author | 2014-03-21 20:45:16 +0100 | |
|---|---|---|
| committer | 2014-03-21 20:45:16 +0100 | |
| commit | daf3b235f4f04c21b2765f61db7ae56ff9cdb6ba (patch) | |
| tree | c0656607175cdeff238a7fe5e2dfe94302992a51 | |
| parent | d95dfaacb04448230a4ab6a3fb152d96d13e959f (diff) | |
| download | libimobiledevice-daf3b235f4f04c21b2765f61db7ae56ff9cdb6ba.tar.gz libimobiledevice-daf3b235f4f04c21b2765f61db7ae56ff9cdb6ba.tar.bz2 | |
implement global thread safe library initialization
| -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 | |||
| 609 | gnutls_x509_privkey_t host_privkey; | 609 | gnutls_x509_privkey_t host_privkey; |
| 610 | gnutls_x509_crt_t host_cert; | 610 | gnutls_x509_crt_t host_cert; |
| 611 | 611 | ||
| 612 | gnutls_global_init(); | ||
| 613 | |||
| 614 | /* use less secure random to speed up key generation */ | 612 | /* use less secure random to speed up key generation */ |
| 615 | gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM); | 613 | gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM); |
| 616 | 614 | ||
| @@ -770,8 +768,6 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
| 770 | gnutls_free(exponent.data); | 768 | gnutls_free(exponent.data); |
| 771 | 769 | ||
| 772 | gnutls_free(der_pub_key.data); | 770 | gnutls_free(der_pub_key.data); |
| 773 | |||
| 774 | gnutls_global_deinit(); | ||
| 775 | #endif | 771 | #endif |
| 776 | if (NULL != root_cert_pem.data && 0 != root_cert_pem.size && | 772 | if (NULL != root_cert_pem.data && 0 != root_cert_pem.size && |
| 777 | NULL != host_cert_pem.data && 0 != host_cert_pem.size) | 773 | 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 @@ | |||
| 36 | #endif | 36 | #endif |
| 37 | #include "idevice.h" | 37 | #include "idevice.h" |
| 38 | #include "common/userpref.h" | 38 | #include "common/userpref.h" |
| 39 | #include "common/thread.h" | ||
| 39 | #include "common/debug.h" | 40 | #include "common/debug.h" |
| 40 | 41 | ||
| 41 | #ifdef HAVE_OPENSSL | 42 | #ifdef HAVE_OPENSSL |
| 42 | static int openssl_init_done = 0; | 43 | static mutex_t *mutex_buf = NULL; |
| 44 | static void locking_function(int mode, int n, const char* file, int line) | ||
| 45 | { | ||
| 46 | if (mode & CRYPTO_LOCK) | ||
| 47 | mutex_lock(&mutex_buf[n]); | ||
| 48 | else | ||
| 49 | mutex_unlock(&mutex_buf[n]); | ||
| 50 | } | ||
| 51 | |||
| 52 | static unsigned long id_function(void) | ||
| 53 | { | ||
| 54 | return ((unsigned long)THREAD_ID); | ||
| 55 | } | ||
| 56 | #endif | ||
| 57 | |||
| 58 | static void internal_idevice_init(void) | ||
| 59 | { | ||
| 60 | #ifdef HAVE_OPENSSL | ||
| 61 | int i; | ||
| 62 | SSL_library_init(); | ||
| 63 | |||
| 64 | mutex_buf = malloc(CRYPTO_num_locks() * sizeof(mutex_t)); | ||
| 65 | if (!mutex_buf) | ||
| 66 | return; | ||
| 67 | for (i = 0; i < CRYPTO_num_locks(); i++) | ||
| 68 | mutex_init(&mutex_buf[i]); | ||
| 69 | |||
| 70 | CRYPTO_set_id_callback(id_function); | ||
| 71 | CRYPTO_set_locking_callback(locking_function); | ||
| 72 | #else | ||
| 73 | gnutls_global_init(); | ||
| 74 | #endif | ||
| 75 | } | ||
| 76 | |||
| 77 | static void internal_idevice_deinit(void) | ||
| 78 | { | ||
| 79 | #ifdef HAVE_OPENSSL | ||
| 80 | int i; | ||
| 81 | if (!mutex_buf) | ||
| 82 | return; | ||
| 83 | CRYPTO_set_id_callback(NULL); | ||
| 84 | CRYPTO_set_locking_callback(NULL); | ||
| 85 | for (i = 0; i < CRYPTO_num_locks(); i++) | ||
| 86 | mutex_destroy(&mutex_buf[i]); | ||
| 87 | free(mutex_buf); | ||
| 88 | mutex_buf = NULL; | ||
| 89 | #else | ||
| 90 | gnutls_global_deinit(); | ||
| 91 | #endif | ||
| 92 | } | ||
| 93 | |||
| 94 | static thread_once_t init_once = THREAD_ONCE_INIT; | ||
| 95 | static thread_once_t deinit_once = THREAD_ONCE_INIT; | ||
| 96 | |||
| 97 | #ifdef WIN32 | ||
| 98 | int APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) | ||
| 99 | { | ||
| 100 | switch (dwReason) { | ||
| 101 | case DLL_PROCESS_ATTACH: | ||
| 102 | thread_once(&init_once, internal_idevice_init); | ||
| 103 | break; | ||
| 104 | case DLL_PROCESS_DETACH: | ||
| 105 | thread_once(&deinit_once, internal_idevice_deinit); | ||
| 106 | break; | ||
| 107 | default: | ||
| 108 | break; | ||
| 109 | } | ||
| 110 | return 1; | ||
| 111 | } | ||
| 112 | #else | ||
| 113 | static void __attribute__((constructor)) libimobiledevice_initialize(void) | ||
| 114 | { | ||
| 115 | thread_once(&init_once, internal_idevice_init); | ||
| 116 | } | ||
| 117 | |||
| 118 | static void __attribute__((destructor)) libimobiledevice_deinitialize(void) | ||
| 119 | { | ||
| 120 | thread_once(&deinit_once, internal_idevice_deinit); | ||
| 121 | } | ||
| 43 | #endif | 122 | #endif |
| 44 | 123 | ||
| 45 | static idevice_event_cb_t event_cb = NULL; | 124 | static idevice_event_cb_t event_cb = NULL; |
| @@ -575,7 +654,6 @@ static void internal_ssl_cleanup(ssl_data_t ssl_data) | |||
| 575 | if (ssl_data->ctx) { | 654 | if (ssl_data->ctx) { |
| 576 | SSL_CTX_free(ssl_data->ctx); | 655 | SSL_CTX_free(ssl_data->ctx); |
| 577 | } | 656 | } |
| 578 | openssl_init_done = 0; | ||
| 579 | #else | 657 | #else |
| 580 | if (ssl_data->session) { | 658 | if (ssl_data->session) { |
| 581 | gnutls_deinit(ssl_data->session); | 659 | gnutls_deinit(ssl_data->session); |
| @@ -691,12 +769,6 @@ idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) | |||
| 691 | if (pair_record) | 769 | if (pair_record) |
| 692 | plist_free(pair_record); | 770 | plist_free(pair_record); |
| 693 | 771 | ||
| 694 | /* Set up OpenSSL */ | ||
| 695 | if (openssl_init_done == 0) { | ||
| 696 | SSL_library_init(); | ||
| 697 | openssl_init_done = 1; | ||
| 698 | } | ||
| 699 | |||
| 700 | BIO *ssl_bio = BIO_new(BIO_s_socket()); | 772 | BIO *ssl_bio = BIO_new(BIO_s_socket()); |
| 701 | if (!ssl_bio) { | 773 | if (!ssl_bio) { |
| 702 | debug_info("ERROR: Could not create SSL bio."); | 774 | debug_info("ERROR: Could not create SSL bio."); |
| @@ -761,7 +833,6 @@ idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) | |||
| 761 | 833 | ||
| 762 | /* Set up GnuTLS... */ | 834 | /* Set up GnuTLS... */ |
| 763 | debug_info("enabling SSL mode"); | 835 | debug_info("enabling SSL mode"); |
| 764 | gnutls_global_init(); | ||
| 765 | errno = 0; | 836 | errno = 0; |
| 766 | gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate); | 837 | gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate); |
| 767 | gnutls_certificate_client_set_retrieve_function(ssl_data_loc->certificate, internal_cert_callback); | 838 | gnutls_certificate_client_set_retrieve_function(ssl_data_loc->certificate, internal_cert_callback); |
