aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/firecfg/firecfg.h10
-rw-r--r--src/firecfg/main.c145
-rw-r--r--src/man/firecfg.1.in57
3 files changed, 159 insertions, 53 deletions
diff --git a/src/firecfg/firecfg.h b/src/firecfg/firecfg.h
index 8f74a1198..11e3ebc67 100644
--- a/src/firecfg/firecfg.h
+++ b/src/firecfg/firecfg.h
@@ -37,6 +37,16 @@
37#include "../include/common.h" 37#include "../include/common.h"
38#define MAX_BUF 4096 38#define MAX_BUF 4096
39 39
40// config files
41#define FIRECFG_CFGFILE SYSCONFDIR "/firecfg.config"
42#define FIRECFG_CONF_GLOB SYSCONFDIR "/firecfg.d/*.conf"
43
44// programs
45#define FIREJAIL_EXEC PREFIX "/bin/firejail"
46#define FIREJAIL_WELCOME_SH LIBDIR "/firejail/firejail-welcome.sh"
47#define FZENITY_EXEC LIBDIR "/firejail/fzenity"
48#define ZENITY_EXEC "/usr/bin/zenity"
49#define SUDO_EXEC "sudo"
40 50
41// main.c 51// main.c
42extern int arg_debug; 52extern int arg_debug;
diff --git a/src/firecfg/main.c b/src/firecfg/main.c
index 4ec81c5b3..604b12633 100644
--- a/src/firecfg/main.c
+++ b/src/firecfg/main.c
@@ -20,6 +20,8 @@
20 20
21#include "firecfg.h" 21#include "firecfg.h"
22#include "../include/firejail_user.h" 22#include "../include/firejail_user.h"
23#include <glob.h>
24
23int arg_debug = 0; 25int arg_debug = 0;
24char *arg_bindir = "/usr/local/bin"; 26char *arg_bindir = "/usr/local/bin";
25int arg_guide = 0; 27int arg_guide = 0;
@@ -76,10 +78,6 @@ static void list(void) {
76 exit(1); 78 exit(1);
77 } 79 }
78 80
79 char *firejail_exec;
80 if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1)
81 errExit("asprintf");
82
83 struct dirent *entry; 81 struct dirent *entry;
84 while ((entry = readdir(dir)) != NULL) { 82 while ((entry = readdir(dir)) != NULL) {
85 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) 83 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
@@ -92,7 +90,7 @@ static void list(void) {
92 if (is_link(fullname)) { 90 if (is_link(fullname)) {
93 char* fname = realpath(fullname, NULL); 91 char* fname = realpath(fullname, NULL);
94 if (fname) { 92 if (fname) {
95 if (strcmp(fname, firejail_exec) == 0) 93 if (strcmp(fname, FIREJAIL_EXEC) == 0)
96 printf("%s\n", fullname); 94 printf("%s\n", fullname);
97 free(fname); 95 free(fname);
98 } 96 }
@@ -101,7 +99,6 @@ static void list(void) {
101 } 99 }
102 100
103 closedir(dir); 101 closedir(dir);
104 free(firejail_exec);
105} 102}
106 103
107static void clean(void) { 104static void clean(void) {
@@ -114,10 +111,6 @@ static void clean(void) {
114 exit(1); 111 exit(1);
115 } 112 }
116 113
117 char *firejail_exec;
118 if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1)
119 errExit("asprintf");
120
121 struct dirent *entry; 114 struct dirent *entry;
122 while ((entry = readdir(dir)) != NULL) { 115 while ((entry = readdir(dir)) != NULL) {
123 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) 116 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
@@ -130,7 +123,7 @@ static void clean(void) {
130 if (is_link(fullname)) { 123 if (is_link(fullname)) {
131 char* fname = realpath(fullname, NULL); 124 char* fname = realpath(fullname, NULL);
132 if (fname) { 125 if (fname) {
133 if (strcmp(fname, firejail_exec) == 0) { 126 if (strcmp(fname, FIREJAIL_EXEC) == 0) {
134 char *ptr = strrchr(fullname, '/'); 127 char *ptr = strrchr(fullname, '/');
135 assert(ptr); 128 assert(ptr);
136 ptr++; 129 ptr++;
@@ -147,10 +140,43 @@ static void clean(void) {
147 } 140 }
148 141
149 closedir(dir); 142 closedir(dir);
150 free(firejail_exec);
151 printf("\n"); 143 printf("\n");
152} 144}
153 145
146#define ignorelist_maxlen 2048
147static const char *ignorelist[ignorelist_maxlen];
148static int ignorelist_len = 0;
149
150static int append_ignorelist(const char *const str) {
151 assert(str);
152 if (ignorelist_len >= ignorelist_maxlen) {
153 fprintf(stderr, "Warning: Ignore list is full (%d/%d), skipping %s\n",
154 ignorelist_len, ignorelist_maxlen, str);
155 return 0;
156 }
157
158 printf(" ignoring '%s'\n", str);
159 const char *const dup = strdup(str);
160 if (!dup)
161 errExit("strdup");
162
163 ignorelist[ignorelist_len] = dup;
164 ignorelist_len++;
165
166 return 1;
167}
168
169static int in_ignorelist(const char *const str) {
170 assert(str);
171 int i;
172 for (i = 0; i < ignorelist_len; i++) {
173 if (strcmp(str, ignorelist[i]) == 0)
174 return 1;
175 }
176
177 return 0;
178}
179
154static void set_file(const char *name, const char *firejail_exec) { 180static void set_file(const char *name, const char *firejail_exec) {
155 if (which(name) == 0) 181 if (which(name) == 0)
156 return; 182 return;
@@ -165,35 +191,26 @@ static void set_file(const char *name, const char *firejail_exec) {
165 if (rv) { 191 if (rv) {
166 fprintf(stderr, "Error: cannot create %s symbolic link\n", fname); 192 fprintf(stderr, "Error: cannot create %s symbolic link\n", fname);
167 perror("symlink"); 193 perror("symlink");
168 } 194 } else {
169 else
170 printf(" %s created\n", name); 195 printf(" %s created\n", name);
171 } 196 }
172 else { 197 } else {
173 fprintf(stderr, "Warning: cannot create %s - already exists! Skipping...\n", fname); 198 fprintf(stderr, "Warning: cannot create %s - already exists! Skipping...\n", fname);
174 } 199 }
175 200
176 free(fname); 201 free(fname);
177} 202}
178 203
179// parse /etc/firejail/firecfg.config file 204// parse a single config file
180static void set_links_firecfg(void) { 205static void set_links_firecfg(const char *cfgfile) {
181 char *cfgfile; 206 printf("Configuring symlinks in %s based on %s\n", arg_bindir, cfgfile);
182 if (asprintf(&cfgfile, "%s/firecfg.config", SYSCONFDIR) == -1)
183 errExit("asprintf");
184
185 char *firejail_exec;
186 if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1)
187 errExit("asprintf");
188 207
189 // parse /etc/firejail/firecfg.config file
190 FILE *fp = fopen(cfgfile, "r"); 208 FILE *fp = fopen(cfgfile, "r");
191 if (!fp) { 209 if (!fp) {
192 perror("fopen"); 210 perror("fopen");
193 fprintf(stderr, "Error: cannot open %s\n", cfgfile); 211 fprintf(stderr, "Error: cannot open %s\n", cfgfile);
194 exit(1); 212 exit(1);
195 } 213 }
196 printf("Configuring symlinks in %s based on firecfg.config\n", arg_bindir);
197 214
198 char buf[MAX_BUF]; 215 char buf[MAX_BUF];
199 int lineno = 0; 216 int lineno = 0;
@@ -223,13 +240,43 @@ static void set_links_firecfg(void) {
223 if (*start == '\0') 240 if (*start == '\0')
224 continue; 241 continue;
225 242
243 // handle ignore command
244 if (*start == '!') {
245 append_ignorelist(start + 1);
246 continue;
247 }
248
226 // set link 249 // set link
227 set_file(start, firejail_exec); 250 if (!in_ignorelist(start))
251 set_file(start, FIREJAIL_EXEC);
252 else
253 printf(" %s ignored\n", start);
228 } 254 }
229 255
230 fclose(fp); 256 fclose(fp);
231 free(cfgfile); 257 printf("\n");
232 free(firejail_exec); 258}
259
260// parse all config files matching pattern
261static void set_links_firecfg_glob(const char *pattern) {
262 printf("Looking for config files in %s\n", pattern);
263
264 glob_t globbuf;
265 int globerr = glob(pattern, 0, NULL, &globbuf);
266 if (globerr == GLOB_NOMATCH) {
267 fprintf(stderr, "No matches for glob pattern %s\n", pattern);
268 goto out;
269 } else if (globerr != 0) {
270 fprintf(stderr, "Warning: Failed to match glob pattern %s: %s\n",
271 pattern, strerror(errno));
272 goto out;
273 }
274
275 size_t i;
276 for (i = 0; i < globbuf.gl_pathc; i++)
277 set_links_firecfg(globbuf.gl_pathv[i]);
278out:
279 globfree(&globbuf);
233} 280}
234 281
235// parse ~/.config/firejail/ directory 282// parse ~/.config/firejail/ directory
@@ -246,10 +293,6 @@ static void set_links_homedir(const char *homedir) {
246 return; 293 return;
247 } 294 }
248 295
249 char *firejail_exec;
250 if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1)
251 errExit("asprintf");
252
253 // parse ~/.config/firejail/ directory 296 // parse ~/.config/firejail/ directory
254 printf("\nConfiguring symlinks in %s based on local firejail config directory\n", arg_bindir); 297 printf("\nConfiguring symlinks in %s based on local firejail config directory\n", arg_bindir);
255 298
@@ -260,6 +303,7 @@ static void set_links_homedir(const char *homedir) {
260 free(dirname); 303 free(dirname);
261 return; 304 return;
262 } 305 }
306 free(dirname);
263 307
264 struct dirent *entry; 308 struct dirent *entry;
265 while ((entry = readdir(dir))) { 309 while ((entry = readdir(dir))) {
@@ -280,12 +324,10 @@ static void set_links_homedir(const char *homedir) {
280 } 324 }
281 325
282 *ptr = '\0'; 326 *ptr = '\0';
283 set_file(exec, firejail_exec); 327 set_file(exec, FIREJAIL_EXEC);
284 free(exec); 328 free(exec);
285 } 329 }
286 closedir(dir); 330 closedir(dir);
287
288 free(firejail_exec);
289} 331}
290 332
291static const char *get_sudo_user(void) { 333static const char *get_sudo_user(void) {
@@ -449,18 +491,20 @@ int main(int argc, char **argv) {
449 } 491 }
450 492
451 if (arg_guide) { 493 if (arg_guide) {
494 const char *zenity_exec;
495 if (arg_debug)
496 zenity_exec = FZENITY_EXEC;
497 else
498 zenity_exec = ZENITY_EXEC;
499
452 char *cmd; 500 char *cmd;
453if (arg_debug) { 501 if (asprintf(&cmd, "%s %s %s %s %s",
454 if (asprintf(&cmd, "sudo %s/firejail/firejail-welcome.sh /usr/lib/firejail/fzenity %s %s", LIBDIR, SYSCONFDIR, user) == -1) 502 SUDO_EXEC, FIREJAIL_WELCOME_SH, zenity_exec, SYSCONFDIR, user) == -1)
455 errExit("asprintf"); 503 errExit("asprintf");
456} 504
457else {
458 if (asprintf(&cmd, "sudo %s/firejail/firejail-welcome.sh /usr/bin/zenity %s %s", LIBDIR, SYSCONFDIR, user) == -1)
459 errExit("asprintf");
460}
461 int status = system(cmd); 505 int status = system(cmd);
462 if (status == -1) { 506 if (status == -1) {
463 fprintf(stderr, "Error: cannot run firejail-welcome.sh\n"); 507 fprintf(stderr, "Error: cannot run %s\n", FIREJAIL_WELCOME_SH);
464 exit(1); 508 exit(1);
465 } 509 }
466 free(cmd); 510 free(cmd);
@@ -474,12 +518,15 @@ else {
474 // clear all symlinks 518 // clear all symlinks
475 clean(); 519 clean();
476 520
477 // set new symlinks based on /etc/firejail/firecfg.config 521 // set new symlinks based on .conf files
478 set_links_firecfg(); 522 set_links_firecfg_glob(FIRECFG_CONF_GLOB);
523
524 // set new symlinks based on firecfg.config
525 set_links_firecfg(FIRECFG_CFGFILE);
479 526
480 if (getuid() == 0) { 527 if (getuid() == 0) {
481 // add user to firejail access database - only for root 528 // add user to firejail access database - only for root
482 printf("\nAdding user %s to Firejail access database in %s/firejail.users\n", user, SYSCONFDIR); 529 printf("Adding user %s to Firejail access database in %s/firejail.users\n", user, SYSCONFDIR);
483 // temporarily set the umask, access database must be world-readable 530 // temporarily set the umask, access database must be world-readable
484 mode_t orig_umask = umask(022); 531 mode_t orig_umask = umask(022);
485 firejail_user_add(user); 532 firejail_user_add(user);
diff --git a/src/man/firecfg.1.in b/src/man/firecfg.1.in
index a85fbc5da..e43a573de 100644
--- a/src/man/firecfg.1.in
+++ b/src/man/firecfg.1.in
@@ -29,9 +29,13 @@ Note: The examples use \fBsudo\fR, but \fBdoas\fR is also supported.
29To set it up, run "sudo firecfg" after installing Firejail software. 29To set it up, run "sudo firecfg" after installing Firejail software.
30The same command should also be run after 30The same command should also be run after
31installing new programs. If the program is supported by Firejail, the symbolic link in /usr/local/bin 31installing new programs. If the program is supported by Firejail, the symbolic link in /usr/local/bin
32will be created. For a full list of programs supported by default run "cat /etc/firejail/firecfg.config". 32will be created.
33 33.PP
34For user-driven manual integration, see \fBDESKTOP INTEGRATION\fR section in \fBman 1 firejail\fR. 34To configure the list of programs used by firecfg when creating symlinks, see
35\fBFILES\fR and \fBSYNTAX\fR.
36.PP
37For user-driven manual integration, see \fBDESKTOP INTEGRATION\fR section in
38\fBman 1 firejail\fR.
35.SH DEFAULT ACTIONS 39.SH DEFAULT ACTIONS
36The following actions are implemented by default by running sudo firecfg: 40The following actions are implemented by default by running sudo firecfg:
37 41
@@ -135,8 +139,53 @@ $ sudo firecfg --clean
135/usr/local/bin/vlc removed 139/usr/local/bin/vlc removed
136.br 140.br
137[...] 141[...]
142.SH FILES
143.PP
144Configuration files are searched for and parsed in the following paths:
145.PP
146.RS
1471. /etc/firejail/firecfg.d/*.conf (in alphabetical order)
148.br
1492. /etc/firejail/firecfg.config
150.RE
151.PP
152The programs that are supported by default are listed in
153/etc/firejail/firecfg.config.
154It is recommended to leave it as is and put all customizations inside
155/etc/firejail/firecfg.d/.
156.PP
157Profile files are also searched in the user configuration directory:
158.PP
159.RS
1603. ~/.config/firejail/*.profile
161.RE
162.PP
163For every \fBPROGRAM.profile\fR file found, firecfg attempts to create a
164symlink for "PROGRAM", as if "PROGRAM" was listed in a configuration file.
165.SH SYNTAX
166Configuration file syntax:
167.PP
168A line that starts with \fB#\fR is considered a comment.
169.br
170A line that starts with \fB!PROGRAM\fR means to ignore "PROGRAM" when creating
171symlinks.
172.br
173A line that starts with anything else is considered to be the name of an
174executable and firecfg will attempt to create a symlink for it.
175.PP
176For example, to prevent firecfg from creating symlinks for "firefox" and
177"patch" while attempting to create a symlink for "myprog", the following lines
178could be added to /etc/firejail/firecfg.d/10-my.conf:
179.PP
180.RS
181!firefox
182.br
183!patch
184.br
138 185
139 186.br
187myprog
188.RE
140.SH LICENSE 189.SH LICENSE
141This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 190This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
142.PP 191.PP