GUAC-779: Synchronize access to shared libssh2 handles.
This commit is contained in:
parent
d608b3a30b
commit
be9c56f9a3
@ -137,6 +137,11 @@ typedef struct ssh_guac_client_data {
|
|||||||
*/
|
*/
|
||||||
LIBSSH2_CHANNEL* term_channel;
|
LIBSSH2_CHANNEL* term_channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock dictating access to the SSH terminal channel.
|
||||||
|
*/
|
||||||
|
pthread_mutex_t term_channel_lock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The terminal which will render all output from the SSH client.
|
* The terminal which will render all output from the SSH client.
|
||||||
*/
|
*/
|
||||||
|
@ -74,9 +74,12 @@ int ssh_guac_client_size_handler(guac_client* client, int width, int height) {
|
|||||||
guac_terminal_resize(terminal, width, height);
|
guac_terminal_resize(terminal, width, height);
|
||||||
|
|
||||||
/* Update SSH pty size if connected */
|
/* Update SSH pty size if connected */
|
||||||
if (guac_client_data->term_channel != NULL)
|
if (guac_client_data->term_channel != NULL) {
|
||||||
|
pthread_mutex_lock(&(guac_client_data->term_channel_lock));
|
||||||
libssh2_channel_request_pty_size(guac_client_data->term_channel,
|
libssh2_channel_request_pty_size(guac_client_data->term_channel,
|
||||||
terminal->term_width, terminal->term_height);
|
terminal->term_width, terminal->term_height);
|
||||||
|
pthread_mutex_unlock(&(guac_client_data->term_channel_lock));
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -64,8 +64,11 @@ void* ssh_input_thread(void* data) {
|
|||||||
int bytes_read;
|
int bytes_read;
|
||||||
|
|
||||||
/* Write all data read */
|
/* Write all data read */
|
||||||
while ((bytes_read = guac_terminal_read_stdin(client_data->term, buffer, sizeof(buffer))) > 0)
|
while ((bytes_read = guac_terminal_read_stdin(client_data->term, buffer, sizeof(buffer))) > 0) {
|
||||||
|
pthread_mutex_lock(&(client_data->term_channel_lock));
|
||||||
libssh2_channel_write(client_data->term_channel, buffer, bytes_read);
|
libssh2_channel_write(client_data->term_channel, buffer, bytes_read);
|
||||||
|
pthread_mutex_unlock(&(client_data->term_channel_lock));
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -474,6 +477,8 @@ void* ssh_client_thread(void* data) {
|
|||||||
/* Logged in */
|
/* Logged in */
|
||||||
guac_client_log_info(client, "SSH connection successful.");
|
guac_client_log_info(client, "SSH connection successful.");
|
||||||
|
|
||||||
|
pthread_mutex_init(&client_data->term_channel_lock, NULL);
|
||||||
|
|
||||||
/* Start input thread */
|
/* Start input thread */
|
||||||
if (pthread_create(&(input_thread), NULL, ssh_input_thread, (void*) client)) {
|
if (pthread_create(&(input_thread), NULL, ssh_input_thread, (void*) client)) {
|
||||||
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start input thread");
|
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start input thread");
|
||||||
@ -485,15 +490,25 @@ void* ssh_client_thread(void* data) {
|
|||||||
|
|
||||||
/* While data available, write to terminal */
|
/* While data available, write to terminal */
|
||||||
bytes_read = 0;
|
bytes_read = 0;
|
||||||
while (!libssh2_channel_eof(client_data->term_channel)) {
|
for (;;) {
|
||||||
|
|
||||||
/* Track total amount of data read */
|
/* Track total amount of data read */
|
||||||
int total_read = 0;
|
int total_read = 0;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&(client_data->term_channel_lock));
|
||||||
|
|
||||||
|
/* Stop reading at EOF */
|
||||||
|
if (libssh2_channel_eof(client_data->term_channel)) {
|
||||||
|
pthread_mutex_unlock(&(client_data->term_channel_lock));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read terminal data */
|
/* Read terminal data */
|
||||||
bytes_read = libssh2_channel_read(client_data->term_channel,
|
bytes_read = libssh2_channel_read(client_data->term_channel,
|
||||||
buffer, sizeof(buffer));
|
buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(client_data->term_channel_lock));
|
||||||
|
|
||||||
/* Attempt to write data received. Exit on failure. */
|
/* Attempt to write data received. Exit on failure. */
|
||||||
if (bytes_read > 0) {
|
if (bytes_read > 0) {
|
||||||
int written = guac_terminal_write_stdout(client_data->term, buffer, bytes_read);
|
int written = guac_terminal_write_stdout(client_data->term, buffer, bytes_read);
|
||||||
@ -540,6 +555,8 @@ void* ssh_client_thread(void* data) {
|
|||||||
pthread_join(input_thread, NULL);
|
pthread_join(input_thread, NULL);
|
||||||
|
|
||||||
__openssl_free_locks(CRYPTO_num_locks());
|
__openssl_free_locks(CRYPTO_num_locks());
|
||||||
|
pthread_mutex_destroy(&client_data->term_channel_lock);
|
||||||
|
|
||||||
guac_client_log_info(client, "SSH connection ended.");
|
guac_client_log_info(client, "SSH connection ended.");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user