From 4c93a7bcce5f0754ade89593cf912bf67dc6f550 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Mon, 8 May 2017 15:28:59 -0400 Subject: merge #1100 from zackw: support for Xpra extra params in firejail config file --- RELNOTES | 1 + etc/firejail.config | 4 ++ src/firejail/checkcfg.c | 14 ++++++- src/firejail/firejail.h | 1 + src/firejail/x11.c | 101 +++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 105 insertions(+), 16 deletions(-) diff --git a/RELNOTES b/RELNOTES index 33088dfe5..ccd841e27 100644 --- a/RELNOTES +++ b/RELNOTES @@ -34,6 +34,7 @@ firejail (0.9.46-rc1) baseline; urgency=low * feature: --fix-sound support in firecfg * feature: added support for sandboxing Xpra, Xvfb and Xephyr in independent sandboxes when started with firejail --x11 + * feature: support for Xpra extra params in firejail config file * new profiles: xiphos, Tor Browser Bundle, display (imagemagick), Wire, * new profiles: mumble, zoom, Guayadeque, qemu, keypass2, xed, pluma, * new profiles: Cryptocat, Bless, Gnome 2048, Gnome Calculator, diff --git a/etc/firejail.config b/etc/firejail.config index 537ac9b38..1db33edda 100644 --- a/etc/firejail.config +++ b/etc/firejail.config @@ -100,6 +100,10 @@ # xephyr-extra-params -keybd ephyr,,,xkbmodel=evdev # xephyr-extra-params -grayscale +# Xpra server command extra parameters. None by default; this is an example. +# xpra-extra-params --dpi 96 + + # Screen size for --x11=xvfb, default 800x600x24. The third dimension is # color depth; use 24 unless you know exactly what you're doing. # xvfb-screen 640x480x24 diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index 24d8d0381..3c0c1b9ac 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c @@ -27,6 +27,7 @@ static int initialized = 0; static int cfg_val[CFG_MAX]; char *xephyr_screen = "800x600"; char *xephyr_extra_params = ""; +char *xpra_extra_params = ""; char *xvfb_screen = "800x600x24"; char *xvfb_extra_params = ""; char *netfilter_default = NULL; @@ -248,14 +249,23 @@ int checkcfg(int val) { } // Xephyr command extra parameters - else if (strncmp(ptr, "xephyr-extra-params ", 19) == 0) { + else if (strncmp(ptr, "xephyr-extra-params ", 20) == 0) { if (*xephyr_extra_params != '\0') goto errout; - xephyr_extra_params = strdup(ptr + 19); + xephyr_extra_params = strdup(ptr + 20); if (!xephyr_extra_params) errExit("strdup"); } + // xpra server extra parameters + else if (strncmp(ptr, "xpra-extra-params ", 18) == 0) { + if (*xpra_extra_params != '\0') + goto errout; + xpra_extra_params = strdup(ptr + 18); + if (!xpra_extra_params) + errExit("strdup"); + } + // Xvfb screen size else if (strncmp(ptr, "xvfb-screen ", 12) == 0) { // expecting three numbers separated by x's diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 09fadcf34..6b1786a93 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -692,6 +692,7 @@ enum { }; extern char *xephyr_screen; extern char *xephyr_extra_params; +extern char *xpra_extra_params; extern char *xvfb_screen; extern char *xvfb_extra_params; extern char *netfilter_default; diff --git a/src/firejail/x11.c b/src/firejail/x11.c index da881f344..0f7ea56b6 100644 --- a/src/firejail/x11.c +++ b/src/firejail/x11.c @@ -239,8 +239,8 @@ void x11_start_xvfb(int argc, char **argv) { // parse xvfb_extra_params // very basic quoting support - char *temp = strdup(xephyr_extra_params); - if (*xephyr_extra_params != '\0') { + char *temp = strdup(xvfb_extra_params); + if (*xvfb_extra_params != '\0') { if (!temp) errExit("strdup"); bool dquote = false; @@ -267,6 +267,7 @@ void x11_start_xvfb(int argc, char **argv) { exit(1); } + server_argv[pos++] = temp; for (i = 0; i < (int) strlen(xvfb_extra_params)-1; i++) { if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { fprintf(stderr, "Error: arg count limit exceeded while parsing xvfb_extra_params\n"); @@ -284,12 +285,12 @@ void x11_start_xvfb(int argc, char **argv) { if (arg_debug) { size_t i = 0; - printf("xvfb server:"); + printf("\n*** Starting xvfb server:"); while (server_argv[i]!=NULL) { printf(" \"%s\"", server_argv[i]); i++; } - putchar('\n'); + printf(" ***\n\n"); } // remove --x11 arg @@ -307,12 +308,12 @@ void x11_start_xvfb(int argc, char **argv) { if (arg_debug) { size_t i = 0; - printf("xvfb client:"); + printf("\n*** Stating xvfb client:"); while (jail_argv[i]!=NULL) { printf(" \"%s\"", jail_argv[i]); i++; } - putchar('\n'); + printf(" ***\n\n"); } server = fork(); @@ -471,13 +472,18 @@ void x11_start_xephyr(int argc, char **argv) { exit(1); } + server_argv[pos++] = temp; for (i = 0; i < (int) strlen(xephyr_extra_params)-1; i++) { if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { fprintf(stderr, "Error: arg count limit exceeded while parsing xephyr_extra_params\n"); exit(1); } - if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) server_argv[pos++] = temp + i + 2; - else if (temp[i] == '\0' && temp[i+1] != '\0') server_argv[pos++] = temp + i + 1; + if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) { + server_argv[pos++] = temp + i + 2; + } + else if (temp[i] == '\0' && temp[i+1] != '\0') { + server_argv[pos++] = temp + i + 1; + } } } @@ -490,12 +496,12 @@ void x11_start_xephyr(int argc, char **argv) { if (arg_debug) { size_t i = 0; - printf("xephyr server:"); + printf("\n*** Starting xephyr server:"); while (server_argv[i]!=NULL) { printf(" \"%s\"", server_argv[i]); i++; } - putchar('\n'); + printf(" ***\n\n"); } // remove --x11 arg @@ -513,12 +519,12 @@ void x11_start_xephyr(int argc, char **argv) { if (arg_debug) { size_t i = 0; - printf("xephyr client:"); + printf("*** Starting xephyr client:"); while (jail_argv[i]!=NULL) { printf(" \"%s\"", jail_argv[i]); i++; } - putchar('\n'); + printf(" ***\n\n"); } server = fork(); @@ -631,7 +637,74 @@ void x11_start_xpra(int argc, char **argv) { errExit("asprintf"); // build the start command - char *server_argv[] = { "xpra", "start", display_str, "--no-daemon", NULL }; + char *server_argv[256] = { // rest initialyzed to NULL + "xpra", "start", display_str, "--no-daemon", + }; + unsigned pos = 0; + while (server_argv[pos] != NULL) pos++; + + assert(xpra_extra_params); // should be "" if empty + + // parse xephyr_extra_params + // very basic quoting support + char *temp = strdup(xpra_extra_params); + if (*xpra_extra_params != '\0') { + if (!temp) + errExit("strdup"); + bool dquote = false; + bool squote = false; + for (i = 0; i < (int) strlen(xpra_extra_params); i++) { + if (temp[i] == '\"') { + dquote = !dquote; + // replace closing quote by \0 + if (dquote) temp[i] = '\0'; + } + if (temp[i] == '\'') { + squote = !squote; + // replace closing quote by \0 + if (squote) temp[i] = '\0'; + } + if (!dquote && !squote && temp[i] == ' ') temp[i] = '\0'; + if (dquote && squote) { + fprintf(stderr, "Error: mixed quoting found while parsing xpra_extra_params\n"); + exit(1); + } + } + if (dquote) { + fprintf(stderr, "Error: unclosed quote found while parsing xpra_extra_params\n"); + exit(1); + } + + server_argv[pos++] = temp; + for (i = 0; i < (int) strlen(xpra_extra_params)-1; i++) { + if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { + fprintf(stderr, "Error: arg count limit exceeded while parsing xpra_extra_params\n"); + exit(1); + } + if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) { + server_argv[pos++] = temp + i + 2; + } + else if (temp[i] == '\0' && temp[i+1] != '\0') { + server_argv[pos++] = temp + i + 1; + } + } + } + + server_argv[pos++] = NULL; + + // no overrun + assert(pos < (sizeof(server_argv)/sizeof(*server_argv))); + assert(server_argv[pos-1] == NULL); // last element is null + + if (arg_debug) { + size_t i = 0; + printf("\n*** Starting xpra server: "); + while (server_argv[i]!=NULL) { + printf(" \"%s\"", server_argv[i]); + i++; + } + printf(" ***\n\n"); + } int fd_null = -1; if (arg_quiet) { @@ -716,7 +789,7 @@ void x11_start_xpra(int argc, char **argv) { // build jail command char *firejail_argv[argc+2]; - int pos = 0; + pos = 0; for (i = 0; i < argc; i++) { if (strncmp(argv[i], "--x11", 5) == 0) continue; -- cgit v1.2.3-70-g09d2