From d3098420552e3ef6774392624e7c1e3c9fbacb51 Mon Sep 17 00:00:00 2001 From: Frode Langelo Date: Wed, 8 Jul 2015 14:28:02 -0700 Subject: [PATCH 1/3] GUAC-298: Add configuration option to allow for VNC clipboard text encoding override --- src/protocols/vnc/client.c | 45 ++++++++++++++++++++++++++++++++ src/protocols/vnc/client.h | 7 +++++ src/protocols/vnc/clipboard.c | 5 ++-- src/protocols/vnc/vnc_handlers.c | 3 ++- 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/protocols/vnc/client.c b/src/protocols/vnc/client.c index a36fb9a9..8945974e 100644 --- a/src/protocols/vnc/client.c +++ b/src/protocols/vnc/client.c @@ -55,6 +55,7 @@ const char* GUAC_CLIENT_ARGS[] = { "color-depth", "cursor", "autoretry", + "clipboard-encoding", #ifdef ENABLE_VNC_REPEATER "dest-host", @@ -85,6 +86,7 @@ enum VNC_ARGS_IDX { IDX_COLOR_DEPTH, IDX_CURSOR, IDX_AUTORETRY, + IDX_CLIPBOARD_ENCODING, #ifdef ENABLE_VNC_REPEATER IDX_DEST_HOST, @@ -193,6 +195,42 @@ static rfbClient* __guac_vnc_get_client(guac_client* client) { } +/** + * Configure the VNC clipboard reader/writer based on configured encoding. + * Defaults to standard ISO8859-1 encoding if an invalid format is encountered. + * + * @param guac_client_data Structure containing VNC client configuration. + * @param name Encoding name. + * @return Returns 0 if standard ISO8859-1 encoding is used, 1 otherwise. + */ +int __guac_client_configure_clipboard_encoding(vnc_guac_client_data* guac_client_data, + const char* name) { + + /* Configure clipboard reader/writer based on encoding name */ + if (strcmp(name, "UTF-8") == 0) { + guac_client_data->clipboard_reader = GUAC_READ_UTF8; + guac_client_data->clipboard_writer = GUAC_WRITE_UTF8; + return 1; + } + else if (strcmp(name, "UTF-16") == 0) { + guac_client_data->clipboard_reader = GUAC_READ_UTF16; + guac_client_data->clipboard_writer = GUAC_WRITE_UTF16; + return 1; + } + else if (strcmp(name, "CP-1252") == 0) { + guac_client_data->clipboard_reader = GUAC_READ_CP1252; + guac_client_data->clipboard_writer = GUAC_WRITE_CP1252; + return 1; + } + else { + /* Default to ISO8859-1 */ + guac_client_data->clipboard_reader = GUAC_READ_ISO8859_1; + guac_client_data->clipboard_writer = GUAC_WRITE_ISO8859_1; + return 0; + } + +} + int guac_client_init(guac_client* client, int argc, char** argv) { rfbClient* rfb_client; @@ -267,6 +305,13 @@ int guac_client_init(guac_client* client, int argc, char** argv) { /* Init clipboard */ guac_client_data->clipboard = guac_common_clipboard_alloc(GUAC_VNC_CLIPBOARD_MAX_LENGTH); + /* Configure clipboard encoding */ + if (__guac_client_configure_clipboard_encoding( + guac_client_data, argv[IDX_CLIPBOARD_ENCODING])) { + guac_client_log(client, GUAC_LOG_INFO, + "Using non-standard VNC clipboard encoding: '%s'.", argv[IDX_CLIPBOARD_ENCODING]); + } + /* Ensure connection is kept alive during lengthy connects */ guac_socket_require_keep_alive(client->socket); diff --git a/src/protocols/vnc/client.h b/src/protocols/vnc/client.h index 4c13b54e..a088921c 100644 --- a/src/protocols/vnc/client.h +++ b/src/protocols/vnc/client.h @@ -27,6 +27,7 @@ #include "config.h" #include "guac_clipboard.h" #include "guac_surface.h" +#include "guac_iconv.h" #include #include @@ -186,6 +187,12 @@ typedef struct vnc_guac_client_data { */ guac_common_surface* default_surface; + /** + * Clipboard encoding specific reader and writer. + */ + guac_iconv_read* clipboard_reader; + guac_iconv_write* clipboard_writer; + } vnc_guac_client_data; #endif diff --git a/src/protocols/vnc/clipboard.c b/src/protocols/vnc/clipboard.c index ca8fe639..6f3a391b 100644 --- a/src/protocols/vnc/clipboard.c +++ b/src/protocols/vnc/clipboard.c @@ -63,10 +63,11 @@ int guac_vnc_clipboard_end_handler(guac_client* client, guac_stream* stream) { const char* input = client_data->clipboard->buffer; char* output = output_data; + guac_iconv_write* writer = client_data->clipboard_writer; - /* Convert clipboard to ISO 8859-1 */ + /* Convert clipboard contents */ guac_iconv(GUAC_READ_UTF8, &input, client_data->clipboard->length, - GUAC_WRITE_ISO8859_1, &output, sizeof(output_data)); + writer, &output, sizeof(output_data)); /* Send via VNC */ SendClientCutText(rfb_client, output_data, output - output_data); diff --git a/src/protocols/vnc/vnc_handlers.c b/src/protocols/vnc/vnc_handlers.c index 3ff26d27..26fdef85 100644 --- a/src/protocols/vnc/vnc_handlers.c +++ b/src/protocols/vnc/vnc_handlers.c @@ -305,9 +305,10 @@ void guac_vnc_cut_text(rfbClient* client, const char* text, int textlen) { const char* input = text; char* output = received_data; + guac_iconv_read* reader = client_data->clipboard_reader; /* Convert clipboard contents */ - guac_iconv(GUAC_READ_ISO8859_1, &input, textlen, + guac_iconv(reader, &input, textlen, GUAC_WRITE_UTF8, &output, sizeof(received_data)); /* Send converted data */ From 7bfd7ce0caded11224f141aad3d14c3316971392 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 27 Jul 2015 17:51:03 -0700 Subject: [PATCH 2/3] GUAC-298: Add missing comment. Update documentation style. --- src/protocols/vnc/client.c | 14 +++++++++----- src/protocols/vnc/client.h | 6 +++++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/protocols/vnc/client.c b/src/protocols/vnc/client.c index 2aa29fd3..990c09f0 100644 --- a/src/protocols/vnc/client.c +++ b/src/protocols/vnc/client.c @@ -225,12 +225,16 @@ static rfbClient* __guac_vnc_get_client(guac_client* client) { * Configure the VNC clipboard reader/writer based on configured encoding. * Defaults to standard ISO8859-1 encoding if an invalid format is encountered. * - * @param guac_client_data Structure containing VNC client configuration. - * @param name Encoding name. - * @return Returns 0 if standard ISO8859-1 encoding is used, 1 otherwise. + * @param guac_client_data + * Structure containing VNC client configuration. + * + * @param name + * Encoding name. + * + * @return + * Returns 0 if standard ISO8859-1 encoding is used, 1 otherwise. */ -int __guac_client_configure_clipboard_encoding(vnc_guac_client_data* guac_client_data, - const char* name) { +int __guac_client_configure_clipboard_encoding(vnc_guac_client_data* guac_client_data, const char* name) { /* Configure clipboard reader/writer based on encoding name */ if (strcmp(name, "UTF-8") == 0) { diff --git a/src/protocols/vnc/client.h b/src/protocols/vnc/client.h index feb181be..ccbac69e 100644 --- a/src/protocols/vnc/client.h +++ b/src/protocols/vnc/client.h @@ -211,9 +211,13 @@ typedef struct vnc_guac_client_data { #endif /** - * Clipboard encoding specific reader and writer. + * Clipboard encoding-specific reader. */ guac_iconv_read* clipboard_reader; + + /** + * Clipboard encoding-specific writer. + */ guac_iconv_write* clipboard_writer; } vnc_guac_client_data; From 5e4c7de5c73099df8842f9b93c57fe7d2dfaa7a8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 27 Jul 2015 18:19:50 -0700 Subject: [PATCH 3/3] GUAC-298: Clarify function documentation and naming. Do not simply silently default to ISO8859-1 if encoding is invalid. --- src/protocols/vnc/client.c | 59 +++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/src/protocols/vnc/client.c b/src/protocols/vnc/client.c index 990c09f0..8d4ad8a7 100644 --- a/src/protocols/vnc/client.c +++ b/src/protocols/vnc/client.c @@ -222,42 +222,62 @@ static rfbClient* __guac_vnc_get_client(guac_client* client) { } /** - * Configure the VNC clipboard reader/writer based on configured encoding. - * Defaults to standard ISO8859-1 encoding if an invalid format is encountered. + * Sets the encoding of clipboard data exchanged with the VNC server to the + * encoding having the given name. If the name is left blank, or is invalid, + * the standard ISO8859-1 encoding will be used. * - * @param guac_client_data - * Structure containing VNC client configuration. + * @param client + * The client to set the clipboard encoding of. * * @param name - * Encoding name. + * The name of the encoding to use for all clipboard data. Valid values + * are: "ISO8859-1", "UTF-8", "UTF-16", "CP1252", or "". * * @return - * Returns 0 if standard ISO8859-1 encoding is used, 1 otherwise. + * Zero if the chosen encoding is standard for VNC, or non-zero if the VNC + * standard is being violated. */ -int __guac_client_configure_clipboard_encoding(vnc_guac_client_data* guac_client_data, const char* name) { +static int guac_vnc_set_clipboard_encoding(guac_client* client, + const char* name) { - /* Configure clipboard reader/writer based on encoding name */ + vnc_guac_client_data* guac_client_data = + (vnc_guac_client_data*) client->data; + + /* Use ISO8859-1 if explicitly selected or blank */ + if (name[0] == '\0' || strcmp(name, "ISO8859-1") == 0) { + guac_client_data->clipboard_reader = GUAC_READ_ISO8859_1; + guac_client_data->clipboard_writer = GUAC_WRITE_ISO8859_1; + return 0; + } + + /* UTF-8 */ if (strcmp(name, "UTF-8") == 0) { guac_client_data->clipboard_reader = GUAC_READ_UTF8; guac_client_data->clipboard_writer = GUAC_WRITE_UTF8; return 1; } - else if (strcmp(name, "UTF-16") == 0) { + + /* UTF-16 */ + if (strcmp(name, "UTF-16") == 0) { guac_client_data->clipboard_reader = GUAC_READ_UTF16; guac_client_data->clipboard_writer = GUAC_WRITE_UTF16; return 1; } - else if (strcmp(name, "CP-1252") == 0) { + + /* CP1252 */ + if (strcmp(name, "CP1252") == 0) { guac_client_data->clipboard_reader = GUAC_READ_CP1252; guac_client_data->clipboard_writer = GUAC_WRITE_CP1252; return 1; } - else { - /* Default to ISO8859-1 */ - guac_client_data->clipboard_reader = GUAC_READ_ISO8859_1; - guac_client_data->clipboard_writer = GUAC_WRITE_ISO8859_1; - return 0; - } + + /* If encoding unrecognized, warn and default to ISO8859-1 */ + guac_client_log(client, GUAC_LOG_WARNING, + "Encoding '%s' is invalid. Defaulting to ISO8859-1.", name); + + guac_client_data->clipboard_reader = GUAC_READ_ISO8859_1; + guac_client_data->clipboard_writer = GUAC_WRITE_ISO8859_1; + return 0; } @@ -336,11 +356,10 @@ int guac_client_init(guac_client* client, int argc, char** argv) { guac_client_data->clipboard = guac_common_clipboard_alloc(GUAC_VNC_CLIPBOARD_MAX_LENGTH); /* Configure clipboard encoding */ - if (__guac_client_configure_clipboard_encoding( - guac_client_data, argv[IDX_CLIPBOARD_ENCODING])) { + if (guac_vnc_set_clipboard_encoding(client, argv[IDX_CLIPBOARD_ENCODING])) guac_client_log(client, GUAC_LOG_INFO, - "Using non-standard VNC clipboard encoding: '%s'.", argv[IDX_CLIPBOARD_ENCODING]); - } + "Using non-standard VNC clipboard encoding: '%s'.", + argv[IDX_CLIPBOARD_ENCODING]); /* Ensure connection is kept alive during lengthy connects */ guac_socket_require_keep_alive(client->socket);