From 942e4bcdb618bc4bd3caa6c81fff3b97fc367b9d Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Fri, 22 May 2015 16:55:45 +0200 Subject: [PATCH] Convert all builtins to the new metadata/arg formats using XdgAppContext --- xdg-app-builtins-build-finish.c | 65 +++-------- xdg-app-builtins-build.c | 22 ++-- xdg-app-builtins-run.c | 30 +++-- xdg-app-run.c | 190 +++++++++++--------------------- xdg-app-run.h | 9 +- 5 files changed, 102 insertions(+), 214 deletions(-) diff --git a/xdg-app-builtins-build-finish.c b/xdg-app-builtins-build-finish.c index 4aeaef39..bff0f30a 100644 --- a/xdg-app-builtins-build-finish.c +++ b/xdg-app-builtins-build-finish.c @@ -31,15 +31,12 @@ #include "xdg-app-builtins.h" #include "xdg-app-utils.h" +#include "xdg-app-run.h" static char *opt_command; -static char **opt_allow; -static char **opt_env_override; static GOptionEntry options[] = { { "command", 0, 0, G_OPTION_ARG_STRING, &opt_command, "Command to set", "COMMAND" }, - { "allow", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_allow, "Environment options to set to true", "KEY" }, - { "env", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_env_override, "Override an environment variable", "VARIABLE=[VALUE]" }, { NULL } }; @@ -216,19 +213,14 @@ out: } static gboolean -update_metadata (GFile *base, GCancellable *cancellable, GError **error) +update_metadata (GFile *base, XdgAppContext *arg_context, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autoptr(GFile) metadata = NULL; g_autofree char *path = NULL; g_autoptr(GKeyFile) keyfile = NULL; + g_autoptr(XdgAppContext) app_context = NULL; GError *temp_error = NULL; - const char *environment_keys[] = { - "x11", "wayland", "ipc", "pulseaudio", "system-dbus", "session-dbus", - "network", "host-fs", "homedir", "dri", NULL - }; - const char *key; - int i; metadata = g_file_get_child (base, "metadata"); if (!g_file_query_exists (metadata, cancellable)) @@ -294,46 +286,11 @@ update_metadata (GFile *base, GCancellable *cancellable, GError **error) } } - g_debug ("Setting environment"); - - for (i = 0; environment_keys[i]; i++) - { - key = environment_keys[i]; - g_key_file_set_boolean (keyfile, "Environment", key, FALSE); - } - - if (opt_allow) - { - for (i = 0; opt_allow[i]; i++) - { - key = opt_allow[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; - } - - g_key_file_set_boolean (keyfile, "Environment", key, TRUE); - } - } - - if (opt_env_override) - { - for (i = 0; opt_env_override[i]; i++) - { - glnx_strfreev char **split = g_strsplit (opt_env_override[i], "=", 2); - if (split && split[0] && split[1]) - { - g_key_file_set_string (keyfile, "Environment Vars", split[0], split[1]); - } - else - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Cannot parse variable %s", opt_env_override[i]); - goto out; - } - } - } - + app_context = xdg_app_context_new (); + if (!xdg_app_context_load_metadata (app_context, keyfile, error)) + goto out; + xdg_app_context_merge (app_context, arg_context); + xdg_app_context_save_metadata (app_context, keyfile); if (!g_key_file_save_to_file (keyfile, path, error)) goto out; @@ -363,9 +320,13 @@ xdg_app_builtin_build_finish (int argc, char **argv, GCancellable *cancellable, gsize metadata_size; const char *directory; g_autoptr(GKeyFile) metakey = NULL; + g_autoptr(XdgAppContext) arg_context = NULL; context = g_option_context_new ("DIRECTORY - Convert a directory to a bundle"); + arg_context = xdg_app_context_new (); + g_option_context_add_group (context, xdg_app_context_get_options (arg_context)); + if (!xdg_app_option_context_parse (context, options, &argc, &argv, XDG_APP_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error)) goto out; @@ -412,7 +373,7 @@ xdg_app_builtin_build_finish (int argc, char **argv, GCancellable *cancellable, goto out; g_debug ("Updating metadata"); - if (!update_metadata (base, cancellable, error)) + if (!update_metadata (base, arg_context, cancellable, error)) goto out; g_print ("Please review the exported files and the metadata\n"); diff --git a/xdg-app-builtins-build.c b/xdg-app-builtins-build.c index f3943255..864c41c9 100644 --- a/xdg-app-builtins-build.c +++ b/xdg-app-builtins-build.c @@ -34,13 +34,9 @@ #include "xdg-app-run.h" static gboolean opt_runtime; -static char **opt_allow; -static char **opt_forbid; static GOptionEntry options[] = { { "runtime", 'r', 0, G_OPTION_ARG_NONE, &opt_runtime, "Use non-devel runtime", NULL }, - { "allow", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_allow, "Environment options to set to true", "KEY" }, - { "forbid", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_forbid, "Environment options to set to false", "KEY" }, { NULL } }; @@ -77,6 +73,8 @@ xdg_app_builtin_build (int argc, char **argv, GCancellable *cancellable, GError g_autofree char *app_id = NULL; int i; int rest_argv_start, rest_argc; + g_autoptr(XdgAppContext) arg_context = NULL; + g_autoptr(XdgAppContext) app_context = NULL; context = g_option_context_new ("DIRECTORY [COMMAND [args...]] - Build in directory"); @@ -93,6 +91,9 @@ xdg_app_builtin_build (int argc, char **argv, GCancellable *cancellable, GError } } + arg_context = xdg_app_context_new (); + g_option_context_add_group (context, xdg_app_context_get_options (arg_context)); + if (!xdg_app_option_context_parse (context, options, &argc, &argv, XDG_APP_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error)) goto out; @@ -147,16 +148,15 @@ xdg_app_builtin_build (int argc, char **argv, GCancellable *cancellable, GError g_ptr_array_add (argv_array, g_strdup ("-H")); g_ptr_array_add (argv_array, g_strdup ("-r")); - if (!xdg_app_run_verify_environment_keys ((const char **)opt_forbid, error)) + app_context = xdg_app_context_new (); + if (!xdg_app_context_load_metadata (app_context, runtime_metakey, error)) goto out; - - if (!xdg_app_run_verify_environment_keys ((const char **)opt_allow, error)) + if (!xdg_app_context_load_metadata (app_context, metakey, error)) goto out; + xdg_app_context_merge (app_context, arg_context); xdg_app_run_add_environment_args (argv_array, NULL, app_id, - runtime_metakey, metakey, - (const char **)opt_allow, - (const char **)opt_forbid); + app_context); g_ptr_array_add (argv_array, g_strdup ("-w")); g_ptr_array_add (argv_array, g_strdup ("-a")); @@ -172,7 +172,7 @@ xdg_app_builtin_build (int argc, char **argv, GCancellable *cancellable, GError g_ptr_array_add (argv_array, NULL); envp = xdg_app_run_get_minimal_env (TRUE); - envp = xdg_app_run_apply_env_vars (envp, runtime_metakey); + envp = xdg_app_run_apply_env_vars (envp, app_context); if (!execve (HELPER, (char **)argv_array->pdata, envp)) { diff --git a/xdg-app-builtins-run.c b/xdg-app-builtins-run.c index 190374a3..dc10bac8 100644 --- a/xdg-app-builtins-run.c +++ b/xdg-app-builtins-run.c @@ -40,8 +40,6 @@ static char *opt_branch; static char *opt_command; static gboolean opt_devel; static char *opt_runtime; -static char **opt_allow; -static char **opt_forbid; static GOptionEntry options[] = { { "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, "Arch to use", "ARCH" }, @@ -49,8 +47,6 @@ 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" }, - { "allow", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_allow, "Environment options to set to true", "KEY" }, - { "forbid", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_forbid, "Environment options to set to false", "KEY" }, { NULL } }; @@ -176,6 +172,8 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** int i; int rest_argv_start, rest_argc; int sync_proxy_pipes[2]; + g_autoptr(XdgAppContext) arg_context = NULL; + g_autoptr(XdgAppContext) app_context = NULL; context = g_option_context_new ("APP [args...] - Run an app"); @@ -192,6 +190,9 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** } } + arg_context = xdg_app_context_new (); + g_option_context_add_group (context, xdg_app_context_get_options (arg_context)); + if (!xdg_app_option_context_parse (context, options, &argc, &argv, XDG_APP_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error)) goto out; @@ -251,6 +252,13 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** runtime_metakey = xdg_app_deploy_get_metadata (runtime_deploy); + app_context = xdg_app_context_new (); + if (!xdg_app_context_load_metadata (app_context, runtime_metakey, error)) + goto out; + if (!xdg_app_context_load_metadata (app_context, metakey, error)) + goto out; + xdg_app_context_merge (app_context, arg_context); + if (!add_extension_args (runtime_metakey, runtime_ref, argv_array, cancellable, error)) goto out; @@ -284,16 +292,8 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** } } - if (!xdg_app_run_verify_environment_keys ((const char **)opt_forbid, error)) - goto out; - - if (!xdg_app_run_verify_environment_keys ((const char **)opt_allow, error)) - goto out; - xdg_app_run_add_environment_args (argv_array, dbus_proxy_argv, - app, runtime_metakey, metakey, - (const char **)opt_allow, - (const char **)opt_forbid); + app, app_context); g_ptr_array_add (argv_array, g_strdup ("-b")); g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/fonts=%s", SYSTEM_FONTS_DIR)); @@ -354,9 +354,7 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** envp = g_get_environ (); envp = xdg_app_run_apply_env_default (envp); - envp = xdg_app_run_apply_env_vars (envp, runtime_metakey); - /* Load application environment overrides *after* runtime */ - envp = xdg_app_run_apply_env_vars (envp, metakey); + envp = xdg_app_run_apply_env_vars (envp, app_context); envp = xdg_app_run_apply_env_appid (envp, app_id_dir); diff --git a/xdg-app-run.c b/xdg-app-run.c index 5ad29018..a29ab240 100644 --- a/xdg-app-run.c +++ b/xdg-app-run.c @@ -985,80 +985,34 @@ xdg_app_run_add_session_dbus_args (GPtrArray *argv_array, return FALSE; } -static void -xdg_app_add_bus_filters_for_meta (GPtrArray *dbus_proxy_argv, - const char *header, - GKeyFile *metakey) -{ - glnx_strfreev char **keys = NULL; - gsize i, keys_count; - - keys = g_key_file_get_keys (metakey, header, &keys_count, NULL); - if (keys) - { - for (i = 0; i < keys_count; i++) - { - const char *key = keys[i]; - const char *key_part; - g_autofree char *tmp = NULL; - g_autofree char *value = g_key_file_get_string (metakey, header, key, NULL); - - if (g_str_has_suffix (key, ".*")) - { - tmp = g_strndup (key, strlen (key) - 2); - key_part = tmp; - } - else - key_part = key; - - if (!(g_dbus_is_name (key_part) && !g_dbus_is_unique_name (key_part))) - { - g_warning ("Invalid dbus name %s\n", key); - continue; - } - - if (strcmp (value, "see") != 0 && - strcmp (value, "talk") != 0 && - strcmp (value, "own") != 0) - { - g_warning ("Invalid dbus policy: %s\n", value); - continue; - } - - g_ptr_array_add (dbus_proxy_argv, g_strdup_printf ("--%s=%s", value, key)); - } - } -} - static void xdg_app_add_bus_filters (GPtrArray *dbus_proxy_argv, const char *app_id, - GKeyFile *runtime_metakey, - GKeyFile *metakey) + XdgAppContext *context) { + GHashTableIter iter; + gpointer key, value; + g_ptr_array_add (dbus_proxy_argv, g_strdup ("--filter")); g_ptr_array_add (dbus_proxy_argv, g_strdup_printf ("--own=%s", app_id)); g_ptr_array_add (dbus_proxy_argv, g_strdup_printf ("--own=%s.*", app_id)); - xdg_app_add_bus_filters_for_meta (dbus_proxy_argv, - XDG_APP_METADATA_GROUP_SESSION_BUS_POLICY, - runtime_metakey); - if (metakey) - xdg_app_add_bus_filters_for_meta (dbus_proxy_argv, - XDG_APP_METADATA_GROUP_SESSION_BUS_POLICY, - metakey); + g_hash_table_iter_init (&iter, context->bus_policy); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + XdgAppPolicy policy = GPOINTER_TO_INT (value); + + if (policy > 0) + g_ptr_array_add (dbus_proxy_argv, g_strdup_printf ("--%s=%s", xdg_app_policy_to_string (policy), (char *)key)); + } } void xdg_app_run_add_environment_args (GPtrArray *argv_array, GPtrArray *dbus_proxy_argv, const char *app_id, - GKeyFile *runtime_metakey, - GKeyFile *metakey, - const char **allow, - const char **forbid) + XdgAppContext *context) { - const char *no_opts[1] = { NULL }; gboolean unrestricted_session_bus; char opts[16]; int i; @@ -1066,89 +1020,67 @@ xdg_app_run_add_environment_args (GPtrArray *argv_array, i = 0; opts[i++] = '-'; - if (allow == NULL) - allow = no_opts; - if (forbid == NULL) - forbid = no_opts; - - if ((g_key_file_get_boolean (metakey, "Environment", "ipc", NULL) || g_strv_contains (allow, "ipc")) && - !g_strv_contains (forbid, "ipc")) + if (context->shares & XDG_APP_CONTEXT_SHARED_IPC) { g_debug ("Allowing ipc access"); opts[i++] = 'i'; } - if ((g_key_file_get_boolean (metakey, "Environment", "dri", NULL) || g_strv_contains (allow, "dri")) && - !g_strv_contains (forbid, "dri")) - { - g_debug ("Allowing dri access"); - opts[i++] = 'g'; - } - - if ((g_key_file_get_boolean (metakey, "Environment", "host-fs", NULL) || g_strv_contains (allow, "nost-fs")) && - !g_strv_contains (forbid, "host-fs")) - { - g_debug ("Allowing host-fs access"); - opts[i++] = 'f'; - } - - if ((g_key_file_get_boolean (metakey, "Environment", "homedir", NULL) || g_strv_contains (allow, "homedir")) && - !g_strv_contains (forbid, "homedir")) - { - g_debug ("Allowing homedir access"); - opts[i++] = 'H'; - } - - if ((g_key_file_get_boolean (metakey, "Environment", "network", NULL) || g_strv_contains (allow, "network")) && - !g_strv_contains (forbid, "network")) + if (context->shares & XDG_APP_CONTEXT_SHARED_NETWORK) { g_debug ("Allowing network access"); opts[i++] = 'n'; } - if ((g_key_file_get_boolean (metakey, "Environment", "x11", NULL) || g_strv_contains (allow, "x11")) && - !g_strv_contains (forbid, "x11")) + if (context->devices & XDG_APP_CONTEXT_DEVICE_DRI) + { + g_debug ("Allowing dri access"); + opts[i++] = 'g'; + } + + if (g_hash_table_lookup (context->filesystems, "host")) + { + g_debug ("Allowing host-fs access"); + opts[i++] = 'f'; + } + else if (g_hash_table_lookup (context->filesystems, "home")) + { + g_debug ("Allowing homedir access"); + opts[i++] = 'H'; + } + + if (context->sockets & XDG_APP_CONTEXT_SOCKET_X11) { g_debug ("Allowing x11 access"); xdg_app_run_add_x11_args (argv_array); } - if ((g_key_file_get_boolean (metakey, "Environment", "wayland", NULL) || g_strv_contains (allow, "wayland")) && - !g_strv_contains (forbid, "wayland")) + if (context->sockets & XDG_APP_CONTEXT_SOCKET_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 (allow, "pulseaudio")) && - !g_strv_contains (forbid, "pulseaudio")) + if (context->sockets & XDG_APP_CONTEXT_SOCKET_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 (allow, "system-dbus")) && - !g_strv_contains (forbid, "system-dbus")) - { - g_debug ("Allowing system-dbus access"); - xdg_app_run_add_system_dbus_args (argv_array, dbus_proxy_argv); - } - - unrestricted_session_bus = - (g_key_file_get_boolean (metakey, "Environment", "session-dbus", NULL) || g_strv_contains (allow, "session-dbus")) && - !g_strv_contains (forbid, "session-dbus"); + unrestricted_session_bus = (context->sockets & XDG_APP_CONTEXT_SOCKET_SESSION_BUS) != 0; + if (unrestricted_session_bus) + g_debug ("Allowing session-dbus access"); if (xdg_app_run_add_session_dbus_args (argv_array, dbus_proxy_argv, unrestricted_session_bus) && !unrestricted_session_bus && dbus_proxy_argv) { - xdg_app_add_bus_filters (dbus_proxy_argv, app_id, - runtime_metakey, metakey); + xdg_app_add_bus_filters (dbus_proxy_argv, app_id, context); } - if ((g_key_file_get_boolean (metakey, "Environment", "session-dbus", NULL) || g_strv_contains (allow, "session-dbus")) && - !g_strv_contains (forbid, "session-dbus")) + if (context->sockets & XDG_APP_CONTEXT_SOCKET_SYSTEM_BUS) { - g_debug ("Allowing session-dbus access"); + g_debug ("Allowing system-dbus access"); + xdg_app_run_add_system_dbus_args (argv_array, dbus_proxy_argv); } g_assert (sizeof(opts) > i); @@ -1157,6 +1089,11 @@ xdg_app_run_add_environment_args (GPtrArray *argv_array, opts[i++] = 0; g_ptr_array_add (argv_array, g_strdup (opts)); } + + /* TODO: + Handle persistent + Handle detailed filesystems + */ } static const struct {const char *env; const char *val;} default_exports[] = { @@ -1277,29 +1214,26 @@ xdg_app_run_apply_env_appid (char **envp, } char ** -xdg_app_run_apply_env_vars (char **envp, GKeyFile *metakey) +xdg_app_run_apply_env_vars (char **envp, XdgAppContext *context) { - glnx_strfreev char **keys = NULL; - gsize i, keys_count; + GHashTableIter iter; + gpointer key, value; - keys = g_key_file_get_keys (metakey, "Environment Vars", &keys_count, NULL); - if (keys) + g_hash_table_iter_init (&iter, context->env_vars); + while (g_hash_table_iter_next (&iter, &key, &value)) { - for (i = 0; i < keys_count; i++) - { - const char *key = keys[i]; - g_autofree char *value = g_key_file_get_string (metakey, "Environment Vars", key, NULL); + const char *var = key; + const char *val = value; - /* We special case LD_LIBRARY_PATH to avoid passing it top - the helper */ - if (strcmp (key, "LD_LIBRARY_PATH") == 0) - key = "_LD_LIBRARY_PATH"; + /* We special case LD_LIBRARY_PATH to avoid passing it top + the helper */ + if (strcmp (var, "LD_LIBRARY_PATH") == 0) + var = "_LD_LIBRARY_PATH"; - if (value) - envp = g_environ_setenv (envp, key, value, TRUE); - else - envp = g_environ_unsetenv (envp, key); - } + if (val && val[0] != 0) + envp = g_environ_setenv (envp, var, val, TRUE); + else + envp = g_environ_unsetenv (envp, var); } return envp; diff --git a/xdg-app-run.h b/xdg-app-run.h index c4b97023..4eed8501 100644 --- a/xdg-app-run.h +++ b/xdg-app-run.h @@ -49,21 +49,16 @@ void xdg_app_context_save_metadata (XdgAppContext G_DEFINE_AUTOPTR_CLEANUP_FUNC(XdgAppContext, xdg_app_context_free) -gboolean xdg_app_run_verify_environment_keys (const char **keys, - GError **error); void xdg_app_run_add_environment_args (GPtrArray *argv_array, GPtrArray *dbus_proxy_argv, const char *app_id, - GKeyFile *runtime_metakey, - GKeyFile *metakey, - const char **allow, - const char **forbid); + XdgAppContext *context); char ** xdg_app_run_get_minimal_env (gboolean devel); char ** xdg_app_run_apply_env_default (char **envp); char ** xdg_app_run_apply_env_appid (char **envp, GFile *app_dir); char ** xdg_app_run_apply_env_vars (char **envp, - GKeyFile *metakey); + XdgAppContext *context); GFile *xdg_app_get_data_dir (const char *app_id); GFile *xdg_app_ensure_data_dir (const char *app_id,