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

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

Issue 2407001: Linux: bring GNOME Keyring and KWallet integration back into a compilable state. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 7 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
« no previous file with comments | « chrome/browser/password_manager/password_store_kwallet.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/password_manager/password_store_kwallet.cc
===================================================================
--- chrome/browser/password_manager/password_store_kwallet.cc (revision 48891)
+++ chrome/browser/password_manager/password_store_kwallet.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -9,12 +9,16 @@
#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";
@@ -25,7 +29,9 @@
const char* PasswordStoreKWallet::kKLauncherPath = "/KLauncher";
const char* PasswordStoreKWallet::kKLauncherInterface = "org.kde.KLauncher";
-PasswordStoreKWallet::PasswordStoreKWallet()
+PasswordStoreKWallet::PasswordStoreKWallet(LoginDatabase* login_db,
+ Profile* profile,
+ WebDataService* web_data_service)
: error_(NULL),
connection_(NULL),
proxy_(NULL) {
@@ -38,13 +44,6 @@
}
bool PasswordStoreKWallet::Init() {
- thread_.reset(new base::Thread("Chrome_KeyringThread"));
-
- if (!thread_->Start()) {
- thread_.reset(NULL);
- return false;
- }
-
// Initialize threading in dbus-glib - it should be fine for
// dbus_g_thread_init to be called multiple times.
if (!g_thread_supported())
@@ -56,8 +55,11 @@
if (CheckError())
return false;
- if (!StartKWalletd()) return false;
- if (!InitWallet()) return false;
+ if (!InitWallet()) {
+ // kwalletd may not be running. Try to start it and try again.
+ if (!StartKWalletd() || !InitWallet())
+ return false;
+ }
return true;
}
@@ -134,11 +136,12 @@
return;
PasswordFormList forms;
- GetLoginsList(&forms, form, wallet_handle);
+ GetLoginsList(&forms, form.signon_realm, wallet_handle);
- forms.push_back(const_cast<PasswordForm*>(&form));
+ forms.push_back(new PasswordForm(form));
+ SetLoginsList(forms, form.signon_realm, wallet_handle);
- SetLoginsList(forms, form, wallet_handle);
+ STLDeleteElements(&forms);
}
void PasswordStoreKWallet::UpdateLoginImpl(const PasswordForm& form) {
@@ -148,16 +151,16 @@
return;
PasswordFormList forms;
- GetLoginsList(&forms, form, wallet_handle);
+ GetLoginsList(&forms, form.signon_realm, wallet_handle);
- for (uint i = 0; i < forms.size(); ++i) {
- if (CompareForms(form, *forms[i])) {
- forms.erase(forms.begin() + i);
- forms.insert(forms.begin() + i, const_cast<PasswordForm*>(&form));
- }
+ for (size_t i = 0; i < forms.size(); ++i) {
+ if (CompareForms(form, *forms[i], true))
+ *forms[i] = form;
}
- SetLoginsList(forms, form, wallet_handle);
+ SetLoginsList(forms, form.signon_realm, wallet_handle);
+
+ STLDeleteElements(&forms);
}
void PasswordStoreKWallet::RemoveLoginImpl(const PasswordForm& form) {
@@ -166,57 +169,126 @@
if (wallet_handle == kInvalidKWalletHandle)
return;
- PasswordFormList forms;
- GetLoginsList(&forms, form, wallet_handle);
+ PasswordFormList all_forms;
+ GetLoginsList(&all_forms, form.signon_realm, wallet_handle);
- for (uint i = 0; i < forms.size(); ++i) {
- if (CompareForms(form, *forms[i])) {
- forms.erase(forms.begin() + i);
- --i;
- }
+ 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]);
}
- 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, form.signon_realm.c_str(), // key
- G_TYPE_STRING, kAppId, // appid
+ // 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,
- G_TYPE_INT, &ret,
+ DBUS_TYPE_G_UCHAR_ARRAY, &byte_array,
G_TYPE_INVALID);
- CheckError();
- if (ret)
- LOG(ERROR) << "Bad return code " << ret << " from kwallet removeEntry";
- } else {
- // Otherwise update the entry in the wallet.
- SetLoginsList(forms, form, wallet_handle);
+
+ 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) {
+void PasswordStoreKWallet::GetLoginsImpl(GetLoginsRequest* request,
+ const PasswordForm& form) {
PasswordFormList forms;
AutoLock l(kwallet_lock_);
int wallet_handle = WalletHandle();
if (wallet_handle != kInvalidKWalletHandle)
- GetLoginsList(&forms, request->form, wallet_handle);
+ 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 PasswordForm& key,
+ 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, key.signon_realm.c_str(), // key
- G_TYPE_STRING, kAppId, // appid
+ 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);
@@ -226,10 +298,10 @@
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, key.signon_realm.c_str(), // key
- G_TYPE_STRING, kAppId, // appid
+ 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);
@@ -238,12 +310,30 @@
return;
Pickle pickle(byte_array->data, byte_array->len);
- DeserializeValue(key, pickle, forms);
+ DeserializeValue(signon_realm, pickle, forms);
+ g_array_free(byte_array, true);
}
void PasswordStoreKWallet::SetLoginsList(const PasswordFormList& forms,
- const PasswordForm& key,
+ 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);
@@ -255,74 +345,144 @@
// 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, key.signon_realm.c_str(), // key
- DBUS_TYPE_G_UCHAR_ARRAY, byte_array, // value
- G_TYPE_STRING, kAppId, // appid
+ 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)
+ 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) {
+ 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.submit_element == b.submit_element &&
a.username_element == b.username_element &&
a.username_value == b.username_value;
}
void PasswordStoreKWallet::SerializeValue(const PasswordFormList& forms,
Pickle* pickle) {
- pickle->WriteInt(forms.size());
+ 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->WriteWString(form->username_element);
- pickle->WriteWString(form->username_value);
- pickle->WriteWString(form->password_element);
- pickle->WriteWString(form->password_value);
- pickle->WriteWString(form->submit_element);
+ 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 PasswordForm& key,
+void PasswordStoreKWallet::DeserializeValue(const string& signon_realm,
const Pickle& pickle,
PasswordFormList* forms) {
void* iter = NULL;
- int count = 0;
- pickle.ReadInt(&iter, &count);
+ int version = -1;
+ pickle.ReadInt(&iter, &version);
+ if (version != kPickleVersion) {
+ // This is the only version so far, so anything else is an error.
+ return;
+ }
- for (int i = 0; i < count; ++i) {
+ 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(key.signon_realm);
+ form->signon_realm.assign(signon_realm);
- pickle.ReadInt(&iter, reinterpret_cast<int*>(&form->scheme));
+ 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.ReadWString(&iter, &form->username_element);
- pickle.ReadWString(&iter, &form->username_value);
- pickle.ReadWString(&iter, &form->password_element);
- pickle.ReadWString(&iter, &form->password_value);
- pickle.ReadWString(&iter, &form->submit_element);
+ 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);
}
}
« no previous file with comments | « chrome/browser/password_manager/password_store_kwallet.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698