[dconf/wip/proxy: 9/12] Confinement, proxied source.



commit 6995c1703ec3d0ff281e5cb925ec1bfeeee6cf10
Author: Allison Lortie <desrt desrt ca>
Date:   Mon Oct 17 10:02:30 2016 +0200

    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(+), 0 deletions(-)
---
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 <http://www.gnu.org/licenses/>.
+ *
+ * Author: Allison Lortie <desrt desrt ca>
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ *
+ * Author: Allison Lortie <desrt desrt ca>
+ */
+
+#ifndef __dconf_engine_confinement_h__
+#define __dconf_engine_confinement_h__
+
+#include <gio/gio.h>
+
+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 <string.h>
@@ -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 <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
+#include "config.h"
+
+#include "dconf-engine-confinement.h"
+#include "dconf-engine-source-private.h"
+
+#include "dconf-engine.h"
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+
+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
@@ -128,6 +128,23 @@ dconf_engine_source_new (const gchar *description)
 }
 
 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)
 {
   DConfEngineSource *source;
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
@@ -61,6 +61,9 @@ 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);
 
 #endif /* __dconf_engine_source_h__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]