[epiphany/mcatanzaro/#993] Remove GSettings use from web process



commit 52bf20a3c077737a3b408139b767307462ad6c94
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Fri Nov 8 17:56:39 2019 -0600

    Remove GSettings use from web process
    
    Our scheme to sync settings from the host to the web process extension
    has failed, because it depended on the web process's ability to read
    host settings: i.e. its design never actually worked, since the whole
    purpose was to avoid depending on host settings, which are inaccessible
    inside the sandbox.
    
    Instead of fixing this, we can just not allow the web process to read
    Epiphany settings at all. Toolkit level settings should go through
    either XSettings or xdg-desktop-portal. Add an assertion to ensure the
    web process crashes if it tries to use ephy_settings_get() to avoid
    mistakes here.
    
    Currently we use two settings: do-not-track, and remember-passwords. We
    can remove the do-not-track setting and just always strip tracking query
    parameters from URLs, especially since this setting is hidden since 3.34
    anyway. In the future, we'll want to remove this code and let ITP do its
    thing instead. As for remember-passwords, we can manually sync the state
    of this setting to the web process using D-Bus.
    
    Finally, remove the unused browser_mode variable.
    
    Fixes #993

 embed/ephy-embed-shell.c                           |  28 ++++-
 embed/ephy-web-process-extension-proxy.c           |  16 +++
 embed/ephy-web-process-extension-proxy.h           |   4 +
 .../ephy-web-process-extension-main.c              |  10 +-
 .../ephy-web-process-extension.c                   |  36 ++++--
 .../ephy-web-process-extension.h                   |   4 +-
 lib/ephy-settings.c                                | 128 ++-------------------
 lib/ephy-settings.h                                |   5 +-
 8 files changed, 92 insertions(+), 139 deletions(-)
---
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index b0c871e5a..2aab3cc45 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -940,7 +940,6 @@ initialize_web_process_extensions (WebKitWebContext *web_context,
   EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
   g_autoptr (GVariant) user_data = NULL;
   gboolean private_profile;
-  gboolean browser_mode;
   const char *address;
 
 #if DEVELOPER_MODE
@@ -952,13 +951,12 @@ initialize_web_process_extensions (WebKitWebContext *web_context,
   address = priv->dbus_server ? g_dbus_server_get_client_address (priv->dbus_server) : NULL;
 
   private_profile = priv->mode == EPHY_EMBED_SHELL_MODE_PRIVATE || priv->mode == 
EPHY_EMBED_SHELL_MODE_INCOGNITO || priv->mode == EPHY_EMBED_SHELL_MODE_AUTOMATION;
-  browser_mode = priv->mode == EPHY_EMBED_SHELL_MODE_BROWSER;
   user_data = g_variant_new ("(smsmsbb)",
                              priv->guid,
                              address,
                              ephy_profile_dir_is_default () ? NULL : ephy_profile_dir (),
-                             private_profile,
-                             browser_mode);
+                             g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_REMEMBER_PASSWORDS),
+                             private_profile);
   webkit_web_context_set_web_extensions_initialization_user_data (web_context, g_steal_pointer (&user_data));
 }
 
@@ -1117,6 +1115,25 @@ download_started_cb (WebKitWebContext *web_context,
   ephy_downloads_manager_add_download (priv->downloads_manager, ephy_download);
 }
 
+static void
+remember_passwords_setting_changed_cb (GSettings      *settings,
+                                       char           *key,
+                                       EphyEmbedShell *shell)
+{
+  EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+  gboolean should_remember_passwords;
+  GList *l;
+
+  should_remember_passwords = g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_REMEMBER_PASSWORDS);
+
+  for (l = priv->web_process_extensions; l; l = g_list_next (l)) {
+    EphyWebProcessExtensionProxy *web_process_extension = (EphyWebProcessExtensionProxy *)l->data;
+
+    ephy_web_process_extension_proxy_set_should_remember_passwords (web_process_extension,
+                                                                    should_remember_passwords);
+  }
+}
+
 static void
 ephy_embed_shell_startup (GApplication *application)
 {
@@ -1288,6 +1305,9 @@ ephy_embed_shell_startup (GApplication *application)
 
   g_signal_connect_object (priv->web_context, "download-started",
                            G_CALLBACK (download_started_cb), shell, 0);
+
+  g_signal_connect_object (EPHY_SETTINGS_WEB, "changed::remember-passwords",
+                           G_CALLBACK (remember_passwords_setting_changed_cb), shell, 0);
 }
 
 static void
diff --git a/embed/ephy-web-process-extension-proxy.c b/embed/ephy-web-process-extension-proxy.c
index 866c2c110..278e8020b 100644
--- a/embed/ephy-web-process-extension-proxy.c
+++ b/embed/ephy-web-process-extension-proxy.c
@@ -336,3 +336,19 @@ ephy_web_process_extension_proxy_password_query_response (EphyWebProcessExtensio
                      web_process_extension->cancellable,
                      NULL, NULL);
 }
+
+void
+ephy_web_process_extension_proxy_set_should_remember_passwords (EphyWebProcessExtensionProxy 
*web_process_extension,
+                                                                gboolean                      
should_remember_passwords)
+{
+  if (!web_process_extension->proxy)
+    return;
+
+  g_dbus_proxy_call (web_process_extension->proxy,
+                     "SetShouldRememberPasswords",
+                     g_variant_new ("(b)", should_remember_passwords),
+                     G_DBUS_CALL_FLAGS_NONE,
+                     -1,
+                     web_process_extension->cancellable,
+                     NULL, NULL);
+}
diff --git a/embed/ephy-web-process-extension-proxy.h b/embed/ephy-web-process-extension-proxy.h
index f4b205dfd..bd03dc023 100644
--- a/embed/ephy-web-process-extension-proxy.h
+++ b/embed/ephy-web-process-extension-proxy.h
@@ -51,4 +51,8 @@ void                          ephy_web_process_extension_proxy_password_query_re
                                                                                                   const char 
                  *password,
                                                                                                   gint32     
                   promise_id,
                                                                                                   guint64    
                   frame_id);
+
+void                          ephy_web_process_extension_proxy_set_should_remember_passwords     
(EphyWebProcessExtensionProxy *web_process_extension,
+                                                                                                  gboolean   
                   should_remember_passwords);
+
 G_END_DECLS
diff --git a/embed/web-process-extension/ephy-web-process-extension-main.c 
b/embed/web-process-extension/ephy-web-process-extension-main.c
index f235dd2dc..050f83e7b 100644
--- a/embed/web-process-extension/ephy-web-process-extension-main.c
+++ b/embed/web-process-extension/ephy-web-process-extension-main.c
@@ -38,10 +38,10 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *webkit_exten
   const char *server_address;
   const char *profile_dir;
   gboolean private_profile;
-  gboolean browser_mode;
+  gboolean should_remember_passwords;
   g_autoptr (GError) error = NULL;
 
-  g_variant_get (user_data, "(&sm&sm&sbb)", &guid, &server_address, &profile_dir, &private_profile, 
&browser_mode);
+  g_variant_get (user_data, "(&sm&sm&sbb)", &guid, &server_address, &profile_dir, 
&should_remember_passwords, &private_profile);
 
   if (!server_address) {
     g_warning ("UI process did not start D-Bus server, giving up.");
@@ -53,14 +53,16 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *webkit_exten
 
   ephy_debug_init ();
 
+  ephy_settings_set_is_web_process_extension ();
+
   extension = ephy_web_process_extension_get ();
 
   ephy_web_process_extension_initialize (extension,
                                          webkit_extension,
                                          guid,
                                          server_address,
-                                         private_profile,
-                                         browser_mode);
+                                         should_remember_passwords,
+                                         private_profile);
 }
 
 static void __attribute__((destructor))
diff --git a/embed/web-process-extension/ephy-web-process-extension.c 
b/embed/web-process-extension/ephy-web-process-extension.c
index 60c47354f..9d9f4f005 100644
--- a/embed/web-process-extension/ephy-web-process-extension.c
+++ b/embed/web-process-extension/ephy-web-process-extension.c
@@ -55,6 +55,7 @@ struct _EphyWebProcessExtension {
 
   WebKitScriptWorld *script_world;
 
+  gboolean should_remember_passwords;
   gboolean is_private_profile;
 
   GHashTable *frames_map;
@@ -95,6 +96,9 @@ static const char introspection_xml[] =
   "    <arg type='i' name='promise_id' direction='in'/>"
   "    <arg type='t' name='frame_id' direction='in'/>"
   "  </method>"
+  "  <method name='SetShouldRememberPasswords'>"
+  "    <arg type='b' name='should_remember_passwords' direction='in'/>"
+  "  </method>"
   " </interface>"
   "</node>";
 
@@ -106,13 +110,15 @@ web_page_send_request (WebKitWebPage           *web_page,
                        WebKitURIResponse       *redirected_response,
                        EphyWebProcessExtension *extension)
 {
-  if (g_settings_get_boolean (EPHY_SETTINGS_WEB_PROCESS_EXTENSION_WEB, EPHY_PREFS_WEB_DO_NOT_TRACK)) {
-    const char *request_uri = webkit_uri_request_get_uri (request);
-    g_autofree char *modified_uri = ephy_remove_tracking_from_uri (request_uri);
-    if (modified_uri && g_strcmp0 (request_uri, modified_uri) != 0) {
-      LOG ("Rewrote %s to %s", request_uri, modified_uri);
-      webkit_uri_request_set_uri (request, modified_uri);
-    }
+  /* FIXME: We should probably remove ephy_remove_tracking_from_uri and instead
+   * trust Intelligent Tracking Prevention to mitigate potential privacy impact
+   * of tracking query parameters. But first we need to enable ITP.
+   */
+  const char *request_uri = webkit_uri_request_get_uri (request);
+  g_autofree char *modified_uri = ephy_remove_tracking_from_uri (request_uri);
+  if (modified_uri && g_strcmp0 (request_uri, modified_uri) != 0) {
+    LOG ("Rewrote %s to %s", request_uri, modified_uri);
+    webkit_uri_request_set_uri (request, modified_uri);
   }
   return FALSE;
 }
@@ -460,6 +466,8 @@ handle_method_call (GDBusConnection       *connection,
                                             G_TYPE_STRING, username,
                                             G_TYPE_STRING, password,
                                             G_TYPE_INT, promise_id, G_TYPE_NONE);
+  } else if (g_strcmp0 (method_name, "SetShouldRememberPasswords") == 0) {
+    g_variant_get (parameters, "(b)", &extension->should_remember_passwords);
   }
 }
 
@@ -615,7 +623,10 @@ js_should_remember_passwords (EphyWebProcessExtension *extension)
 {
   g_assert (EPHY_IS_WEB_PROCESS_EXTENSION (extension));
 
-  return !extension->is_private_profile && g_settings_get_boolean (EPHY_SETTINGS_WEB_PROCESS_EXTENSION_WEB, 
EPHY_PREFS_WEB_REMEMBER_PASSWORDS);
+  /* We currently don't remember passwords in private profiles. But there is
+   * no good reason for this and we should probably change this.
+   */
+  return extension->should_remember_passwords && !extension->is_private_profile;
 }
 
 static void
@@ -746,8 +757,8 @@ ephy_web_process_extension_initialize (EphyWebProcessExtension *extension,
                                        WebKitWebExtension      *wk_extension,
                                        const char              *guid,
                                        const char              *server_address,
-                                       gboolean                 is_private_profile,
-                                       gboolean                 is_browser_mode)
+                                       gboolean                 should_remember_passwords,
+                                       gboolean                 is_private_profile)
 {
   g_autoptr (GDBusAuthObserver) observer = NULL;
 
@@ -766,6 +777,11 @@ ephy_web_process_extension_initialize (EphyWebProcessExtension *extension,
 
   extension->extension = g_object_ref (wk_extension);
 
+  /* For now we don't allow remembering passwords in private profile or
+   * incognito mode, but there's no good reason for this and we should probably
+   * change it.
+   */
+  extension->should_remember_passwords = should_remember_passwords;
   extension->is_private_profile = is_private_profile;
 
   extension->permissions_manager = ephy_permissions_manager_new ();
diff --git a/embed/web-process-extension/ephy-web-process-extension.h 
b/embed/web-process-extension/ephy-web-process-extension.h
index 7fc9fa9da..f11b5e0e8 100644
--- a/embed/web-process-extension/ephy-web-process-extension.h
+++ b/embed/web-process-extension/ephy-web-process-extension.h
@@ -34,7 +34,7 @@ void                     ephy_web_process_extension_initialize (EphyWebProcessEx
                                                                 WebKitWebExtension      *wk_extension,
                                                                 const char              *guid,
                                                                 const char              *server_address,
-                                                                gboolean                 is_private_profile,
-                                                                gboolean                 is_browser_mode);
+                                                                gboolean                 
should_remember_passwords,
+                                                                gboolean                 is_private_profile);
 
 G_END_DECLS
diff --git a/lib/ephy-settings.c b/lib/ephy-settings.c
index 2d29b5618..4cef3c4ee 100644
--- a/lib/ephy-settings.c
+++ b/lib/ephy-settings.c
@@ -33,6 +33,16 @@
 
 static GHashTable *settings = NULL;
 
+static gboolean is_web_process = FALSE;
+
+void
+ephy_settings_set_is_web_process_extension (void)
+{
+  g_assert (!is_web_process);
+
+  is_web_process = TRUE;
+}
+
 static void
 ephy_settings_init (void)
 {
@@ -86,6 +96,8 @@ ephy_settings_get (const char *schema)
 {
   GSettings *gsettings = NULL;
 
+  g_assert (!is_web_process);
+
   ephy_settings_init ();
 
   gsettings = g_hash_table_lookup (settings, schema);
@@ -122,119 +134,3 @@ ephy_settings_get (const char *schema)
 
   return gsettings;
 }
-
-static void
-on_settings_changed (GSettings *settings,
-                     char      *key,
-                     gpointer   user_data)
-{
-  g_autoptr (GVariant) value = g_settings_get_user_value (settings, key);
-  if (value != NULL)
-    g_settings_set_value (user_data, key, value);
-  else
-    g_settings_reset (user_data, key);
-}
-
-/*
- * This is to sync a host dconf settings schema with a keyfile based schema.
- * The reason this is done is to continue supporting dconf usage on the host
- * transparently.
- */
-static void
-sync_settings (GSettings *original,
-               GSettings *new)
-{
-  g_autoptr (GSettingsSchema) schema = NULL;
-  g_auto (GStrv) keys = NULL;
-
-  g_object_get (original, "settings-schema", &schema, NULL);
-  keys = g_settings_schema_list_keys (schema);
-
-  for (size_t i = 0; keys[i] != NULL; ++i) {
-    const char *key = keys[i];
-    g_autoptr (GVariant) value = g_settings_get_user_value (original, key);
-
-    if (value != NULL)
-      g_settings_set_value (new, key, value);
-  }
-
-  g_signal_connect_object (original, "changed", G_CALLBACK (on_settings_changed), new, 0);
-}
-
-static char *
-get_relocatable_path (const char *schema)
-{
-  g_autofree char *base_path = NULL;
-
-  if (ephy_profile_dir_is_web_application ()) {
-    const char *web_app_name = ephy_web_application_get_program_name_from_profile_directory 
(ephy_profile_dir ());
-    base_path = g_build_path ("/", "/org/gnome/epiphany/web-apps/", web_app_name, NULL);
-  } else
-    base_path = g_strdup ("/org/gnome/epiphany/");
-
-  for (size_t i = 0; i < G_N_ELEMENTS (ephy_prefs_relocatable_schemas); i++) {
-    if (g_strcmp0 (ephy_prefs_relocatable_schemas[i].schema, schema) == 0)
-      return g_build_path ("/", base_path, ephy_prefs_relocatable_schemas[i].path, NULL);
-  }
-  return NULL;
-}
-
-/**
- * ephy_settings_get_for_web_process_extension:
- *
- * Equivalent to ephy_settings_get() except it ensures that the
- * settings backend is always keyfile based instead of using DConf.
- *
- * This is required because the WebKitGTK sandbox will not grant
- * access to DConf but we do have access to our local directories.
- *
- * It is also assumed this will only be used as read-only.
- *
- * Returns: (transfer none): #GSettings
- */
-GSettings *
-ephy_settings_get_for_web_process_extension (const char *schema)
-{
-  GSettings *gsettings = NULL;
-  g_autofree char *key_name = NULL;
-
-  ephy_settings_init ();
-
-  key_name = g_strdup_printf ("keyfile-%s", schema);
-  gsettings = g_hash_table_lookup (settings, key_name);
-
-  if (gsettings == NULL) {
-    g_autoptr (GSettingsBackend) backend = NULL;
-    g_autoptr (GSettings) web_gsettings = NULL;
-    g_autofree char *keyfile_path = NULL;
-    g_autofree char *path = NULL;
-
-    gsettings = ephy_settings_get (schema);
-    g_assert (gsettings != NULL);
-
-    /* GLib inside Flatpak will default to this backend in the future */
-    /* so we don't need to do anything extra */
-    g_object_get (gsettings, "backend", &backend, NULL);
-    /* G_IS_KEYFILE_SETTINGS_BACKEND () is private API */
-    if (!g_strcmp0 (g_type_name (G_TYPE_FROM_INSTANCE (backend)), "GKeyfileSettingsBackend")) {
-      g_hash_table_insert (settings, g_steal_pointer (&key_name), g_object_ref (gsettings));
-      return gsettings;
-    }
-
-    keyfile_path = g_build_filename (ephy_config_dir (), "web-extension-settings.ini", NULL);
-    backend = g_keyfile_settings_backend_new (keyfile_path, "/", "/");
-
-    path = get_relocatable_path (schema);
-    if (path != NULL)
-      web_gsettings = g_settings_new_with_backend_and_path (schema, backend, path);
-    else
-      web_gsettings = g_settings_new_with_backend (schema, backend);
-
-    sync_settings (gsettings, web_gsettings);
-    g_hash_table_insert (settings, g_steal_pointer (&key_name), web_gsettings);
-
-    return g_steal_pointer (&web_gsettings);
-  }
-
-  return gsettings;
-}
diff --git a/lib/ephy-settings.h b/lib/ephy-settings.h
index c2b98dd0c..c342e7c6e 100644
--- a/lib/ephy-settings.h
+++ b/lib/ephy-settings.h
@@ -35,11 +35,10 @@ G_BEGIN_DECLS
 #define EPHY_SETTINGS_SYNC                       ephy_settings_get (EPHY_PREFS_SYNC_SCHEMA)
 #define EPHY_SETTINGS_WEB_APP                    ephy_settings_get (EPHY_PREFS_WEB_APP_SCHEMA)
 #define EPHY_SETTINGS_READER                     ephy_settings_get (EPHY_PREFS_READER_SCHEMA)
-#define EPHY_SETTINGS_WEB_PROCESS_EXTENSION_MAIN ephy_settings_get_for_web_process_extension 
(EPHY_PREFS_SCHEMA)
-#define EPHY_SETTINGS_WEB_PROCESS_EXTENSION_WEB  ephy_settings_get_for_web_process_extension 
(EPHY_PREFS_WEB_SCHEMA)
 
 GSettings *ephy_settings_get (const char *schema);
-GSettings *ephy_settings_get_for_web_process_extension (const char *schema);
+
+void ephy_settings_set_is_web_process_extension (void);
 
 void ephy_settings_shutdown (void);
 


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