aboutsummaryrefslogtreecommitdiffstats
path: root/src/firecfg/main.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-09-25 07:38:01 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2017-09-25 07:38:01 -0400
commita6341b904c08b1feb51e264ab487d1f125222a10 (patch)
tree35ea50b8c8e561b710272a0e8ae9418541a32925 /src/firecfg/main.c
parentRemove whitelist from pinta (diff)
downloadfirejail-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.c342
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> 22int 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"
37static int arg_debug = 0;
38#define MAX_BUF 1024
39 23
40static void usage(void) { 24static 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
74static 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
112errexit:
113 fprintf(stderr, "Error: cannot configure sound file\n");
114 exit(1);
115}
116
117// return 1 if the program is found
118static 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
138static 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
168static 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
182static void list(void) { 59static 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
392static 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
431static 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
607int main(int argc, char **argv) { 269int main(int argc, char **argv) {
608 int i; 270 int i;