diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2010-09-01 14:07:45 +0200 |
---|---|---|
committer | Aris Adamantiadis <aris@0xbadc0de.be> | 2010-09-01 14:07:45 +0200 |
commit | 8c55294ea9134c32f80d1a399a6a49ecdc9264b2 (patch) | |
tree | a21f32ae1501abf56c21f49f588503580a2c12ba /libssh | |
parent | 50d8d75d890e16e8d4d3f4dd51de05812c0c3a1f (diff) | |
download | libssh-8c55294ea9134c32f80d1a399a6a49ecdc9264b2.tar.gz libssh-8c55294ea9134c32f80d1a399a6a49ecdc9264b2.tar.xz libssh-8c55294ea9134c32f80d1a399a6a49ecdc9264b2.zip |
Openssl implementation of threading + default imp
Diffstat (limited to 'libssh')
-rw-r--r-- | libssh/dh.c | 2 | ||||
-rw-r--r-- | libssh/threads.c | 121 |
2 files changed, 92 insertions, 31 deletions
diff --git a/libssh/dh.c b/libssh/dh.c index c81ed8f..eff74bf 100644 --- a/libssh/dh.c +++ b/libssh/dh.c @@ -55,6 +55,7 @@ #include "libssh/session.h" #include "libssh/keys.h" #include "libssh/dh.h" +#include "libssh/threads.h" /* todo: remove it */ #include "libssh/string.h" @@ -155,6 +156,7 @@ void ssh_crypto_finalize(void) { bignum_free(p); p = NULL; ssh_crypto_initialized=0; + ssh_threads_finalize(); } } diff --git a/libssh/threads.c b/libssh/threads.c index c7fc37b..63e9d83 100644 --- a/libssh/threads.c +++ b/libssh/threads.c @@ -30,10 +30,13 @@ #include "libssh/priv.h" #include "libssh/threads.h" +#ifndef HAVE_PTHREAD +#warning "You do not have any threading library installed. If the linked" +#warning "application doesn't provide the threading callbacks, you're screwed" +#endif -#ifdef HAVE_LIBGCRYPT -#define HAVE_PTHREADS -#ifdef HAVE_PTHREADS +//#define HAVE_PTHREAD +#ifdef HAVE_PTHREAD #include <errno.h> #include <pthread.h> @@ -66,31 +69,83 @@ static int ssh_pthread_mutex_unlock (void **lock){ return pthread_mutex_unlock (*lock); } +static unsigned long ssh_pthread_thread_id (void){ + return (unsigned long) pthread_self(); +} -static struct ssh_threads_callbacks_struct ssh_gcrypt_user_callbacks= +static struct ssh_threads_callbacks_struct ssh_pthread_user_callbacks= { .mutex_init=ssh_pthread_mutex_init, .mutex_destroy=ssh_pthread_mutex_destroy, .mutex_lock=ssh_pthread_mutex_lock, - .mutex_unlock=ssh_pthread_mutex_unlock + .mutex_unlock=ssh_pthread_mutex_unlock, + .thread_id=ssh_pthread_thread_id }; #endif -static struct gcry_thread_cbs gcrypt_threads_callbacks; - -#endif - static struct ssh_threads_callbacks_struct *user_callbacks; #ifdef HAVE_LIBGCRYPT -static void copy_callback(struct ssh_threads_callbacks_struct *cb){ + +/* Libgcrypt specific way of handling thread callbacks */ + +static struct gcry_thread_cbs gcrypt_threads_callbacks; + +static int libgcrypt_thread_init(void){ + if(user_callbacks == NULL) + return SSH_ERROR; gcrypt_threads_callbacks.option= GCRY_THREAD_OPTION_VERSION << 8 || GCRY_THREAD_OPTION_USER; - gcrypt_threads_callbacks.mutex_init=cb->mutex_init; - gcrypt_threads_callbacks.mutex_destroy=cb->mutex_destroy; - gcrypt_threads_callbacks.mutex_lock=cb->mutex_lock; - gcrypt_threads_callbacks.mutex_unlock=cb->mutex_unlock; + gcrypt_threads_callbacks.mutex_init=user_callbacks->mutex_init; + gcrypt_threads_callbacks.mutex_destroy=user_callbacks->mutex_destroy; + gcrypt_threads_callbacks.mutex_lock=user_callbacks->mutex_lock; + gcrypt_threads_callbacks.mutex_unlock=user_callbacks->mutex_unlock; + gcry_control(GCRYCTL_SET_THREAD_CBS, &gcrypt_threads_callbacks); + return SSH_OK; +} +#else + +/* Libcrypto specific stuff */ + +void **libcrypto_mutexes; + +static void libcrypto_lock_callback(int mode, int i, const char *file, int line){ + (void)file; + (void)line; + if(mode & CRYPTO_LOCK){ + user_callbacks->mutex_lock(&libcrypto_mutexes[i]); + } else { + user_callbacks->mutex_unlock(&libcrypto_mutexes[i]); + } +} + +static int libcrypto_thread_init(){ + int n=CRYPTO_num_locks(); + int i; + libcrypto_mutexes=malloc(sizeof(void *) * n); + if (libcrypto_mutexes == NULL) + return SSH_ERROR; + for (i=0;i<n;++i){ + user_callbacks->mutex_init(&libcrypto_mutexes[i]); + } + CRYPTO_set_id_callback(user_callbacks->thread_id); + CRYPTO_set_locking_callback(libcrypto_lock_callback); + + return SSH_OK; +} + +static void libcrypto_thread_finalize(){ + int n=CRYPTO_num_locks(); + int i; + if (libcrypto_mutexes==NULL) + return; + for (i=0;i<n;++i){ + user_callbacks->mutex_destroy(&libcrypto_mutexes[i]); + } + SAFE_FREE(libcrypto_mutexes); + } + #endif /** @internal @@ -98,34 +153,38 @@ static void copy_callback(struct ssh_threads_callbacks_struct *cb){ */ int ssh_threads_init(void){ -#ifdef HAVE_LIBGCRYPT - if(user_callbacks != NULL){ - copy_callback(user_callbacks); - gcry_control(GCRYCTL_SET_THREAD_CBS, &gcrypt_threads_callbacks); - return SSH_OK; - } -#ifdef HAVE_PTHREADS - else { - copy_callback(&ssh_gcrypt_user_callbacks); - gcry_control(GCRYCTL_SET_THREAD_CBS, &gcrypt_threads_callbacks); - return SSH_OK; - } + /* first initialize the user_callbacks with our default handlers if not + * already the case + */ + if(user_callbacks == NULL){ +#ifdef HAVE_PTHREAD + user_callbacks=&ssh_pthread_user_callbacks; + } else { #endif -#else - + return SSH_ERROR; // Can't do anything to initialize threading + } + /* Then initialize the crypto libraries threading callbacks */ +#ifdef HAVE_LIBGCRYPT + return libgcrypt_thread_init(); +#else /* Libcrypto */ + return libcrypto_thread_init(); #endif return SSH_ERROR; } +void ssh_threads_finalize(void){ +#ifdef HAVE_LIBGCRYPT +#else + libcrypto_thread_finalize(); +#endif +} + int ssh_init_set_threads_callbacks(struct ssh_threads_callbacks_struct *cb){ user_callbacks=cb; return SSH_OK; } -int ssh_init_set_threads_pthreads(void){ - return SSH_OK; -} /** * @} */ |