GUACAMOLE-223: Set required thread-related callbacks for OpenSSL.

This commit is contained in:
Michael Jumper 2016-11-19 23:13:08 -08:00
parent cf01d0d634
commit 9218a79e62

View File

@ -152,6 +152,97 @@ static int daemonize() {
} }
#ifdef ENABLE_SSL
/**
* Array of mutexes, used by OpenSSL.
*/
static pthread_mutex_t* guacd_openssl_locks = NULL;
/**
* Called by OpenSSL when locking or unlocking the Nth mutex.
*
* @param mode
* A bitmask denoting the action to be taken on the Nth lock, such as
* CRYPTO_LOCK or CRYPTO_UNLOCK.
*
* @param n
* The index of the lock to lock or unlock.
*
* @param file
* The filename of the function setting the lock, for debugging purposes.
*
* @param line
* The line number of the function setting the lock, for debugging
* purposes.
*/
static void guacd_openssl_locking_callback(int mode, int n,
const char* file, int line){
/* Lock given mutex upon request */
if (mode & CRYPTO_LOCK)
pthread_mutex_lock(&(guacd_openssl_locks[n]));
/* Unlock given mutex upon request */
else if (mode & CRYPTO_UNLOCK)
pthread_mutex_unlock(&(guacd_openssl_locks[n]));
}
/**
* Called by OpenSSL when determining the current thread ID.
*
* @return
* An ID which uniquely identifies the current thread.
*/
static unsigned long guacd_openssl_id_callback() {
return (unsigned long) pthread_self();
}
/**
* Creates the given number of mutexes, such that OpenSSL will have at least
* this number of mutexes at its disposal.
*
* @param count
* The number of mutexes (locks) to create.
*/
static void guacd_openssl_init_locks(int count) {
int i;
/* Allocate required number of locks */
guacd_openssl_locks =
malloc(sizeof(pthread_mutex_t) * count);
/* Initialize each lock */
for (i=0; i < count; i++)
pthread_mutex_init(&(guacd_openssl_locks[i]), NULL);
}
/**
* Frees the given number of mutexes.
*
* @param count
* The number of mutexes (locks) to free.
*/
static void guacd_openssl_free_locks(int count) {
int i;
/* SSL lock array was not initialized */
if (guacd_openssl_locks == NULL)
return;
/* Free all locks */
for (i=0; i < count; i++)
pthread_mutex_destroy(&(guacd_openssl_locks[i]));
/* Free lock array */
free(guacd_openssl_locks);
}
#endif
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
/* Server */ /* Server */
@ -266,8 +357,14 @@ int main(int argc, char* argv[]) {
/* Init SSL if enabled */ /* Init SSL if enabled */
if (config->key_file != NULL || config->cert_file != NULL) { if (config->key_file != NULL || config->cert_file != NULL) {
/* Init SSL */
guacd_log(GUAC_LOG_INFO, "Communication will require SSL/TLS."); guacd_log(GUAC_LOG_INFO, "Communication will require SSL/TLS.");
/* Init threadsafety in OpenSSL */
guacd_openssl_init_locks(CRYPTO_num_locks());
CRYPTO_set_id_callback(guacd_openssl_id_callback);
CRYPTO_set_locking_callback(guacd_openssl_locking_callback);
/* Init SSL */
SSL_library_init(); SSL_library_init();
SSL_load_error_strings(); SSL_load_error_strings();
ssl_context = SSL_CTX_new(SSLv23_server_method()); ssl_context = SSL_CTX_new(SSLv23_server_method());
@ -391,6 +488,13 @@ int main(int argc, char* argv[]) {
return 3; return 3;
} }
#ifdef ENABLE_SSL
if (ssl_context != NULL) {
guacd_openssl_free_locks(CRYPTO_num_locks());
SSL_CTX_free(ssl_context);
}
#endif
return 0; return 0;
} }