diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c index 7c22c420..931f8ca3 100644 --- a/src/protocols/kubernetes/kubernetes.c +++ b/src/protocols/kubernetes/kubernetes.c @@ -237,7 +237,7 @@ void* guac_kubernetes_client_thread(void* data) { /* Create terminal */ kubernetes_client->term = guac_terminal_create(client, - kubernetes_client->clipboard, + kubernetes_client->clipboard, settings->disable_copy, settings->max_scrollback, settings->font_name, settings->font_size, settings->resolution, settings->width, settings->height, settings->color_scheme, settings->backspace); diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c index 4f00a445..ec23880b 100644 --- a/src/protocols/kubernetes/settings.c +++ b/src/protocols/kubernetes/settings.c @@ -50,6 +50,8 @@ const char* GUAC_KUBERNETES_CLIENT_ARGS[] = { "read-only", "backspace", "scrollback", + "disable-copy", + "disable-paste", NULL }; @@ -216,6 +218,20 @@ enum KUBERNETES_ARGS_IDX { */ IDX_SCROLLBACK, + /** + * 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 + * using the clipboard. By default, clipboard access is not blocked. + */ + IDX_DISABLE_COPY, + + /** + * Whether inbound clipboard access should be blocked. If set to "true", it + * will not be possible to paste data from the client to the terminal using + * the clipboard. By default, clipboard access is not blocked. + */ + IDX_DISABLE_PASTE, + KUBERNETES_ARGS_COUNT }; @@ -364,6 +380,16 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user, guac_user_parse_args_int(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, IDX_BACKSPACE, 127); + /* Parse clipboard copy disable flag */ + settings->disable_copy = + guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, + IDX_DISABLE_COPY, false); + + /* Parse clipboard paste disable flag */ + settings->disable_paste = + guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, + IDX_DISABLE_PASTE, false); + /* Parsing was successful */ return settings; diff --git a/src/protocols/kubernetes/settings.h b/src/protocols/kubernetes/settings.h index 6267a18b..eef4973e 100644 --- a/src/protocols/kubernetes/settings.h +++ b/src/protocols/kubernetes/settings.h @@ -170,6 +170,20 @@ typedef struct guac_kubernetes_settings { */ int resolution; + /** + * 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 + * clipboard. + */ + bool disable_copy; + + /** + * Whether inbound clipboard access should be blocked. If set, it will not + * be possible to paste data from the client to the terminal using the + * clipboard. + */ + bool disable_paste; + /** * The path in which the typescript should be saved, if enabled. If no * typescript should be saved, this will be NULL. diff --git a/src/protocols/kubernetes/user.c b/src/protocols/kubernetes/user.c index f90260e7..f4e9eb44 100644 --- a/src/protocols/kubernetes/user.c +++ b/src/protocols/kubernetes/user.c @@ -79,10 +79,13 @@ int guac_kubernetes_user_join_handler(guac_user* user, int argc, char** argv) { /* Only handle events if not read-only */ if (!settings->read_only) { - /* General mouse/keyboard/clipboard events */ - user->key_handler = guac_kubernetes_user_key_handler; - user->mouse_handler = guac_kubernetes_user_mouse_handler; - user->clipboard_handler = guac_kubernetes_clipboard_handler; + /* General mouse/keyboard events */ + user->key_handler = guac_kubernetes_user_key_handler; + user->mouse_handler = guac_kubernetes_user_mouse_handler; + + /* Inbound (client to server) clipboard transfer */ + if (!settings->disable_paste) + user->clipboard_handler = guac_kubernetes_clipboard_handler; /* STDIN redirection */ user->pipe_handler = guac_kubernetes_pipe_handler; diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c index 042d3893..5b351c5b 100644 --- a/src/protocols/rdp/rdp.c +++ b/src/protocols/rdp/rdp.c @@ -240,11 +240,13 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) { guac_rdp_audio_load_plugin(instance->context, dvc_list); } - /* Load clipboard plugin */ - if (freerdp_channels_load_plugin(channels, instance->settings, - "cliprdr", NULL)) + /* Load clipboard plugin if not disabled */ + if (!(settings->disable_copy && settings->disable_paste) + && freerdp_channels_load_plugin(channels, instance->settings, + "cliprdr", NULL)) { guac_client_log(client, GUAC_LOG_WARNING, "Failed to load cliprdr plugin. Clipboard will not work."); + } /* If RDPSND/RDPDR required, load them */ if (settings->printing_enabled diff --git a/src/protocols/rdp/rdp_cliprdr.c b/src/protocols/rdp/rdp_cliprdr.c index 53019115..903752c8 100644 --- a/src/protocols/rdp/rdp_cliprdr.c +++ b/src/protocols/rdp/rdp_cliprdr.c @@ -230,6 +230,10 @@ void guac_rdp_process_cb_data_response(guac_client* client, guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; char received_data[GUAC_RDP_CLIPBOARD_MAX_LENGTH]; + /* Ignore received text if outbound clipboard transfer is disabled */ + if (rdp_client->settings->disable_copy) + return; + guac_iconv_read* reader; const char* input = (char*) event->data; char* output = received_data; diff --git a/src/protocols/rdp/rdp_settings.c b/src/protocols/rdp/rdp_settings.c index 88d9bc7f..d46cd27c 100644 --- a/src/protocols/rdp/rdp_settings.c +++ b/src/protocols/rdp/rdp_settings.c @@ -118,6 +118,8 @@ const char* GUAC_RDP_CLIENT_ARGS[] = { "load-balance-info", #endif + "disable-copy", + "disable-paste", NULL }; @@ -545,6 +547,20 @@ enum RDP_ARGS_IDX { IDX_LOAD_BALANCE_INFO, #endif + /** + * Whether outbound clipboard access should be blocked. If set to "true", + * it will not be possible to copy data from the remote desktop to the + * client using the clipboard. By default, clipboard access is not blocked. + */ + IDX_DISABLE_COPY, + + /** + * Whether inbound clipboard access should be blocked. If set to "true", it + * will not be possible to paste data from the client to the remote desktop + * using the clipboard. By default, clipboard access is not blocked. + */ + IDX_DISABLE_PASTE, + RDP_ARGS_COUNT }; @@ -1007,6 +1023,16 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user, IDX_LOAD_BALANCE_INFO, NULL); #endif + /* Parse clipboard copy disable flag */ + settings->disable_copy = + guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_DISABLE_COPY, 0); + + /* Parse clipboard paste disable flag */ + settings->disable_paste = + guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_DISABLE_PASTE, 0); + /* Success */ return settings; diff --git a/src/protocols/rdp/rdp_settings.h b/src/protocols/rdp/rdp_settings.h index 6955ed58..9edbedeb 100644 --- a/src/protocols/rdp/rdp_settings.h +++ b/src/protocols/rdp/rdp_settings.h @@ -268,6 +268,20 @@ typedef struct guac_rdp_settings { */ char** svc_names; + /** + * 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 + * clipboard. + */ + int disable_copy; + + /** + * Whether inbound clipboard access should be blocked. If set, it will not + * be possible to paste data from the client to the remote desktop using + * the clipboard. + */ + int disable_paste; + /** * Whether the desktop wallpaper should be visible. If unset, the desktop * wallpaper will be hidden, reducing the amount of bandwidth required. diff --git a/src/protocols/rdp/user.c b/src/protocols/rdp/user.c index 6aa71ae9..025848aa 100644 --- a/src/protocols/rdp/user.c +++ b/src/protocols/rdp/user.c @@ -97,10 +97,13 @@ int guac_rdp_user_join_handler(guac_user* user, int argc, char** argv) { /* Only handle events if not read-only */ if (!settings->read_only) { - /* General mouse/keyboard/clipboard events */ - user->mouse_handler = guac_rdp_user_mouse_handler; - user->key_handler = guac_rdp_user_key_handler; - user->clipboard_handler = guac_rdp_clipboard_handler; + /* General mouse/keyboard events */ + user->mouse_handler = guac_rdp_user_mouse_handler; + user->key_handler = guac_rdp_user_key_handler; + + /* Inbound (client to server) clipboard transfer */ + if (!settings->disable_paste) + user->clipboard_handler = guac_rdp_clipboard_handler; /* Display size change events */ user->size_handler = guac_rdp_user_size_handler; diff --git a/src/protocols/ssh/settings.c b/src/protocols/ssh/settings.c index 962524ce..84364193 100644 --- a/src/protocols/ssh/settings.c +++ b/src/protocols/ssh/settings.c @@ -62,6 +62,8 @@ const char* GUAC_SSH_CLIENT_ARGS[] = { "scrollback", "locale", "timezone", + "disable-copy", + "disable-paste", NULL }; @@ -258,6 +260,20 @@ enum SSH_ARGS_IDX { */ IDX_TIMEZONE, + /** + * 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 + * using the clipboard. By default, clipboard access is not blocked. + */ + IDX_DISABLE_COPY, + + /** + * Whether inbound clipboard access should be blocked. If set to "true", it + * will not be possible to paste data from the client to the terminal using + * the clipboard. By default, clipboard access is not blocked. + */ + IDX_DISABLE_PASTE, + SSH_ARGS_COUNT }; @@ -426,6 +442,16 @@ guac_ssh_settings* guac_ssh_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv, IDX_TIMEZONE, NULL); + /* Parse clipboard copy disable flag */ + settings->disable_copy = + guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv, + IDX_DISABLE_COPY, false); + + /* Parse clipboard paste disable flag */ + settings->disable_paste = + guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv, + IDX_DISABLE_PASTE, false); + /* Parsing was successful */ return settings; diff --git a/src/protocols/ssh/settings.h b/src/protocols/ssh/settings.h index baa634ad..bab21bdf 100644 --- a/src/protocols/ssh/settings.h +++ b/src/protocols/ssh/settings.h @@ -155,6 +155,20 @@ typedef struct guac_ssh_settings { */ int resolution; + /** + * 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 + * clipboard. + */ + bool disable_copy; + + /** + * Whether inbound clipboard access should be blocked. If set, it will not + * be possible to paste data from the client to the terminal using the + * clipboard. + */ + bool disable_paste; + /** * Whether SFTP is enabled. */ diff --git a/src/protocols/ssh/ssh.c b/src/protocols/ssh/ssh.c index 9db545bf..777172ec 100644 --- a/src/protocols/ssh/ssh.c +++ b/src/protocols/ssh/ssh.c @@ -207,9 +207,10 @@ void* ssh_client_thread(void* data) { /* Create terminal */ ssh_client->term = guac_terminal_create(client, ssh_client->clipboard, - settings->max_scrollback, settings->font_name, settings->font_size, - settings->resolution, settings->width, settings->height, - settings->color_scheme, settings->backspace); + settings->disable_copy, settings->max_scrollback, + settings->font_name, settings->font_size, settings->resolution, + settings->width, settings->height, settings->color_scheme, + settings->backspace); /* Fail if terminal init failed */ if (ssh_client->term == NULL) { diff --git a/src/protocols/ssh/user.c b/src/protocols/ssh/user.c index 97ed87c6..76a2a963 100644 --- a/src/protocols/ssh/user.c +++ b/src/protocols/ssh/user.c @@ -80,10 +80,13 @@ int guac_ssh_user_join_handler(guac_user* user, int argc, char** argv) { /* Only handle events if not read-only */ if (!settings->read_only) { - /* General mouse/keyboard/clipboard events */ - user->key_handler = guac_ssh_user_key_handler; - user->mouse_handler = guac_ssh_user_mouse_handler; - user->clipboard_handler = guac_ssh_clipboard_handler; + /* General mouse/keyboard events */ + user->key_handler = guac_ssh_user_key_handler; + user->mouse_handler = guac_ssh_user_mouse_handler; + + /* Inbound (client to server) clipboard transfer */ + if (!settings->disable_paste) + user->clipboard_handler = guac_ssh_clipboard_handler; /* STDIN redirection */ user->pipe_handler = guac_ssh_pipe_handler; diff --git a/src/protocols/telnet/settings.c b/src/protocols/telnet/settings.c index 890d5fec..ded5c4f3 100644 --- a/src/protocols/telnet/settings.c +++ b/src/protocols/telnet/settings.c @@ -55,6 +55,8 @@ const char* GUAC_TELNET_CLIENT_ARGS[] = { "scrollback", "login-success-regex", "login-failure-regex", + "disable-copy", + "disable-paste", NULL }; @@ -216,6 +218,20 @@ enum TELNET_ARGS_IDX { */ IDX_LOGIN_FAILURE_REGEX, + /** + * 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 + * using the clipboard. By default, clipboard access is not blocked. + */ + IDX_DISABLE_COPY, + + /** + * Whether inbound clipboard access should be blocked. If set to "true", it + * will not be possible to paste data from the client to the terminal using + * the clipboard. By default, clipboard access is not blocked. + */ + IDX_DISABLE_PASTE, + TELNET_ARGS_COUNT }; @@ -428,6 +444,16 @@ guac_telnet_settings* guac_telnet_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_TELNET_CLIENT_ARGS, argv, IDX_TERMINAL_TYPE, "linux"); + /* Parse clipboard copy disable flag */ + settings->disable_copy = + guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv, + IDX_DISABLE_COPY, false); + + /* Parse clipboard paste disable flag */ + settings->disable_paste = + guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv, + IDX_DISABLE_PASTE, false); + /* Parsing was successful */ return settings; diff --git a/src/protocols/telnet/settings.h b/src/protocols/telnet/settings.h index 86302b77..691669cb 100644 --- a/src/protocols/telnet/settings.h +++ b/src/protocols/telnet/settings.h @@ -171,6 +171,20 @@ typedef struct guac_telnet_settings { */ int resolution; + /** + * 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 + * clipboard. + */ + bool disable_copy; + + /** + * Whether inbound clipboard access should be blocked. If set, it will not + * be possible to paste data from the client to the terminal using the + * clipboard. + */ + bool disable_paste; + /** * The path in which the typescript should be saved, if enabled. If no * typescript should be saved, this will be NULL. diff --git a/src/protocols/telnet/telnet.c b/src/protocols/telnet/telnet.c index 17abd681..d8fc5e09 100644 --- a/src/protocols/telnet/telnet.c +++ b/src/protocols/telnet/telnet.c @@ -568,7 +568,7 @@ void* guac_telnet_client_thread(void* data) { /* Create terminal */ telnet_client->term = guac_terminal_create(client, - telnet_client->clipboard, + telnet_client->clipboard, settings->disable_copy, settings->max_scrollback, settings->font_name, settings->font_size, settings->resolution, settings->width, settings->height, settings->color_scheme, settings->backspace); diff --git a/src/protocols/telnet/user.c b/src/protocols/telnet/user.c index 44ef9b5e..5c15283b 100644 --- a/src/protocols/telnet/user.c +++ b/src/protocols/telnet/user.c @@ -79,10 +79,13 @@ int guac_telnet_user_join_handler(guac_user* user, int argc, char** argv) { /* Only handle events if not read-only */ if (!settings->read_only) { - /* General mouse/keyboard/clipboard events */ - user->key_handler = guac_telnet_user_key_handler; - user->mouse_handler = guac_telnet_user_mouse_handler; - user->clipboard_handler = guac_telnet_clipboard_handler; + /* General mouse/keyboard events */ + user->key_handler = guac_telnet_user_key_handler; + user->mouse_handler = guac_telnet_user_mouse_handler; + + /* Inbound (client to server) clipboard transfer */ + if (!settings->disable_paste) + user->clipboard_handler = guac_telnet_clipboard_handler; /* STDIN redirection */ user->pipe_handler = guac_telnet_pipe_handler; diff --git a/src/protocols/vnc/clipboard.c b/src/protocols/vnc/clipboard.c index a49f5651..c3b1bd1f 100644 --- a/src/protocols/vnc/clipboard.c +++ b/src/protocols/vnc/clipboard.c @@ -125,6 +125,10 @@ void guac_vnc_cut_text(rfbClient* client, const char* text, int textlen) { guac_client* gc = rfbClientGetClientData(client, GUAC_VNC_CLIENT_KEY); guac_vnc_client* vnc_client = (guac_vnc_client*) gc->data; + /* Ignore received text if outbound clipboard transfer is disabled */ + if (vnc_client->settings->disable_copy) + return; + char received_data[GUAC_VNC_CLIPBOARD_MAX_LENGTH]; const char* input = text; diff --git a/src/protocols/vnc/settings.c b/src/protocols/vnc/settings.c index 8f65cfb2..3e0ebc6b 100644 --- a/src/protocols/vnc/settings.c +++ b/src/protocols/vnc/settings.c @@ -77,7 +77,8 @@ const char* GUAC_VNC_CLIENT_ARGS[] = { "recording-exclude-mouse", "recording-include-keys", "create-recording-path", - + "disable-copy", + "disable-paste", NULL }; @@ -298,6 +299,20 @@ enum VNC_ARGS_IDX { */ IDX_CREATE_RECORDING_PATH, + /** + * Whether outbound clipboard access should be blocked. If set to "true", + * it will not be possible to copy data from the remote desktop to the + * client using the clipboard. By default, clipboard access is not blocked. + */ + IDX_DISABLE_COPY, + + /** + * Whether inbound clipboard access should be blocked. If set to "true", it + * will not be possible to paste data from the client to the remote desktop + * using the clipboard. By default, clipboard access is not blocked. + */ + IDX_DISABLE_PASTE, + VNC_ARGS_COUNT }; @@ -493,6 +508,16 @@ guac_vnc_settings* guac_vnc_parse_args(guac_user* user, guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv, IDX_CREATE_RECORDING_PATH, false); + /* Parse clipboard copy disable flag */ + settings->disable_copy = + guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv, + IDX_DISABLE_COPY, false); + + /* Parse clipboard paste disable flag */ + settings->disable_paste = + guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv, + IDX_DISABLE_PASTE, false); + return settings; } diff --git a/src/protocols/vnc/settings.h b/src/protocols/vnc/settings.h index 3e2ebd5e..13a3d87b 100644 --- a/src/protocols/vnc/settings.h +++ b/src/protocols/vnc/settings.h @@ -127,6 +127,20 @@ typedef struct guac_vnc_settings { */ char* clipboard_encoding; + /** + * 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 + * clipboard. + */ + bool disable_copy; + + /** + * Whether inbound clipboard access should be blocked. If set, it will not + * be possible to paste data from the client to the remote desktop using + * the clipboard. + */ + bool disable_paste; + #ifdef ENABLE_COMMON_SSH /** * Whether SFTP should be enabled for the VNC connection. diff --git a/src/protocols/vnc/user.c b/src/protocols/vnc/user.c index da3b843f..0dee5043 100644 --- a/src/protocols/vnc/user.c +++ b/src/protocols/vnc/user.c @@ -91,10 +91,13 @@ int guac_vnc_user_join_handler(guac_user* user, int argc, char** argv) { /* Only handle events if not read-only */ if (!settings->read_only) { - /* General mouse/keyboard/clipboard events */ - user->mouse_handler = guac_vnc_user_mouse_handler; - user->key_handler = guac_vnc_user_key_handler; - user->clipboard_handler = guac_vnc_clipboard_handler; + /* General mouse/keyboard events */ + user->mouse_handler = guac_vnc_user_mouse_handler; + user->key_handler = guac_vnc_user_key_handler; + + /* Inbound (client to server) clipboard transfer */ + if (!settings->disable_paste) + user->clipboard_handler = guac_vnc_clipboard_handler; #ifdef ENABLE_COMMON_SSH /* Set generic (non-filesystem) file upload handler */ diff --git a/src/terminal/select.c b/src/terminal/select.c index 20fc3cda..0a075ebd 100644 --- a/src/terminal/select.c +++ b/src/terminal/select.c @@ -375,8 +375,10 @@ void guac_terminal_select_end(guac_terminal* terminal) { } /* Send data */ - guac_common_clipboard_send(terminal->clipboard, client); - guac_socket_flush(socket); + if (!terminal->disable_copy) { + guac_common_clipboard_send(terminal->clipboard, client); + guac_socket_flush(socket); + } guac_terminal_notify(terminal); diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index cf70f92d..7ddcb2f1 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -306,8 +306,8 @@ void* guac_terminal_thread(void* data) { } guac_terminal* guac_terminal_create(guac_client* client, - guac_common_clipboard* clipboard, int max_scrollback, - const char* font_name, int font_size, int dpi, + guac_common_clipboard* clipboard, bool disable_copy, + int max_scrollback, const char* font_name, int font_size, int dpi, int width, int height, const char* color_scheme, const int backspace) { @@ -404,6 +404,7 @@ guac_terminal* guac_terminal_create(guac_client* client, term->current_attributes = default_char.attributes; term->default_char = default_char; term->clipboard = clipboard; + term->disable_copy = disable_copy; /* Calculate character size */ int rows = height / term->display->char_height; diff --git a/src/terminal/terminal/terminal.h b/src/terminal/terminal/terminal.h index ac1217eb..28e69357 100644 --- a/src/terminal/terminal/terminal.h +++ b/src/terminal/terminal/terminal.h @@ -511,6 +511,14 @@ struct guac_terminal { */ char backspace; + /** + * Whether copying from the terminal clipboard should be blocked. If set, + * the contents of the terminal can still be copied, but will be usable + * only within the terminal itself. The clipboard contents will not be + * automatically streamed to the client. + */ + bool disable_copy; + }; /** @@ -533,6 +541,12 @@ struct guac_terminal { * clipboard instructions. This clipboard will not be automatically * freed when this terminal is freed. * + * @param disable_copy + * Whether copying from the terminal clipboard should be blocked. If set, + * the contents of the terminal can still be copied, but will be usable + * only within the terminal itself. The clipboard contents will not be + * automatically streamed to the client. + * * @param max_scrollback * The maximum number of rows to allow within the scrollback buffer. The * user may still alter the size of the scrollback buffer using terminal @@ -575,8 +589,8 @@ struct guac_terminal { * which renders all text to the given client. */ guac_terminal* guac_terminal_create(guac_client* client, - guac_common_clipboard* clipboard, int max_scrollback, - const char* font_name, int font_size, int dpi, + guac_common_clipboard* clipboard, bool disable_copy, + int max_scrollback, const char* font_name, int font_size, int dpi, int width, int height, const char* color_scheme, const int backspace);