Skip to content

Commit

Permalink
GUACAMOLE-1969: Implement recording-include-clipboard connection para…
Browse files Browse the repository at this point in the history
…meter
  • Loading branch information
lukasraska committed Jul 19, 2024
1 parent 8bc7319 commit 8180dc0
Show file tree
Hide file tree
Showing 22 changed files with 300 additions and 11 deletions.
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

0 comments on commit 8180dc0

Please sign in to comment.