Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GUACAMOLE-2002: Allow connection clipboard limits to be configured. #564

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/common/clipboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
#include <string.h>
#include <stdlib.h>

guac_common_clipboard* guac_common_clipboard_alloc() {
guac_common_clipboard* guac_common_clipboard_alloc(int buffer_size) {

guac_common_clipboard* clipboard = guac_mem_alloc(sizeof(guac_common_clipboard));

/* Init clipboard */
clipboard->mimetype[0] = '\0';
clipboard->buffer = guac_mem_alloc(GUAC_COMMON_CLIPBOARD_MAX_LENGTH);
clipboard->available = GUAC_COMMON_CLIPBOARD_MAX_LENGTH;
clipboard->buffer = guac_mem_alloc(buffer_size);
clipboard->available = buffer_size;
clipboard->length = 0;

pthread_mutex_init(&(clipboard->lock), NULL);
Expand Down
44 changes: 33 additions & 11 deletions src/common/common/clipboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,16 @@
#define GUAC_COMMON_CLIPBOARD_BLOCK_SIZE 4096

/**
* The maximum number of bytes to allow within the clipboard.
* The minimum clipboard buffer size in bytes.
* This is the original hardcoded clipboard buffer size.
*/
#define GUAC_COMMON_CLIPBOARD_MAX_LENGTH 262144
#define GUAC_COMMON_CLIPBOARD_MIN_LENGTH 262144

/**
* The maximum clipboard buffer size in bytes.
* This should be enough for a raw 4K picture and even more.
*/
#define GUAC_COMMON_CLIPBOARD_MAX_LENGTH 52428800

/**
* Generic clipboard structure.
Expand Down Expand Up @@ -72,30 +79,40 @@ typedef struct guac_common_clipboard {

/**
* Creates a new clipboard.
*
* @param buffer_size
* The buffer size in bytes.
*/
guac_common_clipboard* guac_common_clipboard_alloc();
guac_common_clipboard* guac_common_clipboard_alloc(int buffer_size);

/**
* Frees the given clipboard.
*
* @param clipboard The clipboard to free.
* @param clipboard
* The clipboard to free.
*/
void guac_common_clipboard_free(guac_common_clipboard* clipboard);

/**
* Sends the contents of the clipboard along the given client, splitting
* the contents as necessary.
*
* @param clipboard The clipboard whose contents should be sent.
* @param client The client to send the clipboard contents on.
* @param clipboard
* The clipboard whose contents should be sent.
*
* @param client
* The client to send the clipboard contents on.
*/
void guac_common_clipboard_send(guac_common_clipboard* clipboard, guac_client* client);

/**
* Clears the clipboard contents and assigns a new mimetype for future data.
*
* @param clipboard The clipboard to reset.
* @param mimetype The mimetype of future data.
* @param clipboard
* The clipboard to reset.
*
* @param mimetype
* The mimetype of future data.
*/
void guac_common_clipboard_reset(guac_common_clipboard* clipboard, const char* mimetype);

Expand All @@ -104,9 +121,14 @@ void guac_common_clipboard_reset(guac_common_clipboard* clipboard, const char* m
* match the mimetype chosen for the clipboard data by
* guac_common_clipboard_reset().
*
* @param clipboard The clipboard to append data to.
* @param data The data to append.
* @param length The number of bytes to append from the data given.
* @param clipboard
* The clipboard to append data to.
*
* @param data
* The data to append.
*
* @param length
* The number of bytes to append from the data given.
*/
void guac_common_clipboard_append(guac_common_clipboard* clipboard, const char* data, int length);

Expand Down
1 change: 1 addition & 0 deletions src/protocols/kubernetes/kubernetes.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ void* guac_kubernetes_client_thread(void* data) {
settings->width, settings->height, settings->resolution);

/* Set optional parameters */
options->clipboard_buffer_size = settings->clipboard_buffer_size;
options->disable_copy = settings->disable_copy;
options->max_scrollback = settings->max_scrollback;
options->font_name = settings->font_name;
Expand Down
27 changes: 27 additions & 0 deletions src/protocols/kubernetes/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const char* GUAC_KUBERNETES_CLIENT_ARGS[] = {
"read-only",
"backspace",
"scrollback",
"clipboard-buffer-size",
"disable-copy",
"disable-paste",
NULL
Expand Down Expand Up @@ -241,6 +242,11 @@ enum KUBERNETES_ARGS_IDX {
*/
IDX_SCROLLBACK,

/**
* The maximum number of bytes to allow within the clipboard.
*/
IDX_CLIPBOARD_BUFFER_SIZE,

/**
* Whether outbound clipboard access should be blocked. If set to "true",
* it will not be possible to copy data from the terminal to the client
Expand Down Expand Up @@ -418,6 +424,27 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user,
guac_user_parse_args_int(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
IDX_BACKSPACE, GUAC_TERMINAL_DEFAULT_BACKSPACE);

/* Set the maximum number of bytes to allow within the clipboard. */
settings->clipboard_buffer_size =
guac_user_parse_args_int(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
IDX_CLIPBOARD_BUFFER_SIZE, 0);

/* Use default clipboard buffer size if given one is invalid. */
if (settings->clipboard_buffer_size < GUAC_COMMON_CLIPBOARD_MIN_LENGTH) {
settings->clipboard_buffer_size = GUAC_COMMON_CLIPBOARD_MIN_LENGTH;
guac_user_log(user, GUAC_LOG_ERROR, "Invalid clipboard buffer "
"size: \"%s\". Using the default minimum size: %i.",
argv[IDX_CLIPBOARD_BUFFER_SIZE],
settings->clipboard_buffer_size);
}
else if (settings->clipboard_buffer_size > GUAC_COMMON_CLIPBOARD_MAX_LENGTH) {
settings->clipboard_buffer_size = GUAC_COMMON_CLIPBOARD_MAX_LENGTH;
guac_user_log(user, GUAC_LOG_ERROR, "Invalid clipboard buffer "
"size: \"%s\". Using the default maximum size: %i.",
argv[IDX_CLIPBOARD_BUFFER_SIZE],
settings->clipboard_buffer_size);
}

/* Parse clipboard copy disable flag */
settings->disable_copy =
guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
Expand Down
5 changes: 5 additions & 0 deletions src/protocols/kubernetes/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ typedef struct guac_kubernetes_settings {
*/
int resolution;

/**
* The maximum number of bytes to allow within the clipboard.
*/
int clipboard_buffer_size;

/**
* Whether outbound clipboard access should be blocked. If set, it will not
* be possible to copy data from the terminal to the client using the
Expand Down
20 changes: 13 additions & 7 deletions src/protocols/rdp/channels/cliprdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,9 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,

guac_iconv_write* remote_writer;
const char* input = clipboard->clipboard->buffer;
char* output = guac_mem_alloc(GUAC_COMMON_CLIPBOARD_MAX_LENGTH);

int output_buf_size = clipboard->clipboard->available;
char* output = guac_mem_alloc(output_buf_size);

/* Map requested clipboard format to a guac_iconv writer */
switch (format_data_request->requestedFormatId) {
Expand Down Expand Up @@ -402,7 +404,7 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,
BYTE* start = (BYTE*) output;
guac_iconv_read* local_reader = settings->normalize_clipboard ? GUAC_READ_UTF8_NORMALIZED : GUAC_READ_UTF8;
guac_iconv(local_reader, &input, clipboard->clipboard->length,
remote_writer, &output, GUAC_COMMON_CLIPBOARD_MAX_LENGTH);
remote_writer, &output, output_buf_size);

CLIPRDR_FORMAT_DATA_RESPONSE data_response = {
.requestedFormatData = (BYTE*) start,
Expand Down Expand Up @@ -470,7 +472,8 @@ static UINT guac_rdp_cliprdr_format_data_response(CliprdrClientContext* cliprdr,
return CHANNEL_RC_OK;
}

char received_data[GUAC_COMMON_CLIPBOARD_MAX_LENGTH];
int output_buf_size = clipboard->clipboard->available;
char* received_data = guac_mem_alloc(output_buf_size);

guac_iconv_read* remote_reader;
const char* input = (char*) format_data_response->requestedFormatData;
Expand Down Expand Up @@ -498,6 +501,7 @@ static UINT guac_rdp_cliprdr_format_data_response(CliprdrClientContext* cliprdr,
default:
guac_client_log(client, GUAC_LOG_DEBUG, "Requested clipboard data "
"in unsupported format (0x%X).", clipboard->requested_format);
guac_mem_free(received_data);
return CHANNEL_RC_OK;

}
Expand All @@ -512,13 +516,15 @@ static UINT guac_rdp_cliprdr_format_data_response(CliprdrClientContext* cliprdr,
/* Convert, store, and forward the clipboard data received from RDP
* server */
if (guac_iconv(remote_reader, &input, data_len,
GUAC_WRITE_UTF8, &output, sizeof(received_data))) {
int length = strnlen(received_data, sizeof(received_data));
GUAC_WRITE_UTF8, &output, output_buf_size)) {
int length = strnlen(received_data, output_buf_size);
guac_common_clipboard_reset(clipboard->clipboard, "text/plain");
guac_common_clipboard_append(clipboard->clipboard, received_data, length);
guac_common_clipboard_send(clipboard->clipboard, client);
}

guac_mem_free(received_data);

return CHANNEL_RC_OK;

}
Expand Down Expand Up @@ -618,12 +624,12 @@ static void guac_rdp_cliprdr_channel_disconnected(rdpContext* context,

}

guac_rdp_clipboard* guac_rdp_clipboard_alloc(guac_client* client) {
guac_rdp_clipboard* guac_rdp_clipboard_alloc(guac_client* client, int buffer_size) {

/* Allocate clipboard and underlying storage */
guac_rdp_clipboard* clipboard = guac_mem_zalloc(sizeof(guac_rdp_clipboard));
clipboard->client = client;
clipboard->clipboard = guac_common_clipboard_alloc();
clipboard->clipboard = guac_common_clipboard_alloc(buffer_size);
clipboard->requested_format = CF_TEXT;

return clipboard;
Expand Down
5 changes: 4 additions & 1 deletion src/protocols/rdp/channels/cliprdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,14 @@ typedef struct guac_rdp_clipboard {
* The guac_client associated with the Guacamole side of the RDP
* connection.
*
* @param buffer_size
* The buffer size in bytes.
*
* @return
* A newly-allocated instance of guac_rdp_clipboard which has been
* initialized for processing Guacamole clipboard data.
*/
guac_rdp_clipboard* guac_rdp_clipboard_alloc(guac_client* client);
guac_rdp_clipboard* guac_rdp_clipboard_alloc(guac_client* client, int buffer_size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document the parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


/**
* Initializes clipboard support for RDP and handling of the CLIPRDR channel.
Expand Down
3 changes: 0 additions & 3 deletions src/protocols/rdp/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,6 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
guac_rdp_client* rdp_client = guac_mem_zalloc(sizeof(guac_rdp_client));
client->data = rdp_client;

/* Init clipboard */
rdp_client->clipboard = guac_rdp_clipboard_alloc(client);

/* Init display update module */
rdp_client->disp = guac_rdp_disp_alloc(client);

Expand Down
27 changes: 27 additions & 0 deletions src/protocols/rdp/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ const char* GUAC_RDP_CLIENT_ARGS[] = {

"load-balance-info",

"clipboard-buffer-size",
"disable-copy",
"disable-paste",

Expand Down Expand Up @@ -658,6 +659,11 @@ enum RDP_ARGS_IDX {
* the connection broker, if a connection broker is being used.
*/
IDX_LOAD_BALANCE_INFO,

/**
* The maximum number of bytes to allow within the clipboard.
*/
IDX_CLIPBOARD_BUFFER_SIZE,

/**
* Whether outbound clipboard access should be blocked. If set to "true",
Expand Down Expand Up @@ -1284,6 +1290,27 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user,
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
IDX_LOAD_BALANCE_INFO, NULL);

/* Set the maximum number of bytes to allow within the clipboard. */
settings->clipboard_buffer_size =
guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv,
IDX_CLIPBOARD_BUFFER_SIZE, 0);

/* Use default clipboard buffer size if given one is invalid. */
if (settings->clipboard_buffer_size < GUAC_COMMON_CLIPBOARD_MIN_LENGTH) {
settings->clipboard_buffer_size = GUAC_COMMON_CLIPBOARD_MIN_LENGTH;
guac_user_log(user, GUAC_LOG_ERROR, "Invalid clipboard buffer "
"size: \"%s\". Using the default minimum size: %i.",
argv[IDX_CLIPBOARD_BUFFER_SIZE],
settings->clipboard_buffer_size);
}
else if (settings->clipboard_buffer_size > GUAC_COMMON_CLIPBOARD_MAX_LENGTH) {
settings->clipboard_buffer_size = GUAC_COMMON_CLIPBOARD_MAX_LENGTH;
guac_user_log(user, GUAC_LOG_ERROR, "Invalid clipboard buffer "
"size: \"%s\". Using the default maximum size: %i.",
argv[IDX_CLIPBOARD_BUFFER_SIZE],
settings->clipboard_buffer_size);
}

/* Parse clipboard copy disable flag */
settings->disable_copy =
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
Expand Down
5 changes: 5 additions & 0 deletions src/protocols/rdp/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,11 @@ typedef struct guac_rdp_settings {
*/
char** svc_names;

/**
* The maximum number of bytes to allow within the clipboard.
*/
int clipboard_buffer_size;

/**
* Whether outbound clipboard access should be blocked. If set, it will not
* be possible to copy data from the remote desktop to the client using the
Expand Down
4 changes: 4 additions & 0 deletions src/protocols/rdp/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ int guac_rdp_user_join_handler(guac_user* user, int argc, char** argv) {
/* Store owner's settings at client level */
rdp_client->settings = settings;

/* Init clipboard */
rdp_client->clipboard =
guac_rdp_clipboard_alloc(user->client, settings->clipboard_buffer_size);

/* Start client thread */
if (pthread_create(&rdp_client->client_thread, NULL,
guac_rdp_client_thread, user->client)) {
Expand Down
28 changes: 28 additions & 0 deletions src/protocols/ssh/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "argv.h"
#include "client.h"
#include "common/defaults.h"
#include "common/clipboard.h"
#include "settings.h"
#include "terminal/terminal.h"

Expand Down Expand Up @@ -73,6 +74,7 @@ const char* GUAC_SSH_CLIENT_ARGS[] = {
"scrollback",
"locale",
"timezone",
"clipboard-buffer-size",
"disable-copy",
"disable-paste",
"wol-send-packet",
Expand Down Expand Up @@ -310,6 +312,11 @@ enum SSH_ARGS_IDX {
*/
IDX_TIMEZONE,

/**
* The maximum number of bytes to allow within the clipboard.
*/
IDX_CLIPBOARD_BUFFER_SIZE,

/**
* Whether outbound clipboard access should be blocked. If set to "true",
* it will not be possible to copy data from the terminal to the client
Expand Down Expand Up @@ -555,6 +562,27 @@ guac_ssh_settings* guac_ssh_parse_args(guac_user* user,
guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_TIMEZONE, user->info.timezone);

/* Set the maximum number of bytes to allow within the clipboard. */
settings->clipboard_buffer_size =
guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_CLIPBOARD_BUFFER_SIZE, 0);

/* Use default clipboard buffer size if given one is invalid. */
if (settings->clipboard_buffer_size < GUAC_COMMON_CLIPBOARD_MIN_LENGTH) {
settings->clipboard_buffer_size = GUAC_COMMON_CLIPBOARD_MIN_LENGTH;
guac_user_log(user, GUAC_LOG_ERROR, "Invalid clipboard buffer "
"size: \"%s\". Using the default minimum size: %i.",
argv[IDX_CLIPBOARD_BUFFER_SIZE],
settings->clipboard_buffer_size);
}
else if (settings->clipboard_buffer_size > GUAC_COMMON_CLIPBOARD_MAX_LENGTH) {
settings->clipboard_buffer_size = GUAC_COMMON_CLIPBOARD_MAX_LENGTH;
guac_user_log(user, GUAC_LOG_ERROR, "Invalid clipboard buffer "
"size: \"%s\". Using the default maximum size: %i.",
argv[IDX_CLIPBOARD_BUFFER_SIZE],
settings->clipboard_buffer_size);
}

/* Parse clipboard copy disable flag */
settings->disable_copy =
guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
Expand Down
Loading
Loading