From dbf8d44df8ed36fd4345c65b10fadd22c5572cf9 Mon Sep 17 00:00:00 2001 From: Glenn Washburn Date: Wed, 10 Oct 2018 04:16:49 -0500 Subject: Add support for rudimentary conditionals in profiles, currently only the HAS_APPIMAGE conditional is supported. --- etc/whitelist-common.inc | 1 + src/firejail/profile.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/etc/whitelist-common.inc b/etc/whitelist-common.inc index e1fa809b4..92ee288dc 100644 --- a/etc/whitelist-common.inc +++ b/etc/whitelist-common.inc @@ -13,6 +13,7 @@ whitelist ${HOME}/.config/user-dirs.dirs read-only ${HOME}/.config/user-dirs.dirs whitelist ${HOME}/.drirc whitelist ${HOME}/.icons +?HAS_APPIMAGE: whitelist ${HOME}/.local/share/appimagekit whitelist ${HOME}/.local/share/applications read-only ${HOME}/.local/share/applications whitelist ${HOME}/.local/share/icons diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 4fc710f39..751347b29 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -132,12 +132,99 @@ void profile_add_ignore(const char *str) { } +int profile_check_conditional(char *ptr, int lineno, const char *fname) { + struct cond_t { + char *name; // conditional name + size_t len; // length of name + bool value; // true if set + } conditionals[] = { + {"HAS_APPIMAGE", strlen("HAS_APPIMAGE"), arg_appimage!=0}, + NULL + }, *cond = conditionals; + char *tmp = ptr, *msg = NULL; + + if (*ptr++ != '?') + return 1; + + while (cond->name) { + // continue if not this conditional + if (strncmp(ptr, cond->name, cond->len) != 0) { + cond++; + continue; + } + ptr += cond->len; + + if (*ptr == ' ') + ptr++; + if (*ptr++ != ':') { + msg = "invalid syntax: colon must come after conditional"; + ptr = tmp; + goto error; + } + if (*ptr == '\0') { + msg = "invalid conditional line: no profile line after conditional"; + ptr = tmp; + goto error; + } + if (*ptr == ' ') + ptr++; + + // if set, continue processing statement in caller + if (cond->value) { + // move ptr to start of profile line + ptr = strdup(ptr); + if (!ptr) + errExit("strdup"); + + // check that the profile line does not contain either + // quiet or include directives + if ((strncmp(ptr, "quiet", 5) == 0) || + (strncmp(ptr, "include", 7) == 0)) { + msg = "invalid profile line: quiet and include not allowed in conditionals"; + ptr = tmp; + goto error; + } + free(tmp); + + // verify syntax, exit in case of error + if (profile_check_line(ptr, lineno, fname)) + profile_add(ptr); + } + // tell caller to ignore + return 0; + } + + tmp = ptr; + // get the conditional used + while (*tmp != ':' && *tmp != '\0') + tmp++; + *tmp = '\0'; + + // this was a '?' prefix, but didn't match any of the conditionals + msg = "invalid/unsupported conditional"; + +error: + fprintf(stderr, "Error: %s (\"%s\"", msg, ptr); + if (lineno == 0) ; + else if (fname != NULL) + fprintf(stderr, " on line %d in %s", lineno, fname); + else + fprintf(stderr, " on line %d in the custom profile", lineno); + fprintf(stderr, ")\n"); + exit(1); +} + + // check profile line; if line == 0, this was generated from a command line option // return 1 if the command is to be added to the linked list of profile commands // return 0 if the command was already executed inside the function int profile_check_line(char *ptr, int lineno, const char *fname) { EUID_ASSERT(); + // check and process conditional profile lines + if (profile_check_conditional(ptr, lineno, fname) == 0) + return 0; + // check ignore list if (is_in_ignore_list(ptr)) return 0; -- cgit v1.2.3-54-g00ecf From b9e74120dd771e077c29355192827b12fc15a631 Mon Sep 17 00:00:00 2001 From: Glenn Washburn Date: Wed, 10 Oct 2018 04:45:48 -0500 Subject: Update documentation for profile conditionals. --- src/man/firejail-profile.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index 5daca8abd..ca7b52a51 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt @@ -86,6 +86,18 @@ Example: "blacklist ~/My Virtual Machines" .TP \fB# this is a comment +.TP +\fB?CONDITIONAL: profile line +Conditionally add profile line. + +Example: "?HAS_APPIMAGE: whitelist ${HOME}/special/appimage/dir" + +This example will load the whitelist profile line only if the \-\-appimage option has been specified on the command line. + +Currently the only conditional supported is HAS_APPIMAGE. + +The profile line may be any profile line that you would normally use in a profile \fBexcept\fR for "quiet" and "include" lines. + .TP \fBinclude other.profile Include other.profile file. -- cgit v1.2.3-54-g00ecf