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-1969: Implement recording-include-clipboard connection parameter #530

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
65 changes: 64 additions & 1 deletion src/libguac/guacamole/recording.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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

20 changes: 19 additions & 1 deletion src/libguac/recording.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
}
16 changes: 16 additions & 0 deletions src/protocols/kubernetes/clipboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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);

Expand All @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion src/protocols/kubernetes/kubernetes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
16 changes: 16 additions & 0 deletions src/protocols/kubernetes/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 10 additions & 0 deletions src/protocols/kubernetes/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
13 changes: 13 additions & 0 deletions src/protocols/rdp/channels/cliprdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

}
Expand All @@ -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;
Expand All @@ -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);

Expand Down
3 changes: 2 additions & 1 deletion src/protocols/rdp/rdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
16 changes: 16 additions & 0 deletions src/protocols/rdp/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 10 additions & 0 deletions src/protocols/rdp/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
19 changes: 17 additions & 2 deletions src/protocols/ssh/clipboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,37 @@ 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;
}

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;
Expand Down
Loading
Loading