aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/firecfg/main.c85
-rw-r--r--src/man/firecfg.txt21
-rw-r--r--src/man/firejail.txt2
3 files changed, 63 insertions, 45 deletions
diff --git a/src/firecfg/main.c b/src/firecfg/main.c
index 6b69dd130..04ccbf2c3 100644
--- a/src/firecfg/main.c
+++ b/src/firecfg/main.c
@@ -29,6 +29,8 @@
29#include <string.h> 29#include <string.h>
30#include <errno.h> 30#include <errno.h>
31#include <sys/mman.h> 31#include <sys/mman.h>
32#include <pwd.h>
33
32#include "../include/common.h" 34#include "../include/common.h"
33static int arg_debug = 0; 35static int arg_debug = 0;
34 36
@@ -45,7 +47,6 @@ static void usage(void) {
45 printf(" --debug - print debug messages.\n\n"); 47 printf(" --debug - print debug messages.\n\n");
46 printf(" --help, -? - this help screen.\n\n"); 48 printf(" --help, -? - this help screen.\n\n");
47 printf(" --list - list all firejail symbolic links.\n\n"); 49 printf(" --list - list all firejail symbolic links.\n\n");
48 printf(" --fix - fix .desktop files.\n\n");
49 printf(" --version - print program version and exit.\n\n"); 50 printf(" --version - print program version and exit.\n\n");
50 printf("Example:\n\n"); 51 printf("Example:\n\n");
51 printf(" $ sudo firecfg\n"); 52 printf(" $ sudo firecfg\n");
@@ -60,10 +61,6 @@ static void usage(void) {
60 printf(" /usr/local/bin/firefox removed\n"); 61 printf(" /usr/local/bin/firefox removed\n");
61 printf(" /usr/local/bin/vlc removed\n"); 62 printf(" /usr/local/bin/vlc removed\n");
62 printf(" [...]\n"); 63 printf(" [...]\n");
63 printf(" $ firecfg --fix\n");
64 printf(" /home/user/.local/share/applications/chromium.desktop created\n");
65 printf(" /home/user/.local/share/applications/vlc.desktop created\n");
66 printf(" [...]\n");
67 printf("\n"); 64 printf("\n");
68 printf("License GPL version 2 or later\n"); 65 printf("License GPL version 2 or later\n");
69 printf("Homepage: http://firejail.wordpress.com\n\n"); 66 printf("Homepage: http://firejail.wordpress.com\n\n");
@@ -221,7 +218,7 @@ static void set_file(const char *name, const char *firejail_exec) {
221 218
222 struct stat s; 219 struct stat s;
223 if (stat(fname, &s) == 0) { 220 if (stat(fname, &s) == 0) {
224 printf("%s is already present, skipping...\n", fname); 221 printf(" %s is already present, skipping...\n", name);
225 } 222 }
226 else { 223 else {
227 int rv = symlink(firejail_exec, fname); 224 int rv = symlink(firejail_exec, fname);
@@ -230,19 +227,14 @@ static void set_file(const char *name, const char *firejail_exec) {
230 perror("symlink"); 227 perror("symlink");
231 } 228 }
232 else 229 else
233 printf("%s created\n", fname); 230 printf(" %s created\n", name);
234 } 231 }
235 232
236 free(fname); 233 free(fname);
237} 234}
238 235
239#define MAX_BUF 1024 236#define MAX_BUF 1024
240static void set(void) { 237static void set_links(void) {
241 if (getuid() != 0) {
242 fprintf(stderr, "Error: you need to be root to run this command\n");
243 exit(1);
244 }
245
246 char *cfgfile; 238 char *cfgfile;
247 if (asprintf(&cfgfile, "%s/firejail/firecfg.config", LIBDIR) == -1) 239 if (asprintf(&cfgfile, "%s/firejail/firecfg.config", LIBDIR) == -1)
248 errExit("asprintf"); 240 errExit("asprintf");
@@ -256,6 +248,7 @@ static void set(void) {
256 fprintf(stderr, "Error: cannot open %s\n", cfgfile); 248 fprintf(stderr, "Error: cannot open %s\n", cfgfile);
257 exit(1); 249 exit(1);
258 } 250 }
251 printf("Configuring symlinks in /usr/local/bin\n");
259 252
260 char buf[MAX_BUF]; 253 char buf[MAX_BUF];
261 int lineno = 0; 254 int lineno = 0;
@@ -294,7 +287,8 @@ static void set(void) {
294 free(firejail_exec); 287 free(firejail_exec);
295} 288}
296 289
297static void fix_desktop_files(void) { 290static void fix_desktop_files(char *homedir) {
291 assert(homedir);
298 struct stat sb; 292 struct stat sb;
299 293
300 // check user 294 // check user
@@ -302,9 +296,6 @@ static void fix_desktop_files(void) {
302 fprintf(stderr, "Error: this option is not supported for root user; please run as a regular user.\n"); 296 fprintf(stderr, "Error: this option is not supported for root user; please run as a regular user.\n");
303 exit(1); 297 exit(1);
304 } 298 }
305 char *homedir = getenv("HOME");
306 if (!homedir)
307 errExit("getenv");
308 299
309 // destination 300 // destination
310 // create ~/.local/share/applications directory if necessary 301 // create ~/.local/share/applications directory if necessary
@@ -333,6 +324,7 @@ static void fix_desktop_files(void) {
333 exit(1); 324 exit(1);
334 } 325 }
335 326
327 printf("\nFixing desktop files in ~/.local/shared/applications\n");
336 // copy 328 // copy
337 struct dirent *entry; 329 struct dirent *entry;
338 while ((entry = readdir(dir)) != NULL) { 330 while ((entry = readdir(dir)) != NULL) {
@@ -370,7 +362,7 @@ static void fix_desktop_files(void) {
370 // check format 362 // check format
371 if (strstr(buf, "[Desktop Entry]\n") == NULL) { 363 if (strstr(buf, "[Desktop Entry]\n") == NULL) {
372 if (arg_debug) 364 if (arg_debug)
373 fprintf(stderr, "/usr/share/applications/%s - SKIPPED: wrong format?\n", filename); 365 printf(" %s - SKIPPED: wrong format?\n", filename);
374 munmap(buf, sb.st_size + 1); 366 munmap(buf, sb.st_size + 1);
375 continue; 367 continue;
376 } 368 }
@@ -379,7 +371,7 @@ static void fix_desktop_files(void) {
379 char *ptr1 = strstr(buf,"\nExec="); 371 char *ptr1 = strstr(buf,"\nExec=");
380 if (!ptr1 || strlen(ptr1) < 7) { 372 if (!ptr1 || strlen(ptr1) < 7) {
381 if (arg_debug) 373 if (arg_debug)
382 fprintf(stderr, "/usr/share/applications/%s - SKIPPED: wrong format?\n", filename); 374 printf(" %s - SKIPPED: wrong format?\n", filename);
383 munmap(buf, sb.st_size + 1); 375 munmap(buf, sb.st_size + 1);
384 continue; 376 continue;
385 } 377 }
@@ -390,13 +382,13 @@ static void fix_desktop_files(void) {
390 // or with the name of the executable only 382 // or with the name of the executable only
391 if (execname[0] != '/') { 383 if (execname[0] != '/') {
392 if (arg_debug) 384 if (arg_debug)
393 fprintf(stderr, "/usr/share/applications/%s - already OK\n", filename); 385 printf(" %s - already OK\n", filename);
394 continue; 386 continue;
395 } 387 }
396 // executable name can be quoted, this is rare and currently unsupported, TODO 388 // executable name can be quoted, this is rare and currently unsupported, TODO
397 if (execname[0] == '"') { 389 if (execname[0] == '"') {
398 if (arg_debug) 390 if (arg_debug)
399 fprintf(stderr, "/usr/share/applications/%s - skipped: path quoting unsupported\n", filename); 391 printf(" %s - skipped: path quoting unsupported\n", filename);
400 continue; 392 continue;
401 } 393 }
402 394
@@ -423,7 +415,7 @@ static void fix_desktop_files(void) {
423 415
424 // check if basename in PATH 416 // check if basename in PATH
425 if (!which(bname)) { 417 if (!which(bname)) {
426 fprintf(stderr, "/usr/share/applications/%s - skipped, %s not in PATH\n", filename, bname); 418 printf(" %s - skipped, %s not in PATH\n", filename, bname);
427 continue; 419 continue;
428 } 420 }
429 421
@@ -435,14 +427,14 @@ static void fix_desktop_files(void) {
435 free(outname); 427 free(outname);
436 428
437 if (fd1 == -1) { 429 if (fd1 == -1) {
438 fprintf(stderr, "%s/%s skipped: %s\n", user_apps_dir, filename, strerror(errno)); 430 printf(" %s skipped: %s\n", filename, strerror(errno));
439 munmap(buf, sb.st_size + 1); 431 munmap(buf, sb.st_size + 1);
440 continue; 432 continue;
441 } 433 }
442 434
443 FILE *outfile = fdopen(fd1, "w"); 435 FILE *outfile = fdopen(fd1, "w");
444 if (!outfile) { 436 if (!outfile) {
445 fprintf(stderr, "%s/%s skipped: %s\n", user_apps_dir, filename, strerror(errno)); 437 printf(" %s skipped: %s\n", filename, strerror(errno));
446 munmap(buf, sb.st_size + 1); 438 munmap(buf, sb.st_size + 1);
447 close(fd1); 439 close(fd1);
448 continue; 440 continue;
@@ -460,7 +452,7 @@ static void fix_desktop_files(void) {
460 fclose(outfile); 452 fclose(outfile);
461 munmap(buf, sb.st_size + 1); 453 munmap(buf, sb.st_size + 1);
462 454
463 printf("%s/%s created\n", user_apps_dir, filename); 455 printf(" %s created\n", filename);
464 } 456 }
465 457
466 closedir(dir); 458 closedir(dir);
@@ -491,10 +483,6 @@ int main(int argc, char **argv) {
491 list(); 483 list();
492 return 0; 484 return 0;
493 } 485 }
494 else if (strcmp(argv[i], "--fix") == 0) {
495 fix_desktop_files();
496 return 0;
497 }
498 else { 486 else {
499 fprintf(stderr, "Error: invalid command line option\n"); 487 fprintf(stderr, "Error: invalid command line option\n");
500 usage(); 488 usage();
@@ -502,8 +490,45 @@ int main(int argc, char **argv) {
502 } 490 }
503 } 491 }
504 492
505 set(); 493 // set symlinks in /usr/local/bin
494 if (getuid() != 0) {
495 fprintf(stderr, "Error: you need to be root to run this command\n");
496 exit(1);
497 }
498 set_links();
499
500
501
502 // switch to the local user, and fix desktop files
503 char *user = getlogin();
504 if (!user)
505 goto errexit;
506 if (user) {
507 // find home directory
508 struct passwd *pw = getpwnam(user);
509 if (!pw)
510 goto errexit;
511 char *home = pw->pw_dir;
512 if (!home)
513 goto errexit;
514
515 // drop permissions
516 if (setgroups(0, NULL) < 0)
517 errExit("setgroups");
518 // set uid/gid
519 if (setgid(pw->pw_gid) < 0)
520 errExit("setgid");
521 if (setuid(pw->pw_uid) < 0)
522 errExit("setuid");
523 if (arg_debug)
524 printf("%s %d %d %d %d\n", user, getuid(), getgid(), geteuid(), getegid());
525 fix_desktop_files(home);
526 }
506 527
507 return 0; 528 return 0;
529
530errexit:
531 fprintf(stderr, "Error: cannot set desktop files in ~/.local/share/applications\n");
532 return 1;
508} 533}
509 534
diff --git a/src/man/firecfg.txt b/src/man/firecfg.txt
index b9d336c4c..369c3a7e0 100644
--- a/src/man/firecfg.txt
+++ b/src/man/firecfg.txt
@@ -5,12 +5,14 @@ Firecfg \- Desktop configuration program for Firejail software.
5firecfg [OPTIONS] 5firecfg [OPTIONS]
6.SH DESCRIPTION 6.SH DESCRIPTION
7Firecfg is the desktop configuration utility for Firejail software. The utility 7Firecfg is the desktop configuration utility for Firejail software. The utility
8creates several symbolic links to firejail executable. This allows the user to 8creates several symbolic links to firejail executable in /usr/local/bin.
9sandbox applications automatically, just by clicking on a regular desktop 9
10Firecfg also checks .desktop files in /usr/share/applications/,
11replaces the full path by program name, and writes the result to $HOME/.local/share/applications/.
12This allows the user to sandbox applications automatically, just by clicking on regular desktop
10menus and icons. 13menus and icons.
11 14
12The symbolic links are placed in /usr/local/bin. For more information, see 15For more information, see \fBDESKTOP INTEGRATION\fR section in \fBman 1 firejail\fR.
13\fBDESKTOP INTEGRATION\fR section in \fBman 1 firejail\fR.
14 16
15.SH OPTIONS 17.SH OPTIONS
16.TP 18.TP
@@ -26,9 +28,6 @@ Print options end exit.
26\fB\-\-list 28\fB\-\-list
27List all firejail symbolic links 29List all firejail symbolic links
28.TP 30.TP
29\fB\-\-fix
30Fix .desktop files. Some .desktop files use full path to executable. Firecfg will check .desktop files in /usr/share/applications/, replace full path by name if it is in PATH, and write result to $HOME/.local/share/applications/.
31.TP
32\fB\-\-version 31\fB\-\-version
33Print program version and exit. 32Print program version and exit.
34 33
@@ -61,14 +60,6 @@ $ sudo firecfg --clean
61/usr/local/bin/vlc removed 60/usr/local/bin/vlc removed
62.br 61.br
63[...] 62[...]
64.br
65$ firecfg --fix
66.br
67/home/user/.local/share/applications/chromium.desktop created
68.br
69/home/user/.local/share/applications/vlc.desktop created
70.br
71[...]
72 63
73 64
74.SH LICENSE 65.SH LICENSE
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index bb940840c..23d34ec25 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -1985,6 +1985,8 @@ $ firejail --tree
1985 1221:netblue:/usr/lib/firefox/firefox 1985 1221:netblue:/usr/lib/firefox/firefox
1986.RE 1986.RE
1987 1987
1988For more information, see \fBman 1 firecfg\fR.
1989
1988.SH APPARMOR 1990.SH APPARMOR
1989.TP 1991.TP
1990AppArmor support is disabled by default at compile time. Use --enable-apparmor configuration option to enable it: 1992AppArmor support is disabled by default at compile time. Use --enable-apparmor configuration option to enable it: