diff --git a/app/xdg-app-builtins-build.c b/app/xdg-app-builtins-build.c
index afc2bb39..5042023e 100644
--- a/app/xdg-app-builtins-build.c
+++ b/app/xdg-app-builtins-build.c
@@ -156,7 +156,7 @@ xdg_app_builtin_build (int argc, char **argv, GCancellable *cancellable, GError
xdg_app_context_allow_host_fs (app_context);
xdg_app_context_merge (app_context, arg_context);
- xdg_app_run_add_environment_args (argv_array, NULL, app_id,
+ xdg_app_run_add_environment_args (argv_array, NULL, NULL, app_id,
app_context, NULL);
if (!custom_usr &&
diff --git a/common/xdg-app-run.c b/common/xdg-app-run.c
index 7f722a95..1a7cd35d 100644
--- a/common/xdg-app-run.c
+++ b/common/xdg-app-run.c
@@ -95,7 +95,8 @@ struct XdgAppContext {
GHashTable *env_vars;
GHashTable *persistent;
GHashTable *filesystems;
- GHashTable *bus_policy;
+ GHashTable *session_bus_policy;
+ GHashTable *system_bus_policy;
};
XdgAppContext *
@@ -107,7 +108,8 @@ xdg_app_context_new (void)
context->env_vars = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
context->persistent = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
context->filesystems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- context->bus_policy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ context->session_bus_policy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ context->system_bus_policy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
return context;
}
@@ -118,7 +120,8 @@ xdg_app_context_free (XdgAppContext *context)
g_hash_table_destroy (context->env_vars);
g_hash_table_destroy (context->persistent);
g_hash_table_destroy (context->filesystems);
- g_hash_table_destroy (context->bus_policy);
+ g_hash_table_destroy (context->session_bus_policy);
+ g_hash_table_destroy (context->system_bus_policy);
g_slice_free (XdgAppContext, context);
}
@@ -208,7 +211,6 @@ xdg_app_policy_to_string (XdgAppPolicy policy)
return "none";
}
-
static gboolean
xdg_app_verify_dbus_name (const char *name, GError **error)
{
@@ -325,7 +327,15 @@ xdg_app_context_set_session_bus_policy (XdgAppContext *context,
const char *name,
XdgAppPolicy policy)
{
- g_hash_table_insert (context->bus_policy, g_strdup (name), GINT_TO_POINTER (policy));
+ g_hash_table_insert (context->session_bus_policy, g_strdup (name), GINT_TO_POINTER (policy));
+}
+
+void
+xdg_app_context_set_system_bus_policy (XdgAppContext *context,
+ const char *name,
+ XdgAppPolicy policy)
+{
+ g_hash_table_insert (context->system_bus_policy, g_strdup (name), GINT_TO_POINTER (policy));
}
static void
@@ -478,9 +488,13 @@ xdg_app_context_merge (XdgAppContext *context,
while (g_hash_table_iter_next (&iter, &key, &value))
g_hash_table_insert (context->filesystems, g_strdup (key), value);
- g_hash_table_iter_init (&iter, other->bus_policy);
+ g_hash_table_iter_init (&iter, other->session_bus_policy);
while (g_hash_table_iter_next (&iter, &key, &value))
- g_hash_table_insert (context->bus_policy, g_strdup (key), value);
+ g_hash_table_insert (context->session_bus_policy, g_strdup (key), value);
+
+ g_hash_table_iter_init (&iter, other->system_bus_policy);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ g_hash_table_insert (context->system_bus_policy, g_strdup (key), value);
}
static gboolean
@@ -670,6 +684,36 @@ option_talk_name_cb (const gchar *option_name,
return TRUE;
}
+static gboolean
+option_system_own_name_cb (const gchar *option_name,
+ const gchar *value,
+ gpointer data,
+ GError **error)
+{
+ XdgAppContext *context = data;
+
+ if (!xdg_app_verify_dbus_name (value, error))
+ return FALSE;
+
+ xdg_app_context_set_system_bus_policy (context, value, XDG_APP_POLICY_OWN);
+ return TRUE;
+}
+
+static gboolean
+option_system_talk_name_cb (const gchar *option_name,
+ const gchar *value,
+ gpointer data,
+ GError **error)
+{
+ XdgAppContext *context = data;
+
+ if (!xdg_app_verify_dbus_name (value, error))
+ return FALSE;
+
+ xdg_app_context_set_system_bus_policy (context, value, XDG_APP_POLICY_TALK);
+ return TRUE;
+}
+
static gboolean
option_persist_cb (const gchar *option_name,
const gchar *value,
@@ -694,6 +738,8 @@ static GOptionEntry context_options[] = {
{ "env", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_env_cb, "Set environment variable", "VAR=VALUE" },
{ "own-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_own_name_cb, "Allow app to own name on the session bus", "DBUS_NAME" },
{ "talk-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_talk_name_cb, "Allow app to talk to name on the session bus", "DBUS_NAME" },
+ { "system-own-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_system_own_name_cb, "Allow app to own name on the system bus", "DBUS_NAME" },
+ { "system-talk-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_system_talk_name_cb, "Allow app to talk to name on the system bus", "DBUS_NAME" },
{ "persist", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_persist_cb, "Persist home directory directory", "FILENAME" },
{ NULL }
};
@@ -849,6 +895,29 @@ xdg_app_context_load_metadata (XdgAppContext *context,
}
}
+ if (g_key_file_has_group (metakey, XDG_APP_METADATA_GROUP_SYSTEM_BUS_POLICY))
+ {
+ g_auto(GStrv) keys = NULL;
+ gsize i, keys_count;
+
+ keys = g_key_file_get_keys (metakey, XDG_APP_METADATA_GROUP_SYSTEM_BUS_POLICY, &keys_count, NULL);
+ for (i = 0; i < keys_count; i++)
+ {
+ const char *key = keys[i];
+ g_autofree char *value = g_key_file_get_string (metakey, XDG_APP_METADATA_GROUP_SYSTEM_BUS_POLICY, key, NULL);
+ XdgAppPolicy policy;
+
+ if (!xdg_app_verify_dbus_name (key, error))
+ return FALSE;
+
+ policy = xdg_app_policy_from_string (value, error);
+ if ((int)policy == -1)
+ return FALSE;
+
+ xdg_app_context_set_system_bus_policy (context, key, policy);
+ }
+ }
+
if (g_key_file_has_group (metakey, XDG_APP_METADATA_GROUP_ENVIRONMENT))
{
g_auto(GStrv) keys = NULL;
@@ -952,7 +1021,7 @@ xdg_app_context_save_metadata (XdgAppContext *context,
NULL);
g_key_file_remove_group (metakey, XDG_APP_METADATA_GROUP_SESSION_BUS_POLICY, NULL);
- g_hash_table_iter_init (&iter, context->bus_policy);
+ g_hash_table_iter_init (&iter, context->session_bus_policy);
while (g_hash_table_iter_next (&iter, &key, &value))
{
XdgAppPolicy policy = GPOINTER_TO_INT (value);
@@ -962,6 +1031,17 @@ xdg_app_context_save_metadata (XdgAppContext *context,
(char *)key, xdg_app_policy_to_string (policy));
}
+ g_key_file_remove_group (metakey, XDG_APP_METADATA_GROUP_SYSTEM_BUS_POLICY, NULL);
+ g_hash_table_iter_init (&iter, context->system_bus_policy);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ XdgAppPolicy policy = GPOINTER_TO_INT (value);
+ if (policy > 0)
+ g_key_file_set_string (metakey,
+ XDG_APP_METADATA_GROUP_SYSTEM_BUS_POLICY,
+ (char *)key, xdg_app_policy_to_string (policy));
+ }
+
g_key_file_remove_group (metakey, XDG_APP_METADATA_GROUP_ENVIRONMENT, NULL);
g_hash_table_iter_init (&iter, context->env_vars);
while (g_hash_table_iter_next (&iter, &key, &value))
@@ -1140,11 +1220,14 @@ create_proxy_socket (char *template)
return g_steal_pointer (&proxy_socket);
}
-void
-xdg_app_run_add_system_dbus_args (GPtrArray *argv_array,
- GPtrArray *dbus_proxy_argv)
+gboolean
+xdg_app_run_add_system_dbus_args (XdgAppContext *context,
+ GPtrArray *argv_array,
+ GPtrArray *dbus_proxy_argv,
+ gboolean unrestricted)
{
const char *dbus_address = g_getenv ("DBUS_SYSTEM_BUS_ADDRESS");
+ g_autofree char *real_dbus_address = NULL;
char *dbus_system_socket = NULL;
if (dbus_address != NULL)
@@ -1152,24 +1235,35 @@ xdg_app_run_add_system_dbus_args (GPtrArray *argv_array,
else if (g_file_test ("/var/run/dbus/system_bus_socket", G_FILE_TEST_EXISTS))
dbus_system_socket = g_strdup ("/var/run/dbus/system_bus_socket");
- if (dbus_system_socket != NULL)
+ if (dbus_system_socket != NULL && unrestricted)
{
g_ptr_array_add (argv_array, g_strdup ("-D"));
g_ptr_array_add (argv_array, dbus_system_socket);
+
+ return TRUE;
}
- else if (dbus_proxy_argv && dbus_address != NULL)
+ else if (dbus_proxy_argv &&
+ g_hash_table_size (context->system_bus_policy) > 0)
{
g_autofree char *proxy_socket = create_proxy_socket ("system-bus-proxy-XXXXXX");
if (proxy_socket == NULL)
- return;
+ return FALSE;
- g_ptr_array_add (dbus_proxy_argv, g_strdup (dbus_address));
+ if (dbus_address)
+ real_dbus_address = g_strdup (dbus_address);
+ else
+ real_dbus_address = g_strdup_printf ("unix:path=%s", dbus_system_socket);
+
+ g_ptr_array_add (dbus_proxy_argv, g_strdup (real_dbus_address));
g_ptr_array_add (dbus_proxy_argv, g_strdup (proxy_socket));
g_ptr_array_add (argv_array, g_strdup ("-D"));
g_ptr_array_add (argv_array, g_strdup (proxy_socket));
+
+ return TRUE;
}
+ return FALSE;
}
gboolean
@@ -1212,6 +1306,7 @@ xdg_app_run_add_session_dbus_args (GPtrArray *argv_array,
static void
xdg_app_add_bus_filters (GPtrArray *dbus_proxy_argv,
+ GHashTable *ht,
const char *app_id,
XdgAppContext *context)
{
@@ -1219,10 +1314,13 @@ xdg_app_add_bus_filters (GPtrArray *dbus_proxy_argv,
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));
+ if (app_id)
+ {
+ 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));
+ }
- g_hash_table_iter_init (&iter, context->bus_policy);
+ g_hash_table_iter_init (&iter, ht);
while (g_hash_table_iter_next (&iter, &key, &value))
{
XdgAppPolicy policy = GPOINTER_TO_INT (value);
@@ -1276,7 +1374,8 @@ xdg_app_run_add_extension_args (GPtrArray *argv_array,
void
xdg_app_run_add_environment_args (GPtrArray *argv_array,
- GPtrArray *dbus_proxy_argv,
+ GPtrArray *session_bus_proxy_argv,
+ GPtrArray *system_bus_proxy_argv,
const char *app_id,
XdgAppContext *context,
GFile *app_id_dir)
@@ -1284,6 +1383,7 @@ xdg_app_run_add_environment_args (GPtrArray *argv_array,
GHashTableIter iter;
gpointer key, value;
gboolean unrestricted_session_bus;
+ gboolean unrestricted_system_bus;
gboolean home_access = FALSE;
GString *xdg_dirs_conf = NULL;
char opts[16];
@@ -1475,16 +1575,20 @@ xdg_app_run_add_environment_args (GPtrArray *argv_array,
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)
+ if (xdg_app_run_add_session_dbus_args (argv_array, session_bus_proxy_argv, unrestricted_session_bus) &&
+ !unrestricted_session_bus && session_bus_proxy_argv)
{
- xdg_app_add_bus_filters (dbus_proxy_argv, app_id, context);
+ xdg_app_add_bus_filters (session_bus_proxy_argv, context->session_bus_policy, app_id, context);
}
- if (context->sockets & XDG_APP_CONTEXT_SOCKET_SYSTEM_BUS)
+ unrestricted_system_bus = (context->sockets & XDG_APP_CONTEXT_SOCKET_SYSTEM_BUS) != 0;
+ if (unrestricted_system_bus)
+ g_debug ("Allowing system-dbus access");
+ if (xdg_app_run_add_system_dbus_args (context, argv_array, system_bus_proxy_argv,
+ unrestricted_system_bus) &&
+ !unrestricted_system_bus && system_bus_proxy_argv)
{
- g_debug ("Allowing system-dbus access");
- xdg_app_run_add_system_dbus_args (argv_array, dbus_proxy_argv);
+ xdg_app_add_bus_filters (system_bus_proxy_argv, context->system_bus_policy, NULL, context);
}
g_assert (sizeof(opts) > i);
@@ -2039,7 +2143,8 @@ xdg_app_run_app (const char *app_ref,
g_autoptr(GKeyFile) runtime_metakey = NULL;
g_autoptr(GPtrArray) argv_array = NULL;
g_auto(GStrv) envp = NULL;
- g_autoptr(GPtrArray) dbus_proxy_argv = NULL;
+ g_autoptr(GPtrArray) session_bus_proxy_argv = NULL;
+ g_autoptr(GPtrArray) system_bus_proxy_argv = NULL;
const char *command = "/bin/sh";
g_autoptr(GError) my_error = NULL;
g_auto(GStrv) runtime_parts = NULL;
@@ -2055,7 +2160,8 @@ xdg_app_run_app (const char *app_ref,
metakey = xdg_app_deploy_get_metadata (app_deploy);
argv_array = g_ptr_array_new_with_free_func (g_free);
- dbus_proxy_argv = g_ptr_array_new_with_free_func (g_free);
+ session_bus_proxy_argv = g_ptr_array_new_with_free_func (g_free);
+ system_bus_proxy_argv = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (argv_array, g_strdup (HELPER));
g_ptr_array_add (argv_array, g_strdup ("-l"));
@@ -2135,7 +2241,9 @@ xdg_app_run_app (const char *app_ref,
add_document_portal_args (argv_array, app_ref_parts[1]);
- xdg_app_run_add_environment_args (argv_array, dbus_proxy_argv,
+ xdg_app_run_add_environment_args (argv_array,
+ session_bus_proxy_argv,
+ system_bus_proxy_argv,
app_ref_parts[1], app_context, app_id_dir);
if ((flags & XDG_APP_RUN_FLAG_DEVEL) != 0)
@@ -2148,7 +2256,10 @@ xdg_app_run_app (const char *app_ref,
if (!xdg_app_run_in_transient_unit (app_ref_parts[1], error))
return FALSE;
- if (!add_dbus_proxy_args (argv_array, dbus_proxy_argv, error))
+ if (!add_dbus_proxy_args (argv_array, session_bus_proxy_argv, error))
+ return FALSE;
+
+ if (!add_dbus_proxy_args (argv_array, system_bus_proxy_argv, error))
return FALSE;
app_files = xdg_app_deploy_get_files (app_deploy);
diff --git a/common/xdg-app-run.h b/common/xdg-app-run.h
index fad0957b..00390075 100644
--- a/common/xdg-app-run.h
+++ b/common/xdg-app-run.h
@@ -30,6 +30,7 @@ gboolean xdg_app_run_in_transient_unit (const char *app_id,
#define XDG_APP_METADATA_GROUP_CONTEXT "Context"
#define XDG_APP_METADATA_GROUP_SESSION_BUS_POLICY "Session Bus Policy"
+#define XDG_APP_METADATA_GROUP_SYSTEM_BUS_POLICY "System Bus Policy"
#define XDG_APP_METADATA_GROUP_ENVIRONMENT "Environment"
#define XDG_APP_METADATA_KEY_SHARED "shared"
#define XDG_APP_METADATA_KEY_SOCKETS "sockets"
@@ -51,6 +52,9 @@ void xdg_app_context_allow_host_fs (XdgAppContext
void xdg_app_context_set_session_bus_policy (XdgAppContext *context,
const char *name,
XdgAppPolicy policy);
+void xdg_app_context_set_system_bus_policy (XdgAppContext *context,
+ const char *name,
+ XdgAppPolicy policy);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(XdgAppContext, xdg_app_context_free)
@@ -60,7 +64,8 @@ gboolean xdg_app_run_add_extension_args (GPtrArray *argv_array,
GCancellable *cancellable,
GError **error);
void xdg_app_run_add_environment_args (GPtrArray *argv_array,
- GPtrArray *dbus_proxy_argv,
+ GPtrArray *session_bus_proxy_argv,
+ GPtrArray *system_bus_proxy_argv,
const char *app_id,
XdgAppContext *context,
GFile *app_id_dir);
diff --git a/doc/xdg-app-build-finish.xml b/doc/xdg-app-build-finish.xml
index c1db6d72..8b323f95 100644
--- a/doc/xdg-app-build-finish.xml
+++ b/doc/xdg-app-build-finish.xml
@@ -197,6 +197,27 @@
+
+
+
+
+ Allow the application to own the well known name NAME on the system bus.
+ This updates the [System Bus Policy] group in the metadata.
+ This overrides to the Context section from the application metadata.
+ This option can be used multiple times.
+
+
+
+
+
+
+
+ Allow the application to talk to the well known name NAME on the system bus.
+ This updates the [System Bus Policy] group in the metadata.
+ This option can be used multiple times.
+
+
+