From 6995c1703ec3d0ff281e5cb925ec1bfeeee6cf10 Mon Sep 17 00:00:00 2001 From: Allison Lortie Date: Mon, 17 Oct 2016 10:02:30 +0200 Subject: Confinement, proxied source. --- engine/Makefile.am | 3 + engine/dconf-engine-confinement.c | 45 ++++++++++++++ engine/dconf-engine-confinement.h | 31 ++++++++++ engine/dconf-engine-profile.c | 18 ++++++ engine/dconf-engine-source-private.h | 1 + engine/dconf-engine-source-proxied.c | 110 +++++++++++++++++++++++++++++++++++ engine/dconf-engine-source.c | 17 ++++++ engine/dconf-engine-source.h | 3 + 8 files changed, 228 insertions(+) create mode 100644 engine/dconf-engine-confinement.c create mode 100644 engine/dconf-engine-confinement.h create mode 100644 engine/dconf-engine-source-proxied.c diff --git a/engine/Makefile.am b/engine/Makefile.am index 0f200d5..cb67116 100644 --- a/engine/Makefile.am +++ b/engine/Makefile.am @@ -12,7 +12,10 @@ libdconf_engine_a_SOURCES = \ dconf-engine-source-user.c \ dconf-engine-source-service.c \ dconf-engine-source-system.c \ + dconf-engine-source-proxied.c \ dconf-engine-source.c \ + dconf-engine-confinement.h \ + dconf-engine-confinement.c \ dconf-engine.h \ dconf-engine.c diff --git a/engine/dconf-engine-confinement.c b/engine/dconf-engine-confinement.c new file mode 100644 index 0000000..b8bcd88 --- /dev/null +++ b/engine/dconf-engine-confinement.c @@ -0,0 +1,45 @@ +/* + * Copyright © 2016 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Allison Lortie + */ + +#include "dconf-engine-confinement.h" + +static const gchar *dconf_engine_confinement_app_id; + +gboolean +dconf_engine_confinement_detect (void) +{ + return dconf_engine_confinement_get_app_id ()[0] != '\0'; +} + +const gchar * +dconf_engine_confinement_get_app_id (void) +{ + if (g_once_init_enter (&dconf_engine_confinement_app_id)) + { + const gchar *tmp; + + tmp = g_getenv ("CONFINED_APPID"); + if (!tmp) + tmp = ""; + + g_once_init_leave (&dconf_engine_confinement_app_id, g_strdup (tmp)); + } + + return dconf_engine_confinement_app_id; +} diff --git a/engine/dconf-engine-confinement.h b/engine/dconf-engine-confinement.h new file mode 100644 index 0000000..4afb3b2 --- /dev/null +++ b/engine/dconf-engine-confinement.h @@ -0,0 +1,31 @@ +/* + * Copyright © 2016 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Allison Lortie + */ + +#ifndef __dconf_engine_confinement_h__ +#define __dconf_engine_confinement_h__ + +#include + +G_GNUC_INTERNAL +gboolean dconf_engine_confinement_detect (void); + +G_GNUC_INTERNAL +const gchar * dconf_engine_confinement_get_app_id (void); + +#endif /* __dconf_engine_confinement_h__ */ diff --git a/engine/dconf-engine-profile.c b/engine/dconf-engine-profile.c index cc9f83f..1728617 100644 --- a/engine/dconf-engine-profile.c +++ b/engine/dconf-engine-profile.c @@ -20,6 +20,7 @@ #include "config.h" +#include "dconf-engine-confinement.h" #include "dconf-engine-profile.h" #include @@ -105,6 +106,19 @@ dconf_engine_default_profile (gint *n_sources) return sources; } +static DConfEngineSource ** +dconf_engine_proxied_profile (gint *n_sources) +{ + DConfEngineSource **sources; + + sources = g_new (DConfEngineSource *, 2); + sources[0] = dconf_engine_source_new_proxied (0); + sources[1] = dconf_engine_source_new_proxied (1); + *n_sources = 2; + + return sources; +} + static DConfEngineSource * dconf_engine_profile_handle_line (gchar *line) { @@ -285,6 +299,10 @@ dconf_engine_profile_open (const gchar *profile, if (profile == NULL) file = dconf_engine_open_mandatory_profile (); + /* 2. Proxied profile in case of confinement */ + if (profile == NULL && file == NULL && dconf_engine_confinement_detect ()) + return dconf_engine_proxied_profile (n_sources); + /* 2. Environment variable */ if (profile == NULL && file == NULL) profile = g_getenv ("DCONF_PROFILE"); diff --git a/engine/dconf-engine-source-private.h b/engine/dconf-engine-source-private.h index 4f68935..debfbda 100644 --- a/engine/dconf-engine-source-private.h +++ b/engine/dconf-engine-source-private.h @@ -27,5 +27,6 @@ G_GNUC_INTERNAL extern const DConfEngineSourceVTable dconf_engine_source_file_vt G_GNUC_INTERNAL extern const DConfEngineSourceVTable dconf_engine_source_user_vtable; G_GNUC_INTERNAL extern const DConfEngineSourceVTable dconf_engine_source_service_vtable; G_GNUC_INTERNAL extern const DConfEngineSourceVTable dconf_engine_source_system_vtable; +G_GNUC_INTERNAL extern const DConfEngineSourceVTable dconf_engine_source_proxied_vtable; #endif /* __dconf_engine_source_private_h__ */ diff --git a/engine/dconf-engine-source-proxied.c b/engine/dconf-engine-source-proxied.c new file mode 100644 index 0000000..e2ac404 --- /dev/null +++ b/engine/dconf-engine-source-proxied.c @@ -0,0 +1,110 @@ +/* + * Copyright © 2010 Codethink Limited + * Copyright © 2012 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "dconf-engine-confinement.h" +#include "dconf-engine-source-private.h" + +#include "dconf-engine.h" +#include +#include +#include + +static const gchar * +dconf_engine_source_proxied_get_dir (void) +{ + static const gchar *dir; + + if (g_once_init_enter (&dir)) + { + const gchar *tmp; + + tmp = g_strdup_printf ("%s/%s", g_get_user_runtime_dir (), dconf_engine_confinement_get_app_id ()); + +#if 0 /* will be how it works when actually confined */ + tmp = g_get_user_runtime_dir (); +#endif + + g_once_init_leave (&dir, tmp); + } + + g_print ("pdir %s\n", dir); + + return dir; +} + +static void +dconf_engine_source_proxied_init (DConfEngineSource *source) +{ + source->bus_type = source->writable ? G_BUS_TYPE_SESSION : G_BUS_TYPE_NONE; + source->bus_name = g_strdup ("ca.desrt.dconf.Proxy"); + source->object_path = g_strdup_printf ("/ca/desrt/dconf/Proxy/%s", dconf_engine_confinement_get_app_id ()); +} + +static gboolean +dconf_engine_source_proxied_needs_reopen (DConfEngineSource *source) +{ + return !source->values || !gvdb_table_is_valid (source->values); +} + +static GvdbTable * +dconf_engine_source_proxied_reopen (DConfEngineSource *source) +{ + GError *error = NULL; + GvdbTable *table; + gchar *filename; + + filename = g_build_filename (dconf_engine_source_proxied_get_dir (), source->name, NULL); + table = gvdb_table_new (filename, FALSE, &error); + + if (table == NULL && source->writable) + { + g_clear_error (&error); + + /* If the file does not exist, kick the service to have it created. */ + dconf_engine_dbus_call_sync_func (source->bus_type, source->bus_name, source->object_path, + "ca.desrt.dconf.Proxy", "Init", g_variant_new ("()"), NULL, NULL); + + /* try again */ + table = gvdb_table_new (filename, FALSE, &error); + } + + if (table == NULL) + g_error ("Unable to open proxied dconf database %s", filename); + + g_free (filename); + + return table; +} + +static void +dconf_engine_source_proxied_finalize (DConfEngineSource *source) +{ +} + +G_GNUC_INTERNAL +const DConfEngineSourceVTable dconf_engine_source_proxied_vtable = { + .instance_size = sizeof (DConfEngineSource), + .init = dconf_engine_source_proxied_init, + .finalize = dconf_engine_source_proxied_finalize, + .needs_reopen = dconf_engine_source_proxied_needs_reopen, + .reopen = dconf_engine_source_proxied_reopen +}; diff --git a/engine/dconf-engine-source.c b/engine/dconf-engine-source.c index 019a59c..5dd3fe7 100644 --- a/engine/dconf-engine-source.c +++ b/engine/dconf-engine-source.c @@ -127,6 +127,23 @@ dconf_engine_source_new (const gchar *description) return source; } +DConfEngineSource * +dconf_engine_source_new_proxied (guint level) +{ + DConfEngineSource *source; + + g_assert (level == 0 || level == 1); + + source = g_malloc0 (dconf_engine_source_proxied_vtable.instance_size); + source->vtable = &dconf_engine_source_proxied_vtable; + source->name = g_strdup_printf ("%u", level); + source->writable = level == 0; + + source->vtable->init (source); + + return source; +} + DConfEngineSource * dconf_engine_source_new_default (void) { diff --git a/engine/dconf-engine-source.h b/engine/dconf-engine-source.h index 71e03a6..a1bdfd6 100644 --- a/engine/dconf-engine-source.h +++ b/engine/dconf-engine-source.h @@ -60,6 +60,9 @@ gboolean dconf_engine_source_refresh (DConfEn G_GNUC_INTERNAL DConfEngineSource * dconf_engine_source_new (const gchar *name); +G_GNUC_INTERNAL +DConfEngineSource * dconf_engine_source_new_proxied (guint level); + G_GNUC_INTERNAL DConfEngineSource * dconf_engine_source_new_default (void); -- cgit v1.2.1