diff --git a/src/protocols/vnc/client.c b/src/protocols/vnc/client.c index 874f8579..2aa29fd3 100644 --- a/src/protocols/vnc/client.c +++ b/src/protocols/vnc/client.c @@ -61,6 +61,7 @@ const char* GUAC_CLIENT_ARGS[] = { "color-depth", "cursor", "autoretry", + "clipboard-encoding", #ifdef ENABLE_VNC_REPEATER "dest-host", @@ -101,6 +102,7 @@ enum VNC_ARGS_IDX { IDX_COLOR_DEPTH, IDX_CURSOR, IDX_AUTORETRY, + IDX_CLIPBOARD_ENCODING, #ifdef ENABLE_VNC_REPEATER IDX_DEST_HOST, @@ -219,6 +221,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; @@ -293,6 +331,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 5827f7f9..feb181be 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 @@ -209,6 +210,12 @@ typedef struct vnc_guac_client_data { guac_object* sftp_filesystem; #endif + /** + * 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 */