| Index: chrome/browser/password_manager/native_backend_gnome_x.cc
|
| ===================================================================
|
| --- chrome/browser/password_manager/native_backend_gnome_x.cc (revision 49824)
|
| +++ chrome/browser/password_manager/native_backend_gnome_x.cc (working copy)
|
| @@ -2,7 +2,7 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "chrome/browser/password_manager/password_store_gnome.h"
|
| +#include "chrome/browser/password_manager/native_backend_gnome_x.h"
|
|
|
| #if defined(DLOPEN_GNOME_KEYRING)
|
| #include <dlfcn.h>
|
| @@ -13,13 +13,12 @@
|
|
|
| #include "base/logging.h"
|
| #include "base/string_util.h"
|
| -#include "base/task.h"
|
| #include "base/time.h"
|
| #include "base/utf_string_conversions.h"
|
| +#include "chrome/browser/chrome_thread.h"
|
|
|
| using std::map;
|
| using std::string;
|
| -using std::vector;
|
| using webkit_glue::PasswordForm;
|
|
|
| /* Many of the gnome_keyring_* functions use variable arguments, which makes
|
| @@ -136,7 +135,7 @@
|
| #define GNOME_KEYRING_APPLICATION_CHROME "chrome"
|
|
|
| // Schema is analagous to the fields in PasswordForm.
|
| -const GnomeKeyringPasswordSchema PasswordStoreGnome::kGnomeSchema = {
|
| +const GnomeKeyringPasswordSchema NativeBackendGnome::kGnomeSchema = {
|
| GNOME_KEYRING_ITEM_GENERIC_SECRET, {
|
| { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
|
| { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
|
| @@ -156,26 +155,47 @@
|
| }
|
| };
|
|
|
| -PasswordStoreGnome::PasswordStoreGnome(LoginDatabase* login_db,
|
| - Profile* profile,
|
| - WebDataService* web_data_service) {
|
| +NativeBackendGnome::NativeBackendGnome() {
|
| }
|
|
|
| -PasswordStoreGnome::~PasswordStoreGnome() {
|
| +NativeBackendGnome::~NativeBackendGnome() {
|
| }
|
|
|
| -bool PasswordStoreGnome::Init() {
|
| - return PasswordStore::Init() &&
|
| - LoadGnomeKeyring() &&
|
| - gnome_keyring_is_available();
|
| +bool NativeBackendGnome::Init() {
|
| + return LoadGnomeKeyring() && gnome_keyring_is_available();
|
| }
|
|
|
| -void PasswordStoreGnome::AddLoginImpl(const PasswordForm& form) {
|
| +bool NativeBackendGnome::AddLogin(const PasswordForm& form) {
|
| DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
|
| - AddLoginHelper(form, base::Time::Now());
|
| + GnomeKeyringResult result = gnome_keyring_store_password_sync(
|
| + &kGnomeSchema,
|
| + NULL, // Default keyring.
|
| + form.origin.spec().c_str(), // Display name.
|
| + UTF16ToUTF8(form.password_value).c_str(),
|
| + "origin_url", form.origin.spec().c_str(),
|
| + "action_url", form.action.spec().c_str(),
|
| + "username_element", UTF16ToUTF8(form.username_element).c_str(),
|
| + "username_value", UTF16ToUTF8(form.username_value).c_str(),
|
| + "password_element", UTF16ToUTF8(form.password_element).c_str(),
|
| + "submit_element", UTF16ToUTF8(form.submit_element).c_str(),
|
| + "signon_realm", form.signon_realm.c_str(),
|
| + "ssl_valid", form.ssl_valid,
|
| + "preferred", form.preferred,
|
| + "date_created", Int64ToString(form.date_created.ToTimeT()).c_str(),
|
| + "blacklisted_by_user", form.blacklisted_by_user,
|
| + "scheme", form.scheme,
|
| + "application", GNOME_KEYRING_APPLICATION_CHROME,
|
| + NULL);
|
| +
|
| + if (result != GNOME_KEYRING_RESULT_OK) {
|
| + LOG(ERROR) << "Keyring save failed: "
|
| + << gnome_keyring_result_to_message(result);
|
| + return false;
|
| + }
|
| + return true;
|
| }
|
|
|
| -void PasswordStoreGnome::UpdateLoginImpl(const PasswordForm& form) {
|
| +bool NativeBackendGnome::UpdateLogin(const PasswordForm& form) {
|
| // Based on LoginDatabase::UpdateLogin(), we search for forms to update by
|
| // origin_url, username_element, username_value, password_element, and
|
| // signon_realm. We then compare the result to the updated form. If they
|
| @@ -201,31 +221,35 @@
|
| "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
|
| GNOME_KEYRING_APPLICATION_CHROME,
|
| NULL);
|
| - vector<PasswordForm*> forms;
|
| - if (result == GNOME_KEYRING_RESULT_OK) {
|
| - FillFormVector(found, &forms);
|
| - for (size_t i = 0; i < forms.size(); ++i) {
|
| - if (forms[i]->action != form.action ||
|
| - forms[i]->password_value != form.password_value ||
|
| - forms[i]->ssl_valid != form.ssl_valid ||
|
| - forms[i]->preferred != form.preferred) {
|
| - PasswordForm updated = *forms[i];
|
| - updated.action = form.action;
|
| - updated.password_value = form.password_value;
|
| - updated.ssl_valid = form.ssl_valid;
|
| - updated.preferred = form.preferred;
|
| - if (AddLoginHelper(updated, updated.date_created))
|
| - RemoveLoginImpl(*forms[i]);
|
| - }
|
| - delete forms[i];
|
| - }
|
| - } else {
|
| + if (result != GNOME_KEYRING_RESULT_OK) {
|
| LOG(ERROR) << "Keyring find failed: "
|
| << gnome_keyring_result_to_message(result);
|
| + return false;
|
| }
|
| + bool ok = true;
|
| + PasswordFormList forms;
|
| + ConvertFormList(found, &forms);
|
| + for (size_t i = 0; i < forms.size(); ++i) {
|
| + if (forms[i]->action != form.action ||
|
| + forms[i]->password_value != form.password_value ||
|
| + forms[i]->ssl_valid != form.ssl_valid ||
|
| + forms[i]->preferred != form.preferred) {
|
| + PasswordForm updated = *forms[i];
|
| + updated.action = form.action;
|
| + updated.password_value = form.password_value;
|
| + updated.ssl_valid = form.ssl_valid;
|
| + updated.preferred = form.preferred;
|
| + if (AddLogin(updated))
|
| + RemoveLogin(*forms[i]);
|
| + else
|
| + ok = false;
|
| + }
|
| + delete forms[i];
|
| + }
|
| + return ok;
|
| }
|
|
|
| -void PasswordStoreGnome::RemoveLoginImpl(const PasswordForm& form) {
|
| +bool NativeBackendGnome::RemoveLogin(const PasswordForm& form) {
|
| DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
|
| // We find forms using the same fields as LoginDatabase::RemoveLogin().
|
| GnomeKeyringResult result = gnome_keyring_delete_password_sync(
|
| @@ -241,43 +265,35 @@
|
| if (result != GNOME_KEYRING_RESULT_OK) {
|
| LOG(ERROR) << "Keyring delete failed: "
|
| << gnome_keyring_result_to_message(result);
|
| + return false;
|
| }
|
| + return true;
|
| }
|
|
|
| -void PasswordStoreGnome::RemoveLoginsCreatedBetweenImpl(
|
| +bool NativeBackendGnome::RemoveLoginsCreatedBetween(
|
| const base::Time& delete_begin,
|
| const base::Time& delete_end) {
|
| DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
|
| - GList* found = NULL;
|
| - // Search GNOME keyring for all passwords, then delete the ones in the range.
|
| - // We need to search for something, otherwise we get no results - so we search
|
| - // for the fixed application string.
|
| - GnomeKeyringResult result = gnome_keyring_find_itemsv_sync(
|
| - GNOME_KEYRING_ITEM_GENERIC_SECRET,
|
| - &found,
|
| - "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
|
| - GNOME_KEYRING_APPLICATION_CHROME,
|
| - NULL);
|
| - if (result == GNOME_KEYRING_RESULT_OK) {
|
| - // We could walk the list and delete items as we find them, but it is much
|
| - // easier to build the vector and use RemoveLoginImpl() to delete them.
|
| - vector<PasswordForm*> forms;
|
| - FillFormVector(found, &forms);
|
| - for (size_t i = 0; i < forms.size(); ++i) {
|
| - if (delete_begin <= forms[i]->date_created &&
|
| - (delete_end.is_null() || forms[i]->date_created < delete_end)) {
|
| - RemoveLoginImpl(*forms[i]);
|
| - }
|
| - delete forms[i];
|
| + bool ok = true;
|
| + // We could walk the list and delete items as we find them, but it is much
|
| + // easier to build the list and use RemoveLogin() to delete them.
|
| + PasswordFormList forms;
|
| + if (!GetAllLogins(&forms))
|
| + return false;
|
| +
|
| + for (size_t i = 0; i < forms.size(); ++i) {
|
| + if (delete_begin <= forms[i]->date_created &&
|
| + (delete_end.is_null() || forms[i]->date_created < delete_end)) {
|
| + if (!RemoveLogin(*forms[i]))
|
| + ok = false;
|
| }
|
| - } else if (result != GNOME_KEYRING_RESULT_NO_MATCH) {
|
| - LOG(ERROR) << "Keyring find failed: "
|
| - << gnome_keyring_result_to_message(result);
|
| + delete forms[i];
|
| }
|
| + return ok;
|
| }
|
|
|
| -void PasswordStoreGnome::GetLoginsImpl(GetLoginsRequest* request,
|
| - const PasswordForm& form) {
|
| +bool NativeBackendGnome::GetLogins(const PasswordForm& form,
|
| + PasswordFormList* forms) {
|
| DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
|
| GList* found = NULL;
|
| // Search gnome keyring for matching passwords.
|
| @@ -289,97 +305,96 @@
|
| "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
|
| GNOME_KEYRING_APPLICATION_CHROME,
|
| NULL);
|
| - vector<PasswordForm*> forms;
|
| - if (result == GNOME_KEYRING_RESULT_OK) {
|
| - FillFormVector(found, &forms);
|
| - } else if (result != GNOME_KEYRING_RESULT_NO_MATCH) {
|
| + if (result == GNOME_KEYRING_RESULT_NO_MATCH)
|
| + return true;
|
| + if (result != GNOME_KEYRING_RESULT_OK) {
|
| LOG(ERROR) << "Keyring find failed: "
|
| << gnome_keyring_result_to_message(result);
|
| + return false;
|
| }
|
| - NotifyConsumer(request, forms);
|
| + ConvertFormList(found, forms);
|
| + return true;
|
| }
|
|
|
| -void PasswordStoreGnome::GetAutofillableLoginsImpl(
|
| - GetLoginsRequest* request) {
|
| - std::vector<PasswordForm*> forms;
|
| - FillAutofillableLogins(&forms);
|
| - NotifyConsumer(request, forms);
|
| -}
|
| +bool NativeBackendGnome::GetLoginsCreatedBetween(const base::Time& get_begin,
|
| + const base::Time& get_end,
|
| + PasswordFormList* forms) {
|
| + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
|
| + // We could walk the list and add items as we find them, but it is much
|
| + // easier to build the list and then filter the results.
|
| + PasswordFormList all_forms;
|
| + if (!GetAllLogins(&all_forms))
|
| + return false;
|
|
|
| -void PasswordStoreGnome::GetBlacklistLoginsImpl(
|
| - GetLoginsRequest* request) {
|
| - std::vector<PasswordForm*> forms;
|
| - FillBlacklistLogins(&forms);
|
| - NotifyConsumer(request, forms);
|
| + forms->reserve(forms->size() + all_forms.size());
|
| + for (size_t i = 0; i < all_forms.size(); ++i) {
|
| + if (get_begin <= all_forms[i]->date_created &&
|
| + (get_end.is_null() || all_forms[i]->date_created < get_end)) {
|
| + forms->push_back(all_forms[i]);
|
| + } else {
|
| + delete all_forms[i];
|
| + }
|
| + }
|
| +
|
| + return true;
|
| }
|
|
|
| -bool PasswordStoreGnome::FillAutofillableLogins(
|
| - std::vector<PasswordForm*>* forms) {
|
| - return FillSomeLogins(true, forms);
|
| +bool NativeBackendGnome::GetAutofillableLogins(PasswordFormList* forms) {
|
| + return GetLoginsList(forms, true);
|
| }
|
|
|
| -bool PasswordStoreGnome::FillBlacklistLogins(
|
| - std::vector<PasswordForm*>* forms) {
|
| - return FillSomeLogins(false, forms);
|
| +bool NativeBackendGnome::GetBlacklistLogins(PasswordFormList* forms) {
|
| + return GetLoginsList(forms, false);
|
| }
|
|
|
| -bool PasswordStoreGnome::AddLoginHelper(const PasswordForm& form,
|
| - const base::Time& date_created) {
|
| - GnomeKeyringResult result = gnome_keyring_store_password_sync(
|
| - &kGnomeSchema,
|
| - NULL, // Default keyring.
|
| - form.origin.spec().c_str(), // Display name.
|
| - UTF16ToUTF8(form.password_value).c_str(),
|
| - "origin_url", form.origin.spec().c_str(),
|
| - "action_url", form.action.spec().c_str(),
|
| - "username_element", UTF16ToUTF8(form.username_element).c_str(),
|
| - "username_value", UTF16ToUTF8(form.username_value).c_str(),
|
| - "password_element", UTF16ToUTF8(form.password_element).c_str(),
|
| - "submit_element", UTF16ToUTF8(form.submit_element).c_str(),
|
| - "signon_realm", form.signon_realm.c_str(),
|
| - "ssl_valid", form.ssl_valid,
|
| - "preferred", form.preferred,
|
| - "date_created", Int64ToString(date_created.ToTimeT()).c_str(),
|
| - "blacklisted_by_user", form.blacklisted_by_user,
|
| - "scheme", form.scheme,
|
| - "application", GNOME_KEYRING_APPLICATION_CHROME,
|
| +bool NativeBackendGnome::GetLoginsList(PasswordFormList* forms,
|
| + bool autofillable) {
|
| + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
|
| + GList* found = NULL;
|
| + uint32_t blacklisted_by_user = !autofillable;
|
| + // Search gnome keyring for matching passwords.
|
| + GnomeKeyringResult result = gnome_keyring_find_itemsv_sync(
|
| + GNOME_KEYRING_ITEM_GENERIC_SECRET,
|
| + &found,
|
| + "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32,
|
| + blacklisted_by_user,
|
| + "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
|
| + GNOME_KEYRING_APPLICATION_CHROME,
|
| NULL);
|
| -
|
| + if (result == GNOME_KEYRING_RESULT_NO_MATCH)
|
| + return true;
|
| if (result != GNOME_KEYRING_RESULT_OK) {
|
| - LOG(ERROR) << "Keyring save failed: "
|
| + LOG(ERROR) << "Keyring find failed: "
|
| << gnome_keyring_result_to_message(result);
|
| return false;
|
| }
|
| + ConvertFormList(found, forms);
|
| return true;
|
| }
|
|
|
| -bool PasswordStoreGnome::FillSomeLogins(
|
| - bool autofillable,
|
| - std::vector<PasswordForm*>* forms) {
|
| - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
|
| +bool NativeBackendGnome::GetAllLogins(PasswordFormList* forms) {
|
| GList* found = NULL;
|
| - uint32_t blacklisted_by_user = !autofillable;
|
| - // Search gnome keyring for matching passwords.
|
| + // We need to search for something, otherwise we get no results - so we search
|
| + // for the fixed application string.
|
| GnomeKeyringResult result = gnome_keyring_find_itemsv_sync(
|
| GNOME_KEYRING_ITEM_GENERIC_SECRET,
|
| &found,
|
| - "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32,
|
| - blacklisted_by_user,
|
| "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
|
| GNOME_KEYRING_APPLICATION_CHROME,
|
| NULL);
|
| - if (result == GNOME_KEYRING_RESULT_OK) {
|
| - FillFormVector(found, forms);
|
| - } else if (result != GNOME_KEYRING_RESULT_NO_MATCH) {
|
| + if (result == GNOME_KEYRING_RESULT_NO_MATCH)
|
| + return true;
|
| + if (result != GNOME_KEYRING_RESULT_OK) {
|
| LOG(ERROR) << "Keyring find failed: "
|
| << gnome_keyring_result_to_message(result);
|
| return false;
|
| }
|
| + ConvertFormList(found, forms);
|
| return true;
|
| }
|
|
|
| -void PasswordStoreGnome::FillFormVector(GList* found,
|
| - std::vector<PasswordForm*>* forms) {
|
| +void NativeBackendGnome::ConvertFormList(GList* found,
|
| + PasswordFormList* forms) {
|
| GList* element = g_list_first(found);
|
| while (element != NULL) {
|
| GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data);
|
|
|