GUACAMOLE-313: Add flags for controlling the contents of session recordings.

This commit is contained in:
Michael Jumper 2017-12-08 12:06:30 -08:00
parent 876516a1fb
commit 4fb17d5610
14 changed files with 367 additions and 14 deletions

View File

@ -55,6 +55,31 @@ typedef struct guac_common_recording {
*/ */
guac_socket* socket; guac_socket* socket;
/**
* Non-zero if output which is broadcast to each connected client
* (graphics, streams, etc.) should be included in the session recording,
* zero otherwise. Including output is necessary for any recording which
* must later be viewable as video.
*/
int include_output;
/**
* Non-zero if changes to mouse state, such as position and buttons pressed
* or released, should be included in the session recording, zero
* otherwise. Including mouse state is necessary for the mouse cursor to be
* rendered in any resulting video.
*/
int include_mouse;
/**
* Non-zero if keys pressed and released should be included in the session
* recording, zero otherwise. Including key events within the recording may
* be necessary in certain auditing contexts, but should only be done with
* caution. Key events can easily contain sensitive information, such as
* passwords, credit card numbers, etc.
*/
int include_keys;
} guac_common_recording; } guac_common_recording;
/** /**
@ -82,13 +107,33 @@ typedef struct guac_common_recording {
* written, or non-zero if the path should be created if it does not yet * written, or non-zero if the path should be created if it does not yet
* exist. * exist.
* *
* @param include_output
* Non-zero if output which is broadcast to each connected client
* (graphics, streams, etc.) should be included in the session recording,
* zero otherwise. Including output is necessary for any recording which
* must later be viewable as video.
*
* @param include_mouse
* Non-zero if changes to mouse state, such as position and buttons pressed
* or released, should be included in the session recording, zero
* otherwise. Including mouse state is necessary for the mouse cursor to be
* rendered in any resulting video.
*
* @param include_keys
* Non-zero if keys pressed and released should be included in the session
* recording, zero otherwise. Including key events within the recording may
* be necessary in certain auditing contexts, but should only be done with
* caution. Key events can easily contain sensitive information, such as
* passwords, credit card numbers, etc.
*
* @return * @return
* A new guac_common_recording structure representing the in-progress * A new guac_common_recording structure representing the in-progress
* recording if the recording file has been successfully created and a * recording if the recording file has been successfully created and a
* recording will be written, NULL otherwise. * recording will be written, NULL otherwise.
*/ */
guac_common_recording* guac_common_recording_create(guac_client* client, guac_common_recording* guac_common_recording_create(guac_client* client,
const char* path, const char* name, int create_path); const char* path, const char* name, int create_path,
int include_output, int include_mouse, int include_keys);
/** /**
* Frees the resources associated with the given in-progress recording. Note * Frees the resources associated with the given in-progress recording. Note

View File

@ -136,7 +136,8 @@ static int guac_common_recording_open(const char* path,
} }
guac_common_recording* guac_common_recording_create(guac_client* client, guac_common_recording* guac_common_recording_create(guac_client* client,
const char* path, const char* name, int create_path) { const char* path, const char* name, int create_path,
int include_output, int include_mouse, int include_keys) {
char filename[GUAC_COMMON_RECORDING_MAX_NAME_LENGTH]; char filename[GUAC_COMMON_RECORDING_MAX_NAME_LENGTH];
@ -162,9 +163,14 @@ guac_common_recording* guac_common_recording_create(guac_client* client,
/* Create recording structure with reference to underlying socket */ /* Create recording structure with reference to underlying socket */
guac_common_recording* recording = malloc(sizeof(guac_common_recording)); guac_common_recording* recording = malloc(sizeof(guac_common_recording));
recording->socket = guac_socket_open(fd); recording->socket = guac_socket_open(fd);
recording->include_output = include_output;
recording->include_mouse = include_mouse;
recording->include_keys = include_keys;
/* Replace client socket with wrapped recording socket */ /* Replace client socket with wrapped recording socket only if including
client->socket = guac_socket_tee(client->socket, recording->socket); * output within the recording */
if (include_output)
client->socket = guac_socket_tee(client->socket, recording->socket);
/* Recording creation succeeded */ /* Recording creation succeeded */
guac_client_log(client, GUAC_LOG_INFO, guac_client_log(client, GUAC_LOG_INFO,
@ -176,24 +182,34 @@ guac_common_recording* guac_common_recording_create(guac_client* client,
} }
void guac_common_recording_free(guac_common_recording* recording) { void guac_common_recording_free(guac_common_recording* recording) {
/* If not including broadcast output, the output socket is not associated
* with the client, and must be freed manually */
if (!recording->include_output)
guac_socket_free(recording->socket);
/* Free recording itself */
free(recording); free(recording);
} }
void guac_common_recording_report_mouse(guac_common_recording* recording, void guac_common_recording_report_mouse(guac_common_recording* recording,
int x, int y, int button_mask) { int x, int y, int button_mask) {
/* Report mouse location */ /* Report mouse location only if recording should contain mouse events */
guac_protocol_send_mouse(recording->socket, x, y, button_mask, if (recording->include_mouse)
guac_timestamp_current()); guac_protocol_send_mouse(recording->socket, x, y, button_mask,
guac_timestamp_current());
} }
void guac_common_recording_report_key(guac_common_recording* recording, void guac_common_recording_report_key(guac_common_recording* recording,
int keysym, int pressed) { int keysym, int pressed) {
/* Report key state */ /* Report key state only if recording should contain key events */
guac_protocol_send_key(recording->socket, keysym, pressed, if (recording->include_keys)
guac_timestamp_current()); guac_protocol_send_key(recording->socket, keysym, pressed,
guac_timestamp_current());
} }

View File

@ -671,7 +671,10 @@ static int guac_rdp_handle_connection(guac_client* client) {
rdp_client->recording = guac_common_recording_create(client, rdp_client->recording = guac_common_recording_create(client,
settings->recording_path, settings->recording_path,
settings->recording_name, settings->recording_name,
settings->create_recording_path); settings->create_recording_path,
!settings->recording_exclude_output,
!settings->recording_exclude_mouse,
settings->recording_include_keys);
} }
/* Create display */ /* Create display */

View File

@ -90,6 +90,9 @@ const char* GUAC_RDP_CLIENT_ARGS[] = {
"recording-path", "recording-path",
"recording-name", "recording-name",
"recording-exclude-output",
"recording-exclude-mouse",
"recording-include-keys",
"create-recording-path", "create-recording-path",
"resize-method", "resize-method",
"enable-audio-input", "enable-audio-input",
@ -395,6 +398,32 @@ enum RDP_ARGS_IDX {
*/ */
IDX_RECORDING_NAME, IDX_RECORDING_NAME,
/**
* Whether output which is broadcast to each connected client (graphics,
* streams, etc.) should NOT be included in the session recording. Output
* is included by default, as it is necessary for any recording which must
* later be viewable as video.
*/
IDX_RECORDING_EXCLUDE_OUTPUT,
/**
* Whether changes to mouse state, such as position and buttons pressed or
* released, should NOT be included in the session recording. Mouse state
* is included by default, as it is necessary for the mouse cursor to be
* rendered in any resulting video.
*/
IDX_RECORDING_EXCLUDE_MOUSE,
/**
* Whether keys pressed and released 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 key events
* may be necessary in certain auditing contexts, but should only be done
* with caution. Key events can easily contain sensitive information, such
* as passwords, credit card numbers, etc.
*/
IDX_RECORDING_INCLUDE_KEYS,
/** /**
* Whether the specified screen recording path should automatically be * Whether the specified screen recording path should automatically be
* created if it does not yet exist. * created if it does not yet exist.
@ -812,6 +841,21 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user,
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
IDX_RECORDING_NAME, GUAC_RDP_DEFAULT_RECORDING_NAME); IDX_RECORDING_NAME, GUAC_RDP_DEFAULT_RECORDING_NAME);
/* Parse output exclusion flag */
settings->recording_exclude_output =
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
IDX_RECORDING_EXCLUDE_OUTPUT, 0);
/* Parse mouse exclusion flag */
settings->recording_exclude_mouse =
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
IDX_RECORDING_EXCLUDE_MOUSE, 0);
/* Parse key event inclusion flag */
settings->recording_include_keys =
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
IDX_RECORDING_INCLUDE_KEYS, 0);
/* Parse path creation flag */ /* Parse path creation flag */
settings->create_recording_path = settings->create_recording_path =
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,

View File

@ -392,6 +392,32 @@ typedef struct guac_rdp_settings {
*/ */
int create_recording_path; int create_recording_path;
/**
* Non-zero if output which is broadcast to each connected client
* (graphics, streams, etc.) should NOT be included in the session
* recording, zero otherwise. Output is included by default, as it is
* necessary for any recording which must later be viewable as video.
*/
int recording_exclude_output;
/**
* Non-zero if changes to mouse state, such as position and buttons pressed
* or released, should NOT be included in the session recording, zero
* otherwise. Mouse state is included by default, as it is necessary for
* the mouse cursor to be rendered in any resulting video.
*/
int recording_exclude_mouse;
/**
* Non-zero if keys pressed and released should be included in the session
* recording, zero otherwise. Key events are NOT included by default within
* the recording, as doing so has privacy and security implications.
* Including key events may be necessary in certain auditing contexts, but
* should only be done with caution. Key events can easily contain
* sensitive information, such as passwords, credit card numbers, etc.
*/
int recording_include_keys;
/** /**
* The method to apply when the user's display changes size. * The method to apply when the user's display changes size.
*/ */

View File

@ -50,6 +50,9 @@ const char* GUAC_SSH_CLIENT_ARGS[] = {
"create-typescript-path", "create-typescript-path",
"recording-path", "recording-path",
"recording-name", "recording-name",
"recording-exclude-output",
"recording-exclude-mouse",
"recording-include-keys",
"create-recording-path", "create-recording-path",
"read-only", "read-only",
"server-alive-interval", "server-alive-interval",
@ -161,6 +164,32 @@ enum SSH_ARGS_IDX {
*/ */
IDX_RECORDING_NAME, IDX_RECORDING_NAME,
/**
* Whether output which is broadcast to each connected client (graphics,
* streams, etc.) should NOT be included in the session recording. Output
* is included by default, as it is necessary for any recording which must
* later be viewable as video.
*/
IDX_RECORDING_EXCLUDE_OUTPUT,
/**
* Whether changes to mouse state, such as position and buttons pressed or
* released, should NOT be included in the session recording. Mouse state
* is included by default, as it is necessary for the mouse cursor to be
* rendered in any resulting video.
*/
IDX_RECORDING_EXCLUDE_MOUSE,
/**
* Whether keys pressed and released 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 key events
* may be necessary in certain auditing contexts, but should only be done
* with caution. Key events can easily contain sensitive information, such
* as passwords, credit card numbers, etc.
*/
IDX_RECORDING_INCLUDE_KEYS,
/** /**
* Whether the specified screen recording path should automatically be * Whether the specified screen recording path should automatically be
* created if it does not yet exist. * created if it does not yet exist.
@ -294,6 +323,21 @@ guac_ssh_settings* guac_ssh_parse_args(guac_user* user,
guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv, guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_RECORDING_NAME, GUAC_SSH_DEFAULT_RECORDING_NAME); IDX_RECORDING_NAME, GUAC_SSH_DEFAULT_RECORDING_NAME);
/* Parse output exclusion flag */
settings->recording_exclude_output =
guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_RECORDING_EXCLUDE_OUTPUT, false);
/* Parse mouse exclusion flag */
settings->recording_exclude_mouse =
guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_RECORDING_EXCLUDE_MOUSE, false);
/* Parse key event inclusion flag */
settings->recording_include_keys =
guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_RECORDING_INCLUDE_KEYS, false);
/* Parse path creation flag */ /* Parse path creation flag */
settings->create_recording_path = settings->create_recording_path =
guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv, guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,

View File

@ -192,6 +192,32 @@ typedef struct guac_ssh_settings {
*/ */
bool create_recording_path; bool create_recording_path;
/**
* Whether output which is broadcast to each connected client (graphics,
* streams, etc.) should NOT be included in the session recording. Output
* is included by default, as it is necessary for any recording which must
* later be viewable as video.
*/
bool recording_exclude_output;
/**
* Whether changes to mouse state, such as position and buttons pressed or
* released, should NOT be included in the session recording. Mouse state
* is included by default, as it is necessary for the mouse cursor to be
* rendered in any resulting video.
*/
bool recording_exclude_mouse;
/**
* Whether keys pressed and released 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 key events
* may be necessary in certain auditing contexts, but should only be done
* with caution. Key events can easily contain sensitive information, such
* as passwords, credit card numbers, etc.
*/
bool recording_include_keys;
/** /**
* The number of seconds between sending server alive messages. * The number of seconds between sending server alive messages.
*/ */

View File

@ -196,7 +196,10 @@ void* ssh_client_thread(void* data) {
ssh_client->recording = guac_common_recording_create(client, ssh_client->recording = guac_common_recording_create(client,
settings->recording_path, settings->recording_path,
settings->recording_name, settings->recording_name,
settings->create_recording_path); settings->create_recording_path,
!settings->recording_exclude_output,
!settings->recording_exclude_mouse,
settings->recording_include_keys);
} }
/* Create terminal */ /* Create terminal */

View File

@ -45,6 +45,9 @@ const char* GUAC_TELNET_CLIENT_ARGS[] = {
"create-typescript-path", "create-typescript-path",
"recording-path", "recording-path",
"recording-name", "recording-name",
"recording-exclude-output",
"recording-exclude-mouse",
"recording-include-keys",
"create-recording-path", "create-recording-path",
"read-only", "read-only",
NULL NULL
@ -133,6 +136,32 @@ enum TELNET_ARGS_IDX {
*/ */
IDX_RECORDING_NAME, IDX_RECORDING_NAME,
/**
* Whether output which is broadcast to each connected client (graphics,
* streams, etc.) should NOT be included in the session recording. Output
* is included by default, as it is necessary for any recording which must
* later be viewable as video.
*/
IDX_RECORDING_EXCLUDE_OUTPUT,
/**
* Whether changes to mouse state, such as position and buttons pressed or
* released, should NOT be included in the session recording. Mouse state
* is included by default, as it is necessary for the mouse cursor to be
* rendered in any resulting video.
*/
IDX_RECORDING_EXCLUDE_MOUSE,
/**
* Whether keys pressed and released 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 key events
* may be necessary in certain auditing contexts, but should only be done
* with caution. Key events can easily contain sensitive information, such
* as passwords, credit card numbers, etc.
*/
IDX_RECORDING_INCLUDE_KEYS,
/** /**
* Whether the specified screen recording path should automatically be * Whether the specified screen recording path should automatically be
* created if it does not yet exist. * created if it does not yet exist.
@ -279,6 +308,21 @@ guac_telnet_settings* guac_telnet_parse_args(guac_user* user,
guac_user_parse_args_string(user, GUAC_TELNET_CLIENT_ARGS, argv, guac_user_parse_args_string(user, GUAC_TELNET_CLIENT_ARGS, argv,
IDX_RECORDING_NAME, GUAC_TELNET_DEFAULT_RECORDING_NAME); IDX_RECORDING_NAME, GUAC_TELNET_DEFAULT_RECORDING_NAME);
/* Parse output exclusion flag */
settings->recording_exclude_output =
guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,
IDX_RECORDING_EXCLUDE_OUTPUT, false);
/* Parse mouse exclusion flag */
settings->recording_exclude_mouse =
guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,
IDX_RECORDING_EXCLUDE_MOUSE, false);
/* Parse key event inclusion flag */
settings->recording_include_keys =
guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,
IDX_RECORDING_INCLUDE_KEYS, false);
/* Parse path creation flag */ /* Parse path creation flag */
settings->create_recording_path = settings->create_recording_path =
guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv, guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,

View File

@ -181,6 +181,32 @@ typedef struct guac_telnet_settings {
*/ */
bool create_recording_path; bool create_recording_path;
/**
* Whether output which is broadcast to each connected client (graphics,
* streams, etc.) should NOT be included in the session recording. Output
* is included by default, as it is necessary for any recording which must
* later be viewable as video.
*/
bool recording_exclude_output;
/**
* Whether changes to mouse state, such as position and buttons pressed or
* released, should NOT be included in the session recording. Mouse state
* is included by default, as it is necessary for the mouse cursor to be
* rendered in any resulting video.
*/
bool recording_exclude_mouse;
/**
* Whether keys pressed and released 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 key events
* may be necessary in certain auditing contexts, but should only be done
* with caution. Key events can easily contain sensitive information, such
* as passwords, credit card numbers, etc.
*/
bool recording_include_keys;
} guac_telnet_settings; } guac_telnet_settings;
/** /**

View File

@ -470,7 +470,10 @@ void* guac_telnet_client_thread(void* data) {
telnet_client->recording = guac_common_recording_create(client, telnet_client->recording = guac_common_recording_create(client,
settings->recording_path, settings->recording_path,
settings->recording_name, settings->recording_name,
settings->create_recording_path); settings->create_recording_path,
!settings->recording_exclude_output,
!settings->recording_exclude_mouse,
settings->recording_include_keys);
} }
/* Create terminal */ /* Create terminal */

View File

@ -72,6 +72,9 @@ const char* GUAC_VNC_CLIENT_ARGS[] = {
"recording-path", "recording-path",
"recording-name", "recording-name",
"recording-exclude-output",
"recording-exclude-mouse",
"recording-include-keys",
"create-recording-path", "create-recording-path",
NULL NULL
@ -257,6 +260,32 @@ enum VNC_ARGS_IDX {
*/ */
IDX_RECORDING_NAME, IDX_RECORDING_NAME,
/**
* Whether output which is broadcast to each connected client (graphics,
* streams, etc.) should NOT be included in the session recording. Output
* is included by default, as it is necessary for any recording which must
* later be viewable as video.
*/
IDX_RECORDING_EXCLUDE_OUTPUT,
/**
* Whether changes to mouse state, such as position and buttons pressed or
* released, should NOT be included in the session recording. Mouse state
* is included by default, as it is necessary for the mouse cursor to be
* rendered in any resulting video.
*/
IDX_RECORDING_EXCLUDE_MOUSE,
/**
* Whether keys pressed and released 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 key events
* may be necessary in certain auditing contexts, but should only be done
* with caution. Key events can easily contain sensitive information, such
* as passwords, credit card numbers, etc.
*/
IDX_RECORDING_INCLUDE_KEYS,
/** /**
* Whether the specified screen recording path should automatically be * Whether the specified screen recording path should automatically be
* created if it does not yet exist. * created if it does not yet exist.
@ -433,6 +462,21 @@ guac_vnc_settings* guac_vnc_parse_args(guac_user* user,
guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv, guac_user_parse_args_string(user, GUAC_VNC_CLIENT_ARGS, argv,
IDX_RECORDING_NAME, GUAC_VNC_DEFAULT_RECORDING_NAME); IDX_RECORDING_NAME, GUAC_VNC_DEFAULT_RECORDING_NAME);
/* Parse output exclusion flag */
settings->recording_exclude_output =
guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
IDX_RECORDING_EXCLUDE_OUTPUT, false);
/* Parse mouse exclusion flag */
settings->recording_exclude_mouse =
guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
IDX_RECORDING_EXCLUDE_MOUSE, false);
/* Parse key event inclusion flag */
settings->recording_include_keys =
guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
IDX_RECORDING_INCLUDE_KEYS, false);
/* Parse path creation flag */ /* Parse path creation flag */
settings->create_recording_path = settings->create_recording_path =
guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv, guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,

View File

@ -206,6 +206,32 @@ typedef struct guac_vnc_settings {
*/ */
bool create_recording_path; bool create_recording_path;
/**
* Whether output which is broadcast to each connected client (graphics,
* streams, etc.) should NOT be included in the session recording. Output
* is included by default, as it is necessary for any recording which must
* later be viewable as video.
*/
bool recording_exclude_output;
/**
* Whether changes to mouse state, such as position and buttons pressed or
* released, should NOT be included in the session recording. Mouse state
* is included by default, as it is necessary for the mouse cursor to be
* rendered in any resulting video.
*/
bool recording_exclude_mouse;
/**
* Whether keys pressed and released 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 key events
* may be necessary in certain auditing contexts, but should only be done
* with caution. Key events can easily contain sensitive information, such
* as passwords, credit card numbers, etc.
*/
bool recording_include_keys;
} guac_vnc_settings; } guac_vnc_settings;
/** /**

View File

@ -306,7 +306,10 @@ void* guac_vnc_client_thread(void* data) {
vnc_client->recording = guac_common_recording_create(client, vnc_client->recording = guac_common_recording_create(client,
settings->recording_path, settings->recording_path,
settings->recording_name, settings->recording_name,
settings->create_recording_path); settings->create_recording_path,
!settings->recording_exclude_output,
!settings->recording_exclude_mouse,
settings->recording_include_keys);
} }
/* Send name */ /* Send name */