aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--embed/ephy-web-view.c44
-rw-r--r--lib/ephy-profile-migrator.c9
-rw-r--r--lib/ephy-profile-utils.c211
-rw-r--r--lib/ephy-profile-utils.h39
5 files changed, 216 insertions, 89 deletions
diff --git a/configure.ac b/configure.ac
index 736cd8560..1f51c4c1d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,6 +87,7 @@ WEBKIT_GTK_REQUIRED=1.11.5
LIBSOUP_REQUIRED=2.41.3
GNOME_DESKTOP_REQUIRED=2.91.2
GNOME_KEYRING_REQUIRED=2.26.0
+LIBSECRET_REQUIRED=0.14
GSETTINGS_DESKTOP_SCHEMAS_REQUIRED=0.0.1
LIBNOTIFY_REQUIRED=0.5.1
GCR_REQUIRED=3.5.5
@@ -127,6 +128,7 @@ PKG_CHECK_MODULES([DEPENDENCIES], [
libxslt >= $LIBXSLT_REQUIRED
$WEBKIT_GTK_PC_NAME >= $WEBKIT_GTK_REQUIRED
libsoup-2.4 >= $LIBSOUP_REQUIRED
+ libsecret-1 >= $LIBSECRET_REQUIRED
gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED
gnome-keyring-1 >= $GNOME_KEYRING_REQUIRED
gsettings-desktop-schemas >= $GSETTINGS_DESKTOP_SCHEMAS_REQUIRED
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index 3ddf2b56e..a69b3f9ee 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -49,7 +49,6 @@
#include <gio/gio.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
-#include <gnome-keyring.h>
#include <gtk/gtk.h>
#include <libsoup/soup.h>
@@ -524,33 +523,23 @@ fill_data_free (gpointer data)
}
static void
-fill_form_cb (GnomeKeyringResult retval,
- GList *results,
+fill_form_cb (const char *username,
+ const char *password,
gpointer user_data)
{
FillData *fill_data = (FillData*)user_data;
- GnomeKeyringNetworkPasswordData* keyring_data;
- if (!results) {
+ if (username == NULL && password == NULL) {
LOG ("No result");
return;
}
- /* FIXME: We use only the first result, for now; We need to do
- * something smarter here */
- keyring_data = (GnomeKeyringNetworkPasswordData*)results->data;
-
- if (retval != GNOME_KEYRING_RESULT_OK) {
- LOG ("Query failed.");
- return;
- }
-
- LOG ("Found: user %s pass (hidden)", keyring_data->user);
+ LOG ("Found: user %s pass (hidden)", username);
g_object_set (fill_data->username_node,
- "value", keyring_data->user, NULL);
+ "value", username, NULL);
g_object_set (fill_data->password_node,
- "value", keyring_data->password, NULL);
+ "value", password, NULL);
}
static void
@@ -663,7 +652,8 @@ store_password (GtkInfoBar *info_bar, gint response_id, gpointer data)
name_field_name,
password_field_name,
name_field_value,
- password_field_value);
+ password_field_value,
+ NULL, NULL);
/* Update internal caching */
host = ephy_string_get_host_name (uri);
@@ -732,25 +722,23 @@ request_decision_on_storing (StorePasswordData *store_data)
}
static void
-should_store_cb (GnomeKeyringResult retval,
- GList *results,
+should_store_cb (const char *username,
+ const char *password,
gpointer user_data)
{
StorePasswordData *store_data = (StorePasswordData*)user_data;
- GnomeKeyringNetworkPasswordData* keyring_data;
- if (!results) {
+ if (username == NULL && password == NULL) {
LOG ("No result on query; asking whether we should store.");
request_decision_on_storing (store_data);
return;
}
+
/* FIXME: We use only the first result, for now; We need to do
* something smarter here */
- keyring_data = (GnomeKeyringNetworkPasswordData*)results->data;
-
- if (g_str_equal (keyring_data->user, store_data->name_value) &&
- g_str_equal (keyring_data->password, store_data->password_value)) {
+ if (g_str_equal (username, store_data->name_value) &&
+ g_str_equal (password, store_data->password_value)) {
LOG ("User/password already stored. Not asking about storing.");
store_password_data_free (store_data);
return;
@@ -800,7 +788,7 @@ form_submitted_cb (WebKitDOMHTMLFormElement *dom_form,
_ephy_profile_utils_query_form_auth_data (store_data->uri,
store_data->name_field,
store_data->password_field,
- should_store_cb,
+ (EphyQueryFormDataCallback)should_store_cb,
store_data,
NULL);
@@ -847,7 +835,7 @@ pre_fill_form (WebKitDOMNode *username_node,
_ephy_profile_utils_query_form_auth_data (uri_str,
data->form_username,
data->form_password,
- fill_form_cb,
+ (EphyQueryFormDataCallback)fill_form_cb,
fill_data,
fill_data_free);
g_free (uri_str);
diff --git a/lib/ephy-profile-migrator.c b/lib/ephy-profile-migrator.c
index 35d2f8dcf..43f36a781 100644
--- a/lib/ephy-profile-migrator.c
+++ b/lib/ephy-profile-migrator.c
@@ -298,10 +298,11 @@ parse_and_decrypt_signons (const char *signons,
char *u = soup_uri_to_string (uri, FALSE);
/* We skip the '*' at the beginning of form_password. */
_ephy_profile_utils_store_form_auth_data (u,
- form_username,
- form_password+1,
- username,
- password);
+ form_username,
+ form_password+1,
+ username,
+ password,
+ NULL, NULL);
g_free (u);
} else if (!handle_forms && realm &&
username && password &&
diff --git a/lib/ephy-profile-utils.c b/lib/ephy-profile-utils.c
index 2c685e05f..5a8f1a33b 100644
--- a/lib/ephy-profile-utils.c
+++ b/lib/ephy-profile-utils.c
@@ -25,10 +25,27 @@
#include "ephy-debug.h"
#include "ephy-file-helpers.h"
+#include <glib/gi18n.h>
#include <libsoup/soup.h>
#define PROFILE_MIGRATION_FILE ".migrated"
+const SecretSchema*
+ephy_profile_get_form_password_schema (void)
+{
+ static const SecretSchema schema = {
+ "org.epiphany.FormPassword", SECRET_SCHEMA_NONE,
+ {
+ { URI_KEY, SECRET_SCHEMA_ATTRIBUTE_STRING },
+ { FORM_USERNAME_KEY, SECRET_SCHEMA_ATTRIBUTE_STRING },
+ { FORM_PASSWORD_KEY, SECRET_SCHEMA_ATTRIBUTE_STRING },
+ { USERNAME_KEY, SECRET_SCHEMA_ATTRIBUTE_STRING },
+ { "NULL", 0 },
+ }
+ };
+ return &schema;
+}
+
int
ephy_profile_utils_get_migration_version ()
{
@@ -89,17 +106,7 @@ ephy_profile_utils_set_migration_version (int version)
}
static void
-store_form_password_cb (GnomeKeyringResult result,
- guint32 id,
- gpointer data)
-{
- /* FIXME: should we do anything if the operation failed? */
-}
-
-static void
-normalize_and_prepare_uri (SoupURI *uri,
- const char *form_username,
- const char *form_password)
+normalize_and_prepare_uri (SoupURI *uri)
{
g_return_if_fail (uri != NULL);
@@ -110,26 +117,52 @@ normalize_and_prepare_uri (SoupURI *uri,
soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP);
soup_uri_set_path (uri, "/");
+}
- /* Store the form login and password names encoded in the
- * URL. A bit of an abuse of keyring, but oh well */
- soup_uri_set_query_from_fields (uri,
- FORM_USERNAME_KEY,
- form_username,
- FORM_PASSWORD_KEY,
- form_password,
+static GHashTable *
+ephy_profile_utils_get_attributes_table (const char *uri,
+ const char *field_username,
+ const char *field_password,
+ const char *username)
+{
+ return secret_attributes_build (EPHY_FORM_PASSWORD_SCHEMA,
+ URI_KEY, uri,
+ FORM_USERNAME_KEY, field_username,
+ FORM_PASSWORD_KEY, field_password,
+ username ? USERNAME_KEY : NULL, username,
NULL);
}
+static void
+store_form_password_cb (SecretService *service,
+ GAsyncResult *res,
+ GSimpleAsyncResult *async)
+{
+ GError *error = NULL;
+
+ secret_service_store_finish (service, res, &error);
+ if (error != NULL)
+ g_simple_async_result_take_error (async, error);
+
+ g_simple_async_result_complete (async);
+ g_object_unref (async);
+}
+
void
_ephy_profile_utils_store_form_auth_data (const char *uri,
const char *form_username,
const char *form_password,
const char *username,
- const char *password)
+ const char *password,
+ GAsyncReadyCallback callback,
+ gpointer userdata)
{
SoupURI *fake_uri;
char *fake_uri_str;
+ SecretValue *value;
+ GHashTable *attributes;
+ char *label;
+ GSimpleAsyncResult *res;
g_return_if_fail (uri);
g_return_if_fail (form_username);
@@ -138,38 +171,119 @@ _ephy_profile_utils_store_form_auth_data (const char *uri,
g_return_if_fail (password);
fake_uri = soup_uri_new (uri);
+
if (fake_uri == NULL)
return;
- normalize_and_prepare_uri (fake_uri, form_username, form_password);
- fake_uri_str = soup_uri_to_string (fake_uri, FALSE);
+ res = g_simple_async_result_new (NULL, callback, userdata,
+ _ephy_profile_utils_store_form_auth_data);
- gnome_keyring_set_network_password (NULL,
- username,
- NULL,
- fake_uri_str,
- NULL,
- fake_uri->scheme,
- NULL,
- fake_uri->port,
- password,
- (GnomeKeyringOperationGetIntCallback)store_form_password_cb,
- NULL,
- NULL);
+ normalize_and_prepare_uri (fake_uri);
+ fake_uri_str = soup_uri_to_string (fake_uri, FALSE);
+ value = secret_value_new (password, -1, "text/plain");
+ attributes = ephy_profile_utils_get_attributes_table (fake_uri_str, form_username,
+ form_password, username);
+ /* Translators: The first %s is the username and the second one is the
+ * hostname where this is happening. Example: gnome@gmail.com and
+ * mail.google.com.
+ */
+ label = g_strdup_printf (_("Password for %s in a form in %s"),
+ username, fake_uri_str);
+ secret_service_store (NULL, EPHY_FORM_PASSWORD_SCHEMA,
+ attributes, NULL, label, value,
+ NULL,
+ (GAsyncReadyCallback)store_form_password_cb,
+ g_object_ref (res));
+
+ g_free (label);
+ secret_value_unref (value);
+ g_hash_table_unref (attributes);
soup_uri_free (fake_uri);
g_free (fake_uri_str);
+ g_object_unref (res);
+}
+
+
+gboolean
+_ephy_profile_utils_store_form_auth_data_finish (GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, _ephy_profile_utils_store_form_auth_data), FALSE);
+
+ return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+}
+
+typedef struct
+{
+ EphyQueryFormDataCallback callback;
+ gpointer data;
+ GDestroyNotify destroy_data;
+} EphyProfileQueryClosure;
+
+static void
+ephy_profile_query_closure_free (EphyProfileQueryClosure *closure)
+{
+ if (closure->destroy_data)
+ closure->destroy_data (closure->data);
+
+ g_slice_free (EphyProfileQueryClosure, closure);
+}
+
+static void
+search_form_data_cb (SecretService *service,
+ GAsyncResult *res,
+ EphyProfileQueryClosure *closure)
+{
+ GList *results;
+ SecretItem *item;
+ const char* username = NULL, *password = NULL;
+ SecretValue *value = NULL;
+ GHashTable *attributes = NULL;
+ GError *error = NULL;
+
+ results = secret_service_search_finish (service, res, &error);
+ if (error) {
+ g_warning ("Couldn't retrieve form data: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ if (!results)
+ goto out;
+
+ item = (SecretItem*)results->data;
+ attributes = secret_item_get_attributes (item);
+ username = g_hash_table_lookup (attributes, USERNAME_KEY);
+ value = secret_item_get_secret (item);
+ password = secret_value_get (value, NULL);
+
+ g_list_free_full (results, (GDestroyNotify)g_object_unref);
+
+out:
+ if (closure->callback)
+ closure->callback (username, password, closure->data);
+
+ if (value)
+ secret_value_unref (value);
+ if (attributes)
+ g_hash_table_unref (attributes);
+
+ ephy_profile_query_closure_free (closure);
}
void
_ephy_profile_utils_query_form_auth_data (const char *uri,
const char *form_username,
const char *form_password,
- GnomeKeyringOperationGetListCallback callback,
+ EphyQueryFormDataCallback callback,
gpointer data,
GDestroyNotify destroy_data)
{
SoupURI *key;
char *key_str;
+ EphyProfileQueryClosure *closure;
+ GHashTable *attributes;
g_return_if_fail (uri);
g_return_if_fail (form_username);
@@ -178,21 +292,28 @@ _ephy_profile_utils_query_form_auth_data (const char *uri,
key = soup_uri_new (uri);
g_return_if_fail (key);
- normalize_and_prepare_uri (key, form_username, form_password);
+ normalize_and_prepare_uri (key);
key_str = soup_uri_to_string (key, FALSE);
+ attributes = ephy_profile_utils_get_attributes_table (key_str, form_username,
+ form_password, NULL);
+
+ closure = g_slice_new0 (EphyProfileQueryClosure);
+ closure->callback = callback;
+ closure->data = data;
+ closure->destroy_data = destroy_data;
+
LOG ("Querying Keyring: %s", key_str);
- gnome_keyring_find_network_password (NULL,
- NULL,
- key_str,
- NULL,
- NULL,
- NULL,
- 0,
- callback,
- data,
- destroy_data);
+
+ secret_service_search (NULL,
+ EPHY_FORM_PASSWORD_SCHEMA,
+ attributes,
+ SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS,
+ NULL, (GAsyncReadyCallback)search_form_data_cb,
+ closure);
+
+ g_hash_table_unref (attributes);
soup_uri_free (key);
g_free (key_str);
}
diff --git a/lib/ephy-profile-utils.h b/lib/ephy-profile-utils.h
index 1e9d071db..7e22dd6f8 100644
--- a/lib/ephy-profile-utils.h
+++ b/lib/ephy-profile-utils.h
@@ -20,11 +20,15 @@
#ifndef EPHY_PROFILE_UTILS_H
#define EPHY_PROFILE_UTILS_H
+#define SECRET_API_SUBJECT_TO_CHANGE
+
#include <glib.h>
-#include <gnome-keyring.h>
+#include <libsecret/secret.h>
+#define URI_KEY "uri"
#define FORM_USERNAME_KEY "form_username"
#define FORM_PASSWORD_KEY "form_password"
+#define USERNAME_KEY "username"
#define EPHY_PROFILE_MIGRATION_VERSION 8
@@ -38,18 +42,29 @@ gboolean ephy_profile_utils_set_migration_version (int version);
gboolean ephy_profile_utils_do_migration (const char *profile_directory, int test_to_run, gboolean debug);
-void _ephy_profile_utils_store_form_auth_data (const char *uri,
- const char *form_username,
- const char *form_password,
- const char *username,
- const char *password);
+void _ephy_profile_utils_store_form_auth_data (const char *uri,
+ const char *form_username,
+ const char *form_password,
+ const char *username,
+ const char *password,
+ GAsyncReadyCallback callback,
+ gpointer userdata);
+
+gboolean _ephy_profile_utils_store_form_auth_data_finish (GAsyncResult *result,
+ GError **error);
+
+typedef void (*EphyQueryFormDataCallback) (const char *username, const char *password, gpointer user_data);
void
-_ephy_profile_utils_query_form_auth_data (const char *uri,
- const char *form_username,
- const char *form_password,
- GnomeKeyringOperationGetListCallback callback,
- gpointer data,
- GDestroyNotify destroy_data);
+_ephy_profile_utils_query_form_auth_data (const char *uri,
+ const char *form_username,
+ const char *form_password,
+ EphyQueryFormDataCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+
+const SecretSchema *ephy_profile_get_form_password_schema (void) G_GNUC_CONST;
+
+#define EPHY_FORM_PASSWORD_SCHEMA ephy_profile_get_form_password_schema ()
#endif