aboutsummaryrefslogtreecommitdiffstats
path: root/src/firecfg
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@protonmail.com>2023-12-04 09:11:08 -0500
committerLibravatar GitHub <noreply@github.com>2023-12-04 09:11:08 -0500
commit2033e98e79721c82cb704dcc46b37cdb58afd986 (patch)
treedea825dcf577e7c178f2f4f9bf8d0741cab6f147 /src/firecfg
parentRELNOTES: add modif, bugfix, build and contrib items (diff)
parentfirecfg: add ignore command and docs (diff)
downloadfirejail-2033e98e79721c82cb704dcc46b37cdb58afd986.tar.gz
firejail-2033e98e79721c82cb704dcc46b37cdb58afd986.tar.zst
firejail-2033e98e79721c82cb704dcc46b37cdb58afd986.zip
Merge pull request #5876 from kmk3/firecfg-add-confdir-ignore
feature: firecfg: add firecfg.d & add ignore command
Diffstat (limited to 'src/firecfg')
-rw-r--r--src/firecfg/firecfg.h10
-rw-r--r--src/firecfg/main.c145
2 files changed, 106 insertions, 49 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);