@@ -880,6 +880,7 @@ static void save_clipboard_metadata(struct clipboard_metadata *metadata) {
880880 fprintf (file , "\"buffer_size\":%d,\n" , metadata -> buffer_size );
881881 fprintf (file , "\"protocol_version_xside\":%d,\n" , metadata -> protocol_version_xside );
882882 fprintf (file , "\"protocol_version_vmside\":%d\n" , metadata -> protocol_version_vmside );
883+ fprintf (file , "\"timeout\":%d\n" , metadata -> timeout );
883884 // other key,value pairs could be added if needed in future
884885 fprintf (file , "}\n" );
885886 fclose (file );
@@ -959,6 +960,8 @@ static bool load_clipboard_metadata(struct clipboard_metadata *metadata, bool lo
959960 metadata -> protocol_version_vmside = dummy ;
960961 } else if (strcmp (key , "protocol_version_xside" ) == 0 ) {
961962 metadata -> protocol_version_xside = dummy ;
963+ } else if (strcmp (key , "timeout" ) == 0 ) {
964+ metadata -> timeout = dummy ;
962965 }
963966 }
964967 fclose (file );
@@ -1219,6 +1222,13 @@ static void handle_clipboard_data(Ghandles * g, unsigned int untrusted_len)
12191222 metadata .protocol_version_vmside = g -> protocol_version ;
12201223 metadata .protocol_version_xside = PROTOCOL_VERSION (
12211224 PROTOCOL_VERSION_MAJOR , PROTOCOL_VERSION_MINOR );
1225+ metadata .timeout = g -> clipboard_timeout ;
1226+
1227+ // if a clipboard timeout child is pending, terminate it and clear its PID.
1228+ if (g -> clipboard_timeout_pid ) {
1229+ kill (g -> clipboard_timeout_pid , SIGTERM );
1230+ g -> clipboard_timeout_pid = 0 ;
1231+ }
12221232
12231233 if (g -> log_level > 0 )
12241234 fprintf (stderr , "handle_clipboard_data, len=0x%x\n" ,
@@ -1301,6 +1311,42 @@ static void handle_clipboard_data(Ghandles * g, unsigned int untrusted_len)
13011311 save_clipboard_file_xevent_timestamp (g -> clipboard_xevent_time );
13021312 metadata .successful = true;
13031313 save_clipboard_metadata (& metadata );
1314+
1315+ if (g -> clipboard_timeout > 0 ) {
1316+ struct stat st0 , st1 ;
1317+ if (lstat (QUBES_CLIPBOARD_FILENAME , & st0 ) == -1 ) {
1318+ perror ("Can not get clipboard data file status" );
1319+ exit (1 );
1320+ }
1321+ switch (g -> clipboard_timeout_pid = fork ()) {
1322+ case -1 :
1323+ perror ("fork" );
1324+ exit (1 );
1325+ case 0 :
1326+ if (sleep (g -> clipboard_timeout ) != 0 ) {
1327+ perror ("Clipboard clearing timeout was interrupted" );
1328+ _exit (1 );
1329+ }
1330+ inter_appviewer_lock (g , 1 );
1331+ if (lstat (QUBES_CLIPBOARD_FILENAME , & st1 ) == -1 ) {
1332+ perror ("Can not get clipboard data file status" );
1333+ _exit (1 );
1334+ }
1335+ if (st0 .st_mtime == st1 .st_mtime ) {
1336+ old_umask = umask (0007 );
1337+ metadata .copy_action = false;
1338+ metadata .timeout = g -> clipboard_timeout ;
1339+ clear_clipboard (& metadata );
1340+ umask (old_umask );
1341+ if (g -> log_level > 1 )
1342+ fprintf (stderr , "Clipboard cleared after %d seconds\n" ,
1343+ g -> clipboard_timeout );
1344+ }
1345+ inter_appviewer_lock (g , 0 );
1346+ _exit (1 );
1347+ }
1348+ }
1349+
13041350error :
13051351 umask (old_umask );
13061352 inter_appviewer_lock (g , 0 );
@@ -4494,6 +4540,8 @@ static void load_default_config_values(Ghandles * g)
44944540 g -> paste_seq_mask = ControlMask | ShiftMask ;
44954541 g -> paste_seq_key = XK_v ;
44964542 g -> clipboard_buffer_size = DEFAULT_CLIPBOARD_BUFFER_SIZE ;
4543+ g -> clipboard_timeout = 0 ;
4544+ g -> clipboard_timeout_pid = 0 ;
44974545 g -> allow_fullscreen = 0 ;
44984546 g -> override_redirect_protection = 1 ;
44994547 g -> startup_timeout = 45 ;
@@ -4588,6 +4636,11 @@ static void parse_vm_config(Ghandles * g, config_setting_t * group)
45884636 }
45894637 }
45904638
4639+ if ((setting =
4640+ config_setting_get_member (group , "clipboard_timeout" ))) {
4641+ g -> clipboard_timeout = config_setting_get_int (setting );
4642+ }
4643+
45914644 if ((setting =
45924645 config_setting_get_member (group , "allow_utf8_titles" ))) {
45934646 g -> allow_utf8_titles = config_setting_get_bool (setting );
@@ -4976,6 +5029,8 @@ int main(int argc, char **argv)
49765029 ebuf_release_xevents (& ghandles );
49775030 }
49785031 } while (busy );
5032+ if (ghandles .clipboard_timeout_pid > 0 )
5033+ kill (ghandles .clipboard_timeout_pid , SIGTERM );
49795034 if (ghandles .ebuf_max_delay > 0 ) {
49805035 wait_for_vchan_or_argfd_once (ghandles .vchan , xfd , ghandles .ebuf_next_timeout );
49815036 } else {
0 commit comments