diff options
author | 2016-08-12 08:43:06 +0300 | |
---|---|---|
committer | 2016-08-12 08:43:06 +0300 | |
commit | 702f7b804f940a271b9eca03f70366eae3fe0f60 (patch) | |
tree | 2dc83f629bddf70f0e6419483e914bec126cc6bc /src | |
parent | --x11=xephyr rewrite (diff) | |
download | firejail-702f7b804f940a271b9eca03f70366eae3fe0f60.tar.gz firejail-702f7b804f940a271b9eca03f70366eae3fe0f60.tar.zst firejail-702f7b804f940a271b9eca03f70366eae3fe0f60.zip |
--x11=xpra rewrite
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/x11.c | 118 |
1 files changed, 66 insertions, 52 deletions
diff --git a/src/firejail/x11.c b/src/firejail/x11.c index 9e818ab67..58908e9df 100644 --- a/src/firejail/x11.c +++ b/src/firejail/x11.c | |||
@@ -352,7 +352,7 @@ void x11_start_xephyr(int argc, char **argv) { | |||
352 | 352 | ||
353 | void x11_start_xpra(int argc, char **argv) { | 353 | void x11_start_xpra(int argc, char **argv) { |
354 | EUID_ASSERT(); | 354 | EUID_ASSERT(); |
355 | int i; | 355 | size_t i; |
356 | struct stat s; | 356 | struct stat s; |
357 | pid_t client = 0; | 357 | pid_t client = 0; |
358 | pid_t server = 0; | 358 | pid_t server = 0; |
@@ -374,40 +374,14 @@ void x11_start_xpra(int argc, char **argv) { | |||
374 | } | 374 | } |
375 | 375 | ||
376 | int display = random_display_number(); | 376 | int display = random_display_number(); |
377 | char *display_str; | ||
378 | if (asprintf(&display_str, ":%d", display) == -1) | ||
379 | errExit("asprintf"); | ||
377 | 380 | ||
378 | // build the start command | 381 | // build the start command |
379 | int len = 50; // xpra start... | 382 | char *server_argv[] = { "xpra", "start", display_str, "--no-daemon", NULL }; |
380 | for (i = 0; i < argc; i++) { | ||
381 | len += strlen(argv[i]) + 1; // + ' ' | ||
382 | } | ||
383 | |||
384 | char *cmd1 = malloc(len + 1); // + '\0' | ||
385 | if (!cmd1) | ||
386 | errExit("malloc"); | ||
387 | |||
388 | sprintf(cmd1, "xpra start :%d --exit-with-children --start-child=\"", display); | ||
389 | char *ptr = cmd1 + strlen(cmd1); | ||
390 | for (i = 0; i < argc; i++) { | ||
391 | if (strcmp(argv[i], "--x11") == 0) | ||
392 | continue; | ||
393 | if (strcmp(argv[i], "--x11=xpra") == 0) | ||
394 | continue; | ||
395 | if (strcmp(argv[i], "--x11=xephyr") == 0) | ||
396 | continue; | ||
397 | ptr += sprintf(ptr, "%s ", argv[i]); | ||
398 | } | ||
399 | sprintf(ptr, "\""); | ||
400 | if (arg_debug) | ||
401 | printf("xpra server: %s\n", cmd1); | ||
402 | |||
403 | // build the attach command | ||
404 | char *cmd2; | ||
405 | if (asprintf(&cmd2, "xpra --title=\"firejail x11 sandbox\" attach :%d", display) == -1) | ||
406 | errExit("asprintf"); | ||
407 | if (arg_debug) | ||
408 | printf("xpra client: %s\n", cmd2); | ||
409 | 383 | ||
410 | signal(SIGHUP,SIG_IGN); // fix sleep(1) below | 384 | // start |
411 | server = fork(); | 385 | server = fork(); |
412 | if (server < 0) | 386 | if (server < 0) |
413 | errExit("fork"); | 387 | errExit("fork"); |
@@ -415,13 +389,7 @@ void x11_start_xpra(int argc, char **argv) { | |||
415 | if (arg_debug) | 389 | if (arg_debug) |
416 | printf("Starting xpra...\n"); | 390 | printf("Starting xpra...\n"); |
417 | 391 | ||
418 | char *a[4]; | 392 | execvp(server_argv[0], server_argv); |
419 | a[0] = "/bin/bash"; | ||
420 | a[1] = "-c"; | ||
421 | a[2] = cmd1; | ||
422 | a[3] = NULL; | ||
423 | |||
424 | execvp(a[0], a); | ||
425 | perror("execvp"); | 393 | perror("execvp"); |
426 | exit(1); | 394 | exit(1); |
427 | } | 395 | } |
@@ -437,13 +405,13 @@ void x11_start_xpra(int argc, char **argv) { | |||
437 | if (stat(fname, &s) == 0) | 405 | if (stat(fname, &s) == 0) |
438 | break; | 406 | break; |
439 | }; | 407 | }; |
408 | // sleep(1); | ||
440 | 409 | ||
441 | if (n == 10) { | 410 | if (n == 10) { |
442 | fprintf(stderr, "Error: failed to start xpra\n"); | 411 | fprintf(stderr, "Error: failed to start xpra\n"); |
443 | exit(1); | 412 | exit(1); |
444 | } | 413 | } |
445 | free(fname); | 414 | free(fname); |
446 | sleep(1); | ||
447 | 415 | ||
448 | if (arg_debug) { | 416 | if (arg_debug) { |
449 | printf("X11 sockets: "); fflush(0); | 417 | printf("X11 sockets: "); fflush(0); |
@@ -451,28 +419,74 @@ void x11_start_xpra(int argc, char **argv) { | |||
451 | (void) rv; | 419 | (void) rv; |
452 | } | 420 | } |
453 | 421 | ||
422 | // build attach command | ||
423 | char *attach_argv[] = { "xpra", "--title=\"firejail x11 sandbox\"", "attach", display_str }; | ||
424 | |||
454 | // run attach command | 425 | // run attach command |
455 | client = fork(); | 426 | client = fork(); |
456 | if (client < 0) | 427 | if (client < 0) |
457 | errExit("fork"); | 428 | errExit("fork"); |
458 | if (client == 0) { | 429 | if (client == 0) { |
459 | printf("\n*** Attaching to xpra display %d ***\n\n", display); | 430 | printf("\n*** Attaching to xpra display %d ***\n\n", display); |
460 | char *a[4]; | 431 | execvp(attach_argv[0], attach_argv); |
461 | a[0] = "/bin/bash"; | ||
462 | a[1] = "-c"; | ||
463 | a[2] = cmd2; | ||
464 | a[3] = NULL; | ||
465 | |||
466 | execvp(a[0], a); | ||
467 | perror("execvp"); | 432 | perror("execvp"); |
468 | exit(1); | 433 | exit(1); |
469 | } | 434 | } |
470 | sleep(1); | ||
471 | |||
472 | if (!arg_quiet) | ||
473 | printf("Xpra server pid %d, client pid %d\n", server, client); | ||
474 | 435 | ||
475 | exit(0); | 436 | setenv("DISPLAY", display_str, 1); |
437 | |||
438 | // build jail command | ||
439 | char *firejail_argv[argc+2]; | ||
440 | unsigned pos = 0; | ||
441 | for (i = 0; i < argc; i++) { | ||
442 | if (strcmp(argv[i], "--x11") == 0) | ||
443 | continue; | ||
444 | if (strcmp(argv[i], "--x11=xpra") == 0) | ||
445 | continue; | ||
446 | if (strcmp(argv[i], "--x11=xephyr") == 0) | ||
447 | continue; | ||
448 | firejail_argv[pos] = argv[i]; | ||
449 | pos++; | ||
450 | } | ||
451 | firejail_argv[pos] = NULL; | ||
452 | |||
453 | assert(pos < argc+2); | ||
454 | assert(!firejail_argv[pos]); | ||
455 | |||
456 | // start jail | ||
457 | pid_t jail = fork(); | ||
458 | if (jail < 0) | ||
459 | errExit("fork"); | ||
460 | if (jail == 0) { | ||
461 | execvp(firejail_argv[0], firejail_argv); | ||
462 | perror("execvp"); | ||
463 | exit(1); | ||
464 | } | ||
465 | |||
466 | if (!arg_quiet) | ||
467 | printf("Xpra server pid %d, xpra client pid %d, jail %d\n", server, client, jail); | ||
468 | |||
469 | // wait for jail or server to end | ||
470 | while (1) { | ||
471 | pid_t pid = wait(); | ||
472 | |||
473 | if (pid == jail) { | ||
474 | sleep(3); // FIXME: find better way to wait for xpra | ||
475 | char *stop_argv[] = { "xpra", "stop", display_str, NULL }; | ||
476 | pid_t stop = fork(); | ||
477 | if (stop < 0) | ||
478 | errExit("fork"); | ||
479 | if (stop == 0) { | ||
480 | execvp(stop_argv[0], stop_argv); | ||
481 | perror("execvp"); | ||
482 | exit(1); | ||
483 | } | ||
484 | sleep(3); | ||
485 | kill(client, SIGTERM); | ||
486 | kill(server, SIGTERM); | ||
487 | exit(0); | ||
488 | } | ||
489 | } | ||
476 | } | 490 | } |
477 | 491 | ||
478 | void x11_start(int argc, char **argv) { | 492 | void x11_start(int argc, char **argv) { |