Skip to content

Commit 7553e79

Browse files
authored
GUACAMOLE-1931: Merge addition of configuration option to allow overwriting recording files.
2 parents 3782339 + 2844a7d commit 7553e79

File tree

17 files changed

+126
-20
lines changed

17 files changed

+126
-20
lines changed

src/libguac/guacamole/recording.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ typedef struct guac_recording {
148148
* caution. Key events can easily contain sensitive information, such as
149149
* passwords, credit card numbers, etc.
150150
*
151+
* @param allow_write_existing
152+
* Non-zero if writing to an existing file should be allowed, or zero
153+
* otherwise.
154+
*
151155
* @return
152156
* A new guac_recording structure representing the in-progress
153157
* recording if the recording file has been successfully created and a
@@ -156,7 +160,7 @@ typedef struct guac_recording {
156160
guac_recording* guac_recording_create(guac_client* client,
157161
const char* path, const char* name, int create_path,
158162
int include_output, int include_mouse, int include_touch,
159-
int include_keys);
163+
int include_keys, int allow_write_existing);
160164

161165
/**
162166
* Frees the resources associated with the given in-progress recording. Note

src/libguac/recording.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,13 @@
3939

4040
/**
4141
* Attempts to open a new recording within the given path and having the given
42-
* name. If such a file already exists, sequential numeric suffixes (.1, .2,
43-
* .3, etc.) are appended until a filename is found which does not exist (or
44-
* until the maximum number of numeric suffixes has been tried). If the file
45-
* absolutely cannot be opened due to an error, -1 is returned and errno is set
46-
* appropriately.
42+
* name. If opening the file fails for any reason, or if such a file already
43+
* exists and allow_write_existing is not set, sequential numeric suffixes
44+
* (.1, .2, .3, etc.) are appended until a filename is found which does not
45+
* exist (or until the maximum number of numeric suffixes has been tried).
46+
* If the file exists and allow_write_existing is set, the recording will be
47+
* appended to any existing file contents. If the file absolutely cannot be
48+
* opened due to an error, -1 is returned and errno is set appropriately.
4749
*
4850
* @param path
4951
* The full path to the directory in which the data file should be created.
@@ -60,12 +62,17 @@
6062
* @param basename_size
6163
* The number of bytes available within the provided basename buffer.
6264
*
65+
* @param allow_write_existing
66+
* Non-zero if writing to an existing file should be allowed, or zero
67+
* otherwise.
68+
*
6369
* @return
6470
* The file descriptor of the open data file if open succeeded, or -1 on
6571
* failure.
6672
*/
6773
static int guac_recording_open(const char* path,
68-
const char* name, char* basename, int basename_size) {
74+
const char* name, char* basename, int basename_size,
75+
int allow_write_existing) {
6976

7077
int i;
7178

@@ -81,10 +88,11 @@ static int guac_recording_open(const char* path,
8188
return -1;
8289
}
8390

91+
/* Require the file not exist already if allow_write_existing not set */
92+
int flags = O_CREAT | O_WRONLY | (allow_write_existing ? 0 : O_EXCL);
93+
8494
/* Attempt to open recording */
85-
int fd = open(basename,
86-
O_CREAT | O_EXCL | O_WRONLY,
87-
S_IRUSR | S_IWUSR | S_IRGRP);
95+
int fd = open(basename, flags, S_IRUSR | S_IWUSR | S_IRGRP);
8896

8997
/* Continuously retry with alternate names on failure */
9098
if (fd == -1) {
@@ -101,9 +109,7 @@ static int guac_recording_open(const char* path,
101109
sprintf(suffix, "%i", i);
102110

103111
/* Retry with newly-suffixed filename */
104-
fd = open(basename,
105-
O_CREAT | O_EXCL | O_WRONLY,
106-
S_IRUSR | S_IWUSR | S_IRGRP);
112+
fd = open(basename, flags, S_IRUSR | S_IWUSR | S_IRGRP);
107113

108114
}
109115

@@ -138,7 +144,7 @@ static int guac_recording_open(const char* path,
138144
guac_recording* guac_recording_create(guac_client* client,
139145
const char* path, const char* name, int create_path,
140146
int include_output, int include_mouse, int include_touch,
141-
int include_keys) {
147+
int include_keys, int allow_write_existing) {
142148

143149
char filename[GUAC_COMMON_RECORDING_MAX_NAME_LENGTH];
144150

@@ -155,7 +161,8 @@ guac_recording* guac_recording_create(guac_client* client,
155161
}
156162

157163
/* Attempt to open recording file */
158-
int fd = guac_recording_open(path, name, filename, sizeof(filename));
164+
int fd = guac_recording_open(
165+
path, name, filename, sizeof(filename), allow_write_existing);
159166
if (fd == -1) {
160167
guac_client_log(client, GUAC_LOG_ERROR,
161168
"Creation of recording failed: %s", strerror(errno));

src/protocols/kubernetes/kubernetes.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ void* guac_kubernetes_client_thread(void* data) {
237237
!settings->recording_exclude_output,
238238
!settings->recording_exclude_mouse,
239239
0, /* Touch events not supported */
240-
settings->recording_include_keys);
240+
settings->recording_include_keys,
241+
settings->recording_write_existing);
241242
}
242243

243244
/* Create terminal options with required parameters */

src/protocols/kubernetes/settings.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const char* GUAC_KUBERNETES_CLIENT_ARGS[] = {
5151
"recording-exclude-mouse",
5252
"recording-include-keys",
5353
"create-recording-path",
54+
"recording-write-existing",
5455
"read-only",
5556
"backspace",
5657
"scrollback",
@@ -210,6 +211,12 @@ enum KUBERNETES_ARGS_IDX {
210211
*/
211212
IDX_CREATE_RECORDING_PATH,
212213

214+
/**
215+
* Whether existing files should be appended to when creating a new recording.
216+
* Disabled by default.
217+
*/
218+
IDX_RECORDING_WRITE_EXISTING,
219+
213220
/**
214221
* "true" if this connection should be read-only (user input should be
215222
* dropped), "false" or blank otherwise.
@@ -389,6 +396,11 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user,
389396
guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
390397
IDX_CREATE_RECORDING_PATH, false);
391398

399+
/* Parse allow write existing file flag */
400+
settings->recording_write_existing =
401+
guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
402+
IDX_RECORDING_WRITE_EXISTING, false);
403+
392404
/* Parse backspace key code */
393405
settings->backspace =
394406
guac_user_parse_args_int(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,

src/protocols/kubernetes/settings.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,12 @@ typedef struct guac_kubernetes_settings {
234234
*/
235235
bool recording_include_keys;
236236

237+
/**
238+
* Whether existing files should be appended to when creating a new recording.
239+
* Disabled by default.
240+
*/
241+
bool recording_write_existing;
242+
237243
/**
238244
* The ASCII code, as an integer, that the Kubernetes client will use when
239245
* the backspace key is pressed. By default, this is 127, ASCII delete, if

src/protocols/rdp/rdp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,8 @@ void* guac_rdp_client_thread(void* data) {
841841
!settings->recording_exclude_output,
842842
!settings->recording_exclude_mouse,
843843
!settings->recording_exclude_touch,
844-
settings->recording_include_keys);
844+
settings->recording_include_keys,
845+
settings->recording_write_existing);
845846
}
846847

847848
/* Continue handling connections until error or client disconnect */

src/protocols/rdp/settings.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ const char* GUAC_RDP_CLIENT_ARGS[] = {
122122
"recording-exclude-touch",
123123
"recording-include-keys",
124124
"create-recording-path",
125+
"recording-write-existing",
125126
"resize-method",
126127
"enable-audio-input",
127128
"enable-touch",
@@ -564,6 +565,12 @@ enum RDP_ARGS_IDX {
564565
*/
565566
IDX_CREATE_RECORDING_PATH,
566567

568+
/**
569+
* Whether existing files should be appended to when creating a new recording.
570+
* Disabled by default.
571+
*/
572+
IDX_RECORDING_WRITE_EXISTING,
573+
567574
/**
568575
* The method to use to apply screen size changes requested by the user.
569576
* Valid values are blank, "display-update", and "reconnect".
@@ -1161,6 +1168,11 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user,
11611168
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
11621169
IDX_CREATE_RECORDING_PATH, 0);
11631170

1171+
/* Parse allow write existing file flag */
1172+
settings->recording_write_existing =
1173+
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
1174+
IDX_RECORDING_WRITE_EXISTING, 0);
1175+
11641176
/* No resize method */
11651177
if (strcmp(argv[IDX_RESIZE_METHOD], "") == 0) {
11661178
guac_user_log(user, GUAC_LOG_INFO, "Resize method: none");

src/protocols/rdp/settings.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,12 @@ typedef struct guac_rdp_settings {
560560
int recording_include_keys;
561561

562562
/**
563+
* Non-zero if existing files should be appended to when creating a new
564+
* recording. Disabled by default.
565+
*/
566+
int recording_write_existing;
567+
568+
/**
563569
* The method to apply when the user's display changes size.
564570
*/
565571
guac_rdp_resize_method resize_method;

src/protocols/ssh/settings.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const char* GUAC_SSH_CLIENT_ARGS[] = {
6363
"recording-exclude-mouse",
6464
"recording-include-keys",
6565
"create-recording-path",
66+
"recording-write-existing",
6667
"read-only",
6768
"server-alive-interval",
6869
"backspace",
@@ -241,6 +242,12 @@ enum SSH_ARGS_IDX {
241242
*/
242243
IDX_CREATE_RECORDING_PATH,
243244

245+
/**
246+
* Whether existing files should be appended to when creating a new recording.
247+
* Disabled by default.
248+
*/
249+
IDX_RECORDING_WRITE_EXISTING,
250+
244251
/**
245252
* "true" if this connection should be read-only (user input should be
246253
* dropped), "false" or blank otherwise.
@@ -495,6 +502,11 @@ guac_ssh_settings* guac_ssh_parse_args(guac_user* user,
495502
guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
496503
IDX_CREATE_RECORDING_PATH, false);
497504

505+
/* Parse allow write existing file flag */
506+
settings->recording_write_existing =
507+
guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
508+
IDX_RECORDING_WRITE_EXISTING, false);
509+
498510
/* Parse server alive interval */
499511
settings->server_alive_interval =
500512
guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv,

src/protocols/ssh/settings.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,12 @@ typedef struct guac_ssh_settings {
251251
*/
252252
bool recording_include_keys;
253253

254+
/**
255+
* Whether existing files should be appended to when creating a new recording.
256+
* Disabled by default.
257+
*/
258+
bool recording_write_existing;
259+
254260
/**
255261
* The number of seconds between sending server alive messages.
256262
*/

src/protocols/ssh/ssh.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,8 @@ void* ssh_client_thread(void* data) {
264264
!settings->recording_exclude_output,
265265
!settings->recording_exclude_mouse,
266266
0, /* Touch events not supported */
267-
settings->recording_include_keys);
267+
settings->recording_include_keys,
268+
settings->recording_write_existing);
268269
}
269270

270271
/* Create terminal options with required parameters */

src/protocols/telnet/settings.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ const char* GUAC_TELNET_CLIENT_ARGS[] = {
5555
"recording-exclude-mouse",
5656
"recording-include-keys",
5757
"create-recording-path",
58+
"recording-write-existing",
5859
"read-only",
5960
"backspace",
6061
"terminal-type",
@@ -193,6 +194,12 @@ enum TELNET_ARGS_IDX {
193194
*/
194195
IDX_CREATE_RECORDING_PATH,
195196

197+
/**
198+
* Whether existing files should be appended to when creating a new recording.
199+
* Disabled by default.
200+
*/
201+
IDX_RECORDING_WRITE_EXISTING,
202+
196203
/**
197204
* "true" if this connection should be read-only (user input should be
198205
* dropped), "false" or blank otherwise.
@@ -486,6 +493,11 @@ guac_telnet_settings* guac_telnet_parse_args(guac_user* user,
486493
guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,
487494
IDX_CREATE_RECORDING_PATH, false);
488495

496+
/* Parse allow write existing file flag */
497+
settings->recording_write_existing =
498+
guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,
499+
IDX_RECORDING_WRITE_EXISTING, false);
500+
489501
/* Parse backspace key code */
490502
settings->backspace =
491503
guac_user_parse_args_int(user, GUAC_TELNET_CLIENT_ARGS, argv,

src/protocols/telnet/settings.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,12 @@ typedef struct guac_telnet_settings {
239239
*/
240240
bool recording_include_keys;
241241

242+
/**
243+
* Whether existing files should be appended to when creating a new recording.
244+
* Disabled by default.
245+
*/
246+
bool recording_write_existing;
247+
242248
/**
243249
* The ASCII code, as an integer, that the telnet client will use when the
244250
* backspace key is pressed. By default, this is 127, ASCII delete, if

src/protocols/telnet/telnet.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,8 @@ void* guac_telnet_client_thread(void* data) {
606606
!settings->recording_exclude_output,
607607
!settings->recording_exclude_mouse,
608608
0, /* Touch events not supported */
609-
settings->recording_include_keys);
609+
settings->recording_include_keys,
610+
settings->recording_write_existing);
610611
}
611612

612613
/* Create terminal options with required parameters */

src/protocols/vnc/settings.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ const char* GUAC_VNC_CLIENT_ARGS[] = {
8484
"recording-exclude-mouse",
8585
"recording-include-keys",
8686
"create-recording-path",
87+
"recording-write-existing",
8788
"disable-copy",
8889
"disable-paste",
8990

@@ -331,6 +332,12 @@ enum VNC_ARGS_IDX {
331332
*/
332333
IDX_CREATE_RECORDING_PATH,
333334

335+
/**
336+
* Whether existing files should be appended to when creating a new recording.
337+
* Disabled by default.
338+
*/
339+
IDX_RECORDING_WRITE_EXISTING,
340+
334341
/**
335342
* Whether outbound clipboard access should be blocked. If set to "true",
336343
* it will not be possible to copy data from the remote desktop to the
@@ -594,6 +601,11 @@ guac_vnc_settings* guac_vnc_parse_args(guac_user* user,
594601
guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
595602
IDX_CREATE_RECORDING_PATH, false);
596603

604+
/* Parse allow write existing file flag */
605+
settings->recording_write_existing =
606+
guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
607+
IDX_RECORDING_WRITE_EXISTING, false);
608+
597609
/* Parse clipboard copy disable flag */
598610
settings->disable_copy =
599611
guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,

src/protocols/vnc/settings.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,12 @@ typedef struct guac_vnc_settings {
274274
* as passwords, credit card numbers, etc.
275275
*/
276276
bool recording_include_keys;
277+
278+
/**
279+
* Whether existing files should be appended to when creating a new recording.
280+
* Disabled by default.
281+
*/
282+
bool recording_write_existing;
277283

278284
/**
279285
* Whether or not to send the magic Wake-on-LAN (WoL) packet prior to

src/protocols/vnc/vnc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,8 @@ void* guac_vnc_client_thread(void* data) {
428428
!settings->recording_exclude_output,
429429
!settings->recording_exclude_mouse,
430430
0, /* Touch events not supported */
431-
settings->recording_include_keys);
431+
settings->recording_include_keys,
432+
settings->recording_write_existing);
432433
}
433434

434435
/* Create display */

0 commit comments

Comments
 (0)