From d562cb7648ab228cdd5d8ab528ee8804faba2d20 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 22 Jan 2018 12:16:09 -0800 Subject: [PATCH 1/3] GUACAMOLE-484: Ensure disconnect reason code is checked for orderly RDP disconnect. --- src/protocols/rdp/rdp.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c index 0b15d055..c8f7a859 100644 --- a/src/protocols/rdp/rdp.c +++ b/src/protocols/rdp/rdp.c @@ -763,21 +763,14 @@ static int guac_rdp_handle_connection(guac_client* client) { pthread_mutex_lock(&(rdp_client->rdp_lock)); /* Check the libfreerdp fds */ - if (!freerdp_check_fds(rdp_inst)) { - guac_client_abort(client, - GUAC_PROTOCOL_STATUS_UPSTREAM_UNAVAILABLE, - "Error handling RDP file descriptors"); - pthread_mutex_unlock(&(rdp_client->rdp_lock)); - return 1; - } + if (!freerdp_check_fds(rdp_inst) + || !freerdp_channels_check_fds(channels, rdp_inst)) { - /* Check channel fds */ - if (!freerdp_channels_check_fds(channels, rdp_inst)) { - guac_client_abort(client, - GUAC_PROTOCOL_STATUS_UPSTREAM_UNAVAILABLE, - "Error handling RDP channel file descriptors"); + /* Flag connection failure */ + wait_result = -1; pthread_mutex_unlock(&(rdp_client->rdp_lock)); - return 1; + break; + } /* Check for channel events */ @@ -801,13 +794,6 @@ static int guac_rdp_handle_connection(guac_client* client) { } - /* Handle RDP disconnect */ - if (freerdp_shall_disconnect(rdp_inst)) { - guac_rdp_client_abort(client); - pthread_mutex_unlock(&(rdp_client->rdp_lock)); - return 1; - } - pthread_mutex_unlock(&(rdp_client->rdp_lock)); /* Calculate time remaining in frame */ @@ -841,6 +827,17 @@ static int guac_rdp_handle_connection(guac_client* client) { } + /* Test whether the RDP server is closing the connection */ + pthread_mutex_lock(&(rdp_client->rdp_lock)); + int connection_closing = freerdp_shall_disconnect(rdp_inst); + pthread_mutex_unlock(&(rdp_client->rdp_lock)); + + /* Close connection cleanly if server is disconnecting */ + if (connection_closing) { + guac_rdp_client_abort(client); + return 1; + } + /* If an error occurred, fail */ if (wait_result < 0) guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_UNAVAILABLE, From 61c16a89d2def4457ba5198d599c0c2218ee35ec Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 22 Jan 2018 12:23:39 -0800 Subject: [PATCH 2/3] GUACAMOLE-484: Always clean up after orderly disconnect. --- src/protocols/rdp/rdp.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c index c8f7a859..0909d9ca 100644 --- a/src/protocols/rdp/rdp.c +++ b/src/protocols/rdp/rdp.c @@ -833,13 +833,11 @@ static int guac_rdp_handle_connection(guac_client* client) { pthread_mutex_unlock(&(rdp_client->rdp_lock)); /* Close connection cleanly if server is disconnecting */ - if (connection_closing) { + if (connection_closing) guac_rdp_client_abort(client); - return 1; - } - /* If an error occurred, fail */ - if (wait_result < 0) + /* If a low-level connection error occurred, fail */ + else if (wait_result < 0) guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_UNAVAILABLE, "Connection closed."); From 822a6c6b9dcc278c55ac3dd13c13c78ff1402acc Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 22 Jan 2018 12:24:07 -0800 Subject: [PATCH 3/3] GUACAMOLE-484: Do not flush frame if connection closed mid-frame. --- src/protocols/rdp/rdp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c index 0909d9ca..f21e30c5 100644 --- a/src/protocols/rdp/rdp.c +++ b/src/protocols/rdp/rdp.c @@ -841,10 +841,12 @@ static int guac_rdp_handle_connection(guac_client* client) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_UNAVAILABLE, "Connection closed."); - /* Flush frame */ - guac_common_display_flush(rdp_client->display); - guac_client_end_frame(client); - guac_socket_flush(client->socket); + /* Flush frame only if successful */ + else { + guac_common_display_flush(rdp_client->display); + guac_client_end_frame(client); + guac_socket_flush(client->socket); + } }