Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2628)

Unified Diff: chrome/browser/password_manager/password_store_kwallet.cc

Issue 2806002: Linux: refactor GNOME Keyring and KWallet integration to allow migration. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/password_manager/password_store_kwallet.cc
===================================================================
--- chrome/browser/password_manager/password_store_kwallet.cc (revision 49824)
+++ chrome/browser/password_manager/password_store_kwallet.cc (working copy)
@@ -1,547 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// 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_kwallet.h"
-
-#include <sstream>
-
-#include "base/logging.h"
-#include "base/md5.h"
-#include "base/pickle.h"
-#include "base/stl_util-inl.h"
-#include "base/string_util.h"
-#include "base/task.h"
-
-using std::string;
-using std::vector;
-using webkit_glue::PasswordForm;
-
-// We could localize these strings, but then changing your locale would cause
-// you to lose access to all your stored passwords. Maybe best not to do that.
-const char* PasswordStoreKWallet::kAppId = "Chrome";
-const char* PasswordStoreKWallet::kKWalletFolder = "Chrome Form Data";
-
-const char* PasswordStoreKWallet::kKWalletServiceName = "org.kde.kwalletd";
-const char* PasswordStoreKWallet::kKWalletPath = "/modules/kwalletd";
-const char* PasswordStoreKWallet::kKWalletInterface = "org.kde.KWallet";
-const char* PasswordStoreKWallet::kKLauncherServiceName = "org.kde.klauncher";
-const char* PasswordStoreKWallet::kKLauncherPath = "/KLauncher";
-const char* PasswordStoreKWallet::kKLauncherInterface = "org.kde.KLauncher";
-
-PasswordStoreKWallet::PasswordStoreKWallet(LoginDatabase* login_db,
- Profile* profile,
- WebDataService* web_data_service)
- : error_(NULL),
- connection_(NULL),
- proxy_(NULL) {
-}
-
-PasswordStoreKWallet::~PasswordStoreKWallet() {
- if (proxy_) {
- g_object_unref(proxy_);
- }
-}
-
-bool PasswordStoreKWallet::Init() {
- // Initialize threading in dbus-glib - it should be fine for
- // dbus_g_thread_init to be called multiple times.
- if (!g_thread_supported())
- g_thread_init(NULL);
- dbus_g_thread_init();
-
- // Get a connection to the session bus.
- connection_ = dbus_g_bus_get(DBUS_BUS_SESSION, &error_);
- if (CheckError())
- return false;
-
- if (!InitWallet()) {
- // kwalletd may not be running. Try to start it and try again.
- if (!StartKWalletd() || !InitWallet())
- return false;
- }
-
- return true;
-}
-
-bool PasswordStoreKWallet::StartKWalletd() {
- // Sadly kwalletd doesn't use DBUS activation, so we have to make a call to
- // klauncher to start it.
- DBusGProxy* klauncher_proxy =
- dbus_g_proxy_new_for_name(connection_, kKLauncherServiceName,
- kKLauncherPath, kKLauncherInterface);
-
- char* empty_string_list = NULL;
- int ret = 1;
- char* error = NULL;
- dbus_g_proxy_call(klauncher_proxy, "start_service_by_desktop_name", &error_,
- G_TYPE_STRING, "kwalletd", // serviceName
- G_TYPE_STRV, &empty_string_list, // urls
- G_TYPE_STRV, &empty_string_list, // envs
- G_TYPE_STRING, "", // startup_id
- G_TYPE_BOOLEAN, (gboolean) false, // blind
- G_TYPE_INVALID,
- G_TYPE_INT, &ret, // result
- G_TYPE_STRING, NULL, // dubsName
- G_TYPE_STRING, &error, // error
- G_TYPE_INT, NULL, // pid
- G_TYPE_INVALID);
-
- if (error && *error) {
- LOG(ERROR) << "Error launching kwalletd: " << error;
- ret = 1; // Make sure we return false after freeing.
- }
-
- g_free(error);
- g_object_unref(klauncher_proxy);
-
- if (CheckError() || ret != 0)
- return false;
- return true;
-}
-
-bool PasswordStoreKWallet::InitWallet() {
- // Make a proxy to KWallet.
- proxy_ = dbus_g_proxy_new_for_name(connection_, kKWalletServiceName,
- kKWalletPath, kKWalletInterface);
-
- // Check KWallet is enabled.
- gboolean is_enabled = false;
- dbus_g_proxy_call(proxy_, "isEnabled", &error_,
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &is_enabled,
- G_TYPE_INVALID);
- if (CheckError() || !is_enabled)
- return false;
-
- // Get the wallet name.
- char* wallet_name = NULL;
- dbus_g_proxy_call(proxy_, "networkWallet", &error_,
- G_TYPE_INVALID,
- G_TYPE_STRING, &wallet_name,
- G_TYPE_INVALID);
- if (CheckError() || !wallet_name)
- return false;
-
- wallet_name_.assign(wallet_name);
- g_free(wallet_name);
-
- return true;
-}
-
-void PasswordStoreKWallet::AddLoginImpl(const PasswordForm& form) {
- AutoLock l(kwallet_lock_);
- int wallet_handle = WalletHandle();
- if (wallet_handle == kInvalidKWalletHandle)
- return;
-
- PasswordFormList forms;
- GetLoginsList(&forms, form.signon_realm, wallet_handle);
-
- forms.push_back(new PasswordForm(form));
- SetLoginsList(forms, form.signon_realm, wallet_handle);
-
- STLDeleteElements(&forms);
-}
-
-void PasswordStoreKWallet::UpdateLoginImpl(const PasswordForm& form) {
- AutoLock l(kwallet_lock_);
- int wallet_handle = WalletHandle();
- if (wallet_handle == kInvalidKWalletHandle)
- return;
-
- PasswordFormList forms;
- GetLoginsList(&forms, form.signon_realm, wallet_handle);
-
- for (size_t i = 0; i < forms.size(); ++i) {
- if (CompareForms(form, *forms[i], true))
- *forms[i] = form;
- }
-
- SetLoginsList(forms, form.signon_realm, wallet_handle);
-
- STLDeleteElements(&forms);
-}
-
-void PasswordStoreKWallet::RemoveLoginImpl(const PasswordForm& form) {
- AutoLock l(kwallet_lock_);
- int wallet_handle = WalletHandle();
- if (wallet_handle == kInvalidKWalletHandle)
- return;
-
- PasswordFormList all_forms;
- GetLoginsList(&all_forms, form.signon_realm, wallet_handle);
-
- PasswordFormList kept_forms;
- kept_forms.reserve(all_forms.size());
- for (size_t i = 0; i < all_forms.size(); ++i) {
- if (CompareForms(form, *all_forms[i], false))
- delete all_forms[i];
- else
- kept_forms.push_back(all_forms[i]);
- }
-
- // Update the entry in the wallet.
- SetLoginsList(kept_forms, form.signon_realm, wallet_handle);
- STLDeleteElements(&kept_forms);
-}
-
-void PasswordStoreKWallet::RemoveLoginsCreatedBetweenImpl(
- const base::Time& delete_begin,
- const base::Time& delete_end) {
- AutoLock l(kwallet_lock_);
- int wallet_handle = WalletHandle();
- if (wallet_handle == kInvalidKWalletHandle)
- return;
-
- // We could probably also use readEntryList here.
- char** realm_list = NULL;
- dbus_g_proxy_call(proxy_, "entryList", &error_,
- G_TYPE_INT, wallet_handle, // handle
- G_TYPE_STRING, kKWalletFolder, // folder
- G_TYPE_STRING, kAppId, // appid
- G_TYPE_INVALID,
- G_TYPE_STRV, &realm_list,
- G_TYPE_INVALID);
- if (CheckError())
- return;
-
- for (char** realm = realm_list; *realm; ++realm) {
- GArray* byte_array = NULL;
- dbus_g_proxy_call(proxy_, "readEntry", &error_,
- G_TYPE_INT, wallet_handle, // handle
- G_TYPE_STRING, kKWalletFolder, // folder
- G_TYPE_STRING, *realm, // key
- G_TYPE_STRING, kAppId, // appid
- G_TYPE_INVALID,
- DBUS_TYPE_G_UCHAR_ARRAY, &byte_array,
- G_TYPE_INVALID);
-
- if (CheckError() || !byte_array || !byte_array->len)
- continue;
-
- string signon_realm(*realm);
- Pickle pickle(byte_array->data, byte_array->len);
- PasswordFormList all_forms;
- DeserializeValue(signon_realm, pickle, &all_forms);
- g_array_free(byte_array, true);
-
- PasswordFormList kept_forms;
- kept_forms.reserve(all_forms.size());
- for (size_t i = 0; i < all_forms.size(); ++i) {
- if (delete_begin <= all_forms[i]->date_created &&
- (delete_end.is_null() || all_forms[i]->date_created < delete_end)) {
- delete all_forms[i];
- } else {
- kept_forms.push_back(all_forms[i]);
- }
- }
-
- SetLoginsList(kept_forms, signon_realm, wallet_handle);
- STLDeleteElements(&kept_forms);
- }
- g_strfreev(realm_list);
-}
-
-void PasswordStoreKWallet::GetLoginsImpl(GetLoginsRequest* request,
- const PasswordForm& form) {
- PasswordFormList forms;
-
- AutoLock l(kwallet_lock_);
- int wallet_handle = WalletHandle();
- if (wallet_handle != kInvalidKWalletHandle)
- GetLoginsList(&forms, form.signon_realm, wallet_handle);
-
- NotifyConsumer(request, forms);
-}
-
-void PasswordStoreKWallet::GetAutofillableLoginsImpl(
- GetLoginsRequest* request) {
- std::vector<PasswordForm*> forms;
- FillAutofillableLogins(&forms);
- NotifyConsumer(request, forms);
-}
-
-void PasswordStoreKWallet::GetBlacklistLoginsImpl(
- GetLoginsRequest* request) {
- std::vector<PasswordForm*> forms;
- FillBlacklistLogins(&forms);
- NotifyConsumer(request, forms);
-}
-
-bool PasswordStoreKWallet::FillAutofillableLogins(
- std::vector<PasswordForm*>* forms) {
- return FillSomeLogins(true, forms);
-}
-
-bool PasswordStoreKWallet::FillBlacklistLogins(
- std::vector<PasswordForm*>* forms) {
- return FillSomeLogins(false, forms);
-}
-
-void PasswordStoreKWallet::GetLoginsList(PasswordFormList* forms,
- const string& signon_realm,
- int wallet_handle) {
- // Is there an entry in the wallet?
- gboolean has_entry = false;
- dbus_g_proxy_call(proxy_, "hasEntry", &error_,
- G_TYPE_INT, wallet_handle, // handle
- G_TYPE_STRING, kKWalletFolder, // folder
- G_TYPE_STRING, signon_realm.c_str(), // key
- G_TYPE_STRING, kAppId, // appid
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &has_entry,
- G_TYPE_INVALID);
-
- if (CheckError() || !has_entry)
- return;
-
- GArray* byte_array = NULL;
- dbus_g_proxy_call(proxy_, "readEntry", &error_,
- G_TYPE_INT, wallet_handle, // handle
- G_TYPE_STRING, kKWalletFolder, // folder
- G_TYPE_STRING, signon_realm.c_str(), // key
- G_TYPE_STRING, kAppId, // appid
- G_TYPE_INVALID,
- DBUS_TYPE_G_UCHAR_ARRAY, &byte_array,
- G_TYPE_INVALID);
-
- if (CheckError() || !byte_array || !byte_array->len)
- return;
-
- Pickle pickle(byte_array->data, byte_array->len);
- DeserializeValue(signon_realm, pickle, forms);
- g_array_free(byte_array, true);
-}
-
-void PasswordStoreKWallet::SetLoginsList(const PasswordFormList& forms,
- const string& signon_realm,
- int wallet_handle) {
- if (forms.empty()) {
- // No items left? Remove the entry from the wallet.
- int ret = 0;
- dbus_g_proxy_call(proxy_, "removeEntry", &error_,
- G_TYPE_INT, wallet_handle, // handle
- G_TYPE_STRING, kKWalletFolder, // folder
- G_TYPE_STRING, signon_realm.c_str(), // key
- G_TYPE_STRING, kAppId, // appid
- G_TYPE_INVALID,
- G_TYPE_INT, &ret,
- G_TYPE_INVALID);
- CheckError();
- if (ret != 0)
- LOG(ERROR) << "Bad return code " << ret << " from kwallet removeEntry";
- return;
- }
-
- Pickle value;
- SerializeValue(forms, &value);
-
- // Convert the pickled bytes to a GByteArray.
- GArray* byte_array = g_array_sized_new(false, false, sizeof(char),
- value.size());
- g_array_append_vals(byte_array, value.data(), value.size());
-
- // Make the call.
- int ret = 0;
- dbus_g_proxy_call(proxy_, "writeEntry", &error_,
- G_TYPE_INT, wallet_handle, // handle
- G_TYPE_STRING, kKWalletFolder, // folder
- G_TYPE_STRING, signon_realm.c_str(), // key
- DBUS_TYPE_G_UCHAR_ARRAY, byte_array, // value
- G_TYPE_STRING, kAppId, // appid
- G_TYPE_INVALID,
- G_TYPE_INT, &ret,
- G_TYPE_INVALID);
- g_array_free(byte_array, true);
-
- CheckError();
- if (ret != 0)
- LOG(ERROR) << "Bad return code " << ret << " from kwallet writeEntry";
-}
-
-bool PasswordStoreKWallet::FillSomeLogins(bool autofillable,
- PasswordFormList* forms) {
- AutoLock l(kwallet_lock_);
- int wallet_handle = WalletHandle();
- if (wallet_handle == kInvalidKWalletHandle)
- return false;
-
- // We could probably also use readEntryList here.
- char** realm_list = NULL;
- dbus_g_proxy_call(proxy_, "entryList", &error_,
- G_TYPE_INT, wallet_handle, // handle
- G_TYPE_STRING, kKWalletFolder, // folder
- G_TYPE_STRING, kAppId, // appid
- G_TYPE_INVALID,
- G_TYPE_STRV, &realm_list,
- G_TYPE_INVALID);
- if (CheckError())
- return false;
-
- PasswordFormList all_forms;
- for (char** realm = realm_list; *realm; ++realm) {
- GArray* byte_array = NULL;
- dbus_g_proxy_call(proxy_, "readEntry", &error_,
- G_TYPE_INT, wallet_handle, // handle
- G_TYPE_STRING, kKWalletFolder, // folder
- G_TYPE_STRING, *realm, // key
- G_TYPE_STRING, kAppId, // appid
- G_TYPE_INVALID,
- DBUS_TYPE_G_UCHAR_ARRAY, &byte_array,
- G_TYPE_INVALID);
-
- if (CheckError() || !byte_array || !byte_array->len)
- continue;
-
- Pickle pickle(byte_array->data, byte_array->len);
- DeserializeValue(*realm, pickle, &all_forms);
- g_array_free(byte_array, true);
- }
- g_strfreev(realm_list);
-
- // We have to read all the entries, and then filter them here.
- forms->reserve(forms->size() + all_forms.size());
- for (size_t i = 0; i < all_forms.size(); ++i) {
- if (all_forms[i]->blacklisted_by_user == !autofillable)
- forms->push_back(all_forms[i]);
- else
- delete all_forms[i];
- }
-
- return true;
-}
-
-bool PasswordStoreKWallet::CompareForms(const PasswordForm& a,
- const PasswordForm& b,
- bool update_check) {
- // An update check doesn't care about the submit element.
- if (!update_check && a.submit_element != b.submit_element)
- return false;
- return a.origin == b.origin &&
- a.password_element == b.password_element &&
- a.signon_realm == b.signon_realm &&
- a.username_element == b.username_element &&
- a.username_value == b.username_value;
-}
-
-void PasswordStoreKWallet::SerializeValue(const PasswordFormList& forms,
- Pickle* pickle) {
- pickle->WriteInt(kPickleVersion);
- pickle->WriteSize(forms.size());
- for (PasswordFormList::const_iterator it = forms.begin() ;
- it != forms.end() ; ++it) {
- const PasswordForm* form = *it;
- pickle->WriteInt(form->scheme);
- pickle->WriteString(form->origin.spec());
- pickle->WriteString(form->action.spec());
- pickle->WriteString16(form->username_element);
- pickle->WriteString16(form->username_value);
- pickle->WriteString16(form->password_element);
- pickle->WriteString16(form->password_value);
- pickle->WriteString16(form->submit_element);
- pickle->WriteBool(form->ssl_valid);
- pickle->WriteBool(form->preferred);
- pickle->WriteBool(form->blacklisted_by_user);
- pickle->WriteInt64(form->date_created.ToTimeT());
- }
-}
-
-void PasswordStoreKWallet::DeserializeValue(const string& signon_realm,
- const Pickle& pickle,
- PasswordFormList* forms) {
- void* iter = NULL;
-
- int version = -1;
- pickle.ReadInt(&iter, &version);
- if (version != kPickleVersion) {
- // This is the only version so far, so anything else is an error.
- return;
- }
-
- size_t count = 0;
- pickle.ReadSize(&iter, &count);
-
- forms->reserve(forms->size() + count);
- for (size_t i = 0; i < count; ++i) {
- PasswordForm* form = new PasswordForm();
- form->signon_realm.assign(signon_realm);
-
- int scheme = 0;
- pickle.ReadInt(&iter, &scheme);
- form->scheme = static_cast<PasswordForm::Scheme>(scheme);
- ReadGURL(pickle, &iter, &form->origin);
- ReadGURL(pickle, &iter, &form->action);
- pickle.ReadString16(&iter, &form->username_element);
- pickle.ReadString16(&iter, &form->username_value);
- pickle.ReadString16(&iter, &form->password_element);
- pickle.ReadString16(&iter, &form->password_value);
- pickle.ReadString16(&iter, &form->submit_element);
- pickle.ReadBool(&iter, &form->ssl_valid);
- pickle.ReadBool(&iter, &form->preferred);
- pickle.ReadBool(&iter, &form->blacklisted_by_user);
- int64 date_created = 0;
- pickle.ReadInt64(&iter, &date_created);
- form->date_created = base::Time::FromTimeT(date_created);
- forms->push_back(form);
- }
-}
-
-void PasswordStoreKWallet::ReadGURL(const Pickle& pickle, void** iter,
- GURL* url) {
- string url_string;
- pickle.ReadString(iter, &url_string);
- *url = GURL(url_string);
-}
-
-bool PasswordStoreKWallet::CheckError() {
- if (error_) {
- LOG(ERROR) << "Failed to complete KWallet call: " << error_->message;
- g_error_free(error_);
- error_ = NULL;
- return true;
- }
- return false;
-}
-
-int PasswordStoreKWallet::WalletHandle() {
- // Open the wallet.
- int handle = kInvalidKWalletHandle;
- dbus_g_proxy_call(proxy_, "open", &error_,
- G_TYPE_STRING, wallet_name_.c_str(), // wallet
- G_TYPE_INT64, 0LL, // wid
- G_TYPE_STRING, kAppId, // appid
- G_TYPE_INVALID,
- G_TYPE_INT, &handle,
- G_TYPE_INVALID);
- if (CheckError() || handle == kInvalidKWalletHandle)
- return kInvalidKWalletHandle;
-
- // Check if our folder exists.
- gboolean has_folder = false;
- dbus_g_proxy_call(proxy_, "hasFolder", &error_,
- G_TYPE_INT, handle, // handle
- G_TYPE_STRING, kKWalletFolder, // folder
- G_TYPE_STRING, kAppId, // appid
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &has_folder,
- G_TYPE_INVALID);
- if (CheckError())
- return kInvalidKWalletHandle;
-
- // Create it if it didn't.
- if (!has_folder) {
- gboolean success = false;
- dbus_g_proxy_call(proxy_, "createFolder", &error_,
- G_TYPE_INT, handle, // handle
- G_TYPE_STRING, kKWalletFolder, // folder
- G_TYPE_STRING, kAppId, // appid
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &success,
- G_TYPE_INVALID);
- if (CheckError() || !success)
- return kInvalidKWalletHandle;
- }
-
- return handle;
-}
« no previous file with comments | « chrome/browser/password_manager/password_store_kwallet.h ('k') | chrome/browser/password_manager/password_store_x.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698