diff --git a/src/libguac/guacamole/recording.h b/src/libguac/guacamole/recording.h index e44bc8468..beaa4928b 100644 --- a/src/libguac/guacamole/recording.h +++ b/src/libguac/guacamole/recording.h @@ -95,6 +95,15 @@ typedef struct guac_recording { */ int include_keys; + /** + * Non-zero if clipboard paste data should be included in the session + * recording, zero otherwise. Including clipboard data within the recording may + * be necessary in certain auditing contexts, but should only be done with + * caution. Clipboard can easily contain sensitive information, such as + * passwords, credit card numbers, etc. + */ + int include_clipboard; + } guac_recording; /** @@ -152,6 +161,13 @@ typedef struct guac_recording { * Non-zero if writing to an existing file should be allowed, or zero * otherwise. * + * @param include_clipboard + * Non-zero if clipboard paste data should be included in the session + * recording, zero otherwise. Including clipboard data within the recording may + * be necessary in certain auditing contexts, but should only be done with + * caution. Clipboard can easily contain sensitive information, such as + * passwords, credit card numbers, etc. + * * @return * A new guac_recording structure representing the in-progress * recording if the recording file has been successfully created and a @@ -160,7 +176,7 @@ typedef struct guac_recording { guac_recording* guac_recording_create(guac_client* client, const char* path, const char* name, int create_path, int include_output, int include_mouse, int include_touch, - int include_keys, int allow_write_existing); + int include_keys, int allow_write_existing, int include_clipboard); /** * Frees the resources associated with the given in-progress recording. Note @@ -256,5 +272,52 @@ void guac_recording_report_touch(guac_recording* recording, void guac_recording_report_key(guac_recording* recording, int keysym, int pressed); +/** + * Reports a clipboard paste instruction within the recording. + * The full structure consists of clipboard instruction, one or more + * blob instructions and end instruction. + * + * @param recording + * The guac_recording associated with the clipboard instruction. + * + * @param stream + * The guac_stream allocated for the clipboard paste instruction. + * + * @param mimetype + * The clipboard data mimetype + */ +void guac_recording_report_clipboard(guac_recording* recording, + guac_stream* stream, char* mimetype); + +/** + * Report a clipboard paste blob within the recording. + * + * @param recording + * The guac_recording associated with the clipboard instruction. + * + * @param stream + * The guac_stream associated with the clipboard instruction. + * + * @param data + * The clipboard blob data. + * + * @param length + * Length of the blob data. + */ +void guac_recording_report_clipboard_blob(guac_recording* recording, + guac_stream* stream, void* data, int length); + +/** + * Report a clipboard paste end instruction within the recording. + * + * @param recording + * The guac_recording associated with the clipboard instruction. + * + * @param stream + * The guac_stream associated with the clipboard instruction. + */ +void guac_recording_report_clipboard_end(guac_recording* recording, + guac_stream* stream); + #endif diff --git a/src/libguac/recording.c b/src/libguac/recording.c index 7e36f4613..893eaa162 100644 --- a/src/libguac/recording.c +++ b/src/libguac/recording.c @@ -144,7 +144,7 @@ static int guac_recording_open(const char* path, guac_recording* guac_recording_create(guac_client* client, const char* path, const char* name, int create_path, int include_output, int include_mouse, int include_touch, - int include_keys, int allow_write_existing) { + int include_keys, int allow_write_existing, int include_clipboard) { char filename[GUAC_COMMON_RECORDING_MAX_NAME_LENGTH]; @@ -176,6 +176,7 @@ guac_recording* guac_recording_create(guac_client* client, recording->include_mouse = include_mouse; recording->include_touch = include_touch; recording->include_keys = include_keys; + recording->include_clipboard = include_clipboard; /* Replace client socket with wrapped recording socket only if including * output within the recording */ @@ -234,3 +235,20 @@ void guac_recording_report_key(guac_recording* recording, } +void guac_recording_report_clipboard(guac_recording* recording, guac_stream* stream, char* mimetype) { + /* Report clipboard only if recording should contain it */ + if (recording->include_clipboard) + guac_protocol_send_clipboard(recording->socket, stream, mimetype); +} + +void guac_recording_report_clipboard_blob(guac_recording* recording, guac_stream* stream, void* data, int length) { + /* Report clipboard only if recording should contain it */ + if (recording->include_clipboard) + guac_protocol_send_blob(recording->socket, stream, data, length); +} + +void guac_recording_report_clipboard_end(guac_recording* recording, guac_stream* stream) { + /* Report clipboard only if recording should contain it */ + if (recording->include_clipboard) + guac_protocol_send_end(recording->socket, stream); +} diff --git a/src/protocols/kubernetes/clipboard.c b/src/protocols/kubernetes/clipboard.c index f031f11e2..a11109b1a 100644 --- a/src/protocols/kubernetes/clipboard.c +++ b/src/protocols/kubernetes/clipboard.c @@ -39,6 +39,10 @@ int guac_kubernetes_clipboard_handler(guac_user* user, guac_stream* stream, stream->blob_handler = guac_kubernetes_clipboard_blob_handler; stream->end_handler = guac_kubernetes_clipboard_end_handler; + /* Report clipboard within recording */ + if (kubernetes_client->recording != NULL) + guac_recording_report_clipboard(kubernetes_client->recording, stream, mimetype); + return 0; } @@ -49,6 +53,10 @@ int guac_kubernetes_clipboard_blob_handler(guac_user* user, guac_kubernetes_client* kubernetes_client = (guac_kubernetes_client*) client->data; + /* Report clipboard blob within recording */ + if (kubernetes_client->recording != NULL) + guac_recording_report_clipboard_blob(kubernetes_client->recording, stream, data, length); + /* Append new data */ guac_terminal_clipboard_append(kubernetes_client->term, data, length); @@ -58,6 +66,14 @@ int guac_kubernetes_clipboard_blob_handler(guac_user* user, int guac_kubernetes_clipboard_end_handler(guac_user* user, guac_stream* stream) { + guac_client* client = user->client; + guac_kubernetes_client* kubernetes_client = + (guac_kubernetes_client*) client->data; + + /* Report clipboard blob within recording */ + if (kubernetes_client->recording != NULL) + guac_recording_report_clipboard_end(kubernetes_client->recording, stream); + /* Nothing to do - clipboard is implemented within client */ return 0; diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c index a4ce74a0e..cc96a35a8 100644 --- a/src/protocols/kubernetes/kubernetes.c +++ b/src/protocols/kubernetes/kubernetes.c @@ -238,7 +238,8 @@ void* guac_kubernetes_client_thread(void* data) { !settings->recording_exclude_mouse, 0, /* Touch events not supported */ settings->recording_include_keys, - settings->recording_write_existing); + settings->recording_write_existing, + settings->recording_include_clipboard); } /* Create terminal options with required parameters */ diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c index 698fcc1ed..44f883deb 100644 --- a/src/protocols/kubernetes/settings.c +++ b/src/protocols/kubernetes/settings.c @@ -51,6 +51,7 @@ const char* GUAC_KUBERNETES_CLIENT_ARGS[] = { "recording-exclude-output", "recording-exclude-mouse", "recording-include-keys", + "recording-include-clipboard", "create-recording-path", "recording-write-existing", "read-only", @@ -212,6 +213,16 @@ enum KUBERNETES_ARGS_IDX { */ IDX_RECORDING_INCLUDE_KEYS, + /** + * Whether clipboard paste data should be included in the session recording. + * Key events are NOT included by default within the recording, + * as doing so has privacy and security implications. Including clipboard data + * may be necessary in certain auditing contexts, but should only be done + * with caution. Clipboard data can easily contain sensitive information, such + * as passwords, credit card numbers, etc. + */ + IDX_RECORDING_INCLUDE_CLIPBOARD, + /** * Whether the specified screen recording path should automatically be * created if it does not yet exist. @@ -403,6 +414,11 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user, guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, IDX_RECORDING_INCLUDE_KEYS, false); + /* Parse clipboard inclusion flag */ + settings->recording_include_clipboard = + guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, + IDX_RECORDING_INCLUDE_CLIPBOARD, false); + /* Parse path creation flag */ settings->create_recording_path = guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, diff --git a/src/protocols/kubernetes/settings.h b/src/protocols/kubernetes/settings.h index 468029c93..dddb7e61e 100644 --- a/src/protocols/kubernetes/settings.h +++ b/src/protocols/kubernetes/settings.h @@ -240,6 +240,16 @@ typedef struct guac_kubernetes_settings { */ bool recording_include_keys; + /** + * Whether clipboard paste data should be included in the session recording. + * Key events are NOT included by default within the recording, + * as doing so has privacy and security implications. Including clipboard data + * may be necessary in certain auditing contexts, but should only be done + * with caution. Clipboard data can easily contain sensitive information, such + * as passwords, credit card numbers, etc. + */ + bool recording_include_clipboard; + /** * Whether existing files should be appended to when creating a new recording. * Disabled by default. diff --git a/src/protocols/rdp/channels/cliprdr.c b/src/protocols/rdp/channels/cliprdr.c index 34bacf3ba..1e03f5e43 100644 --- a/src/protocols/rdp/channels/cliprdr.c +++ b/src/protocols/rdp/channels/cliprdr.c @@ -689,6 +689,11 @@ int guac_rdp_clipboard_handler(guac_user* user, guac_stream* stream, /* Clear any current contents, assigning the mimetype the data which will * be received */ guac_common_clipboard_reset(clipboard->clipboard, mimetype); + + /* Report clipboard within recording */ + if (rdp_client->recording != NULL) + guac_recording_report_clipboard(rdp_client->recording, stream, mimetype); + return 0; } @@ -705,6 +710,10 @@ int guac_rdp_clipboard_blob_handler(guac_user* user, guac_stream* stream, if (clipboard == NULL) return 0; + /* Report clipboard blob within recording */ + if (rdp_client->recording != NULL) + guac_recording_report_clipboard_blob(rdp_client->recording, stream, data, length); + /* Append received data to current clipboard contents */ guac_common_clipboard_append(clipboard->clipboard, (char*) data, length); return 0; @@ -722,6 +731,10 @@ int guac_rdp_clipboard_end_handler(guac_user* user, guac_stream* stream) { if (clipboard == NULL) return 0; + /* Report clipboard stream end within recording */ + if (rdp_client->recording != NULL) + guac_recording_report_clipboard_end(rdp_client->recording, stream); + /* Terminate clipboard data with NULL */ guac_common_clipboard_append(clipboard->clipboard, "", 1); diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c index e8f146f8a..2a8d68031 100644 --- a/src/protocols/rdp/rdp.c +++ b/src/protocols/rdp/rdp.c @@ -865,7 +865,8 @@ void* guac_rdp_client_thread(void* data) { !settings->recording_exclude_mouse, !settings->recording_exclude_touch, settings->recording_include_keys, - settings->recording_write_existing); + settings->recording_write_existing, + settings->recording_include_clipboard); } /* Continue handling connections until error or client disconnect */ diff --git a/src/protocols/rdp/settings.c b/src/protocols/rdp/settings.c index 0737f043b..89ac91742 100644 --- a/src/protocols/rdp/settings.c +++ b/src/protocols/rdp/settings.c @@ -122,6 +122,7 @@ const char* GUAC_RDP_CLIENT_ARGS[] = { "recording-exclude-mouse", "recording-exclude-touch", "recording-include-keys", + "recording-include-clipboard", "create-recording-path", "recording-write-existing", "resize-method", @@ -560,6 +561,16 @@ enum RDP_ARGS_IDX { */ IDX_RECORDING_INCLUDE_KEYS, + /** + * Whether clipboard paste data should be included in the session recording. + * Key events are NOT included by default within the recording, + * as doing so has privacy and security implications. Including clipboard data + * may be necessary in certain auditing contexts, but should only be done + * with caution. Clipboard data can easily contain sensitive information, such + * as passwords, credit card numbers, etc. + */ + IDX_RECORDING_INCLUDE_CLIPBOARD, + /** * Whether the specified screen recording path should automatically be * created if it does not yet exist. @@ -1164,6 +1175,11 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user, guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_RECORDING_INCLUDE_KEYS, 0); + /* Parse clipboard inclusion flag */ + settings->recording_include_clipboard = + guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_RECORDING_INCLUDE_CLIPBOARD, false); + /* Parse path creation flag */ settings->create_recording_path = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, diff --git a/src/protocols/rdp/settings.h b/src/protocols/rdp/settings.h index 7837e6aeb..eb08580c7 100644 --- a/src/protocols/rdp/settings.h +++ b/src/protocols/rdp/settings.h @@ -559,6 +559,16 @@ typedef struct guac_rdp_settings { */ int recording_include_keys; + /** + * Whether clipboard paste data should be included in the session recording. + * Key events are NOT included by default within the recording, + * as doing so has privacy and security implications. Including clipboard data + * may be necessary in certain auditing contexts, but should only be done + * with caution. Clipboard data can easily contain sensitive information, such + * as passwords, credit card numbers, etc. + */ + bool recording_include_clipboard; + /** * Non-zero if existing files should be appended to when creating a new * recording. Disabled by default. diff --git a/src/protocols/ssh/clipboard.c b/src/protocols/ssh/clipboard.c index 0e2363259..b9ed966c1 100644 --- a/src/protocols/ssh/clipboard.c +++ b/src/protocols/ssh/clipboard.c @@ -38,15 +38,23 @@ int guac_ssh_clipboard_handler(guac_user* user, guac_stream* stream, stream->blob_handler = guac_ssh_clipboard_blob_handler; stream->end_handler = guac_ssh_clipboard_end_handler; + /* Report clipboard within recording */ + if (ssh_client->recording != NULL) + guac_recording_report_clipboard(ssh_client->recording, stream, mimetype); + return 0; } int guac_ssh_clipboard_blob_handler(guac_user* user, guac_stream* stream, void* data, int length) { - - /* Append new data */ guac_client* client = user->client; guac_ssh_client* ssh_client = (guac_ssh_client*) client->data; + + /* Report clipboard blob within recording */ + if (ssh_client->recording != NULL) + guac_recording_report_clipboard_blob(ssh_client->recording, stream, data, length); + + /* Append new data */ guac_terminal_clipboard_append(ssh_client->term, data, length); return 0; @@ -54,6 +62,13 @@ int guac_ssh_clipboard_blob_handler(guac_user* user, guac_stream* stream, int guac_ssh_clipboard_end_handler(guac_user* user, guac_stream* stream) { + guac_client* client = user->client; + guac_ssh_client* ssh_client = (guac_ssh_client*) client->data; + + /* Report clipboard stream end within recording */ + if (ssh_client->recording != NULL) + guac_recording_report_clipboard_end(ssh_client->recording, stream); + /* Nothing to do - clipboard is implemented within client */ return 0; diff --git a/src/protocols/ssh/settings.c b/src/protocols/ssh/settings.c index a297963bc..339f43f0a 100644 --- a/src/protocols/ssh/settings.c +++ b/src/protocols/ssh/settings.c @@ -63,6 +63,7 @@ const char* GUAC_SSH_CLIENT_ARGS[] = { "recording-exclude-output", "recording-exclude-mouse", "recording-include-keys", + "recording-include-clipboard", "create-recording-path", "recording-write-existing", "read-only", @@ -243,6 +244,16 @@ enum SSH_ARGS_IDX { */ IDX_RECORDING_INCLUDE_KEYS, + /** + * Whether clipboard paste data should be included in the session recording. + * Key events are NOT included by default within the recording, + * as doing so has privacy and security implications. Including clipboard data + * may be necessary in certain auditing contexts, but should only be done + * with caution. Clipboard data can easily contain sensitive information, such + * as passwords, credit card numbers, etc. + */ + IDX_RECORDING_INCLUDE_CLIPBOARD, + /** * Whether the specified screen recording path should automatically be * created if it does not yet exist. @@ -509,6 +520,11 @@ guac_ssh_settings* guac_ssh_parse_args(guac_user* user, guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv, IDX_RECORDING_INCLUDE_KEYS, false); + /* Parse clipboard inclusion flag */ + settings->recording_include_clipboard = + guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv, + IDX_RECORDING_INCLUDE_CLIPBOARD, false); + /* Parse path creation flag */ settings->create_recording_path = guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv, diff --git a/src/protocols/ssh/settings.h b/src/protocols/ssh/settings.h index 0f9668327..1ed95af87 100644 --- a/src/protocols/ssh/settings.h +++ b/src/protocols/ssh/settings.h @@ -257,6 +257,16 @@ typedef struct guac_ssh_settings { */ bool recording_include_keys; + /** + * Whether clipboard paste data should be included in the session recording. + * Key events are NOT included by default within the recording, + * as doing so has privacy and security implications. Including clipboard data + * may be necessary in certain auditing contexts, but should only be done + * with caution. Clipboard data can easily contain sensitive information, such + * as passwords, credit card numbers, etc. + */ + bool recording_include_clipboard; + /** * Whether existing files should be appended to when creating a new recording. * Disabled by default. diff --git a/src/protocols/ssh/ssh.c b/src/protocols/ssh/ssh.c index 8db094af6..dff5a32df 100644 --- a/src/protocols/ssh/ssh.c +++ b/src/protocols/ssh/ssh.c @@ -284,7 +284,8 @@ void* ssh_client_thread(void* data) { !settings->recording_exclude_mouse, 0, /* Touch events not supported */ settings->recording_include_keys, - settings->recording_write_existing); + settings->recording_write_existing, + settings->recording_include_clipboard); } /* Create terminal options with required parameters */ diff --git a/src/protocols/telnet/clipboard.c b/src/protocols/telnet/clipboard.c index 08d28b111..439df7991 100644 --- a/src/protocols/telnet/clipboard.c +++ b/src/protocols/telnet/clipboard.c @@ -38,15 +38,24 @@ int guac_telnet_clipboard_handler(guac_user* user, guac_stream* stream, stream->blob_handler = guac_telnet_clipboard_blob_handler; stream->end_handler = guac_telnet_clipboard_end_handler; + /* Report clipboard within recording */ + if (telnet_client->recording != NULL) + guac_recording_report_clipboard(telnet_client->recording, stream, mimetype); + return 0; } int guac_telnet_clipboard_blob_handler(guac_user* user, guac_stream* stream, void* data, int length) { - /* Append new data */ guac_client* client = user->client; guac_telnet_client* telnet_client = (guac_telnet_client*) client->data; + + /* Report clipboard blob within recording */ + if (telnet_client->recording != NULL) + guac_recording_report_clipboard_blob(telnet_client->recording, stream, data, length); + + /* Append new data */ guac_terminal_clipboard_append(telnet_client->term, data, length); return 0; @@ -54,6 +63,13 @@ int guac_telnet_clipboard_blob_handler(guac_user* user, guac_stream* stream, int guac_telnet_clipboard_end_handler(guac_user* user, guac_stream* stream) { + guac_client* client = user->client; + guac_telnet_client* telnet_client = (guac_telnet_client*) client->data; + + /* Report clipboard stream end within recording */ + if (telnet_client->recording != NULL) + guac_recording_report_clipboard_end(telnet_client->recording, stream); + /* Nothing to do - clipboard is implemented within client */ return 0; diff --git a/src/protocols/telnet/settings.c b/src/protocols/telnet/settings.c index e55356948..3df01ea47 100644 --- a/src/protocols/telnet/settings.c +++ b/src/protocols/telnet/settings.c @@ -55,6 +55,7 @@ const char* GUAC_TELNET_CLIENT_ARGS[] = { "recording-exclude-output", "recording-exclude-mouse", "recording-include-keys", + "recording-include-clipboard", "create-recording-path", "recording-write-existing", "read-only", @@ -195,6 +196,16 @@ enum TELNET_ARGS_IDX { */ IDX_RECORDING_INCLUDE_KEYS, + /** + * Whether clipboard paste data should be included in the session recording. + * Key events are NOT included by default within the recording, + * as doing so has privacy and security implications. Including clipboard data + * may be necessary in certain auditing contexts, but should only be done + * with caution. Clipboard data can easily contain sensitive information, such + * as passwords, credit card numbers, etc. + */ + IDX_RECORDING_INCLUDE_CLIPBOARD, + /** * Whether the specified screen recording path should automatically be * created if it does not yet exist. @@ -500,6 +511,11 @@ guac_telnet_settings* guac_telnet_parse_args(guac_user* user, guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv, IDX_RECORDING_INCLUDE_KEYS, false); + /* Parse clipboard inclusion flag */ + settings->recording_include_clipboard = + guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv, + IDX_RECORDING_INCLUDE_CLIPBOARD, false); + /* Parse path creation flag */ settings->create_recording_path = guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv, diff --git a/src/protocols/telnet/settings.h b/src/protocols/telnet/settings.h index a28e440fe..8cf10f831 100644 --- a/src/protocols/telnet/settings.h +++ b/src/protocols/telnet/settings.h @@ -245,6 +245,16 @@ typedef struct guac_telnet_settings { */ bool recording_include_keys; + /** + * Whether clipboard paste data should be included in the session recording. + * Key events are NOT included by default within the recording, + * as doing so has privacy and security implications. Including clipboard data + * may be necessary in certain auditing contexts, but should only be done + * with caution. Clipboard data can easily contain sensitive information, such + * as passwords, credit card numbers, etc. + */ + bool recording_include_clipboard; + /** * Whether existing files should be appended to when creating a new recording. * Disabled by default. diff --git a/src/protocols/telnet/telnet.c b/src/protocols/telnet/telnet.c index 80ce6c878..e11d29542 100644 --- a/src/protocols/telnet/telnet.c +++ b/src/protocols/telnet/telnet.c @@ -536,7 +536,8 @@ void* guac_telnet_client_thread(void* data) { !settings->recording_exclude_mouse, 0, /* Touch events not supported */ settings->recording_include_keys, - settings->recording_write_existing); + settings->recording_write_existing, + settings->recording_include_clipboard); } /* Create terminal options with required parameters */ diff --git a/src/protocols/vnc/clipboard.c b/src/protocols/vnc/clipboard.c index 319ca95f6..594eee2d1 100644 --- a/src/protocols/vnc/clipboard.c +++ b/src/protocols/vnc/clipboard.c @@ -85,14 +85,23 @@ int guac_vnc_clipboard_handler(guac_user* user, guac_stream* stream, stream->blob_handler = guac_vnc_clipboard_blob_handler; stream->end_handler = guac_vnc_clipboard_end_handler; + /* Report clipboard within recording */ + if (vnc_client->recording != NULL) + guac_recording_report_clipboard(vnc_client->recording, stream, mimetype); + return 0; } int guac_vnc_clipboard_blob_handler(guac_user* user, guac_stream* stream, void* data, int length) { - /* Append new data */ guac_vnc_client* vnc_client = (guac_vnc_client*) user->client->data; + + /* Report clipboard blob within recording */ + if (vnc_client->recording != NULL) + guac_recording_report_clipboard_blob(vnc_client->recording, stream, data, length); + + /* Append new data */ guac_common_clipboard_append(vnc_client->clipboard, (char*) data, length); return 0; @@ -109,6 +118,10 @@ int guac_vnc_clipboard_end_handler(guac_user* user, guac_stream* stream) { char* output = output_data; guac_iconv_write* writer = vnc_client->clipboard_writer; + /* Report clipboard stream end within recording */ + if (vnc_client->recording != NULL) + guac_recording_report_clipboard_end(vnc_client->recording, stream); + /* Convert clipboard contents */ guac_iconv(GUAC_READ_UTF8, &input, vnc_client->clipboard->length, writer, &output, sizeof(output_data)); diff --git a/src/protocols/vnc/settings.c b/src/protocols/vnc/settings.c index 09ee8a7a4..6270717e7 100644 --- a/src/protocols/vnc/settings.c +++ b/src/protocols/vnc/settings.c @@ -83,6 +83,7 @@ const char* GUAC_VNC_CLIENT_ARGS[] = { "recording-exclude-output", "recording-exclude-mouse", "recording-include-keys", + "recording-include-clipboard", "create-recording-path", "recording-write-existing", "disable-copy", @@ -329,6 +330,16 @@ enum VNC_ARGS_IDX { */ IDX_RECORDING_INCLUDE_KEYS, + /** + * Whether clipboard paste data should be included in the session recording. + * Key events are NOT included by default within the recording, + * as doing so has privacy and security implications. Including clipboard data + * may be necessary in certain auditing contexts, but should only be done + * with caution. Clipboard data can easily contain sensitive information, such + * as passwords, credit card numbers, etc. + */ + IDX_RECORDING_INCLUDE_CLIPBOARD, + /** * Whether the specified screen recording path should automatically be * created if it does not yet exist. @@ -632,6 +643,11 @@ guac_vnc_settings* guac_vnc_parse_args(guac_user* user, guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv, IDX_RECORDING_INCLUDE_KEYS, false); + /* Parse clipboard inclusion flag */ + settings->recording_include_clipboard = + guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv, + IDX_RECORDING_INCLUDE_CLIPBOARD, false); + /* Parse path creation flag */ settings->create_recording_path = guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv, diff --git a/src/protocols/vnc/settings.h b/src/protocols/vnc/settings.h index 3b885816d..ea2e4656f 100644 --- a/src/protocols/vnc/settings.h +++ b/src/protocols/vnc/settings.h @@ -285,6 +285,16 @@ typedef struct guac_vnc_settings { */ bool recording_include_keys; + /** + * Whether clipboard paste data should be included in the session recording. + * Key events are NOT included by default within the recording, + * as doing so has privacy and security implications. Including clipboard data + * may be necessary in certain auditing contexts, but should only be done + * with caution. Clipboard data can easily contain sensitive information, such + * as passwords, credit card numbers, etc. + */ + bool recording_include_clipboard; + /** * Whether existing files should be appended to when creating a new recording. * Disabled by default. diff --git a/src/protocols/vnc/vnc.c b/src/protocols/vnc/vnc.c index ec2c505d4..037e32803 100644 --- a/src/protocols/vnc/vnc.c +++ b/src/protocols/vnc/vnc.c @@ -476,7 +476,8 @@ void* guac_vnc_client_thread(void* data) { !settings->recording_exclude_mouse, 0, /* Touch events not supported */ settings->recording_include_keys, - settings->recording_write_existing); + settings->recording_write_existing, + settings->recording_include_clipboard); } /* Create display */