diff --git a/completion/xdg-app b/completion/xdg-app
index 1d924cd9..c8b0561c 100755
--- a/completion/xdg-app
+++ b/completion/xdg-app
@@ -28,12 +28,12 @@ _xdg-app() {
[LIST_REMOTES]='--show-urls'
[REPO_CONTENTS]='--show-details --runtimes --apps --update'
[UNINSTALL]='--keep-ref'
- [RUN]='--command --branch --devel'
+ [RUN]='--command --branch --devel --forbid'
[BUILD_INIT]='--arch --var'
[BUILD]='--runtime --network --x11'
[BUILD_FINISH]='--command --allow'
[BUILD_EXPORT]='--subject --body'
- [ARG]='--arch --command --branch --var --allow --subject --body'
+ [ARG]='--arch --command --branch --var --allow --forbid --subject --body'
)
if __contains_word "--user" ${COMP_WORDS[*]}; then
@@ -53,7 +53,7 @@ _xdg-app() {
--var)
comps=$(xdg-app $mode list-runtimes)
;;
- --allow)
+ --allow|--forbid)
comps='x11 wayland ipc pulseaudio system-dbus session-dbus network host-fs homedir'
;;
--branch|--subject|--body)
diff --git a/doc/xdg-app-run.xml b/doc/xdg-app-run.xml
index 6d3918a2..8ef3db6e 100644
--- a/doc/xdg-app-run.xml
+++ b/doc/xdg-app-run.xml
@@ -51,6 +51,12 @@
directory at /var, whose content is preserved between
application runs. The application itself is mounted at /self.
+
+ The details of the sandboxed environment are controlled by the application
+ metadata and the --forbid option that are passed to the run command: Access
+ is allowed if the application requested it in its metadata file and the
+ user hasn;t forbidden it.
+
@@ -110,6 +116,17 @@
+
+
+
+
+ Disallow access to the named facility. KEY must
+ be one of: x11, wayland, ipc, pulseaudio, system-dbus,
+ session-dbus, network, host-fs, homedir.
+ This option can be used multiple times.
+
+
+
diff --git a/xdg-app-builtins-run.c b/xdg-app-builtins-run.c
index 6433254a..383720b5 100644
--- a/xdg-app-builtins-run.c
+++ b/xdg-app-builtins-run.c
@@ -17,6 +17,7 @@ static char *opt_branch;
static char *opt_command;
static gboolean opt_devel;
static char *opt_runtime;
+static char **opt_forbid;
static GOptionEntry options[] = {
{ "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, "Arch to use", "ARCH" },
@@ -24,6 +25,7 @@ static GOptionEntry options[] = {
{ "branch", 0, 0, G_OPTION_ARG_STRING, &opt_branch, "Branch to use", "BRANCH" },
{ "devel", 'd', 0, G_OPTION_ARG_NONE, &opt_devel, "Use development runtime", NULL },
{ "runtime", 0, 0, G_OPTION_ARG_STRING, &opt_runtime, "Runtime to use", "RUNTIME" },
+ { "forbid", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_forbid, "Environment options to set to false", "KEY" },
{ NULL }
};
@@ -259,6 +261,12 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **
const char *command = "/bin/sh";
int i;
int rest_argv_start, rest_argc;
+ const char *environment_keys[] = {
+ "x11", "wayland", "ipc", "pulseaudio", "system-dbus", "session-dbus",
+ "network", "host-fs", "homedir", NULL
+ };
+ const char *no_opts[1] = { NULL };
+ const char **forbid;
context = g_option_context_new ("APP [args...] - Run an app");
@@ -399,34 +407,89 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **
}
}
- if (g_key_file_get_boolean (metakey, "Environment", "ipc", NULL))
- g_ptr_array_add (argv_array, g_strdup ("-i"));
-
- if (g_key_file_get_boolean (metakey, "Environment", "host-fs", NULL))
- g_ptr_array_add (argv_array, g_strdup ("-f"));
-
- if (g_key_file_get_boolean (metakey, "Environment", "homedir", NULL))
- g_ptr_array_add (argv_array, g_strdup ("-H"));
-
- if (g_key_file_get_boolean (metakey, "Environment", "network", NULL))
- g_ptr_array_add (argv_array, g_strdup ("-n"));
-
- if (g_key_file_get_boolean (metakey, "Environment", "x11", NULL))
- xdg_app_run_add_x11_args (argv_array);
+ if (opt_forbid)
+ forbid = (const char **)opt_forbid;
else
- xdg_app_run_add_no_x11_args (argv_array);
+ forbid = no_opts;
- if (g_key_file_get_boolean (metakey, "Environment", "wayland", NULL))
- xdg_app_run_add_wayland_args (argv_array);
+ for (i = 0; forbid[i]; i++)
+ {
+ const char *key;
- if (g_key_file_get_boolean (metakey, "Environment", "pulseaudio", NULL))
- xdg_app_run_add_pulseaudio_args (argv_array);
+ key = forbid[i];
+ if (!g_strv_contains (environment_keys, key))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown Environment key %s", key);
+ goto out;
+ }
+ }
- if (g_key_file_get_boolean (metakey, "Environment", "system-dbus", NULL))
- xdg_app_run_add_system_dbus_args (argv_array);
+ if (g_key_file_get_boolean (metakey, "Environment", "ipc", NULL) &&
+ !g_strv_contains (forbid, "ipc"))
+ {
+ g_debug ("Allowing ipc access");
+ g_ptr_array_add (argv_array, g_strdup ("-i"));
+ }
- if (g_key_file_get_boolean (metakey, "Environment", "session-dbus", NULL))
- xdg_app_run_add_session_dbus_args (argv_array);
+ if (g_key_file_get_boolean (metakey, "Environment", "host-fs", NULL) &&
+ !g_strv_contains (forbid, "host-fs"))
+ {
+ g_debug ("Allowing host-fs access");
+ g_ptr_array_add (argv_array, g_strdup ("-f"));
+ }
+
+ if (g_key_file_get_boolean (metakey, "Environment", "homedir", NULL) &&
+ !g_strv_contains (forbid, "homedir"))
+ {
+ g_debug ("Allowing homedir access");
+ g_ptr_array_add (argv_array, g_strdup ("-H"));
+ }
+
+ if (g_key_file_get_boolean (metakey, "Environment", "network", NULL) &&
+ !g_strv_contains (forbid, "network"))
+ {
+ g_debug ("Allowing network access");
+ g_ptr_array_add (argv_array, g_strdup ("-n"));
+ }
+
+ if (g_key_file_get_boolean (metakey, "Environment", "x11", NULL) &&
+ !g_strv_contains (forbid, "x11"))
+ {
+ g_debug ("Allowing x11 access");
+ xdg_app_run_add_x11_args (argv_array);
+ }
+ else
+ {
+ xdg_app_run_add_no_x11_args (argv_array);
+ }
+
+ if (g_key_file_get_boolean (metakey, "Environment", "wayland", NULL) &&
+ !g_strv_contains (forbid, "wayland"))
+ {
+ g_debug ("Allowing wayland access");
+ xdg_app_run_add_wayland_args (argv_array);
+ }
+
+ if (g_key_file_get_boolean (metakey, "Environment", "pulseaudio", NULL) &&
+ !g_strv_contains (forbid, "pulseaudio"))
+ {
+ g_debug ("Allowing pulseaudio access");
+ xdg_app_run_add_pulseaudio_args (argv_array);
+ }
+
+ if (g_key_file_get_boolean (metakey, "Environment", "system-dbus", NULL) &&
+ !g_strv_contains (forbid, "system-dbus"));
+ {
+ g_debug ("Allowing system-dbus access");
+ xdg_app_run_add_system_dbus_args (argv_array);
+ }
+
+ if (g_key_file_get_boolean (metakey, "Environment", "session-dbus", NULL) &&
+ !g_strv_contains (forbid, "session-dbus"))
+ {
+ g_debug ("Allowing session-dbus access");
+ xdg_app_run_add_session_dbus_args (argv_array);
+ }
g_ptr_array_add (argv_array, g_strdup ("-a"));
g_ptr_array_add (argv_array, g_file_get_path (app_files));