summaryrefslogtreecommitdiffstats
path: root/chrome/browser/password_manager
diff options
context:
space:
mode:
authormdm@chromium.org <mdm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-10 07:11:53 +0000
committermdm@chromium.org <mdm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-10 07:11:53 +0000
commite8dd1b272971bdf556b84a599fa4edaa33367191 (patch)
tree6aca6fad560b7fa82836f55758c76f1005309bd5 /chrome/browser/password_manager
parent425d3baa8fa8cabe8da825a3b37877daff6ecd3e (diff)
downloadchromium_src-e8dd1b272971bdf556b84a599fa4edaa33367191.zip
chromium_src-e8dd1b272971bdf556b84a599fa4edaa33367191.tar.gz
chromium_src-e8dd1b272971bdf556b84a599fa4edaa33367191.tar.bz2
Linux: fix several bugs in KWallet password store support.
* Don't disable kwallet support if the first site visited with a login form has no saved passwords. * Don't crash when there are certain types of invalid entries stored in the wallet that fail to deserialize. TEST=start with --password-store=detect in KDE and check that the above happens BUG=49968 Review URL: http://codereview.chromium.org/3048052 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55535 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/password_manager')
-rw-r--r--chrome/browser/password_manager/native_backend_kwallet_x.cc36
-rw-r--r--chrome/browser/password_manager/native_backend_kwallet_x.h4
2 files changed, 36 insertions, 4 deletions
diff --git a/chrome/browser/password_manager/native_backend_kwallet_x.cc b/chrome/browser/password_manager/native_backend_kwallet_x.cc
index 0cc4bf2..5f07bb8 100644
--- a/chrome/browser/password_manager/native_backend_kwallet_x.cc
+++ b/chrome/browser/password_manager/native_backend_kwallet_x.cc
@@ -208,8 +208,10 @@ bool NativeBackendKWallet::RemoveLoginsCreatedBetween(
DBUS_TYPE_G_UCHAR_ARRAY, &byte_array,
G_TYPE_INVALID);
- if (CheckError() || !byte_array || !byte_array->len)
+ if (CheckError() || !byte_array ||
+ !CheckSerializedValue(byte_array, *realm)) {
continue;
+ }
string signon_realm(*realm);
Pickle pickle(byte_array->data, byte_array->len);
@@ -281,8 +283,12 @@ bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms,
G_TYPE_BOOLEAN, &has_entry,
G_TYPE_INVALID);
- if (CheckError() || !has_entry)
+ if (CheckError())
return false;
+ if (!has_entry) {
+ // This is not an error. There just isn't a matching entry.
+ return true;
+ }
GArray* byte_array = NULL;
dbus_g_proxy_call(proxy_, "readEntry", &error_,
@@ -294,8 +300,16 @@ bool NativeBackendKWallet::GetLoginsList(PasswordFormList* forms,
DBUS_TYPE_G_UCHAR_ARRAY, &byte_array,
G_TYPE_INVALID);
- if (CheckError() || !byte_array || !byte_array->len)
+ if (CheckError() || !byte_array)
return false;
+ if (!CheckSerializedValue(byte_array, signon_realm.c_str())) {
+ // This is weird, but we choose not to call it an error. There's an invalid
+ // entry somehow, but by pretending it just doesn't exist, we make it easier
+ // to repair without having to delete it using kwalletmanager (that is, by
+ // just saving a new password within this realm to overwrite it).
+ g_array_free(byte_array, true);
+ return true;
+ }
Pickle pickle(byte_array->data, byte_array->len);
DeserializeValue(signon_realm, pickle, forms);
@@ -370,8 +384,10 @@ bool NativeBackendKWallet::GetAllLogins(PasswordFormList* forms,
DBUS_TYPE_G_UCHAR_ARRAY, &byte_array,
G_TYPE_INVALID);
- if (CheckError() || !byte_array || !byte_array->len)
+ if (CheckError() || !byte_array ||
+ !CheckSerializedValue(byte_array, *realm)) {
continue;
+ }
Pickle pickle(byte_array->data, byte_array->len);
DeserializeValue(*realm, pickle, forms);
@@ -463,6 +479,18 @@ void NativeBackendKWallet::SerializeValue(const PasswordFormList& forms,
}
}
+bool NativeBackendKWallet::CheckSerializedValue(const GArray* byte_array,
+ const char* realm) {
+ const Pickle::Header* header =
+ reinterpret_cast<const Pickle::Header*>(byte_array->data);
+ if (byte_array->len < sizeof(*header) ||
+ header->payload_size > byte_array->len - sizeof(*header)) {
+ LOG(WARNING) << "Invalid KWallet entry detected! (realm: " << realm << ")";
+ return false;
+ }
+ return true;
+}
+
void NativeBackendKWallet::DeserializeValue(const string& signon_realm,
const Pickle& pickle,
PasswordFormList* forms) {
diff --git a/chrome/browser/password_manager/native_backend_kwallet_x.h b/chrome/browser/password_manager/native_backend_kwallet_x.h
index 6c427db..16e3c46 100644
--- a/chrome/browser/password_manager/native_backend_kwallet_x.h
+++ b/chrome/browser/password_manager/native_backend_kwallet_x.h
@@ -92,6 +92,10 @@ class NativeBackendKWallet : public PasswordStoreX::NativeBackend {
// Serializes a list of PasswordForms to be stored in the wallet.
static void SerializeValue(const PasswordFormList& forms, Pickle* pickle);
+ // Checks a serialized list of PasswordForms for sanity. Returns true if OK.
+ // Note that |realm| is only used for generating a useful warning message.
+ static bool CheckSerializedValue(const GArray* byte_array, const char* realm);
+
// Deserializes a list of PasswordForms from the wallet.
static void DeserializeValue(const std::string& signon_realm,
const Pickle& pickle,