aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-03-26 09:38:27 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2016-03-26 09:38:27 -0400
commitc6fc14e5327c4c13399b1d1e548b92816ac4ac6f (patch)
tree386a5114fc7566a11c98eacb5675fa09887b7e48
parentman page fix (diff)
downloadfirejail-c6fc14e5327c4c13399b1d1e548b92816ac4ac6f.tar.gz
firejail-c6fc14e5327c4c13399b1d1e548b92816ac4ac6f.tar.zst
firejail-c6fc14e5327c4c13399b1d1e548b92816ac4ac6f.zip
x11 xephyr support
-rw-r--r--src/firejail/firejail.h6
-rw-r--r--src/firejail/main.c20
-rw-r--r--src/firejail/usage.c5
-rw-r--r--src/firejail/x11.c200
4 files changed, 210 insertions, 21 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 0e2ae16c2..d729504a2 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -527,10 +527,10 @@ void fs_mkdir(const char *name);
527 527
528// x11.c 528// x11.c
529void fs_x11(void); 529void fs_x11(void);
530void x11_start(int argc, char **argv);
531int x11_display(void); 530int x11_display(void);
532// return 1 if xpra is installed on the system 531void x11_start(int argc, char **argv);
533int x11_check_xpra(void); 532void x11_start_xpra(int argc, char **argv);
533void x11_start_xephyr(int argc, char **argv);
534 534
535// ls.c 535// ls.c
536#define SANDBOX_FS_LS 0 536#define SANDBOX_FS_LS 0
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 1f8907e4c..0269ff585 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -287,6 +287,26 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
287 exit(1); 287 exit(1);
288 } 288 }
289 } 289 }
290 else if (strcmp(argv[i], "--x11=xpra") == 0) {
291 if (checkcfg(CFG_X11)) {
292 x11_start_xpra(argc, argv);
293 exit(0);
294 }
295 else {
296 fprintf(stderr, "Error: --x11 feature is disabled in Firejail configuration file\n");
297 exit(1);
298 }
299 }
300 else if (strcmp(argv[i], "--x11=xephyr") == 0) {
301 if (checkcfg(CFG_X11)) {
302 x11_start_xephyr(argc, argv);
303 exit(0);
304 }
305 else {
306 fprintf(stderr, "Error: --x11 feature is disabled in Firejail configuration file\n");
307 exit(1);
308 }
309 }
290#endif 310#endif
291#ifdef HAVE_NETWORK 311#ifdef HAVE_NETWORK
292 else if (strncmp(argv[i], "--bandwidth=", 12) == 0) { 312 else if (strncmp(argv[i], "--bandwidth=", 12) == 0) {
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index 7bc6ea47a..da5fd4e2f 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -245,7 +245,10 @@ void usage(void) {
245 printf(" --user=new_user - switch the user before starting the sandbox.\n\n"); 245 printf(" --user=new_user - switch the user before starting the sandbox.\n\n");
246 printf(" --version - print program version and exit.\n\n"); 246 printf(" --version - print program version and exit.\n\n");
247 printf(" --whitelist=dirname_or_filename - whitelist directory or file.\n\n"); 247 printf(" --whitelist=dirname_or_filename - whitelist directory or file.\n\n");
248 printf(" --x11 - enable x11 server.\n\n"); 248 printf(" --x11 - enable X11 server. The software checks first if Xpra is installed,\n");
249 printf("\tthen it checks if Xephyr is installed.\n\n");
250 printf(" --x11=xpra - enable Xpra X11 server.\n\n");
251 printf(" --x11=xephyr - enable Xephyr X11 server. The window size is 800x600.\n\n");
249 printf(" --zsh - use /usr/bin/zsh as default shell.\n\n"); 252 printf(" --zsh - use /usr/bin/zsh as default shell.\n\n");
250 printf("\n"); 253 printf("\n");
251 printf("\n"); 254 printf("\n");
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index a7bd9fd29..10e89ea7e 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -27,7 +27,7 @@
27#include <sys/mount.h> 27#include <sys/mount.h>
28 28
29// return 1 if xpra is installed on the system 29// return 1 if xpra is installed on the system
30int x11_check_xpra(void) { 30static int x11_check_xpra(void) {
31 struct stat s; 31 struct stat s;
32 32
33 // check xpra 33 // check xpra
@@ -37,6 +37,42 @@ int x11_check_xpra(void) {
37 return 1; 37 return 1;
38} 38}
39 39
40// return 1 if xephyr is installed on the system
41static int x11_check_xephyr(void) {
42 struct stat s;
43
44 // check xpra
45 if (stat("/usr/bin/Xephyr", &s) == -1)
46 return 0;
47
48 return 1;
49}
50
51static int random_display_number(void) {
52 int i;
53 int found = 1;
54 int display;
55 for (i = 0; i < 100; i++) {
56 display = rand() % 1024;
57 if (display < 10)
58 continue;
59 char *fname;
60 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1)
61 errExit("asprintf");
62 struct stat s;
63 if (stat(fname, &s) == -1) {
64 found = 1;
65 break;
66 }
67 }
68 if (!found) {
69 fprintf(stderr, "Error: cannot pick up a random X11 display number, exiting...\n");
70 exit(1);
71 }
72
73 return display;
74}
75
40// return display number, -1 if not configured 76// return display number, -1 if not configured
41int x11_display(void) { 77int x11_display(void) {
42 // extract display 78 // extract display
@@ -120,7 +156,9 @@ void fs_x11(void) {
120 156
121 157
122#ifdef HAVE_X11 158#ifdef HAVE_X11
123void x11_start(int argc, char **argv) { 159//$ Xephyr -ac -br -noreset -screen 800x600 :22 &
160//$ DISPLAY=:22 firejail --net=eth0 --blacklist=/tmp/.X11-unix/x0 firefox
161void x11_start_xephyr(int argc, char **argv) {
124 EUID_ASSERT(); 162 EUID_ASSERT();
125 int i; 163 int i;
126 struct stat s; 164 struct stat s;
@@ -136,29 +174,129 @@ void x11_start(int argc, char **argv) {
136 174
137 // check xpra 175 // check xpra
138 if (x11_check_xpra() == 0) { 176 if (x11_check_xpra() == 0) {
139 fprintf(stderr, "\nError: Xpra program was not found in /usr/bin directory, please install it:\n"); 177 fprintf(stderr, "\nError: Xephyr program was not found in /usr/bin directory, please install it:\n");
140 fprintf(stderr, " Debian/Ubuntu/Mint: sudo apt-get install xpra\n"); 178 fprintf(stderr, " Debian/Ubuntu/Mint: sudo apt-get install xserver-xephyr\n");
141 exit(0); 179 exit(0);
142 } 180 }
143 181
144 int display; 182 int display = random_display_number();
145 int found = 1; 183
146 for (i = 0; i < 100; i++) { 184 // start xephyr
147 display = rand() % 1024; 185 char *cmd1;
148 if (display < 10) 186 if (asprintf(&cmd1, "Xephyr -ac -br -noreset -screen 800x600 :%d", display) == -1)
187 errExit("asprintf");
188
189 int len = 50; // DISPLAY...
190 for (i = 0; i < argc; i++) {
191 len += strlen(argv[i]) + 1; // + ' '
192 }
193
194 char *cmd2 = malloc(len + 1); // + '\0'
195 if (!cmd2)
196 errExit("malloc");
197
198 sprintf(cmd2, "DISPLAY=:%d ", display);
199 char *ptr = cmd2 + strlen(cmd2);
200 for (i = 0; i < argc; i++) {
201 if (strcmp(argv[i], "--x11") == 0)
149 continue; 202 continue;
150 char *fname; 203 ptr += sprintf(ptr, "%s ", argv[i]);
151 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1) 204 }
152 errExit("asprintf"); 205 if (arg_debug)
153 if (stat(fname, &s) == -1) { 206 printf("xephyr server: %s\n", cmd1);
154 found = 1; 207 if (arg_debug)
208 printf("xephyr client: %s\n", cmd2);
209
210 signal(SIGHUP,SIG_IGN); // fix sleep(1) below
211 server = fork();
212 if (server < 0)
213 errExit("fork");
214 if (server == 0) {
215 if (arg_debug)
216 printf("Starting xpra...\n");
217
218 char *a[4];
219 a[0] = "/bin/bash";
220 a[1] = "-c";
221 a[2] = cmd1;
222 a[3] = NULL;
223
224 execvp(a[0], a);
225 perror("execvp");
226 exit(1);
227 }
228
229 // check X11 socket
230 char *fname;
231 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1)
232 errExit("asprintf");
233 int n = 0;
234 // wait for x11 server to start
235 while (++n < 10) {
236 sleep(1);
237 if (stat(fname, &s) == 0)
155 break; 238 break;
156 } 239 };
240
241 if (n == 10) {
242 fprintf(stderr, "Error: failed to start xpra\n");
243 exit(1);
157 } 244 }
158 if (!found) { 245 free(fname);
159 fprintf(stderr, "Error: cannot pick up a random X11 display number, exiting...\n"); 246 sleep(1);
247
248 if (arg_debug) {
249 printf("X11 sockets: "); fflush(0);
250 int rv = system("ls /tmp/.X11-unix");
251 (void) rv;
252 }
253
254 // run attach command
255 client = fork();
256 if (client < 0)
257 errExit("fork");
258 if (client == 0) {
259 printf("\n*** Attaching to Xephyr display %d ***\n\n", display);
260 char *a[4];
261 a[0] = "/bin/bash";
262 a[1] = "-c";
263 a[2] = cmd2;
264 a[3] = NULL;
265
266 execvp(a[0], a);
267 perror("execvp");
160 exit(1); 268 exit(1);
161 } 269 }
270 sleep(1);
271
272 if (!arg_quiet)
273 printf("Xphyr server pid %d, client pid %d\n", server, client);
274
275 exit(0);
276}
277
278void x11_start_xpra(int argc, char **argv) {
279 EUID_ASSERT();
280 int i;
281 struct stat s;
282 pid_t client = 0;
283 pid_t server = 0;
284
285
286 // unfortunately, xpra does a number of wired things when started by root user!!!
287 if (getuid() == 0) {
288 fprintf(stderr, "Error: this feature is not available when running as root\n");
289 exit(1);
290 }
291
292 // check xpra
293 if (x11_check_xpra() == 0) {
294 fprintf(stderr, "\nError: Xpra program was not found in /usr/bin directory, please install it:\n");
295 fprintf(stderr, " Debian/Ubuntu/Mint: sudo apt-get install xpra\n");
296 exit(0);
297 }
298
299 int display = random_display_number();
162 300
163 // build the start command 301 // build the start command
164 int len = 50; // xpra start... 302 int len = 50; // xpra start...
@@ -255,4 +393,32 @@ void x11_start(int argc, char **argv) {
255 393
256 exit(0); 394 exit(0);
257} 395}
396
397void x11_start(int argc, char **argv) {
398 EUID_ASSERT();
399 int i;
400 struct stat s;
401 pid_t client = 0;
402 pid_t server = 0;
403
404
405 // unfortunately, xpra does a number of wired things when started by root user!!!
406 if (getuid() == 0) {
407 fprintf(stderr, "Error: this feature is not available when running as root\n");
408 exit(1);
409 }
410
411 // check xpra
412 if (x11_check_xpra() == 1)
413 x11_start_xpra(argc, argv);
414 else if (x11_check_xephyr() == 1)
415 x11_start_xephyr(argc, argv);
416 else {
417 fprintf(stderr, "\nError: Xpra or Xephyr not found in /usr/bin directory, please install one of them:\n");
418 fprintf(stderr, " Debian/Ubuntu/Mint: sudo apt-get install xpra\n");
419 fprintf(stderr, " Debian/Ubuntu/Mint: sudo apt-get install xserver-xephyr\n");
420 exit(0);
421 }
422}
423
258#endif 424#endif