threads: Automatically call ssh_init on load
This makes unnecessary to call ssh_init() when the library is dynamically loaded. Also removes the threads shared library. The used threads implementation is chosen in configuration time, changing the ssh_threads_get_default() depending on the available threads library. Internally, it is expected a threads implementation providing: - void ssh_mutex_lock(void **mutex); - void ssh_mutex_unlock(void **mutex); - struct ssh_threads_callbacks_struct *ssh_threads_get_default(void); and a crypto implementation providing: - int crypto_thread_init(struct ssh_threads_callbacks_struct *user_callbacks); - void crypto_thread_finalize(void); This adds internal threads implementation for pthreads and noop. Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Этот коммит содержится в:
родитель
6a077fe750
Коммит
83b43443e5
@ -69,6 +69,7 @@ endif(WITH_GCRYPT)
|
||||
|
||||
# Find out if we have threading available
|
||||
set(CMAKE_THREAD_PREFER_PTHREADS ON)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads)
|
||||
|
||||
if (WITH_GSSAPI)
|
||||
@ -101,30 +102,15 @@ configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc)
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc
|
||||
DESTINATION
|
||||
${LIB_INSTALL_DIR}/pkgconfig
|
||||
COMPONENT
|
||||
pkgconfig
|
||||
)
|
||||
|
||||
if (LIBSSH_THREADS)
|
||||
configure_file(libssh_threads.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc)
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc
|
||||
DESTINATION
|
||||
${LIB_INSTALL_DIR}/pkgconfig
|
||||
COMPONENT
|
||||
pkgconfig
|
||||
)
|
||||
endif (LIBSSH_THREADS)
|
||||
endif (UNIX)
|
||||
|
||||
# cmake config files
|
||||
set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
set(LIBSSH_THREADS_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
|
||||
configure_file(${PROJECT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY)
|
||||
configure_file(${PROJECT_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake @ONLY)
|
||||
|
@ -24,8 +24,33 @@
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/callbacks.h>
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
|
||||
#include <pthread.h>
|
||||
#define SSH_MUTEX pthread_mutex_t
|
||||
|
||||
#if defined _GNU_SOURCE
|
||||
#define SSH_MUTEX_STATIC_INIT PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
|
||||
#else
|
||||
#define SSH_MUTEX_STATIC_INIT PTHREAD_MUTEX_INITIALIZER
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
# define SSH_MUTEX void *
|
||||
#define SSH_MUTEX_STATIC_INIT NULL
|
||||
|
||||
#endif
|
||||
|
||||
int ssh_threads_init(void);
|
||||
void ssh_threads_finalize(void);
|
||||
const char *ssh_threads_get_type(void);
|
||||
|
||||
void ssh_mutex_lock(SSH_MUTEX *mutex);
|
||||
void ssh_mutex_unlock(SSH_MUTEX *mutex);
|
||||
|
||||
struct ssh_threads_callbacks_struct *ssh_threads_get_default(void);
|
||||
int crypto_thread_init(struct ssh_threads_callbacks_struct *user_callbacks);
|
||||
void crypto_thread_finalize(void);
|
||||
|
||||
#endif /* THREADS_H_ */
|
||||
|
@ -167,9 +167,23 @@ set(libssh_SRCS
|
||||
chachapoly.c
|
||||
)
|
||||
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
threads/noop.c
|
||||
threads/pthread.c
|
||||
)
|
||||
else()
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
threads/noop.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if (WITH_GCRYPT)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
threads/libgcrypt.c
|
||||
libgcrypt.c
|
||||
gcrypt_missing.c
|
||||
pki_gcrypt.c
|
||||
@ -178,6 +192,7 @@ if (WITH_GCRYPT)
|
||||
elseif (WITH_MBEDTLS)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
threads/mbedtls.c
|
||||
libmbedcrypto.c
|
||||
mbedcrypto_missing.c
|
||||
pki_mbedcrypto.c
|
||||
@ -186,6 +201,7 @@ elseif (WITH_MBEDTLS)
|
||||
else (WITH_GCRYPT)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
threads/libcrypto.c
|
||||
pki_crypto.c
|
||||
ecdh_crypto.c
|
||||
libcrypto.c
|
||||
@ -319,6 +335,3 @@ if (WITH_STATIC_LIB)
|
||||
endif (WITH_STATIC_LIB)
|
||||
|
||||
message(STATUS "Threads_FOUND=${Threads_FOUND}")
|
||||
if (Threads_FOUND)
|
||||
add_subdirectory(threads)
|
||||
endif (Threads_FOUND)
|
||||
|
196
src/init.c
196
src/init.c
@ -32,12 +32,94 @@
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#define CONSTRUCTOR_ATTRIBUTE __attribute__((constructor))
|
||||
#define DESTRUCTOR_ATTRIBUTE __attribute__((destructor))
|
||||
|
||||
/* Declare static mutex */
|
||||
static SSH_MUTEX ssh_init_mutex = SSH_MUTEX_STATIC_INIT;
|
||||
|
||||
/* Counter for initializations */
|
||||
static int _ssh_initialized = 0;
|
||||
|
||||
/* Cache the returned value */
|
||||
static int _ssh_init_ret = 0;
|
||||
|
||||
void libssh_constructor(void) CONSTRUCTOR_ATTRIBUTE;
|
||||
void libssh_destructor(void) DESTRUCTOR_ATTRIBUTE;
|
||||
|
||||
static int _ssh_init(unsigned constructor) {
|
||||
|
||||
int rc = 0;
|
||||
|
||||
if (!constructor) {
|
||||
ssh_mutex_lock(&ssh_init_mutex);
|
||||
}
|
||||
|
||||
_ssh_initialized++;
|
||||
|
||||
if (_ssh_initialized > 1) {
|
||||
rc = _ssh_init_ret;
|
||||
goto _ret;
|
||||
}
|
||||
|
||||
rc = ssh_threads_init();
|
||||
if (rc) {
|
||||
goto _ret;
|
||||
}
|
||||
|
||||
rc = ssh_crypto_init();
|
||||
if (rc) {
|
||||
goto _ret;
|
||||
}
|
||||
|
||||
rc = ssh_dh_init();
|
||||
if (rc) {
|
||||
goto _ret;
|
||||
}
|
||||
|
||||
rc = ssh_socket_init();
|
||||
if (rc) {
|
||||
goto _ret;
|
||||
}
|
||||
|
||||
_ret:
|
||||
_ssh_init_ret = rc;
|
||||
|
||||
if (!constructor) {
|
||||
ssh_mutex_unlock(&ssh_init_mutex);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize global cryptographic data structures.
|
||||
*
|
||||
* This functions is automatically called when the library is loaded.
|
||||
*
|
||||
* @returns 0 on success, -1 if an error occured.
|
||||
*/
|
||||
void libssh_constructor(void)
|
||||
{
|
||||
|
||||
int rc;
|
||||
|
||||
rc = _ssh_init(1);
|
||||
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error in auto_init()\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @defgroup libssh The libssh API
|
||||
*
|
||||
* The libssh library is implementing the SSH protocols and some of its
|
||||
* extensions. This group of functions is mostly used to implment a SSH client.
|
||||
* Some function are needed to implement a SSH server too.
|
||||
* extensions. This group of functions is mostly used to implement an SSH
|
||||
* client.
|
||||
* Some function are needed to implement an SSH server too.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
@ -45,57 +127,97 @@
|
||||
/**
|
||||
* @brief Initialize global cryptographic data structures.
|
||||
*
|
||||
* This function should only be called once, at the beginning of the program, in
|
||||
* the main thread. It may be omitted if your program is not multithreaded.
|
||||
* Since version 0.8.0, it is not necessary to call this function on systems
|
||||
* which are fully supported with regards to threading (that is, system with
|
||||
* pthreads available).
|
||||
*
|
||||
* If the library is already initialized, increments the _ssh_initialized
|
||||
* counter and return the error code cached in _ssh_init_ret.
|
||||
*
|
||||
* @returns 0 on success, -1 if an error occured.
|
||||
*/
|
||||
int ssh_init(void) {
|
||||
int rc;
|
||||
|
||||
rc = ssh_threads_init();
|
||||
if (rc != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ssh_crypto_init();
|
||||
if (rc != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ssh_dh_init();
|
||||
if (rc != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ssh_socket_init();
|
||||
if (rc != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return _ssh_init(0);
|
||||
}
|
||||
|
||||
static int _ssh_finalize(unsigned destructor) {
|
||||
|
||||
if (!destructor) {
|
||||
ssh_mutex_lock(&ssh_init_mutex);
|
||||
}
|
||||
|
||||
if (_ssh_initialized == 1) {
|
||||
_ssh_initialized = 0;
|
||||
|
||||
if (_ssh_init_ret < 0) {
|
||||
goto _ret;
|
||||
}
|
||||
|
||||
ssh_dh_finalize();
|
||||
ssh_crypto_finalize();
|
||||
ssh_socket_cleanup();
|
||||
/* It is important to finalize threading after CRYPTO because
|
||||
* it still depends on it */
|
||||
ssh_threads_finalize();
|
||||
|
||||
}
|
||||
else {
|
||||
if (_ssh_initialized > 0) {
|
||||
_ssh_initialized--;
|
||||
}
|
||||
}
|
||||
|
||||
_ret:
|
||||
if (!destructor) {
|
||||
ssh_mutex_unlock(&ssh_init_mutex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finalize and cleanup all libssh and cryptographic data structures.
|
||||
*
|
||||
* This function should only be called once, at the end of the program!
|
||||
* This function is automatically called when the library is unloaded.
|
||||
*
|
||||
* @returns 0 on succes, -1 if an error occured.
|
||||
*
|
||||
@returns 0 otherwise
|
||||
*/
|
||||
int ssh_finalize(void)
|
||||
void libssh_destructor(void)
|
||||
{
|
||||
ssh_dh_finalize();
|
||||
ssh_crypto_finalize();
|
||||
ssh_socket_cleanup();
|
||||
/* It is important to finalize threading after CRYPTO because
|
||||
* it still depends on it */
|
||||
ssh_threads_finalize();
|
||||
int rc;
|
||||
|
||||
return 0;
|
||||
rc = _ssh_finalize(1);
|
||||
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error in libssh_destructor()\n");
|
||||
}
|
||||
|
||||
/* Detect if ssh_init() was called without matching ssh_finalize() */
|
||||
if (_ssh_initialized > 0) {
|
||||
fprintf(stderr,
|
||||
"Error: ssh still initialized; probably ssh_init() was"
|
||||
" called more than once\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finalize and cleanup all libssh and cryptographic data structures.
|
||||
*
|
||||
* Since version 0.8.0, it is not necessary to call this function, since it is
|
||||
* automatically called when the library is unloaded.
|
||||
*
|
||||
* If ssh_init() is called explicitly, then ssh_finalize() must be called
|
||||
* explicitly.
|
||||
*
|
||||
* When called, decrements the counter _ssh_initialized. If the counter reaches
|
||||
* zero, then the libssh and cryptographic data structures are cleaned up.
|
||||
*
|
||||
* @returns 0 on succes, -1 if an error occured.
|
||||
*
|
||||
@returns 0 otherwise
|
||||
*/
|
||||
int ssh_finalize(void) {
|
||||
return _ssh_finalize(0);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
240
src/threads.c
240
src/threads.c
@ -33,213 +33,63 @@
|
||||
#include "libssh/crypto.h"
|
||||
#include "libssh/threads.h"
|
||||
|
||||
#ifdef HAVE_LIBMBEDCRYPTO
|
||||
#include <mbedtls/threading.h>
|
||||
#endif
|
||||
|
||||
static int threads_noop (void **lock){
|
||||
(void)lock;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long threads_id_noop (void){
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ssh_threads_callbacks_struct ssh_threads_noop =
|
||||
{
|
||||
"threads_noop",
|
||||
threads_noop,
|
||||
threads_noop,
|
||||
threads_noop,
|
||||
threads_noop,
|
||||
threads_id_noop
|
||||
};
|
||||
|
||||
struct ssh_threads_callbacks_struct *ssh_threads_get_noop(void) {
|
||||
return &ssh_threads_noop;
|
||||
}
|
||||
|
||||
static struct ssh_threads_callbacks_struct *user_callbacks =&ssh_threads_noop;
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#if (GCRYPT_VERSION_NUMBER >= 0x010600)
|
||||
/* libgcrypt >= 1.6 does not support custom callbacks */
|
||||
GCRY_THREAD_OPTION_PTHREAD_IMPL;
|
||||
|
||||
static int libgcrypt_thread_init(void){
|
||||
if(user_callbacks == NULL)
|
||||
return SSH_ERROR;
|
||||
if(user_callbacks == &ssh_threads_noop)
|
||||
return SSH_OK;
|
||||
if (strcmp(user_callbacks->type, "threads_pthread") == 0){
|
||||
gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
|
||||
return SSH_OK;
|
||||
} else {
|
||||
/* not supported */
|
||||
SSH_LOG(SSH_LOG_WARN, "Custom thread handlers not supported with libgcrypt >=1.6, using pthreads");
|
||||
gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
|
||||
return SSH_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* Libgcrypt < 1.6 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;
|
||||
if(user_callbacks == &ssh_threads_noop){
|
||||
gcrypt_threads_callbacks.option= GCRY_THREAD_OPTION_VERSION << 8 || GCRY_THREAD_OPTION_DEFAULT;
|
||||
} else {
|
||||
gcrypt_threads_callbacks.option= GCRY_THREAD_OPTION_VERSION << 8 || GCRY_THREAD_OPTION_USER;
|
||||
}
|
||||
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;
|
||||
}
|
||||
#endif /* GCRYPT_VERSION_NUMBER */
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
static int libmbedcrypto_thread_init(void)
|
||||
{
|
||||
if (user_callbacks == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (user_callbacks == &ssh_threads_noop) {
|
||||
return SSH_OK;
|
||||
}
|
||||
#ifdef MBEDTLS_THREADING_ALT
|
||||
else {
|
||||
mbedtls_threading_set_alt(user_callbacks->mutex_init,
|
||||
user_callbacks->mutex_destroy, user_callbacks->mutex_lock,
|
||||
user_callbacks->mutex_unlock);
|
||||
}
|
||||
#elif defined MBEDTLS_THREADING_PTHREAD
|
||||
return SSH_OK;
|
||||
#else
|
||||
return SSH_ERROR;
|
||||
#endif
|
||||
}
|
||||
#else /* HAVE_LIBGCRYPT */
|
||||
|
||||
/* Libcrypto specific stuff */
|
||||
|
||||
static void **libcrypto_mutexes;
|
||||
|
||||
void libcrypto_lock_callback(int mode, int i, const char *file, int line);
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK
|
||||
static void libcrypto_THREADID_callback(CRYPTO_THREADID *id)
|
||||
{
|
||||
unsigned long thread_id = (*user_callbacks->thread_id)();
|
||||
|
||||
CRYPTO_THREADID_set_numeric(id, thread_id);
|
||||
}
|
||||
#endif /* HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK */
|
||||
|
||||
static int libcrypto_thread_init(void){
|
||||
int n=CRYPTO_num_locks();
|
||||
int i;
|
||||
if(user_callbacks == &ssh_threads_noop)
|
||||
return SSH_OK;
|
||||
libcrypto_mutexes = calloc(n, sizeof(void *));
|
||||
if (libcrypto_mutexes == NULL)
|
||||
return SSH_ERROR;
|
||||
for (i=0;i<n;++i){
|
||||
user_callbacks->mutex_init(&libcrypto_mutexes[i]);
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK
|
||||
CRYPTO_THREADID_set_callback(libcrypto_THREADID_callback);
|
||||
#else
|
||||
CRYPTO_set_id_callback(user_callbacks->thread_id);
|
||||
#endif
|
||||
|
||||
CRYPTO_set_locking_callback(libcrypto_lock_callback);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static void libcrypto_thread_finalize(void){
|
||||
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
|
||||
static struct ssh_threads_callbacks_struct *user_callbacks = NULL;
|
||||
|
||||
/** @internal
|
||||
* @brief inits the threading with the backend cryptographic libraries
|
||||
*/
|
||||
|
||||
int ssh_threads_init(void){
|
||||
static int threads_initialized=0;
|
||||
int ret;
|
||||
if(threads_initialized)
|
||||
return SSH_OK;
|
||||
/* first initialize the user_callbacks with our default handlers if not
|
||||
* already the case
|
||||
*/
|
||||
if(user_callbacks == NULL){
|
||||
user_callbacks=&ssh_threads_noop;
|
||||
}
|
||||
int ssh_threads_init(void)
|
||||
{
|
||||
static int threads_initialized = 0;
|
||||
int rc;
|
||||
|
||||
/* Then initialize the crypto libraries threading callbacks */
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
ret = libgcrypt_thread_init();
|
||||
#elif HAVE_LIBMBEDCRYPTO
|
||||
ret = libmbedcrypto_thread_init();
|
||||
#else /* Libcrypto */
|
||||
ret = libcrypto_thread_init();
|
||||
#endif
|
||||
if(ret == SSH_OK)
|
||||
threads_initialized=1;
|
||||
return ret;
|
||||
if (threads_initialized) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/* first initialize the user_callbacks with our default handlers if not
|
||||
* already the case
|
||||
*/
|
||||
if (user_callbacks == NULL){
|
||||
user_callbacks = ssh_threads_get_default();
|
||||
}
|
||||
|
||||
/* Then initialize the crypto libraries threading callbacks */
|
||||
rc = crypto_thread_init(user_callbacks);
|
||||
if (rc == SSH_OK) {
|
||||
threads_initialized = 1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ssh_threads_finalize(void){
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#elif HAVE_LIBMBEDCRYPTO
|
||||
#ifdef MBEDTLS_THREADING_ALT
|
||||
mbedtls_threading_free_alt();
|
||||
#endif
|
||||
#else
|
||||
libcrypto_thread_finalize();
|
||||
#endif
|
||||
void ssh_threads_finalize(void)
|
||||
{
|
||||
crypto_thread_finalize();
|
||||
}
|
||||
|
||||
int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct *cb){
|
||||
user_callbacks=cb;
|
||||
return SSH_OK;
|
||||
int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct *cb)
|
||||
{
|
||||
|
||||
int rc;
|
||||
|
||||
if (user_callbacks != NULL) {
|
||||
crypto_thread_finalize();
|
||||
}
|
||||
|
||||
user_callbacks = cb;
|
||||
|
||||
rc = crypto_thread_init(user_callbacks);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
const char *ssh_threads_get_type(void) {
|
||||
if(user_callbacks != NULL)
|
||||
return user_callbacks->type;
|
||||
return NULL;
|
||||
const char *ssh_threads_get_type(void)
|
||||
{
|
||||
if (user_callbacks != NULL) {
|
||||
return user_callbacks->type;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,132 +0,0 @@
|
||||
project(libssh-threads C)
|
||||
|
||||
set(LIBSSH_THREADS_PUBLIC_INCLUDE_DIRS
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}
|
||||
CACHE INTERNAL "libssh public include directories"
|
||||
)
|
||||
|
||||
set(LIBSSH_THREADS_PRIVATE_INCLUDE_DIRS
|
||||
${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
||||
set(LIBSSH_THREADS_SHARED_LIBRARY
|
||||
ssh_threads_shared
|
||||
CACHE INTERNAL "libssh threads shared library"
|
||||
)
|
||||
|
||||
if (WITH_STATIC_LIB)
|
||||
set(LIBSSH_THREADS_STATIC_LIBRARY
|
||||
ssh_threads_static
|
||||
CACHE INTERNAL "libssh threads static library"
|
||||
)
|
||||
endif (WITH_STATIC_LIB)
|
||||
|
||||
set(LIBSSH_THREADS_LINK_LIBRARIES
|
||||
${LIBSSH_SHARED_LIBRARY}
|
||||
)
|
||||
|
||||
message(STATUS "threads library: Threads_FOUND=${Threads_FOUND}")
|
||||
|
||||
set(libssh_threads_SRCS) # empty SRC
|
||||
|
||||
# build and link pthread
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
set(libssh_threads_SRCS
|
||||
${libssh_threads_SRCS}
|
||||
pthread.c
|
||||
)
|
||||
|
||||
set(LIBSSH_THREADS_LINK_LIBRARIES
|
||||
${LIBSSH_THREADS_LINK_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
|
||||
message(STATUS "libssh_threads_SRCS=${libssh_threads_SRCS}")
|
||||
endif (CMAKE_USE_PTHREADS_INIT)
|
||||
|
||||
set(LIBSSH_THREADS_LINK_LIBRARIES
|
||||
${LIBSSH_THREADS_LINK_LIBRARIES}
|
||||
CACHE INTERNAL "libssh threads link libraries"
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${LIBSSH_THREADS_PUBLIC_INCLUDE_DIRS}
|
||||
${LIBSSH_THREADS_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
if (libssh_threads_SRCS)
|
||||
set(LIBSSH_THREADS ON CACHE "libssh threads lib" INTERNAL)
|
||||
|
||||
add_library(${LIBSSH_THREADS_SHARED_LIBRARY} SHARED ${libssh_threads_SRCS})
|
||||
|
||||
target_link_libraries(${LIBSSH_THREADS_SHARED_LIBRARY} ${LIBSSH_THREADS_LINK_LIBRARIES})
|
||||
|
||||
set_target_properties(
|
||||
${LIBSSH_THREADS_SHARED_LIBRARY}
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
OUTPUT_NAME
|
||||
ssh_threads
|
||||
DEFINE_SYMBOL
|
||||
LIBSSH_EXPORTS
|
||||
)
|
||||
|
||||
if (WITH_VISIBILITY_HIDDEN)
|
||||
set_target_properties(${LIBSSH_THREADS_SHARED_LIBRARY} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
|
||||
endif (WITH_VISIBILITY_HIDDEN)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
${LIBSSH_THREADS_SHARED_LIBRARY}
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
COMPONENT libraries
|
||||
)
|
||||
|
||||
if (WITH_STATIC_LIB)
|
||||
add_library(${LIBSSH_THREADS_STATIC_LIBRARY} STATIC ${libssh_threads_SRCS})
|
||||
|
||||
if (MSVC)
|
||||
set(OUTPUT_SUFFIX static)
|
||||
else (MSVC)
|
||||
set(OUTPUT_SUFFIX )
|
||||
endif (MSVC)
|
||||
|
||||
set_target_properties(
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
OUTPUT_NAME
|
||||
ssh_threads
|
||||
ARCHIVE_OUTPUT_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SUFFIX}
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
set_target_properties(
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS
|
||||
"-DLIBSSH_STATIC"
|
||||
)
|
||||
endif (WIN32)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
DESTINATION
|
||||
${LIB_INSTALL_DIR}/${OUTPUT_SUFFIX}
|
||||
COMPONENT
|
||||
libraries
|
||||
)
|
||||
endif (WITH_STATIC_LIB)
|
||||
endif (libssh_threads_SRCS)
|
125
src/threads/libcrypto.c
Обычный файл
125
src/threads/libcrypto.c
Обычный файл
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2018 by Anderson Toshiyuki Sasaki
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/crypto.h"
|
||||
#include "libssh/threads.h"
|
||||
#include <libssh/callbacks.h>
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000)
|
||||
|
||||
int crypto_thread_init(struct ssh_threads_callbacks_struct *cb)
|
||||
{
|
||||
(void) cb;
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
void crypto_thread_finalize(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static struct ssh_threads_callbacks_struct *user_callbacks = NULL;
|
||||
|
||||
static void **libcrypto_mutexes;
|
||||
|
||||
void libcrypto_lock_callback(int mode, int i, const char *file, int line);
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK
|
||||
static void libcrypto_THREADID_callback(CRYPTO_THREADID *id)
|
||||
{
|
||||
unsigned long thread_id = (*user_callbacks->thread_id)();
|
||||
|
||||
CRYPTO_THREADID_set_numeric(id, thread_id);
|
||||
}
|
||||
#endif /* HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK */
|
||||
|
||||
int crypto_thread_init(struct ssh_threads_callbacks_struct *cb)
|
||||
{
|
||||
int n = CRYPTO_num_locks();
|
||||
int cmp;
|
||||
int i;
|
||||
|
||||
if (cb == NULL) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
if (user_callbacks != NULL) {
|
||||
crypto_thread_finalize();
|
||||
}
|
||||
|
||||
user_callbacks = cb;
|
||||
|
||||
cmp = strcmp(user_callbacks->type, "threads_noop");
|
||||
if (cmp == 0) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
libcrypto_mutexes = calloc(n, sizeof(void *));
|
||||
if (libcrypto_mutexes == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; ++i){
|
||||
user_callbacks->mutex_init(&libcrypto_mutexes[i]);
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK
|
||||
CRYPTO_THREADID_set_callback(libcrypto_THREADID_callback);
|
||||
#else
|
||||
CRYPTO_set_id_callback(user_callbacks->thread_id);
|
||||
#endif
|
||||
|
||||
CRYPTO_set_locking_callback(libcrypto_lock_callback);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
void crypto_thread_finalize(void)
|
||||
{
|
||||
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
|
74
src/threads/libgcrypt.c
Обычный файл
74
src/threads/libgcrypt.c
Обычный файл
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2018 by Anderson Toshiyuki Sasaki
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/crypto.h"
|
||||
#include "libssh/threads.h"
|
||||
#include <libssh/callbacks.h>
|
||||
|
||||
#if (GCRYPT_VERSION_NUMBER >= 0x010600)
|
||||
/* libgcrypt >= 1.6 does not support custom callbacks */
|
||||
GCRY_THREAD_OPTION_PTHREAD_IMPL;
|
||||
|
||||
int crypto_thread_init(struct ssh_threads_callbacks_struct *user_callbacks)
|
||||
{
|
||||
(void) user_callbacks;
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
/* Libgcrypt < 1.6 specific way of handling thread callbacks */
|
||||
|
||||
static struct gcry_thread_cbs gcrypt_threads_callbacks;
|
||||
|
||||
int crypto_thread_init(struct ssh_threads_callbacks_struct *user_callbacks)
|
||||
{
|
||||
int cmp;
|
||||
|
||||
if (user_callbacks == NULL) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
cmp = strcmp(user_callbacks->type, "threads_noop");
|
||||
if (cmp == 0) {
|
||||
gcrypt_threads_callbacks.option= GCRY_THREAD_OPTION_VERSION << 8 ||
|
||||
GCRY_THREAD_OPTION_DEFAULT;
|
||||
} else {
|
||||
gcrypt_threads_callbacks.option= GCRY_THREAD_OPTION_VERSION << 8 ||
|
||||
GCRY_THREAD_OPTION_USER;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#endif /* GCRYPT_VERSION_NUMBER */
|
||||
|
||||
void crypto_thread_finalize(void)
|
||||
{
|
||||
return;
|
||||
}
|
65
src/threads/mbedtls.c
Обычный файл
65
src/threads/mbedtls.c
Обычный файл
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2018 by Anderson Toshiyuki Sasaki
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/crypto.h"
|
||||
#include "libssh/threads.h"
|
||||
#include <libssh/callbacks.h>
|
||||
|
||||
#include <mbedtls/threading.h>
|
||||
|
||||
int crypto_thread_init(struct ssh_threads_callbacks_struct *user_callbacks)
|
||||
{
|
||||
int cmp;
|
||||
|
||||
if (user_callbacks == NULL) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
cmp = strcmp(user_callbacks->type, "threads_noop");
|
||||
if (cmp == 0) {
|
||||
return SSH_OK;
|
||||
}
|
||||
#ifdef MBEDTLS_THREADING_ALT
|
||||
else {
|
||||
if (user_callbacks != NULL) {
|
||||
crypto_thread_finalize();
|
||||
}
|
||||
|
||||
mbedtls_threading_set_alt(user_callbacks->mutex_init,
|
||||
user_callbacks->mutex_destroy,
|
||||
user_callbacks->mutex_lock,
|
||||
user_callbacks->mutex_unlock);
|
||||
}
|
||||
#elif defined MBEDTLS_THREADING_PTHREAD
|
||||
return SSH_OK;
|
||||
#else
|
||||
return SSH_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
void crypto_thread_finalize(void)
|
||||
{
|
||||
#ifdef MBEDTLS_THREADING_ALT
|
||||
mbedtls_threading_free_alt();
|
||||
#endif
|
||||
return;
|
||||
}
|
74
src/threads/noop.c
Обычный файл
74
src/threads/noop.c
Обычный файл
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2018 by Anderson Toshiyuki Sasaki
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/threads.h"
|
||||
#include <libssh/callbacks.h>
|
||||
|
||||
static int threads_noop(void **lock)
|
||||
{
|
||||
(void)lock;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long threads_id_noop (void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ssh_threads_callbacks_struct ssh_threads_noop =
|
||||
{
|
||||
.type = "threads_noop",
|
||||
.mutex_init = threads_noop,
|
||||
.mutex_destroy = threads_noop,
|
||||
.mutex_lock = threads_noop,
|
||||
.mutex_unlock = threads_noop,
|
||||
.thread_id = threads_id_noop
|
||||
};
|
||||
|
||||
/* Threads interface implementation */
|
||||
|
||||
#if !(HAVE_PTHREAD)
|
||||
void ssh_mutex_lock(SSH_MUTEX *mutex)
|
||||
{
|
||||
(void) mutex;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ssh_mutex_unlock(SSH_MUTEX *mutex)
|
||||
{
|
||||
(void) mutex;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct ssh_threads_callbacks_struct *ssh_threads_get_default(void)
|
||||
{
|
||||
return &ssh_threads_noop;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct ssh_threads_callbacks_struct *ssh_threads_get_noop(void)
|
||||
{
|
||||
return &ssh_threads_noop;
|
||||
}
|
@ -20,61 +20,64 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/threads.h"
|
||||
#include <libssh/callbacks.h>
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/** @brief Defines the needed callbacks for pthread. Use this if your
|
||||
* OS supports libpthread and want to use it for threading.
|
||||
* @code
|
||||
* #include <libssh/callbacks.h>
|
||||
* #include <errno.h>
|
||||
* #include <pthread.h>
|
||||
* SSH_THREADS_PTHREAD(ssh_pthread_callbacks);
|
||||
* int main(){
|
||||
* ssh_init_set_threads_callbacks(&ssh_pthread_callbacks);
|
||||
* ssh_init();
|
||||
* ...
|
||||
* }
|
||||
* @endcode
|
||||
* @param name name of the structure to be declared, containing the
|
||||
* callbacks for threading
|
||||
*
|
||||
*/
|
||||
static int ssh_pthread_mutex_init (void **mutex)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
static int ssh_pthread_mutex_init (void **priv){
|
||||
int err = 0;
|
||||
*priv = malloc (sizeof (pthread_mutex_t));
|
||||
if (*priv==NULL)
|
||||
return ENOMEM;
|
||||
err = pthread_mutex_init (*priv, NULL);
|
||||
if (err != 0){
|
||||
free (*priv);
|
||||
*priv=NULL;
|
||||
}
|
||||
return err;
|
||||
if (mutex == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*mutex = malloc(sizeof(pthread_mutex_t));
|
||||
if (*mutex == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
rc = pthread_mutex_init ((pthread_mutex_t *)*mutex, NULL);
|
||||
if (rc){
|
||||
free (*mutex);
|
||||
*mutex = NULL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ssh_pthread_mutex_destroy (void **lock) {
|
||||
int err = pthread_mutex_destroy (*lock);
|
||||
free (*lock);
|
||||
*lock=NULL;
|
||||
return err;
|
||||
static int ssh_pthread_mutex_destroy (void **mutex)
|
||||
{
|
||||
|
||||
int rc = 0;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
rc = pthread_mutex_destroy ((pthread_mutex_t *)*mutex);
|
||||
|
||||
free (*mutex);
|
||||
*mutex = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ssh_pthread_mutex_lock (void **lock) {
|
||||
return pthread_mutex_lock (*lock);
|
||||
static int ssh_pthread_mutex_lock (void **mutex)
|
||||
{
|
||||
return pthread_mutex_lock((pthread_mutex_t *)*mutex);
|
||||
}
|
||||
|
||||
static int ssh_pthread_mutex_unlock (void **lock){
|
||||
return pthread_mutex_unlock (*lock);
|
||||
static int ssh_pthread_mutex_unlock (void **mutex)
|
||||
{
|
||||
return pthread_mutex_unlock((pthread_mutex_t *)*mutex);
|
||||
}
|
||||
|
||||
static unsigned long ssh_pthread_thread_id (void){
|
||||
static unsigned long ssh_pthread_thread_id (void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__WINPTHREADS_VERSION)
|
||||
return (unsigned long) pthread_self().p;
|
||||
#else
|
||||
@ -84,16 +87,54 @@ static unsigned long ssh_pthread_thread_id (void){
|
||||
|
||||
static struct ssh_threads_callbacks_struct ssh_threads_pthread =
|
||||
{
|
||||
.type="threads_pthread",
|
||||
.mutex_init=ssh_pthread_mutex_init,
|
||||
.mutex_destroy=ssh_pthread_mutex_destroy,
|
||||
.mutex_lock=ssh_pthread_mutex_lock,
|
||||
.mutex_unlock=ssh_pthread_mutex_unlock,
|
||||
.thread_id=ssh_pthread_thread_id
|
||||
.type = "threads_pthread",
|
||||
.mutex_init = ssh_pthread_mutex_init,
|
||||
.mutex_destroy = ssh_pthread_mutex_destroy,
|
||||
.mutex_lock = ssh_pthread_mutex_lock,
|
||||
.mutex_unlock = ssh_pthread_mutex_unlock,
|
||||
.thread_id = ssh_pthread_thread_id
|
||||
};
|
||||
|
||||
struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void) {
|
||||
return &ssh_threads_pthread;
|
||||
/* Threads interface implementation */
|
||||
|
||||
#if (HAVE_PTHREAD)
|
||||
void ssh_mutex_lock(SSH_MUTEX *mutex)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (mutex == NULL) {
|
||||
exit(EINVAL);
|
||||
}
|
||||
|
||||
rc = pthread_mutex_lock(mutex);
|
||||
|
||||
if (rc) {
|
||||
exit(rc);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_PTHREAD */
|
||||
void ssh_mutex_unlock(SSH_MUTEX *mutex)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (mutex == NULL) {
|
||||
exit(EINVAL);
|
||||
}
|
||||
|
||||
rc = pthread_mutex_unlock(mutex);
|
||||
|
||||
if (rc) {
|
||||
exit(rc);
|
||||
}
|
||||
}
|
||||
|
||||
struct ssh_threads_callbacks_struct *ssh_threads_get_default(void)
|
||||
{
|
||||
return &ssh_threads_pthread;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void)
|
||||
{
|
||||
return &ssh_threads_pthread;
|
||||
}
|
||||
|
@ -22,13 +22,6 @@ set(TORTURE_LINK_LIBRARIES
|
||||
${LIBSSH_STATIC_LIBRARY}
|
||||
${LIBSSH_LINK_LIBRARIES})
|
||||
|
||||
if (LIBSSH_THREADS)
|
||||
set(TORTURE_LINK_LIBRARIES
|
||||
${TORTURE_LINK_LIBRARIES}
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
${LIBSSH_THREADS_LINK_LIBRARIES})
|
||||
endif (LIBSSH_THREADS)
|
||||
|
||||
# create test library
|
||||
add_library(${TORTURE_LIBRARY}
|
||||
STATIC
|
||||
|
@ -6,8 +6,4 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "-fsanitize=fuzzer"
|
||||
LINK_FLAGS "-fsanitize=fuzzer")
|
||||
|
||||
target_link_libraries(ssh_server_fuzzer
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
${LIBSSH_THREADS_LINK_LIBRARIES})
|
||||
endif()
|
||||
|
@ -24,9 +24,8 @@ set(pkd_libs
|
||||
${CMOCKA_LIBRARY}
|
||||
${LIBSSH_STATIC_LIBRARY}
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
${LIBSSH_THREADS_LINK_LIBRARIES}
|
||||
${ARGP_LIBRARIES}
|
||||
pthread
|
||||
)
|
||||
|
||||
add_executable(pkd_hello ${pkd_hello_src})
|
||||
|
@ -32,11 +32,12 @@ if (UNIX AND NOT WIN32)
|
||||
# requires /dev/null
|
||||
add_cmocka_test(torture_channel torture_channel.c ${TORTURE_LIBRARY})
|
||||
# requires pthread
|
||||
if (LIBSSH_THREADS)
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
add_cmocka_test(torture_rand torture_rand.c ${TORTURE_LIBRARY})
|
||||
target_link_libraries(torture_rand Threads::Threads)
|
||||
# Not working correctly
|
||||
#if (WITH_SERVER)
|
||||
# add_cmocka_test(torture_server_x11 torture_server_x11.c ${TORTURE_LIBRARY})
|
||||
#endif (WITH_SERVER)
|
||||
endif (LIBSSH_THREADS)
|
||||
endif ()
|
||||
endif (UNIX AND NOT WIN32)
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user