diff options
author | mdm@chromium.org <mdm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-10 07:11:53 +0000 |
---|---|---|
committer | mdm@chromium.org <mdm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-10 07:11:53 +0000 |
commit | e8dd1b272971bdf556b84a599fa4edaa33367191 (patch) | |
tree | 6aca6fad560b7fa82836f55758c76f1005309bd5 /chrome/browser/password_manager | |
parent | 425d3baa8fa8cabe8da825a3b37877daff6ecd3e (diff) | |
download | chromium_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.cc | 36 | ||||
-rw-r--r-- | chrome/browser/password_manager/native_backend_kwallet_x.h | 4 |
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, |