diff --git a/src/protocols/rdp/rdp_settings.c b/src/protocols/rdp/rdp_settings.c index 82af859b..fd77e92a 100644 --- a/src/protocols/rdp/rdp_settings.c +++ b/src/protocols/rdp/rdp_settings.c @@ -91,6 +91,7 @@ const char* GUAC_RDP_CLIENT_ARGS[] = { "create-recording-path", "resize-method", "enable-audio-input", + "read-only", NULL }; @@ -385,6 +386,12 @@ enum RDP_ARGS_IDX { */ IDX_ENABLE_AUDIO_INPUT, + /** + * "true" if this connection should be read-only (user input should be + * dropped), "false" or blank otherwise. + */ + IDX_READ_ONLY, + RDP_ARGS_COUNT }; @@ -528,6 +535,11 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_PASSWORD, NULL); + /* Read-only mode */ + settings->read_only = + guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_READ_ONLY, 0); + /* Client name */ settings->client_name = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, diff --git a/src/protocols/rdp/rdp_settings.h b/src/protocols/rdp/rdp_settings.h index 90c79cee..bcbe9b66 100644 --- a/src/protocols/rdp/rdp_settings.h +++ b/src/protocols/rdp/rdp_settings.h @@ -141,6 +141,11 @@ typedef struct guac_rdp_settings { */ char* password; + /** + * Whether this connection is read-only, and user input should be dropped. + */ + int read_only; + /** * The color depth of the display to request, in bits. */ diff --git a/src/protocols/rdp/user.c b/src/protocols/rdp/user.c index 638f2d11..ae02a106 100644 --- a/src/protocols/rdp/user.c +++ b/src/protocols/rdp/user.c @@ -94,12 +94,24 @@ int guac_rdp_user_join_handler(guac_user* user, int argc, char** argv) { } - user->file_handler = guac_rdp_user_file_handler; - user->mouse_handler = guac_rdp_user_mouse_handler; - user->key_handler = guac_rdp_user_key_handler; - user->size_handler = guac_rdp_user_size_handler; - user->pipe_handler = guac_rdp_svc_pipe_handler; - user->clipboard_handler = guac_rdp_clipboard_handler; + /* 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; + + /* Display size change events */ + user->size_handler = guac_rdp_user_size_handler; + + /* Set generic (non-filesystem) file upload handler */ + user->file_handler = guac_rdp_user_file_handler; + + /* Inbound arbitrary named pipes */ + user->pipe_handler = guac_rdp_svc_pipe_handler; + + } return 0; diff --git a/src/protocols/ssh/settings.c b/src/protocols/ssh/settings.c index 417c114e..35f88e0f 100644 --- a/src/protocols/ssh/settings.c +++ b/src/protocols/ssh/settings.c @@ -50,6 +50,7 @@ const char* GUAC_SSH_CLIENT_ARGS[] = { "recording-path", "recording-name", "create-recording-path", + "read-only", NULL }; @@ -158,6 +159,12 @@ enum SSH_ARGS_IDX { */ IDX_CREATE_RECORDING_PATH, + /** + * "true" if this connection should be read-only (user input should be + * dropped), "false" or blank otherwise. + */ + IDX_READ_ONLY, + SSH_ARGS_COUNT }; @@ -232,6 +239,11 @@ guac_ssh_settings* guac_ssh_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv, IDX_PORT, GUAC_SSH_DEFAULT_PORT); + /* Read-only mode */ + settings->read_only = + guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv, + IDX_READ_ONLY, false); + /* Read command, if any */ settings->command = guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv, diff --git a/src/protocols/ssh/settings.h b/src/protocols/ssh/settings.h index 5fe10a5b..6d3e47a5 100644 --- a/src/protocols/ssh/settings.h +++ b/src/protocols/ssh/settings.h @@ -94,6 +94,11 @@ typedef struct guac_ssh_settings { */ char* key_passphrase; + /** + * Whether this connection is read-only, and user input should be dropped. + */ + bool read_only; + /** * The command to run instead of the default shell. If a normal shell * session is desired, this will be NULL. diff --git a/src/protocols/ssh/user.c b/src/protocols/ssh/user.c index cd62ad38..4ebbab2f 100644 --- a/src/protocols/ssh/user.c +++ b/src/protocols/ssh/user.c @@ -75,14 +75,21 @@ int guac_ssh_user_join_handler(guac_user* user, int argc, char** argv) { guac_socket_flush(user->socket); } - /* Set per-user event handlers */ - user->key_handler = guac_ssh_user_key_handler; - user->mouse_handler = guac_ssh_user_mouse_handler; - user->size_handler = guac_ssh_user_size_handler; - user->clipboard_handler = guac_ssh_clipboard_handler; + /* Only handle events if not read-only */ + if (!settings->read_only) { - /* Set generic (non-filesystem) file upload handler */ - user->file_handler = guac_sftp_file_handler; + /* 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; + + /* Display size change events */ + user->size_handler = guac_ssh_user_size_handler; + + /* Set generic (non-filesystem) file upload handler */ + user->file_handler = guac_sftp_file_handler; + + } return 0; diff --git a/src/protocols/telnet/settings.c b/src/protocols/telnet/settings.c index 6754211c..df7b2958 100644 --- a/src/protocols/telnet/settings.c +++ b/src/protocols/telnet/settings.c @@ -46,6 +46,7 @@ const char* GUAC_TELNET_CLIENT_ARGS[] = { "recording-path", "recording-name", "create-recording-path", + "read-only", NULL }; @@ -138,6 +139,12 @@ enum TELNET_ARGS_IDX { */ IDX_CREATE_RECORDING_PATH, + /** + * "true" if this connection should be read-only (user input should be + * dropped), "false" or blank otherwise. + */ + IDX_READ_ONLY, + TELNET_ARGS_COUNT }; @@ -217,6 +224,11 @@ guac_telnet_settings* guac_telnet_parse_args(guac_user* user, IDX_PASSWORD_REGEX, GUAC_TELNET_DEFAULT_PASSWORD_REGEX)); } + /* Read-only mode */ + settings->read_only = + guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv, + IDX_READ_ONLY, false); + /* Read font name */ settings->font_name = guac_user_parse_args_string(user, GUAC_TELNET_CLIENT_ARGS, argv, diff --git a/src/protocols/telnet/settings.h b/src/protocols/telnet/settings.h index 062f4779..434e5938 100644 --- a/src/protocols/telnet/settings.h +++ b/src/protocols/telnet/settings.h @@ -112,6 +112,11 @@ typedef struct guac_telnet_settings { */ regex_t* password_regex; + /** + * Whether this connection is read-only, and user input should be dropped. + */ + bool read_only; + /** * The name of the font to use for display rendering. */ diff --git a/src/protocols/telnet/user.c b/src/protocols/telnet/user.c index 8df697f4..aab8f629 100644 --- a/src/protocols/telnet/user.c +++ b/src/protocols/telnet/user.c @@ -74,11 +74,18 @@ int guac_telnet_user_join_handler(guac_user* user, int argc, char** argv) { guac_socket_flush(user->socket); } - /* Set per-user event handlers */ - user->key_handler = guac_telnet_user_key_handler; - user->mouse_handler = guac_telnet_user_mouse_handler; - user->size_handler = guac_telnet_user_size_handler; - user->clipboard_handler = guac_telnet_clipboard_handler; + /* 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; + + /* Display size change events */ + user->size_handler = guac_telnet_user_size_handler; + + } return 0;