Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

firecfg: use ignorelist also for .profile/.desktop files #6153

Merged
merged 4 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions src/firecfg/desktop_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ void fix_desktop_files(const char *homedir) {
exit(1);
}

// build ignorelist
parse_config_all(0);

// destination
// create ~/.local/share/applications directory if necessary
char *user_apps_dir;
Expand Down Expand Up @@ -163,7 +166,8 @@ void fix_desktop_files(const char *homedir) {
// copy
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
const char *filename = entry->d_name;
if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
continue;

// skip if not regular file or link
Expand All @@ -172,10 +176,25 @@ void fix_desktop_files(const char *homedir) {
continue;

// skip if not .desktop file
if (strstr(entry->d_name,".desktop") != (entry->d_name+strlen(entry->d_name)-8))
char *exec = strdup(filename);
if (!exec)
errExit("strdup");
char *ptr = strstr(exec, ".desktop");
if (ptr == NULL || *(ptr + 8) != '\0') {
printf(" %s skipped (not a .desktop file)\n", exec);
free(exec);
continue;
}

// skip if program is in ignorelist
*ptr = '\0';
if (in_ignorelist(exec)) {
printf(" %s ignored\n", exec);
free(exec);
continue;
}

char *filename = entry->d_name;
free(exec);

// skip links - Discord on Arch #4235 seems to be a symlink to /opt directory
// if (is_link(filename))
Expand Down Expand Up @@ -221,7 +240,7 @@ void fix_desktop_files(const char *homedir) {
}

// get executable name
char *ptr = strstr(buf,"\nExec=");
ptr = strstr(buf,"\nExec=");
if (!ptr || strlen(ptr) < 7) {
if (arg_debug)
printf(" %s - skipped: wrong format?\n", filename);
Expand Down
2 changes: 2 additions & 0 deletions src/firecfg/firecfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@

// main.c
extern int arg_debug;
int in_ignorelist(const char *const str);
void parse_config_all(int do_symlink);

// util.c
int which(const char *program);
Expand Down
61 changes: 40 additions & 21 deletions src/firecfg/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
int arg_debug = 0;
char *arg_bindir = "/usr/local/bin";
int arg_guide = 0;
int done_config = 0;

static const char *const usage_str =
"Firecfg is the desktop configuration utility for Firejail software. The utility\n"
Expand Down Expand Up @@ -166,7 +167,7 @@ static int append_ignorelist(const char *const str) {
return 1;
}

static int in_ignorelist(const char *const str) {
int in_ignorelist(const char *const str) {
assert(str);
int i;
for (i = 0; i < ignorelist_len; i++) {
Expand Down Expand Up @@ -202,8 +203,11 @@ static void set_file(const char *name, const char *firejail_exec) {
}

// parse a single config file
static void set_links_firecfg(const char *cfgfile) {
printf("Configuring symlinks in %s based on %s\n", arg_bindir, cfgfile);
static void parse_config_file(const char *cfgfile, int do_symlink) {
if (do_symlink)
printf("Configuring symlinks in %s\n", arg_bindir);

printf("Parsing %s\n", cfgfile);

FILE *fp = fopen(cfgfile, "r");
if (!fp) {
Expand Down Expand Up @@ -246,19 +250,23 @@ static void set_links_firecfg(const char *cfgfile) {
continue;
}

// skip ignored programs
if (in_ignorelist(start)) {
printf(" %s ignored\n", start);
continue;
}

// set link
if (!in_ignorelist(start))
if (do_symlink)
set_file(start, FIREJAIL_EXEC);
else
printf(" %s ignored\n", start);
}

fclose(fp);
printf("\n");
}

// parse all config files matching pattern
static void set_links_firecfg_glob(const char *pattern) {
static void parse_config_glob(const char *pattern, int do_symlink) {
printf("Looking for config files in %s\n", pattern);

glob_t globbuf;
Expand All @@ -274,11 +282,23 @@ static void set_links_firecfg_glob(const char *pattern) {

size_t i;
for (i = 0; i < globbuf.gl_pathc; i++)
set_links_firecfg(globbuf.gl_pathv[i]);
parse_config_file(globbuf.gl_pathv[i], do_symlink);
out:
globfree(&globbuf);
}

// parse all config files
// do_symlink 0 just builds the ignorelist, 1 creates the symlinks
void parse_config_all(int do_symlink) {
if (done_config)
return;

parse_config_glob(FIRECFG_CONF_GLOB, do_symlink);
parse_config_file(FIRECFG_CFGFILE, do_symlink);

done_config = 1;
}

// parse ~/.config/firejail/ directory
static void set_links_homedir(const char *homedir) {
assert(homedir);
Expand Down Expand Up @@ -314,17 +334,19 @@ static void set_links_homedir(const char *homedir) {
if (!exec)
errExit("strdup");
char *ptr = strrchr(exec, '.');
if (!ptr) {
free(exec);
continue;
}
if (strcmp(ptr, ".profile") != 0) {
free(exec);
continue;
}
if (!ptr)
goto next;
if (strcmp(ptr, ".profile") != 0)
goto next;

*ptr = '\0';
if (in_ignorelist(exec)) {
printf(" %s ignored\n", exec);
goto next;
}

set_file(exec, FIREJAIL_EXEC);
next:
free(exec);
}
closedir(dir);
Expand Down Expand Up @@ -518,11 +540,8 @@ int main(int argc, char **argv) {
// clear all symlinks
clean();

// set new symlinks based on .conf files
set_links_firecfg_glob(FIRECFG_CONF_GLOB);

// set new symlinks based on firecfg.config
set_links_firecfg(FIRECFG_CFGFILE);
// set new symlinks based on config files
parse_config_all(1);

if (getuid() == 0) {
// add user to firejail access database - only for root
Expand Down
2 changes: 1 addition & 1 deletion src/man/firecfg.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ Configuration file syntax:
A line that starts with \fB#\fR is considered a comment.
.br
A line that starts with \fB!PROGRAM\fR means to ignore "PROGRAM" when creating
symlinks.
symlinks and fixing .desktop files.
.br
A line that starts with anything else is considered to be the name of an
executable and firecfg will attempt to create a symlink for it.
Expand Down