[epiphany] Switch web extensions to using private D-Bus connections
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany] Switch web extensions to using private D-Bus connections
- Date: Mon, 8 Feb 2016 19:53:50 +0000 (UTC)
commit b8b391393aca52274063653b2d6e4b3c00e960fd
Author: Michael Catanzaro <mcatanzaro igalia com>
Date: Sun Feb 7 21:35:02 2016 -0600
Switch web extensions to using private D-Bus connections
Instead of using the session bus. There's no point in advertising the
web extension D-Bus interface as if it could be meaningfully used by
anything other than the Epiphany UI process.
EphyEmbedShell will run the D-Bus server, and the web extensions will
connect to it.
https://bugzilla.gnome.org/show_bug.cgi?id=761009
embed/ephy-embed-shell.c | 215 +++++++++++++------------
embed/ephy-web-extension-proxy.c | 168 +++++++++++---------
embed/ephy-web-extension-proxy.h | 4 +-
embed/web-extension/ephy-web-extension-main.c | 46 +++---
embed/web-extension/ephy-web-extension.c | 105 ++++++++-----
embed/web-extension/ephy-web-extension.h | 3 +-
lib/Makefile.am | 2 +
lib/ephy-dbus-util.c | 37 +++++
lib/ephy-dbus-util.h | 29 ++++
9 files changed, 360 insertions(+), 249 deletions(-)
---
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 6a3abcf..340709f 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -21,6 +21,7 @@
#include "ephy-embed-shell.h"
#include "ephy-about-handler.h"
+#include "ephy-dbus-util.h"
#include "ephy-debug.h"
#include "ephy-embed-prefs.h"
#include "ephy-embed-private.h"
@@ -56,9 +57,8 @@ typedef struct {
EphyAboutHandler *about_handler;
guint update_overview_timeout_id;
guint hiding_overview_item;
- GDBusConnection *bus;
+ GDBusServer *dbus_server;
GList *web_extensions;
- guint web_extensions_page_created_signal_id;
} EphyEmbedShellPrivate;
enum
@@ -105,32 +105,11 @@ ephy_embed_shell_dispose (GObject *object)
g_clear_object (&priv->user_content);
g_clear_object (&priv->downloads_manager);
g_clear_object (&priv->web_context);
+ g_clear_object (&priv->dbus_server);
G_OBJECT_CLASS (ephy_embed_shell_parent_class)->dispose (object);
}
-static gint
-web_extension_compare (EphyWebExtensionProxy *proxy,
- const char *name_owner)
-{
- return g_strcmp0 (ephy_web_extension_proxy_get_name_owner (proxy), name_owner);
-}
-
-static EphyWebExtensionProxy *
-ephy_embed_shell_find_web_extension (EphyEmbedShell *shell,
- const char *name_owner)
-{
- EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
- GList *l;
-
- l = g_list_find_custom (priv->web_extensions, name_owner, (GCompareFunc)web_extension_compare);
-
- if (!l)
- g_warning ("Could not find extension with name owner `%s´.", name_owner);
-
- return l ? EPHY_WEB_EXTENSION_PROXY (l->data) : NULL;
-}
-
static void
web_extension_form_auth_data_message_received_cb (WebKitUserContentManager *manager,
WebKitJavascriptResult *message,
@@ -154,26 +133,6 @@ web_extension_form_auth_data_message_received_cb (WebKitUserContentManager *mana
}
static void
-web_extension_page_created (GDBusConnection *connection,
- const char *sender_name,
- const char *object_path,
- const char *interface_name,
- const char *signal_name,
- GVariant *parameters,
- EphyEmbedShell *shell)
-{
- EphyWebExtensionProxy *web_extension;
- guint64 page_id;
-
- g_variant_get (parameters, "(t)", &page_id);
-
- web_extension = ephy_embed_shell_find_web_extension (shell, sender_name);
- if (!web_extension)
- return;
- g_signal_emit (shell, signals[PAGE_CREATED], 0, page_id, web_extension);
-}
-
-static void
history_service_query_urls_cb (EphyHistoryService *service,
gboolean success,
GList *urls,
@@ -300,40 +259,6 @@ web_extension_about_apps_message_received_cb (WebKitUserContentManager *manager,
}
static void
-web_extension_destroyed (EphyEmbedShell *shell,
- GObject *web_extension)
-{
- EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
-
- priv->web_extensions = g_list_remove (priv->web_extensions, web_extension);
-}
-
-static void
-ephy_embed_shell_watch_web_extension (EphyEmbedShell *shell,
- const char *web_extension_id)
-{
- EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
- EphyWebExtensionProxy *web_extension;
- char *service_name;
-
- if (!priv->bus)
- return;
-
- service_name = g_strdup_printf ("%s-%s", EPHY_WEB_EXTENSION_SERVICE_NAME, web_extension_id);
- web_extension = ephy_web_extension_proxy_new (priv->bus, service_name);
- priv->web_extensions = g_list_prepend (priv->web_extensions, web_extension);
- g_object_weak_ref (G_OBJECT (web_extension), (GWeakNotify)web_extension_destroyed, shell);
- g_free (service_name);
-}
-
-static void
-ephy_embed_shell_unwatch_web_extension (EphyWebExtensionProxy *web_extension,
- EphyEmbedShell *shell)
-{
- g_object_weak_unref (G_OBJECT (web_extension), (GWeakNotify)web_extension_destroyed, shell);
-}
-
-static void
history_service_url_title_changed_cb (EphyHistoryService *service,
const char *url,
const char *title,
@@ -519,47 +444,129 @@ ephy_resource_request_cb (WebKitURISchemeRequest *request)
}
static void
+web_extension_destroyed (EphyEmbedShell *shell,
+ GObject *web_extension)
+{
+ EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+
+ priv->web_extensions = g_list_remove (priv->web_extensions, web_extension);
+}
+
+static void
+ephy_embed_shell_watch_web_extension (EphyEmbedShell *shell,
+ EphyWebExtensionProxy *web_extension)
+{
+ EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+
+ priv->web_extensions = g_list_prepend (priv->web_extensions, web_extension);
+ g_object_weak_ref (G_OBJECT (web_extension), (GWeakNotify)web_extension_destroyed, shell);
+}
+
+static void
+ephy_embed_shell_unwatch_web_extension (EphyWebExtensionProxy *web_extension,
+ EphyEmbedShell *shell)
+{
+ g_object_weak_unref (G_OBJECT (web_extension), (GWeakNotify)web_extension_destroyed, shell);
+}
+
+static void
initialize_web_extensions (WebKitWebContext* web_context,
EphyEmbedShell *shell)
{
EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
GVariant *user_data;
gboolean private_profile;
- char *web_extension_id;
- static guint web_extension_count = 0;
+ const char *address;
webkit_web_context_set_web_extensions_directory (web_context, EPHY_WEB_EXTENSIONS_DIR);
- web_extension_id = g_strdup_printf ("%u-%u", getpid (), ++web_extension_count);
- ephy_embed_shell_watch_web_extension (shell, web_extension_id);
+ address = priv->dbus_server ? g_dbus_server_get_client_address (priv->dbus_server) : NULL;
private_profile = EPHY_EMBED_SHELL_MODE_HAS_PRIVATE_PROFILE (priv->mode);
- user_data = g_variant_new ("(ssb)", web_extension_id, ephy_dot_dir (), private_profile);
+ user_data = g_variant_new ("(mssb)",
+ address,
+ ephy_dot_dir (),
+ private_profile);
webkit_web_context_set_web_extensions_initialization_user_data (web_context, user_data);
}
static void
-ephy_embed_shell_setup_web_extensions_connection (EphyEmbedShell *shell)
+web_extension_page_created (EphyWebExtensionProxy *extension,
+ guint64 page_id,
+ EphyEmbedShell *shell)
+{
+ g_signal_emit (shell, signals[PAGE_CREATED], 0, page_id, extension);
+}
+
+static gboolean
+new_connection_cb (GDBusServer *server,
+ GDBusConnection *connection,
+ EphyEmbedShell *shell)
+{
+ EphyWebExtensionProxy *extension = ephy_web_extension_proxy_new (connection);
+ ephy_embed_shell_watch_web_extension (shell, extension);
+
+ g_signal_connect_object (extension, "page-created",
+ G_CALLBACK (web_extension_page_created), shell, 0);
+
+ return TRUE;
+}
+
+static gboolean
+authorize_authenticated_peer_cb (GDBusAuthObserver *observer,
+ GIOStream *stream,
+ GCredentials *credentials,
+ EphyEmbedShell *shell)
+{
+ return ephy_dbus_peer_is_authorized (credentials);
+}
+
+static void
+ephy_embed_shell_setup_web_extensions_server (EphyEmbedShell *shell)
{
EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+ GDBusAuthObserver *observer;
+ char *address;
+ char *guid;
+ GError *error = NULL;
- priv->bus = g_application_get_dbus_connection (G_APPLICATION (shell));
- if (!priv->bus) {
- g_warning ("Application not connected to session bus");
- return;
+ /* On Linux, this creates an abstract socket with a name that unnecessarily
+ * begins with the tmp dir. Where abstract sockets are unavailable, it
+ * actually creates the socket under the tmp dir. */
+ address = g_strdup_printf ("unix:tmpdir=%s", g_get_tmp_dir ());
+
+ guid = g_dbus_generate_guid ();
+ observer = g_dbus_auth_observer_new ();
+
+ g_signal_connect (observer, "authorize-authenticated-peer",
+ G_CALLBACK (authorize_authenticated_peer_cb), shell);
+
+ /* Why sync?
+ *
+ * (a) The server must be started before web extensions try to connect.
+ * (b) Gio actually has no async version. Don't know why.
+ */
+ priv->dbus_server = g_dbus_server_new_sync (address,
+ G_DBUS_SERVER_FLAGS_NONE,
+ guid,
+ observer,
+ NULL,
+ &error);
+
+ if (error) {
+ g_warning ("Failed to start web extension server on %s: %s", address, error->message);
+ g_error_free (error);
+ goto out;
}
- priv->web_extensions_page_created_signal_id =
- g_dbus_connection_signal_subscribe (priv->bus,
- NULL,
- EPHY_WEB_EXTENSION_INTERFACE,
- "PageCreated",
- EPHY_WEB_EXTENSION_OBJECT_PATH,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- (GDBusSignalCallback)web_extension_page_created,
- shell,
- NULL);
+ g_signal_connect (priv->dbus_server, "new-connection",
+ G_CALLBACK (new_connection_cb), shell);
+ g_dbus_server_start (priv->dbus_server);
+
+out:
+ g_free (address);
+ g_free (guid);
+ g_object_unref (observer);
}
static void
@@ -631,7 +638,7 @@ ephy_embed_shell_startup (GApplication* application)
if (priv->mode != EPHY_EMBED_SHELL_MODE_TEST)
ephy_embed_shell_create_web_context (embed_shell);
- ephy_embed_shell_setup_web_extensions_connection (shell);
+ ephy_embed_shell_setup_web_extensions_server (shell);
/* User content manager */
if (priv->mode != EPHY_EMBED_SHELL_MODE_TEST)
@@ -713,16 +720,14 @@ ephy_embed_shell_shutdown (GApplication* application)
G_APPLICATION_CLASS (ephy_embed_shell_parent_class)->shutdown (application);
+ if (priv->dbus_server)
+ g_dbus_server_stop (priv->dbus_server);
+
webkit_user_content_manager_unregister_script_message_handler (priv->user_content, "overview");
webkit_user_content_manager_unregister_script_message_handler (priv->user_content, "tlsErrorPage");
webkit_user_content_manager_unregister_script_message_handler (priv->user_content, "formAuthData");
webkit_user_content_manager_unregister_script_message_handler (priv->user_content, "aboutApps");
- if (priv->web_extensions_page_created_signal_id > 0) {
- g_dbus_connection_signal_unsubscribe (priv->bus, priv->web_extensions_page_created_signal_id);
- priv->web_extensions_page_created_signal_id = 0;
- }
-
g_list_foreach (priv->web_extensions, (GFunc)ephy_embed_shell_unwatch_web_extension, application);
g_object_unref (ephy_embed_prefs_get_settings ());
diff --git a/embed/ephy-web-extension-proxy.c b/embed/ephy-web-extension-proxy.c
index a62ff4d..6cf067a 100644
--- a/embed/ephy-web-extension-proxy.c
+++ b/embed/ephy-web-extension-proxy.c
@@ -26,37 +26,38 @@ struct _EphyWebExtensionProxy
{
GObject parent_instance;
- GDBusProxy *proxy;
- gchar *name_owner;
GCancellable *cancellable;
- guint watch_name_id;
-};
+ GDBusProxy *proxy;
+ GDBusConnection *connection;
-G_DEFINE_TYPE (EphyWebExtensionProxy, ephy_web_extension_proxy, G_TYPE_OBJECT)
+ guint page_created_signal_id;
+};
-static void
-ephy_web_extension_proxy_finalize (GObject *object)
+enum
{
- EphyWebExtensionProxy *web_extension = EPHY_WEB_EXTENSION_PROXY (object);
+ PAGE_CREATED,
- g_clear_object (&web_extension->proxy);
+ LAST_SIGNAL
+};
- G_OBJECT_CLASS (ephy_web_extension_proxy_parent_class)->finalize (object);
-}
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (EphyWebExtensionProxy, ephy_web_extension_proxy, G_TYPE_OBJECT)
static void
ephy_web_extension_proxy_dispose (GObject *object)
{
EphyWebExtensionProxy *web_extension = EPHY_WEB_EXTENSION_PROXY (object);
- g_clear_object (&web_extension->cancellable);
-
- if (web_extension->watch_name_id > 0) {
- g_bus_unwatch_name (web_extension->watch_name_id);
- web_extension->watch_name_id = 0;
+ if (web_extension->page_created_signal_id > 0) {
+ g_dbus_connection_signal_unsubscribe (web_extension->connection,
+ web_extension->page_created_signal_id);
+ web_extension->page_created_signal_id = 0;
}
- g_clear_pointer (&web_extension->name_owner, g_free);
+ g_clear_object (&web_extension->cancellable);
+ g_clear_object (&web_extension->proxy);
+ g_clear_object (&web_extension->connection);
G_OBJECT_CLASS (ephy_web_extension_proxy_parent_class)->dispose (object);
}
@@ -71,8 +72,36 @@ ephy_web_extension_proxy_class_init (EphyWebExtensionProxyClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = ephy_web_extension_proxy_finalize;
object_class->dispose = ephy_web_extension_proxy_dispose;
+
+ /**
+ * EphyWebExtensionProxy::page-created:
+ * @web_extension: the #EphyWebExtensionProxy
+ * @page_id: the identifier of the web page created
+ *
+ * Emitted when a web page is created in the web process.
+ */
+ signals[PAGE_CREATED] =
+ g_signal_new ("page-created",
+ EPHY_TYPE_WEB_EXTENSION_PROXY,
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT64);
+}
+
+static void
+web_extension_page_created (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *interface_name,
+ const char *signal_name,
+ GVariant *parameters,
+ EphyWebExtensionProxy *web_extension)
+{
+ guint64 page_id;
+ g_variant_get (parameters, "(t)", &page_id);
+ g_signal_emit (web_extension, signals[PAGE_CREATED], 0, page_id);
}
static void
@@ -84,81 +113,72 @@ web_extension_proxy_created_cb (GDBusProxy *proxy,
web_extension->proxy = g_dbus_proxy_new_finish (result, &error);
if (!web_extension->proxy) {
- g_warning ("Error creating web extension proxy: %s\n", error->message);
+ g_warning ("Error creating web extension proxy: %s", error->message);
g_error_free (error);
+
+ /* Attempt to trigger connection_closed_cb, which will destroy us, and ensure that
+ * that EphyEmbedShell will remove us from its extensions list.
+ */
+ g_dbus_connection_close (web_extension->connection,
+ web_extension->cancellable,
+ NULL /* GAsyncReadyCallback */,
+ NULL);
+ return;
}
- g_object_unref (web_extension);
+ web_extension->page_created_signal_id =
+ g_dbus_connection_signal_subscribe (web_extension->connection,
+ NULL,
+ EPHY_WEB_EXTENSION_INTERFACE,
+ "PageCreated",
+ EPHY_WEB_EXTENSION_OBJECT_PATH,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ (GDBusSignalCallback)web_extension_page_created,
+ web_extension,
+ NULL);
}
static void
-web_extension_appeared_cb (GDBusConnection *connection,
- const gchar *name,
- const gchar *name_owner,
- EphyWebExtensionProxy *web_extension)
+connection_closed_cb (GDBusConnection *connection,
+ gboolean remote_peer_vanished,
+ GError *error,
+ EphyWebExtensionProxy *web_extension)
{
- web_extension->name_owner = g_strdup (name_owner);
- web_extension->cancellable = g_cancellable_new ();
- g_dbus_proxy_new (connection,
- G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
- NULL,
- name,
- EPHY_WEB_EXTENSION_OBJECT_PATH,
- EPHY_WEB_EXTENSION_INTERFACE,
- web_extension->cancellable,
- (GAsyncReadyCallback)web_extension_proxy_created_cb,
- /* Ref here because the web process could crash, triggering
- * web_extension_vanished_cb() before this finishes. */
- g_object_ref (web_extension));
-}
-
-static void
-web_extension_vanished_cb (GDBusConnection *connection,
- const gchar *name,
- EphyWebExtensionProxy *web_extension)
-{
- if (web_extension->name_owner)
- g_object_unref (web_extension);
-}
+ if (error) {
+ if (!remote_peer_vanished)
+ g_warning ("Unexpectedly lost connection to web extension: %s", error->message);
+ }
-static void
-ephy_web_extension_proxy_watch_name (EphyWebExtensionProxy *web_extension,
- GDBusConnection* bus,
- const char *service_name)
-{
- web_extension->watch_name_id =
- g_bus_watch_name_on_connection (bus,
- service_name,
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- (GBusNameAppearedCallback)web_extension_appeared_cb,
- (GBusNameVanishedCallback)web_extension_vanished_cb,
- web_extension,
- NULL);
+ g_object_unref (web_extension);
}
EphyWebExtensionProxy *
-ephy_web_extension_proxy_new (GDBusConnection *bus,
- const char *service_name)
+ephy_web_extension_proxy_new (GDBusConnection *connection)
{
EphyWebExtensionProxy *web_extension;
- g_return_val_if_fail (G_IS_DBUS_CONNECTION (bus), NULL);
- g_return_val_if_fail (service_name != NULL, NULL);
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
web_extension = g_object_new (EPHY_TYPE_WEB_EXTENSION_PROXY, NULL);
- ephy_web_extension_proxy_watch_name (web_extension, bus, service_name);
- return web_extension;
-}
+ g_signal_connect (connection, "closed",
+ G_CALLBACK (connection_closed_cb), web_extension);
-const char *
-ephy_web_extension_proxy_get_name_owner (EphyWebExtensionProxy *web_extension)
-{
- g_return_val_if_fail (EPHY_IS_WEB_EXTENSION_PROXY (web_extension), NULL);
+ web_extension->cancellable = g_cancellable_new ();
+ web_extension->connection = g_object_ref (connection);
- return web_extension->name_owner;
+ g_dbus_proxy_new (connection,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ NULL,
+ NULL,
+ EPHY_WEB_EXTENSION_OBJECT_PATH,
+ EPHY_WEB_EXTENSION_INTERFACE,
+ web_extension->cancellable,
+ (GAsyncReadyCallback)web_extension_proxy_created_cb,
+ web_extension);
+
+ return web_extension;
}
void
diff --git a/embed/ephy-web-extension-proxy.h b/embed/ephy-web-extension-proxy.h
index a80e8bf..28cf0af 100644
--- a/embed/ephy-web-extension-proxy.h
+++ b/embed/ephy-web-extension-proxy.h
@@ -27,9 +27,7 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (EphyWebExtensionProxy, ephy_web_extension_proxy, EPHY, WEB_EXTENSION_PROXY, GObject)
-EphyWebExtensionProxy *ephy_web_extension_proxy_new (GDBusConnection
*bus,
- const char
*service_name);
-const char * ephy_web_extension_proxy_get_name_owner
(EphyWebExtensionProxy *web_extension);
+EphyWebExtensionProxy *ephy_web_extension_proxy_new (GDBusConnection
*connection);
void ephy_web_extension_proxy_form_auth_data_save_confirmation_response
(EphyWebExtensionProxy *web_extension,
guint
request_id,
gboolean
response);
diff --git a/embed/web-extension/ephy-web-extension-main.c b/embed/web-extension/ephy-web-extension-main.c
index 6db5673..9c416a0 100644
--- a/embed/web-extension/ephy-web-extension-main.c
+++ b/embed/web-extension/ephy-web-extension-main.c
@@ -20,59 +20,51 @@
#include "config.h"
#include "ephy-web-extension.h"
-#include "ephy-web-extension-names.h"
#include "ephy-debug.h"
#include "ephy-file-helpers.h"
-static void
-name_acquired_cb (GDBusConnection *connection,
- const char *name,
- EphyWebExtension *extension)
-{
- ephy_web_extension_dbus_register (extension, connection);
-}
-
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+static EphyWebExtension *extension = NULL;
+
G_MODULE_EXPORT void
-webkit_web_extension_initialize_with_user_data (WebKitWebExtension *extension,
+webkit_web_extension_initialize_with_user_data (WebKitWebExtension *webkit_extension,
GVariant *user_data)
{
- EphyWebExtension *web_extension;
- char *service_name;
- const char *extension_id;
+ const char *server_address;
const char *dot_dir;
gboolean private_profile;
GError *error = NULL;
- g_variant_get (user_data, "(&s&sb)", &extension_id, &dot_dir, &private_profile);
+ g_variant_get (user_data, "(m&s&sb)", &server_address, &dot_dir, &private_profile);
+
+ if (!server_address) {
+ g_warning ("UI process did not start D-Bus server, giving up.");
+ return;
+ }
if (!ephy_file_helpers_init (dot_dir, 0, &error)) {
- g_printerr ("Failed to initialize file helpers: %s\n", error->message);
+ g_warning ("Failed to initialize file helpers: %s", error->message);
g_error_free (error);
}
ephy_debug_init ();
- web_extension = ephy_web_extension_get ();
- ephy_web_extension_initialize (web_extension, extension, dot_dir, private_profile);
+ extension = ephy_web_extension_get ();
- service_name = g_strdup_printf ("%s-%s", EPHY_WEB_EXTENSION_SERVICE_NAME, extension_id);
- g_bus_own_name (G_BUS_TYPE_SESSION,
- service_name,
- G_BUS_NAME_OWNER_FLAGS_NONE,
- NULL,
- (GBusNameAcquiredCallback)name_acquired_cb,
- NULL,
- web_extension, NULL);
- g_free (service_name);
+ ephy_web_extension_initialize (extension,
+ webkit_extension,
+ server_address,
+ dot_dir,
+ private_profile);
}
static void __attribute__((destructor))
ephy_web_extension_shutdown (void)
{
- g_object_unref (ephy_web_extension_get ());
+ if (extension)
+ g_object_unref (extension);
}
#pragma GCC diagnostic pop
diff --git a/embed/web-extension/ephy-web-extension.c b/embed/web-extension/ephy-web-extension.c
index 672b803..d72245a 100644
--- a/embed/web-extension/ephy-web-extension.c
+++ b/embed/web-extension/ephy-web-extension.c
@@ -20,6 +20,7 @@
#include "config.h"
#include "ephy-web-extension.h"
+#include "ephy-dbus-util.h"
#include "ephy-debug.h"
#include "ephy-embed-form-auth.h"
#include "ephy-file-helpers.h"
@@ -49,7 +50,7 @@ struct _EphyWebExtension
gboolean initialized;
GDBusConnection *dbus_connection;
- guint registration_id;
+ GCancellable *cancellable;
GArray *page_created_signals_pending;
EphyUriTester *uri_tester;
@@ -1299,16 +1300,10 @@ ephy_web_extension_dispose (GObject *object)
if (extension->page_created_signals_pending) {
g_array_free (extension->page_created_signals_pending, TRUE);
extension->page_created_signals_pending = NULL;
- }
+ }
- if (extension->dbus_connection) {
- g_object_remove_weak_pointer (G_OBJECT (extension->dbus_connection),
- (gpointer *)&extension->dbus_connection);
- g_dbus_connection_unregister_object (extension->dbus_connection,
- extension->registration_id);
- extension->registration_id = 0;
- extension->dbus_connection = NULL;
- }
+ g_clear_object (&extension->cancellable);
+ g_clear_object (&extension->dbus_connection);
g_clear_object (&extension->extension);
@@ -1342,12 +1337,63 @@ ephy_web_extension_get (void)
return EPHY_WEB_EXTENSION (g_once (&once_init, ephy_web_extension_create_instance, NULL));
}
+static void
+dbus_connection_created_cb (GObject *source_object,
+ GAsyncResult *result,
+ EphyWebExtension *extension)
+{
+ static GDBusNodeInfo *introspection_data = NULL;
+ GDBusConnection *connection;
+ guint registration_id;
+ GError *error = NULL;
+
+ if (!introspection_data)
+ introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+
+ connection = g_dbus_connection_new_for_address_finish (result, &error);
+ if (error) {
+ g_warning ("Failed to connect to UI process: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ registration_id =
+ g_dbus_connection_register_object (connection,
+ EPHY_WEB_EXTENSION_OBJECT_PATH,
+ introspection_data->interfaces[0],
+ &interface_vtable,
+ extension,
+ NULL,
+ &error);
+ if (!registration_id) {
+ g_warning ("Failed to register web extension object: %s\n", error->message);
+ g_error_free (error);
+ g_object_unref (connection);
+ return;
+ }
+
+ extension->dbus_connection = connection;
+ ephy_web_extension_emit_page_created_signals_pending (extension);
+}
+
+static gboolean
+authorize_authenticated_peer_cb (GDBusAuthObserver *observer,
+ GIOStream *stream,
+ GCredentials *credentials,
+ EphyWebExtension *extension)
+{
+ return ephy_dbus_peer_is_authorized (credentials);
+}
+
void
ephy_web_extension_initialize (EphyWebExtension *extension,
WebKitWebExtension *wk_extension,
+ const char *server_address,
const char *dot_dir,
gboolean is_private_profile)
{
+ GDBusAuthObserver *observer;
+
g_return_if_fail (EPHY_IS_WEB_EXTENSION (extension));
if (extension->initialized)
@@ -1363,35 +1409,18 @@ ephy_web_extension_initialize (EphyWebExtension *extension,
g_signal_connect_swapped (extension->extension, "page-created",
G_CALLBACK (ephy_web_extension_page_created_cb),
extension);
-}
-
-void
-ephy_web_extension_dbus_register (EphyWebExtension *extension,
- GDBusConnection *connection)
-{
- GError *error = NULL;
- static GDBusNodeInfo *introspection_data = NULL;
- g_return_if_fail (EPHY_IS_WEB_EXTENSION (extension));
- g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
+ extension->cancellable = g_cancellable_new ();
- if (!introspection_data)
- introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+ observer = g_dbus_auth_observer_new ();
+ g_signal_connect (observer, "authorize-authenticated-peer",
+ G_CALLBACK (authorize_authenticated_peer_cb), extension);
- extension->registration_id =
- g_dbus_connection_register_object (connection,
- EPHY_WEB_EXTENSION_OBJECT_PATH,
- introspection_data->interfaces[0],
- &interface_vtable,
- extension,
- NULL,
- &error);
- if (!extension->registration_id) {
- g_warning ("Failed to register web extension object: %s\n", error->message);
- g_error_free (error);
- } else {
- extension->dbus_connection = connection;
- g_object_add_weak_pointer (G_OBJECT (connection), (gpointer *)&extension->dbus_connection);
- ephy_web_extension_emit_page_created_signals_pending (extension);
- }
+ g_dbus_connection_new_for_address (server_address,
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+ observer,
+ extension->cancellable,
+ (GAsyncReadyCallback)dbus_connection_created_cb,
+ extension);
+ g_object_unref (observer);
}
diff --git a/embed/web-extension/ephy-web-extension.h b/embed/web-extension/ephy-web-extension.h
index ce62c06..f3535f4 100644
--- a/embed/web-extension/ephy-web-extension.h
+++ b/embed/web-extension/ephy-web-extension.h
@@ -30,10 +30,9 @@ G_DECLARE_FINAL_TYPE (EphyWebExtension, ephy_web_extension, EPHY, WEB_EXTENSION,
EphyWebExtension *ephy_web_extension_get (void);
void ephy_web_extension_initialize (EphyWebExtension *extension,
WebKitWebExtension *wk_extension,
+ const char *server_address,
const char *dot_dir,
gboolean is_private_profile);
-void ephy_web_extension_dbus_register (EphyWebExtension *extension,
- GDBusConnection *connection);
G_END_DECLS
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e8e96b5..4dc98e6 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -11,6 +11,8 @@ TYPES_H_FILES = \
ephy-security-levels.h
libephymisc_la_SOURCES = \
+ ephy-dbus-util.c \
+ ephy-dbus-util.h \
ephy-debug.c \
ephy-debug.h \
ephy-dnd.c \
diff --git a/lib/ephy-dbus-util.c b/lib/ephy-dbus-util.c
new file mode 100644
index 0000000..961c805
--- /dev/null
+++ b/lib/ephy-dbus-util.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2016 Igalia S.L.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ephy-dbus-util.h"
+
+gboolean
+ephy_dbus_peer_is_authorized (GCredentials *peer_credentials)
+{
+ static GCredentials *own_credentials = NULL;
+ GError *error = NULL;
+
+ if (!own_credentials)
+ own_credentials = g_credentials_new ();
+
+ if (peer_credentials && g_credentials_is_same_user (peer_credentials, own_credentials, &error))
+ return TRUE;
+
+ if (error) {
+ g_warning ("Failed to authorize web extension connection: %s", error->message);
+ g_error_free (error);
+ }
+ return FALSE;
+}
diff --git a/lib/ephy-dbus-util.h b/lib/ephy-dbus-util.h
new file mode 100644
index 0000000..0da7bb7
--- /dev/null
+++ b/lib/ephy-dbus-util.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2016 Igalia S.L.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EPHY_DBUS_UTIL_H
+#define EPHY_DBUS_UTIL_H
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+gboolean ephy_dbus_peer_is_authorized (GCredentials *peer_credentials);
+
+G_END_DECLS
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]