GUACAMOLE-414: Merge support for libvncclient's TLS threadsafety callbacks.
This commit is contained in:
commit
fc68113d75
27
configure.ac
27
configure.ac
@ -527,6 +527,33 @@ then
|
||||
|
||||
fi
|
||||
|
||||
#
|
||||
# TLS Locking Support within libVNCServer
|
||||
#
|
||||
|
||||
if test "x${have_libvncserver}" = "xyes"
|
||||
then
|
||||
|
||||
have_vnc_tls_locking=yes
|
||||
AC_CHECK_MEMBERS([rfbClient.LockWriteToTLS, rfbClient.UnlockWriteToTLS],
|
||||
[], [have_vnc_tls_locking=no],
|
||||
[[#include <rfb/rfbclient.h>]])
|
||||
|
||||
if test "x${have_vnc_tls_locking}" = "xno"
|
||||
then
|
||||
AC_MSG_WARN([
|
||||
--------------------------------------------
|
||||
This version of libvncclient lacks support
|
||||
for TLS locking. VNC connections that use
|
||||
TLS may experience instability as documented
|
||||
in GUACAMOLE-414])
|
||||
else
|
||||
AC_DEFINE([ENABLE_VNC_TLS_LOCKING],,
|
||||
[Whether support for TLS locking within VNC is enabled.])
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
#
|
||||
# FreeRDP
|
||||
#
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include <guacamole/client.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -48,6 +49,11 @@ int guac_client_init(guac_client* client) {
|
||||
guac_vnc_client* vnc_client = calloc(1, sizeof(guac_vnc_client));
|
||||
client->data = vnc_client;
|
||||
|
||||
#ifdef ENABLE_VNC_TLS_LOCKING
|
||||
/* Initialize the write lock */
|
||||
pthread_mutex_init(&(vnc_client->tls_lock), NULL);
|
||||
#endif
|
||||
|
||||
/* Init clipboard */
|
||||
vnc_client->clipboard = guac_common_clipboard_alloc(GUAC_VNC_CLIPBOARD_MAX_LENGTH);
|
||||
|
||||
@ -125,6 +131,11 @@ int guac_vnc_client_free_handler(guac_client* client) {
|
||||
if (settings != NULL)
|
||||
guac_vnc_settings_free(settings);
|
||||
|
||||
#ifdef ENABLE_VNC_TLS_LOCKING
|
||||
/* Clean up TLS lock mutex. */
|
||||
pthread_mutex_destroy(&(vnc_client->tls_lock));
|
||||
#endif
|
||||
|
||||
/* Free generic data struct */
|
||||
free(client->data);
|
||||
|
||||
|
@ -55,6 +55,66 @@
|
||||
|
||||
char* GUAC_VNC_CLIENT_KEY = "GUAC_VNC";
|
||||
|
||||
#ifdef ENABLE_VNC_TLS_LOCKING
|
||||
/**
|
||||
* A callback function that is called by the VNC library prior to writing
|
||||
* data to a TLS-encrypted socket. This returns the rfbBool FALSE value
|
||||
* if there's an error locking the mutex, or rfbBool TRUE otherwise.
|
||||
*
|
||||
* @param rfb_client
|
||||
* The rfbClient for which to lock the TLS mutex.
|
||||
*
|
||||
* @returns
|
||||
* rfbBool FALSE if an error occurs locking the mutex, otherwise
|
||||
* TRUE.
|
||||
*/
|
||||
static rfbBool guac_vnc_lock_write_to_tls(rfbClient* rfb_client) {
|
||||
|
||||
/* Retrieve the Guacamole data structures */
|
||||
guac_client* gc = rfbClientGetClientData(rfb_client, GUAC_VNC_CLIENT_KEY);
|
||||
guac_vnc_client* vnc_client = (guac_vnc_client*) gc->data;
|
||||
|
||||
/* Lock write access */
|
||||
int retval = pthread_mutex_lock(&(vnc_client->tls_lock));
|
||||
if (retval) {
|
||||
guac_client_log(gc, GUAC_LOG_ERROR, "Error locking TLS write mutex: %s",
|
||||
strerror(retval));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A callback function for use by the VNC library that is called once
|
||||
* the client is finished writing to a TLS-encrypted socket. A rfbBool
|
||||
* FALSE value is returned if an error occurs unlocking the mutex,
|
||||
* otherwise TRUE is returned.
|
||||
*
|
||||
* @param rfb_client
|
||||
* The rfbClient for which to unlock the TLS mutex.
|
||||
*
|
||||
* @returns
|
||||
* rfbBool FALSE if an error occurs unlocking the mutex, otherwise
|
||||
* TRUE.
|
||||
*/
|
||||
static rfbBool guac_vnc_unlock_write_to_tls(rfbClient* rfb_client) {
|
||||
|
||||
/* Retrieve the Guacamole data structures */
|
||||
guac_client* gc = rfbClientGetClientData(rfb_client, GUAC_VNC_CLIENT_KEY);
|
||||
guac_vnc_client* vnc_client = (guac_vnc_client*) gc->data;
|
||||
|
||||
/* Unlock write access */
|
||||
int retval = pthread_mutex_unlock(&(vnc_client->tls_lock));
|
||||
if (retval) {
|
||||
guac_client_log(gc, GUAC_LOG_ERROR, "Error unlocking TLS write mutex: %s",
|
||||
strerror(retval));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
rfbClient* guac_vnc_get_client(guac_client* client) {
|
||||
|
||||
rfbClient* rfb_client = rfbGetClient(8, 3, 4); /* 32-bpp client */
|
||||
@ -68,6 +128,12 @@ rfbClient* guac_vnc_get_client(guac_client* client) {
|
||||
rfb_client->GotFrameBufferUpdate = guac_vnc_update;
|
||||
rfb_client->GotCopyRect = guac_vnc_copyrect;
|
||||
|
||||
#ifdef ENABLE_VNC_TLS_LOCKING
|
||||
/* TLS Locking and Unlocking */
|
||||
rfb_client->LockWriteToTLS = guac_vnc_lock_write_to_tls;
|
||||
rfb_client->UnlockWriteToTLS = guac_vnc_unlock_write_to_tls;
|
||||
#endif
|
||||
|
||||
/* Do not handle clipboard and local cursor if read-only */
|
||||
if (vnc_settings->read_only == 0) {
|
||||
|
||||
@ -403,4 +469,3 @@ void* guac_vnc_client_thread(void* data) {
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,13 @@ typedef struct guac_vnc_client {
|
||||
*/
|
||||
pthread_t client_thread;
|
||||
|
||||
#ifdef ENABLE_VNC_TLS_LOCKING
|
||||
/**
|
||||
* The TLS mutex lock for the client.
|
||||
*/
|
||||
pthread_mutex_t tls_lock;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The underlying VNC client.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user