Commit 68b0f857 authored by Patrick Griffis's avatar Patrick Griffis Committed by Michael Catanzaro

Move password management out of web process

This is done to move all libsecret usage out of the webprocess
for sandboxing. This also makes it more robust against vulernabilities
such as Spectre moving it out of process.
parent 0487d089
Pipeline #27181 passed with stage
in 2 minutes and 35 seconds
This diff is collapsed.
......@@ -28,6 +28,7 @@
#include "ephy-encodings.h"
#include "ephy-gsb-service.h"
#include "ephy-history-service.h"
#include "ephy-password-manager.h"
#include "ephy-permissions-manager.h"
#include "ephy-search-engine-manager.h"
......@@ -84,5 +85,6 @@ WebKitUserContentManager *ephy_embed_shell_get_user_content_manager (EphyEmbedSh
EphyDownloadsManager *ephy_embed_shell_get_downloads_manager (EphyEmbedShell *shell);
EphyPermissionsManager *ephy_embed_shell_get_permissions_manager (EphyEmbedShell *shell);
EphySearchEngineManager *ephy_embed_shell_get_search_engine_manager (EphyEmbedShell *shell);
EphyPasswordManager *ephy_embed_shell_get_password_manager (EphyEmbedShell *shell);
G_END_DECLS
......@@ -188,25 +188,6 @@ ephy_web_extension_proxy_new (GDBusConnection *connection)
return web_extension;
}
void
ephy_web_extension_proxy_form_auth_data_save_confirmation_response (EphyWebExtensionProxy *web_extension,
guint request_id,
gboolean response)
{
g_assert (EPHY_IS_WEB_EXTENSION_PROXY (web_extension));
if (!web_extension->proxy)
return;
g_dbus_proxy_call (web_extension->proxy,
"FormAuthDataSaveConfirmationResponse",
g_variant_new ("(ub)", request_id, response),
G_DBUS_CALL_FLAGS_NONE,
-1,
web_extension->cancellable,
NULL, NULL);
}
void
ephy_web_extension_proxy_history_set_urls (EphyWebExtensionProxy *web_extension,
GList *urls)
......@@ -313,3 +294,43 @@ ephy_web_extension_proxy_history_clear (EphyWebExtensionProxy *web_extension)
web_extension->cancellable,
NULL, NULL);
}
void
ephy_web_extension_proxy_password_cached_users_response (EphyWebExtensionProxy *web_extension,
GList *users,
gint32 id)
{
if (!web_extension->proxy)
return;
GList *l;
g_auto(GVariantBuilder) builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_STRING_ARRAY);
for (l = users; l != NULL; l = l->next)
g_variant_builder_add (&builder, "s", l->data);
g_dbus_proxy_call (web_extension->proxy,
"PasswordQueryUsernamesResponse",
g_variant_new ("(asi)", &builder, id),
G_DBUS_CALL_FLAGS_NONE,
-1,
web_extension->cancellable,
NULL, NULL);
}
void
ephy_web_extension_proxy_password_query_response (EphyWebExtensionProxy *web_extension,
const char *username,
const char *password,
gint32 id)
{
if (!web_extension->proxy)
return;
g_dbus_proxy_call (web_extension->proxy,
"PasswordQueryResponse",
g_variant_new ("(ssi)", username ?: "", password ?: "", id),
G_DBUS_CALL_FLAGS_NONE,
-1,
web_extension->cancellable,
NULL, NULL);
}
\ No newline at end of file
......@@ -29,9 +29,6 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (EphyWebExtensionProxy, ephy_web_extension_proxy, EPHY, WEB_EXTENSION_PROXY, GObject)
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);
void ephy_web_extension_proxy_history_set_urls (EphyWebExtensionProxy *web_extension,
GList *urls);
void ephy_web_extension_proxy_history_set_url_thumbnail (EphyWebExtensionProxy *web_extension,
......@@ -45,5 +42,11 @@ void ephy_web_extension_proxy_history_delete_url
void ephy_web_extension_proxy_history_delete_host (EphyWebExtensionProxy *web_extension,
const char *host);
void ephy_web_extension_proxy_history_clear (EphyWebExtensionProxy *web_extension);
void ephy_web_extension_proxy_password_cached_users_response (EphyWebExtensionProxy *web_extension,
GList *users,
gint32 id);
void ephy_web_extension_proxy_password_query_response (EphyWebExtensionProxy *web_extension,
const char *username,
const char *password,
gint32 id);
G_END_DECLS
......@@ -44,7 +44,6 @@
#include "ephy-uri-helpers.h"
#include "ephy-view-source-handler.h"
#include "ephy-web-app-utils.h"
#include "ephy-web-extension-proxy.h"
#include "ephy-zoom.h"
#include <gio/gio.h>
......@@ -571,6 +570,56 @@ ephy_web_view_create_form_auth_save_confirmation_info_bar (EphyWebView *web_view
return info_bar;
}
typedef struct {
EphyPasswordSaveRequestCallback callback;
gpointer callback_data;
GDestroyNotify callback_destroy;
} SaveRequestData;
static void
save_auth_request_destroy (SaveRequestData *data,
GClosure *ignored)
{
if (data->callback_destroy)
data->callback_destroy (data->callback_data);
g_free (data);
}
static void
info_bar_save_request_response_cb (GtkInfoBar *info_bar,
gint response_id,
SaveRequestData *data)
{
g_assert (data->callback);
data->callback (response_id, data->callback_data);
gtk_widget_destroy (GTK_WIDGET (info_bar));
}
void
ephy_web_view_show_auth_form_save_request (EphyWebView *web_view,
const char *origin,
const char *username,
EphyPasswordSaveRequestCallback response_callback,
gpointer response_data,
GDestroyNotify response_destroy)
{
GtkWidget *info_bar;
info_bar = ephy_web_view_create_form_auth_save_confirmation_info_bar (web_view, origin, username);
SaveRequestData *data = g_new(SaveRequestData, 1);
data->callback = response_callback;
data->callback_data = response_data;
data->callback_destroy = response_destroy;
g_signal_connect_data (info_bar, "response",
G_CALLBACK (info_bar_save_request_response_cb),
data, (GClosureNotify)save_auth_request_destroy, 0);
gtk_widget_show (info_bar);
}
static void
update_navigation_flags (WebKitWebView *view)
{
......@@ -721,94 +770,6 @@ icon_changed_cb (EphyWebView *view,
_ephy_web_view_update_icon (view);
}
typedef struct {
EphyWebView *web_view;
guint request_id;
char *origin;
} FormAuthRequestData;
static FormAuthRequestData *
form_auth_request_data_new (EphyWebView *web_view,
guint request_id,
const char *origin)
{
FormAuthRequestData *data;
data = g_slice_new (FormAuthRequestData);
data->web_view = web_view;
data->request_id = request_id;
data->origin = g_strdup (origin);
return data;
}
static void
form_auth_request_data_free (FormAuthRequestData *data)
{
g_free (data->origin);
g_slice_free (FormAuthRequestData, data);
}
static void
form_auth_save_confirmation_info_bar_destroyed_cb (FormAuthRequestData *data,
GObject *where_the_info_bar_was)
{
/* Ensure the hash table entry in the web process is removed. */
if (data->web_view->web_extension)
ephy_web_extension_proxy_form_auth_data_save_confirmation_response (data->web_view->web_extension,
data->request_id,
FALSE);
form_auth_request_data_free (data);
}
static void
form_auth_data_save_confirmation_response (GtkInfoBar *info_bar,
gint response_id,
FormAuthRequestData *data)
{
if (data->web_view->web_extension) {
ephy_web_extension_proxy_form_auth_data_save_confirmation_response (data->web_view->web_extension,
data->request_id,
response_id == GTK_RESPONSE_YES);
}
if (response_id == GTK_RESPONSE_REJECT) {
EphyEmbedShell *shell = ephy_embed_shell_get_default ();
EphyPermissionsManager *manager = ephy_embed_shell_get_permissions_manager (shell);
ephy_permissions_manager_set_permission (manager,
EPHY_PERMISSION_TYPE_SAVE_PASSWORD,
data->origin,
EPHY_PERMISSION_DENY);
}
g_object_weak_unref (G_OBJECT (info_bar), (GWeakNotify)form_auth_save_confirmation_info_bar_destroyed_cb, data);
gtk_widget_destroy (GTK_WIDGET (info_bar));
form_auth_request_data_free (data);
}
static void
form_auth_data_save_requested (EphyEmbedShell *shell,
guint request_id,
guint64 page_id,
const char *origin,
const char *username,
EphyWebView *web_view)
{
GtkWidget *info_bar;
FormAuthRequestData *data;
if (webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view)) != page_id)
return;
info_bar = ephy_web_view_create_form_auth_save_confirmation_info_bar (web_view, origin, username);
data = form_auth_request_data_new (web_view, request_id, origin);
g_signal_connect (info_bar, "response",
G_CALLBACK (form_auth_data_save_confirmation_response),
data);
g_object_weak_ref (G_OBJECT (info_bar), (GWeakNotify)form_auth_save_confirmation_info_bar_destroyed_cb, data);
gtk_widget_show (info_bar);
}
static void
sensitive_form_focused_cb (EphyEmbedShell *shell,
guint64 page_id,
......@@ -892,10 +853,6 @@ page_created_cb (EphyEmbedShell *shell,
view->web_extension = web_extension;
g_object_add_weak_pointer (G_OBJECT (view->web_extension), (gpointer *)&view->web_extension);
g_signal_connect_object (shell, "form-auth-data-save-requested",
G_CALLBACK (form_auth_data_save_requested),
view, 0);
g_signal_connect_object (shell, "sensitive-form-focused",
G_CALLBACK (sensitive_form_focused_cb),
view, 0);
......@@ -3746,3 +3703,9 @@ ephy_web_view_get_reader_mode_state (EphyWebView *view)
{
return view->reader_active;
}
EphyWebExtensionProxy *
ephy_web_view_get_web_extension_proxy (EphyWebView *view)
{
return view->web_extension;
}
......@@ -26,6 +26,7 @@
#include "ephy-embed-shell.h"
#include "ephy-history-types.h"
#include "ephy-security-levels.h"
#include "ephy-web-extension-proxy.h"
G_BEGIN_DECLS
......@@ -69,6 +70,9 @@ typedef enum {
EPHY_WEB_VIEW_ERROR_UNSAFE_BROWSING
} EphyWebViewErrorPage;
typedef void (* EphyPasswordSaveRequestCallback) (int response_id,
gpointer data);
GType ephy_web_view_chrome_get_type (void);
GType ephy_web_view_security_level_get_type (void);
GtkWidget * ephy_web_view_new (void);
......@@ -157,4 +161,13 @@ gboolean ephy_web_view_is_reader_mode_available (EphyWebView
gboolean ephy_web_view_get_reader_mode_state (EphyWebView *view);
EphyWebExtensionProxy *ephy_web_view_get_web_extension_proxy (EphyWebView *view);
void ephy_web_view_show_auth_form_save_request (EphyWebView *web_view,
const char *origin,
const char *username,
EphyPasswordSaveRequestCallback response_callback,
gpointer response_data,
GDestroyNotify response_destroy);
G_END_DECLS
......@@ -25,12 +25,9 @@
#include "ephy-dbus-util.h"
#include "ephy-debug.h"
#include "ephy-file-helpers.h"
#include "ephy-password-manager.h"
#include "ephy-permissions-manager.h"
#include "ephy-prefs.h"
#include "ephy-settings.h"
#include "ephy-sync-service.h"
#include "ephy-sync-utils.h"
#include "ephy-uri-helpers.h"
#include "ephy-uri-tester.h"
#include "ephy-web-overview-model.h"
......@@ -53,14 +50,14 @@ struct _EphyWebExtension {
GDBusConnection *dbus_connection;
GArray *page_created_signals_pending;
EphySyncService *sync_service;
EphyPasswordManager *password_manager;
GHashTable *form_auth_data_save_requests;
EphyWebOverviewModel *overview_model;
EphyPermissionsManager *permissions_manager;
EphyUriTester *uri_tester;
WebKitScriptWorld *script_world;
WebKitWebPage *web_page;
gboolean is_private_profile;
};
static const char introspection_xml[] =
......@@ -69,10 +66,6 @@ static const char introspection_xml[] =
" <signal name='PageCreated'>"
" <arg type='t' name='page_id' direction='out'/>"
" </signal>"
" <method name='FormAuthDataSaveConfirmationResponse'>"
" <arg type='u' name='request_id' direction='in'/>"
" <arg type='b' name='should_store' direction='in'/>"
" </method>"
" <method name='HistorySetURLs'>"
" <arg type='a(ss)' name='urls' direction='in'/>"
" </method>"
......@@ -91,6 +84,15 @@ static const char introspection_xml[] =
" <arg type='s' name='host' direction='in'/>"
" </method>"
" <method name='HistoryClear'/>"
" <method name='PasswordQueryResponse'>"
" <arg type='s' name='username' direction='in'/>"
" <arg type='s' name='password' direction='in'/>"
" <arg type='i' name='id' direction='in'/>"
" </method>"
" <method name='PasswordQueryUsernamesResponse'>"
" <arg type='as' name='users' direction='in'/>"
" <arg type='i' name='id' direction='in'/>"
" </method>"
" </interface>"
"</node>";
......@@ -187,106 +189,6 @@ web_page_send_request (WebKitWebPage *web_page,
return FALSE;
}
typedef struct {
char *origin;
char *target_origin;
char *username;
char *password;
char *username_field_name;
char *password_field_name;
gboolean is_new;
} SaveAuthRequest;
static SaveAuthRequest *
save_auth_request_new (const char *origin,
const char *target_origin,
const char *username,
const char *password,
const char *username_field_name,
const char *password_field_name,
gboolean is_new)
{
SaveAuthRequest *request;
request = g_new (SaveAuthRequest, 1);
request->origin = g_strdup (origin);
request->target_origin = g_strdup (target_origin);
request->username = g_strdup (username);
request->password = g_strdup (password);
request->username_field_name = g_strdup (username_field_name);
request->password_field_name = g_strdup (password_field_name);
request->is_new = is_new;
return request;
}
static void
save_auth_request_free (SaveAuthRequest *request)
{
g_free (request->origin);
g_free (request->target_origin);
g_free (request->username);
g_free (request->password);
g_free (request->username_field_name);
g_free (request->password_field_name);
g_free (request);
}
static GHashTable *
ephy_web_extension_get_form_auth_data_save_requests (EphyWebExtension *extension)
{
if (!extension->form_auth_data_save_requests) {
extension->form_auth_data_save_requests =
g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
(GDestroyNotify)save_auth_request_free);
}
return extension->form_auth_data_save_requests;
}
static guint
form_auth_data_save_request_new_id (void)
{
static guint form_auth_data_save_request_id = 0;
return ++form_auth_data_save_request_id;
}
static char *
save_auth_requester (guint64 page_id,
const char *origin,
const char *target_origin,
const char *username,
const char *password,
const char *username_field_name,
const char *password_field_name,
gboolean is_new)
{
GVariant *variant;
guint request_id;
char *retval;
request_id = form_auth_data_save_request_new_id ();
variant = g_variant_new ("(utss)",
request_id,
page_id,
origin,
username ? username : "");
retval = g_variant_print (variant, FALSE);
g_variant_unref (variant);
g_hash_table_insert (ephy_web_extension_get_form_auth_data_save_requests (ephy_web_extension_get ()),
GINT_TO_POINTER (request_id), save_auth_request_new (origin, target_origin, username,
password, username_field_name,
password_field_name, is_new));
return retval;
}
static void
web_page_will_submit_form (WebKitWebPage *web_page,
WebKitDOMHTMLFormElement *dom_form,
......@@ -301,7 +203,6 @@ web_page_will_submit_form (WebKitWebPage *web_page,
JSCContext *js_context;
JSCValue *js_ephy;
JSCValue *js_form;
JSCValue *js_requester;
JSCValue *js_result;
form_submit_handled =
......@@ -318,21 +219,12 @@ web_page_will_submit_form (WebKitWebPage *web_page,
js_context = webkit_frame_get_js_context_for_script_world (source_frame, extension->script_world);
js_ephy = jsc_context_get_value (js_context, "Ephy");
js_form = webkit_frame_get_js_value_for_dom_object_in_script_world (frame, WEBKIT_DOM_OBJECT (dom_form), extension->script_world);
js_requester = jsc_value_new_function (js_context,
"saveAuthRequester",
G_CALLBACK (save_auth_requester), NULL, NULL,
G_TYPE_STRING, 8,
G_TYPE_UINT64, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_BOOLEAN);
js_result = jsc_value_object_invoke_method (js_ephy,
"handleFormSubmission",
G_TYPE_UINT64, webkit_web_page_get_id (web_page),
JSC_TYPE_VALUE, js_form,
JSC_TYPE_VALUE, js_requester,
G_TYPE_NONE);
g_object_unref (js_result);
g_object_unref (js_requester);
g_object_unref (js_form);
g_object_unref (js_ephy);
g_object_unref (js_context);
......@@ -382,7 +274,7 @@ web_page_form_controls_associated (WebKitWebPage *web_page,
G_CALLBACK (sensitive_form_message_serializer), NULL, NULL,
G_TYPE_STRING, 2,
G_TYPE_UINT64, G_TYPE_BOOLEAN);
remember_passwords = extension->password_manager &&
remember_passwords = !extension->is_private_profile &&
g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_REMEMBER_PASSWORDS);
js_result = jsc_value_object_invoke_method (js_ephy,
"formControlsAssociated",
......@@ -496,6 +388,7 @@ ephy_web_extension_page_created_cb (EphyWebExtension *extension,
g_object_unref (js_context);
page_id = webkit_web_page_get_id (web_page);
extension->web_page = web_page;
  • This is wrong when process model is single web process, when process limit is reached or when related web view is created, it's assuming there's only one page per process and it's not invalidating the pointer when the page is destroyed. This is causing crashes indeed. Please, fix or revert.

  • So we'll need to add pageID to these methods, in addition to the existing ID (which corresponds to "promiseID" in the JS, and which should probably be guint64 rather than gint32).

  • So the page id is safe to keep around just not the web page? That means webkit_web_extension_get_page(self, self->page_id) for example would be the solution?

    EDIT: Well I guess that would solve crashes but then the problem is that multiple page ids may share the same page/frame/js?

    Edited by Patrick Griffis
  • You shouldn't need to store the page id at all, the web view knows the page id that should be passed to the extension. I don't understand why this is now handled by the shell, instead of keeping the signal and letting the web view handle it.

  • We can have it send the page id with everything else, sure.

    I don't understand why this is now handled by the shell, instead of keeping the signal and letting the web view handle it.

    Could you elaborate on which parts you think should be handled elsewhere?

  • We are now getting the extension proxy for a page in shell, instead of emitting the signal and letting the corresponding view handle it using its extension proxy.

  • I can look into redesigning that later but does this at least fix the crashing concerns you had since it no longer carries around a WebPage: 38a72f6b

  • They are not concerns, my ephy is crashing all the time because of this in build.webkit.org (note that the website is auto-reloading). But yes, that commit look good.

  • OK... sounds like it's ready for a MR?

  • If multiple page-ids return the same JS object then that still needs fixed.

  • Not sure I understand. What same JS object?

  • JSCContext *context = webkit_frame_get_js_context_for_script_world (frame,
                              self->script_world)

    Now that I look at it, it has a private script world so should be fine, I'll open an MR.

Please register or sign in to reply
if (extension->dbus_connection)
ephy_web_extension_emit_page_created (extension, page_id);
else
......@@ -515,6 +408,18 @@ ephy_web_extension_page_created_cb (EphyWebExtension *extension,
extension);
}
static JSCValue *
get_password_manager (EphyWebExtension *self)
{
g_assert (self->web_page);
WebKitFrame *frame = webkit_web_page_get_main_frame (self->web_page);
JSCContext *context = webkit_frame_get_js_context_for_script_world (frame,
self->script_world);
g_autoptr(JSCValue) ephy = jsc_context_get_value (context, "Ephy");
return jsc_value_object_get_property (ephy, "passwordManager");
}
static void
handle_method_call (GDBusConnection *connection,
const char *sender,
......@@ -530,32 +435,7 @@ handle_method_call (GDBusConnection *connection,
if (g_strcmp0 (interface_name, EPHY_WEB_EXTENSION_INTERFACE) != 0)
return;
if (g_strcmp0 (method_name, "FormAuthDataSaveConfirmationResponse") == 0) {
SaveAuthRequest *request;
guint request_id;
gboolean should_store;
GHashTable *requests;
requests = ephy_web_extension_get_form_auth_data_save_requests (extension);
g_variant_get (parameters, "(ub)", &request_id, &should_store);
request = g_hash_table_lookup (requests, GINT_TO_POINTER (request_id));
if (!request)
return;
if (should_store) {
ephy_password_manager_save (extension->password_manager,
request->origin,
request->target_origin,
request->username,
request->password,
request->username_field_name,
request->password_field_name,
request->is_new);
}
g_hash_table_remove (requests, GINT_TO_POINTER (request_id));
} else if (g_strcmp0 (method_name, "HistorySetURLs") == 0) {
if (g_strcmp0 (method_name, "HistorySetURLs") == 0) {
if (extension->overview_model) {
GVariantIter iter;
GVariant *array;
......@@ -611,6 +491,29 @@ handle_method_call (GDBusConnection *connection,
if (extension->overview_model)
ephy_web_overview_model_clear (extension->overview_model);
g_dbus_method_invocation_return_value (invocation, NULL);
} else if (g_strcmp0 (method_name, "PasswordQueryUsernamesResponse") == 0) {
g_autofree const char **users;
g_autoptr(JSCValue) ret;
gint32 id;
users = g_variant_get_strv (g_variant_get_child_value (parameters, 0), NULL);
g_variant_get_child (parameters, 1, "i", &id);
g_autoptr(JSCValue) password_manager = get_password_manager (extension);
ret = jsc_value_object_invoke_method (password_manager, "_onQueryUsernamesResponse",
G_TYPE_STRV, users, G_TYPE_INT, id, G_TYPE_NONE);
} else if(g_strcmp0 (method_name, "PasswordQueryResponse") == 0) {
const char *username;
const char *password;
gint32 id;
g_autoptr(JSCValue) ret;
g_variant_get (parameters, "(&s&si)", &username, &password, &id);
g_autoptr(JSCValue) password_manager = get_password_manager (extension);
ret = jsc_value_object_invoke_method (password_manager, "_onQueryResponse",
G_TYPE_STRING, username,
G_TYPE_STRING, password,
G_TYPE_INT, id, G_TYPE_NONE);
}
}
......@@ -620,78 +523,6 @@ static const GDBusInterfaceVTable interface_vtable = {
NULL
};
static void
ephy_prefs_passwords_sync_enabled_cb (GSettings *settings,
char *key,
gpointer user_data)
{
EphyWebExtension *extension;
EphySynchronizableManager *manager;
extension = EPHY_WEB_EXTENSION (user_data);
manager = EPHY_SYNCHRONIZABLE_MANAGER (extension->password_manager);
if (g_settings_get_boolean (settings, key))
ephy_sync_service_register_manager (extension->sync_service, manager);
else
ephy_sync_service_unregister_manager (extension->sync_service, manager);
}
static void
ephy_web_extension_create_sync_service (EphyWebExtension *extension)
{
EphySynchronizableManager *manager;
g_assert (EPHY_IS_WEB_EXTENSION (extension));
g_assert (EPHY_IS_PASSWORD_MANAGER (extension->password_manager));
g_assert (!extension->sync_service);
extension->sync_service = ephy_sync_service_new (FALSE);
manager = EPHY_SYNCHRONIZABLE_MANAGER (extension->password_manager);
if (ephy_sync_utils_passwords_sync_is_enabled ())
ephy_sync_service_register_manager (extension->sync_service, manager);
g_signal_connect (EPHY_SETTINGS_SYNC, "changed::"EPHY_PREFS_SYNC_PASSWORDS_ENABLED,
G_CALLBACK (ephy_prefs_passwords_sync_enabled_cb), extension);
}
static void
ephy_web_extension_destroy_sync_service (EphyWebExtension *extension)
{
EphySynchronizableManager *manager;
g_assert (EPHY_IS_WEB_EXTENSION (extension));
g_assert (EPHY_IS_PASSWORD_MANAGER (extension->password_manager));
g_assert (EPHY_IS_SYNC_SERVICE (extension->sync_service));
manager = EPHY_SYNCHRONIZABLE_MANAGER (extension->password_manager);
ephy_sync_service_unregister_manager (extension->sync_service, manager);
g_signal_handlers_disconnect_by_func (EPHY_SETTINGS_SYNC,
ephy_prefs_passwords_sync_enabled_cb,
extension);
g_clear_object (&extension->sync_service);
}
static void
ephy_prefs_sync_user_cb (GSettings *settings,
char *key,
gpointer user_data)
{
EphyWebExtension *extension = EPHY_WEB_EXTENSION (user_data);
/* If the sync user has changed we need to destroy the previous sync service
* (which is no longer valid because the user specific data has been cleared)
* and create a new one which will load the new user specific data. This way
* we will correctly upload new saved passwords in the future.
*/
if (ephy_sync_utils_user_is_signed_in ())
ephy_web_extension_create_sync_service (extension);
else if (extension->sync_service)
ephy_web_extension_destroy_sync_service (extension);
}
static void
ephy_web_extension_dispose (GObject *object)
{
......@@ -701,17 +532,6 @@ ephy_web_extension_dispose (GObject *object)
g_clear_object (&extension->overview_model);
g_clear_object (&extension->permissions_manager);
if (extension->password_manager) {
if (extension->sync_service)
ephy_web_extension_destroy_sync_service (extension);
g_clear_object (&extension->password_manager);
}
if (extension->form_auth_data_save_requests) {
g_hash_table_destroy (extension->form_auth_data_save_requests);
extension->form_auth_data_save_requests = NULL;
}
if (extension->page_created_signals_pending) {
g_array_free (extension->page_created_signals_pending, TRUE);
extension->page_created_signals_pending = NULL;
......@@ -923,10 +743,14 @@ window_object_cleared_cb (WebKitScriptWorld *world,
js_context,
js_ephy);
if (extension->password_manager) {