diff options
author | netblue30 <netblue30@yahoo.com> | 2017-09-25 07:38:01 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2017-09-25 07:38:01 -0400 |
commit | a6341b904c08b1feb51e264ab487d1f125222a10 (patch) | |
tree | 35ea50b8c8e561b710272a0e8ae9418541a32925 /src/firecfg/main.c | |
parent | Remove whitelist from pinta (diff) | |
download | firejail-a6341b904c08b1feb51e264ab487d1f125222a10.tar.gz firejail-a6341b904c08b1feb51e264ab487d1f125222a10.tar.zst firejail-a6341b904c08b1feb51e264ab487d1f125222a10.zip |
disable DBus activation in firecfg
Diffstat (limited to 'src/firecfg/main.c')
-rw-r--r-- | src/firecfg/main.c | 342 |
1 files changed, 2 insertions, 340 deletions
diff --git a/src/firecfg/main.c b/src/firecfg/main.c index 5928b9ae5..1cdd39c1f 100644 --- a/src/firecfg/main.c +++ b/src/firecfg/main.c | |||
@@ -18,24 +18,8 @@ | |||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define _GNU_SOURCE | 21 | #include "firecfg.h" |
22 | #include <stdio.h> | 22 | int arg_debug = 0; |
23 | #include <sys/types.h> | ||
24 | #include <dirent.h> | ||
25 | #include <sys/types.h> | ||
26 | #include <sys/stat.h> | ||
27 | #include <fcntl.h> | ||
28 | #include <unistd.h> | ||
29 | #include <grp.h> | ||
30 | #include <string.h> | ||
31 | #include <errno.h> | ||
32 | #include <sys/mman.h> | ||
33 | #include <pwd.h> | ||
34 | #include <dirent.h> | ||
35 | |||
36 | #include "../include/common.h" | ||
37 | static int arg_debug = 0; | ||
38 | #define MAX_BUF 1024 | ||
39 | 23 | ||
40 | static void usage(void) { | 24 | static void usage(void) { |
41 | printf("firecfg - version %s\n\n", VERSION); | 25 | printf("firecfg - version %s\n\n", VERSION); |
@@ -71,113 +55,6 @@ static void usage(void) { | |||
71 | printf("Homepage: http://firejail.wordpress.com\n\n"); | 55 | printf("Homepage: http://firejail.wordpress.com\n\n"); |
72 | } | 56 | } |
73 | 57 | ||
74 | static void sound(void) { | ||
75 | struct passwd *pw = getpwuid(getuid()); | ||
76 | if (!pw) { | ||
77 | goto errexit; | ||
78 | } | ||
79 | char *home = pw->pw_dir; | ||
80 | if (!home) { | ||
81 | goto errexit; | ||
82 | } | ||
83 | |||
84 | // the input file is /etc/pulse/client.conf | ||
85 | FILE *fpin = fopen("/etc/pulse/client.conf", "r"); | ||
86 | if (!fpin) { | ||
87 | fprintf(stderr, "PulseAudio is not available on this platform, there is nothing to fix...\n"); | ||
88 | return; | ||
89 | } | ||
90 | |||
91 | // the dest is PulseAudio user config file | ||
92 | char *fname; | ||
93 | if (asprintf(&fname, "%s/.config/pulse/client.conf", home) == -1) | ||
94 | errExit("asprintf"); | ||
95 | FILE *fpout = fopen(fname, "w"); | ||
96 | free(fname); | ||
97 | if (!fpout) | ||
98 | goto errexit; | ||
99 | |||
100 | // copy default config | ||
101 | char buf[MAX_BUF]; | ||
102 | while (fgets(buf, MAX_BUF, fpin)) | ||
103 | fputs(buf, fpout); | ||
104 | |||
105 | // disable shm | ||
106 | fprintf(fpout, "\nenable-shm = no\n"); | ||
107 | fclose(fpin); | ||
108 | fclose(fpout); | ||
109 | printf("PulseAudio configured, please logout and login back again\n"); | ||
110 | return; | ||
111 | |||
112 | errexit: | ||
113 | fprintf(stderr, "Error: cannot configure sound file\n"); | ||
114 | exit(1); | ||
115 | } | ||
116 | |||
117 | // return 1 if the program is found | ||
118 | static int find(const char *program, const char *directory) { | ||
119 | int retval = 0; | ||
120 | |||
121 | char *fname; | ||
122 | if (asprintf(&fname, "/%s/%s", directory, program) == -1) | ||
123 | errExit("asprintf"); | ||
124 | |||
125 | struct stat s; | ||
126 | if (stat(fname, &s) == 0) { | ||
127 | if (arg_debug) | ||
128 | printf("found %s in directory %s\n", program, directory); | ||
129 | retval = 1; | ||
130 | } | ||
131 | |||
132 | free(fname); | ||
133 | return retval; | ||
134 | } | ||
135 | |||
136 | |||
137 | // return 1 if program is installed on the system | ||
138 | static int which(const char *program) { | ||
139 | // check some well-known paths | ||
140 | if (find(program, "/bin") || find(program, "/usr/bin") || | ||
141 | find(program, "/sbin") || find(program, "/usr/sbin") || | ||
142 | find(program, "/usr/games")) | ||
143 | return 1; | ||
144 | |||
145 | // check environment | ||
146 | char *path1 = getenv("PATH"); | ||
147 | if (path1) { | ||
148 | char *path2 = strdup(path1); | ||
149 | if (!path2) | ||
150 | errExit("strdup"); | ||
151 | |||
152 | // use path2 to count the entries | ||
153 | char *ptr = strtok(path2, ":"); | ||
154 | while (ptr) { | ||
155 | if (find(program, ptr)) { | ||
156 | free(path2); | ||
157 | return 1; | ||
158 | } | ||
159 | ptr = strtok(NULL, ":"); | ||
160 | } | ||
161 | free(path2); | ||
162 | } | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | // return 1 if the file is a link | ||
168 | static int is_link(const char *fname) { | ||
169 | assert(fname); | ||
170 | if (*fname == '\0') | ||
171 | return 0; | ||
172 | |||
173 | struct stat s; | ||
174 | if (lstat(fname, &s) == 0) { | ||
175 | if (S_ISLNK(s.st_mode)) | ||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | 58 | ||
182 | static void list(void) { | 59 | static void list(void) { |
183 | DIR *dir = opendir("/usr/local/bin"); | 60 | DIR *dir = opendir("/usr/local/bin"); |
@@ -388,221 +265,6 @@ static void set_links_homedir(const char *homedir) { | |||
388 | free(firejail_exec); | 265 | free(firejail_exec); |
389 | } | 266 | } |
390 | 267 | ||
391 | // look for a profile file in /etc/firejail diectory and in homedir/.config/firejail directory | ||
392 | static int have_profile(const char *filename, const char *homedir) { | ||
393 | assert(filename); | ||
394 | assert(homedir); | ||
395 | |||
396 | if (arg_debug) | ||
397 | printf("checking profile for %s\n", filename); | ||
398 | |||
399 | // remove .desktop extension | ||
400 | char *f1 = strdup(filename); | ||
401 | if (!f1) | ||
402 | errExit("strdup"); | ||
403 | f1[strlen(filename) - 8] = '\0'; | ||
404 | |||
405 | // build profile name | ||
406 | char *profname1; | ||
407 | char *profname2; | ||
408 | if (asprintf(&profname1, "%s/%s.profile", SYSCONFDIR, f1) == -1) | ||
409 | errExit("asprintf"); | ||
410 | if (asprintf(&profname2, "%s/.config/firejail/%s.profile", homedir, f1) == -1) | ||
411 | errExit("asprintf"); | ||
412 | |||
413 | int rv = 0; | ||
414 | if (access(profname1, R_OK) == 0) { | ||
415 | if (arg_debug) | ||
416 | printf("found %s\n", profname1); | ||
417 | rv = 1; | ||
418 | } | ||
419 | else if (access(profname2, R_OK) == 0) { | ||
420 | if (arg_debug) | ||
421 | printf("found %s\n", profname2); | ||
422 | rv = 1; | ||
423 | } | ||
424 | |||
425 | free(f1); | ||
426 | free(profname1); | ||
427 | free(profname2); | ||
428 | return rv; | ||
429 | } | ||
430 | |||
431 | static void fix_desktop_files(char *homedir) { | ||
432 | assert(homedir); | ||
433 | struct stat sb; | ||
434 | |||
435 | // check user | ||
436 | if (getuid() == 0) { | ||
437 | fprintf(stderr, "Error: this option is not supported for root user; please run as a regular user.\n"); | ||
438 | exit(1); | ||
439 | } | ||
440 | |||
441 | // destination | ||
442 | // create ~/.local/share/applications directory if necessary | ||
443 | char *user_apps_dir; | ||
444 | if (asprintf(&user_apps_dir, "%s/.local/share/applications", homedir) == -1) | ||
445 | errExit("asprintf"); | ||
446 | if (stat(user_apps_dir, &sb) == -1) { | ||
447 | int rv = mkdir(user_apps_dir, 0700); | ||
448 | if (rv) { | ||
449 | fprintf(stderr, "Error: cannot create ~/.local/application directory\n"); | ||
450 | perror("mkdir"); | ||
451 | exit(1); | ||
452 | } | ||
453 | rv = chmod(user_apps_dir, 0700); | ||
454 | (void) rv; | ||
455 | } | ||
456 | |||
457 | // source | ||
458 | DIR *dir = opendir("/usr/share/applications"); | ||
459 | if (!dir) { | ||
460 | perror("Error: cannot open /usr/share/applications directory"); | ||
461 | exit(1); | ||
462 | } | ||
463 | if (chdir("/usr/share/applications")) { | ||
464 | perror("Error: cannot chdir to /usr/share/applications"); | ||
465 | exit(1); | ||
466 | } | ||
467 | |||
468 | printf("\nFixing desktop files in %s\n", user_apps_dir); | ||
469 | // copy | ||
470 | struct dirent *entry; | ||
471 | while ((entry = readdir(dir)) != NULL) { | ||
472 | if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) | ||
473 | continue; | ||
474 | |||
475 | // skip if not regular file or link | ||
476 | // d_type is not available on some file systems | ||
477 | if (entry->d_type != DT_REG && entry->d_type != DT_LNK && entry->d_type != DT_UNKNOWN) | ||
478 | continue; | ||
479 | |||
480 | // skip if not .desktop file | ||
481 | if (strstr(entry->d_name,".desktop") != (entry->d_name+strlen(entry->d_name)-8)) | ||
482 | continue; | ||
483 | |||
484 | char *filename = entry->d_name; | ||
485 | |||
486 | // skip links | ||
487 | if (is_link(filename)) | ||
488 | continue; | ||
489 | if (stat(filename, &sb) == -1) | ||
490 | errExit("stat"); | ||
491 | |||
492 | // no profile in /etc/firejail, no desktop file fixing | ||
493 | if (!have_profile(filename, homedir)) | ||
494 | continue; | ||
495 | |||
496 | /* coverity[toctou] */ | ||
497 | int fd = open(filename, O_RDONLY); | ||
498 | if (fd == -1) | ||
499 | errExit("open"); | ||
500 | |||
501 | char *buf = mmap(NULL, sb.st_size + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); | ||
502 | if (buf == MAP_FAILED) | ||
503 | errExit("mmap"); | ||
504 | |||
505 | close(fd); | ||
506 | |||
507 | // check format | ||
508 | if (strstr(buf, "[Desktop Entry]\n") == NULL) { | ||
509 | if (arg_debug) | ||
510 | printf(" %s - SKIPPED: wrong format?\n", filename); | ||
511 | munmap(buf, sb.st_size + 1); | ||
512 | continue; | ||
513 | } | ||
514 | |||
515 | // get executable name | ||
516 | char *ptr1 = strstr(buf,"\nExec="); | ||
517 | if (!ptr1 || strlen(ptr1) < 7) { | ||
518 | if (arg_debug) | ||
519 | printf(" %s - SKIPPED: wrong format?\n", filename); | ||
520 | munmap(buf, sb.st_size + 1); | ||
521 | continue; | ||
522 | } | ||
523 | |||
524 | char *execname = ptr1 + 6; | ||
525 | // https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s06.html | ||
526 | // The executable program can either be specified with its full path | ||
527 | // or with the name of the executable only | ||
528 | if (execname[0] != '/') { | ||
529 | if (arg_debug) | ||
530 | printf(" %s - already OK\n", filename); | ||
531 | continue; | ||
532 | } | ||
533 | // executable name can be quoted, this is rare and currently unsupported, TODO | ||
534 | if (execname[0] == '"') { | ||
535 | if (arg_debug) | ||
536 | printf(" %s - skipped: path quoting unsupported\n", filename); | ||
537 | continue; | ||
538 | } | ||
539 | |||
540 | // put '\0' at end of filename | ||
541 | char *tail = NULL; | ||
542 | char endchar = ' '; | ||
543 | if (execname[0] == '/') { | ||
544 | char *ptr2 = index(execname, ' '); | ||
545 | char *ptr3 = index(execname, '\n'); | ||
546 | if (ptr2 && (!ptr3 || (ptr2 < ptr3))) { | ||
547 | endchar = ptr2[0]; | ||
548 | ptr2[0] = '\0'; | ||
549 | tail = ptr2 + 1; | ||
550 | } else if (ptr3 && (!ptr2 || (ptr3 < ptr2))) { | ||
551 | endchar = ptr3[0]; | ||
552 | ptr3[0] = '\0'; | ||
553 | tail = ptr3 + 1; | ||
554 | } | ||
555 | ptr1[5] = '\0'; | ||
556 | } | ||
557 | |||
558 | char *bname = basename(execname); | ||
559 | assert(bname); | ||
560 | |||
561 | // check if basename in PATH | ||
562 | if (!which(bname)) { | ||
563 | printf(" %s - skipped, %s not in PATH\n", filename, bname); | ||
564 | continue; | ||
565 | } | ||
566 | |||
567 | char *outname; | ||
568 | if (asprintf(&outname ,"%s/%s", user_apps_dir, filename) == -1) | ||
569 | errExit("asprintf"); | ||
570 | |||
571 | int fd1 = open(outname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR); | ||
572 | free(outname); | ||
573 | |||
574 | if (fd1 == -1) { | ||
575 | printf(" %s skipped: %s\n", filename, strerror(errno)); | ||
576 | munmap(buf, sb.st_size + 1); | ||
577 | continue; | ||
578 | } | ||
579 | |||
580 | FILE *outfile = fdopen(fd1, "w"); | ||
581 | if (!outfile) { | ||
582 | printf(" %s skipped: %s\n", filename, strerror(errno)); | ||
583 | munmap(buf, sb.st_size + 1); | ||
584 | close(fd1); | ||
585 | continue; | ||
586 | } | ||
587 | |||
588 | if (fprintf(outfile,\ | ||
589 | "# Converted by firecfg --fix from /usr/share/applications/%s\n\n%s=%s%c%s",\ | ||
590 | filename, buf, bname, endchar, tail) < 0) { | ||
591 | fprintf(stderr, "Unable to write %s/%s: %s\n", user_apps_dir, filename, strerror(errno)); | ||
592 | munmap(buf, sb.st_size + 1); | ||
593 | fclose(outfile); | ||
594 | continue; | ||
595 | } | ||
596 | |||
597 | fclose(outfile); | ||
598 | munmap(buf, sb.st_size + 1); | ||
599 | |||
600 | printf(" %s created\n", filename); | ||
601 | } | ||
602 | |||
603 | closedir(dir); | ||
604 | free(user_apps_dir); | ||
605 | } | ||
606 | 268 | ||
607 | int main(int argc, char **argv) { | 269 | int main(int argc, char **argv) { |
608 | int i; | 270 | int i; |