| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/password_manager/native_backend_gnome_x.h" | 5 #include "chrome/browser/password_manager/native_backend_gnome_x.h" |
| 6 | 6 |
| 7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
| 8 #include <gnome-keyring.h> | 8 #include <gnome-keyring.h> |
| 9 | 9 |
| 10 #include <map> | 10 #include <map> |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 int64 date_synced = 0; | 151 int64 date_synced = 0; |
| 152 base::StringToInt64(string_attr_map["date_synced"], &date_synced); | 152 base::StringToInt64(string_attr_map["date_synced"], &date_synced); |
| 153 form->date_synced = base::Time::FromInternalValue(date_synced); | 153 form->date_synced = base::Time::FromInternalValue(date_synced); |
| 154 form->display_name = UTF8ToUTF16(string_attr_map["display_name"]); | 154 form->display_name = UTF8ToUTF16(string_attr_map["display_name"]); |
| 155 form->avatar_url = GURL(string_attr_map["avatar_url"]); | 155 form->avatar_url = GURL(string_attr_map["avatar_url"]); |
| 156 form->federation_url = GURL(string_attr_map["federation_url"]); | 156 form->federation_url = GURL(string_attr_map["federation_url"]); |
| 157 form->skip_zero_click = uint_attr_map["skip_zero_click"]; | 157 form->skip_zero_click = uint_attr_map["skip_zero_click"]; |
| 158 form->generation_upload_status = | 158 form->generation_upload_status = |
| 159 static_cast<PasswordForm::GenerationUploadStatus>( | 159 static_cast<PasswordForm::GenerationUploadStatus>( |
| 160 uint_attr_map["generation_upload_status"]); | 160 uint_attr_map["generation_upload_status"]); |
| 161 | 161 DeserializeFormDataFromBase64String(string_attr_map["form_data"], |
| 162 &form->form_data); |
| 162 return form.Pass(); | 163 return form.Pass(); |
| 163 } | 164 } |
| 164 | 165 |
| 165 // Parse all the results from the given GList into a | 166 // Parse all the results from the given GList into a |
| 166 // ScopedVector<autofill::PasswordForm>, and free the GList. PasswordForms are | 167 // ScopedVector<autofill::PasswordForm>, and free the GList. PasswordForms are |
| 167 // allocated on the heap, and should be deleted by the consumer. If not NULL, | 168 // allocated on the heap, and should be deleted by the consumer. If not NULL, |
| 168 // |lookup_form| is used to filter out results -- only credentials with signon | 169 // |lookup_form| is used to filter out results -- only credentials with signon |
| 169 // realms passing the PSL matching against |lookup_form->signon_realm| will be | 170 // realms passing the PSL matching against |lookup_form->signon_realm| will be |
| 170 // kept. PSL matched results get their signon_realm, origin, and action | 171 // kept. PSL matched results get their signon_realm, origin, and action |
| 171 // rewritten to those of |lookup_form_|, with the original signon_realm saved | 172 // rewritten to those of |lookup_form_|, with the original signon_realm saved |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 UMA_HISTOGRAM_ENUMERATION( | 214 UMA_HISTOGRAM_ENUMERATION( |
| 214 "PasswordManager.PslDomainMatchTriggering", | 215 "PasswordManager.PslDomainMatchTriggering", |
| 215 password_manager::ShouldPSLDomainMatchingApply(registered_domain) | 216 password_manager::ShouldPSLDomainMatchingApply(registered_domain) |
| 216 ? psl_domain_match_metric | 217 ? psl_domain_match_metric |
| 217 : password_manager::PSL_DOMAIN_MATCH_NOT_USED, | 218 : password_manager::PSL_DOMAIN_MATCH_NOT_USED, |
| 218 password_manager::PSL_DOMAIN_MATCH_COUNT); | 219 password_manager::PSL_DOMAIN_MATCH_COUNT); |
| 219 } | 220 } |
| 220 } | 221 } |
| 221 | 222 |
| 222 // Schema is analagous to the fields in PasswordForm. | 223 // Schema is analagous to the fields in PasswordForm. |
| 223 // TODO(gcasto): Adding 'form_data' would be nice, but we would need to | |
| 224 // serialize in a way that is guaranteed to not have any embedded NULLs. Pickle | |
| 225 // doesn't make this guarantee, so we just don't serialize this field. Since | |
| 226 // it's only used to crowd source data collection it doesn't matter that much | |
| 227 // if it's not available on this platform. | |
| 228 const GnomeKeyringPasswordSchema kGnomeSchema = { | 224 const GnomeKeyringPasswordSchema kGnomeSchema = { |
| 229 GNOME_KEYRING_ITEM_GENERIC_SECRET, { | 225 GNOME_KEYRING_ITEM_GENERIC_SECRET, { |
| 230 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 226 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 231 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 227 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 232 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 228 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 233 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 229 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 234 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 230 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 235 { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 231 { "submit_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 236 { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 232 { "signon_realm", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 237 { "ssl_valid", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 233 { "ssl_valid", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 238 { "preferred", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 234 { "preferred", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 239 { "date_created", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 235 { "date_created", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 240 { "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 236 { "blacklisted_by_user", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 241 { "scheme", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 237 { "scheme", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 242 { "type", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 238 { "type", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 243 { "times_used", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 239 { "times_used", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 244 { "date_synced", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 240 { "date_synced", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 245 { "display_name", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 241 { "display_name", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 246 { "avatar_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 242 { "avatar_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 247 { "federation_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 243 { "federation_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 248 { "skip_zero_click", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 244 { "skip_zero_click", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 249 { "generation_upload_status", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, | 245 { "generation_upload_status", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, |
| 246 { "form_data", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 250 // This field is always "chrome" so that we can search for it. | 247 // This field is always "chrome" so that we can search for it. |
| 251 { "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, | 248 { "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, |
| 252 { nullptr } | 249 { nullptr } |
| 253 } | 250 } |
| 254 }; | 251 }; |
| 255 | 252 |
| 256 // Sadly, PasswordStore goes to great lengths to switch from the originally | 253 // Sadly, PasswordStore goes to great lengths to switch from the originally |
| 257 // calling thread to the DB thread, and to provide an asynchronous API to | 254 // calling thread to the DB thread, and to provide an asynchronous API to |
| 258 // callers while using a synchronous (virtual) API provided by subclasses like | 255 // callers while using a synchronous (virtual) API provided by subclasses like |
| 259 // PasswordStoreX -- but GNOME Keyring really wants to be on the GLib main | 256 // PasswordStoreX -- but GNOME Keyring really wants to be on the GLib main |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 }; | 329 }; |
| 333 | 330 |
| 334 void GKRMethod::AddLogin(const PasswordForm& form, const char* app_string) { | 331 void GKRMethod::AddLogin(const PasswordForm& form, const char* app_string) { |
| 335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 332 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 336 int64 date_created = form.date_created.ToInternalValue(); | 333 int64 date_created = form.date_created.ToInternalValue(); |
| 337 // If we are asked to save a password with 0 date, use the current time. | 334 // If we are asked to save a password with 0 date, use the current time. |
| 338 // We don't want to actually save passwords as though on January 1, 1601. | 335 // We don't want to actually save passwords as though on January 1, 1601. |
| 339 if (!date_created) | 336 if (!date_created) |
| 340 date_created = base::Time::Now().ToInternalValue(); | 337 date_created = base::Time::Now().ToInternalValue(); |
| 341 int64 date_synced = form.date_synced.ToInternalValue(); | 338 int64 date_synced = form.date_synced.ToInternalValue(); |
| 339 std::string form_data; |
| 340 SerializeFormDataToBase64String(form.form_data, &form_data); |
| 342 gnome_keyring_store_password( | 341 gnome_keyring_store_password( |
| 343 &kGnomeSchema, | 342 &kGnomeSchema, |
| 344 nullptr, // Default keyring. | 343 nullptr, // Default keyring. |
| 345 form.origin.spec().c_str(), // Display name. | 344 form.origin.spec().c_str(), // Display name. |
| 346 UTF16ToUTF8(form.password_value).c_str(), | 345 UTF16ToUTF8(form.password_value).c_str(), |
| 347 OnOperationDone, | 346 OnOperationDone, |
| 348 this, // data | 347 this, // data |
| 349 nullptr, // destroy_data | 348 nullptr, // destroy_data |
| 350 "origin_url", form.origin.spec().c_str(), | 349 "origin_url", form.origin.spec().c_str(), |
| 351 "action_url", form.action.spec().c_str(), | 350 "action_url", form.action.spec().c_str(), |
| 352 "username_element", UTF16ToUTF8(form.username_element).c_str(), | 351 "username_element", UTF16ToUTF8(form.username_element).c_str(), |
| 353 "username_value", UTF16ToUTF8(form.username_value).c_str(), | 352 "username_value", UTF16ToUTF8(form.username_value).c_str(), |
| 354 "password_element", UTF16ToUTF8(form.password_element).c_str(), | 353 "password_element", UTF16ToUTF8(form.password_element).c_str(), |
| 355 "submit_element", UTF16ToUTF8(form.submit_element).c_str(), | 354 "submit_element", UTF16ToUTF8(form.submit_element).c_str(), |
| 356 "signon_realm", form.signon_realm.c_str(), | 355 "signon_realm", form.signon_realm.c_str(), |
| 357 "ssl_valid", form.ssl_valid, | 356 "ssl_valid", form.ssl_valid, |
| 358 "preferred", form.preferred, | 357 "preferred", form.preferred, |
| 359 "date_created", base::Int64ToString(date_created).c_str(), | 358 "date_created", base::Int64ToString(date_created).c_str(), |
| 360 "blacklisted_by_user", form.blacklisted_by_user, | 359 "blacklisted_by_user", form.blacklisted_by_user, |
| 361 "type", form.type, | 360 "type", form.type, |
| 362 "times_used", form.times_used, | 361 "times_used", form.times_used, |
| 363 "scheme", form.scheme, | 362 "scheme", form.scheme, |
| 364 "date_synced", base::Int64ToString(date_synced).c_str(), | 363 "date_synced", base::Int64ToString(date_synced).c_str(), |
| 365 "display_name", UTF16ToUTF8(form.display_name).c_str(), | 364 "display_name", UTF16ToUTF8(form.display_name).c_str(), |
| 366 "avatar_url", form.avatar_url.spec().c_str(), | 365 "avatar_url", form.avatar_url.spec().c_str(), |
| 367 "federation_url", form.federation_url.spec().c_str(), | 366 "federation_url", form.federation_url.spec().c_str(), |
| 368 "skip_zero_click", form.skip_zero_click, | 367 "skip_zero_click", form.skip_zero_click, |
| 369 "generation_upload_status", form.generation_upload_status, | 368 "generation_upload_status", form.generation_upload_status, |
| 369 "form_data", form_data.c_str(), |
| 370 "application", app_string, | 370 "application", app_string, |
| 371 nullptr); | 371 nullptr); |
| 372 } | 372 } |
| 373 | 373 |
| 374 void GKRMethod::AddLoginSearch(const PasswordForm& form, | 374 void GKRMethod::AddLoginSearch(const PasswordForm& form, |
| 375 const char* app_string) { | 375 const char* app_string) { |
| 376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 377 lookup_form_.reset(nullptr); | 377 lookup_form_.reset(nullptr); |
| 378 // Search GNOME Keyring for matching passwords to update. | 378 // Search GNOME Keyring for matching passwords to update. |
| 379 ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); | 379 ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 } | 806 } |
| 807 return ok; | 807 return ok; |
| 808 } | 808 } |
| 809 | 809 |
| 810 std::string NativeBackendGnome::GetProfileSpecificAppString() const { | 810 std::string NativeBackendGnome::GetProfileSpecificAppString() const { |
| 811 // Originally, the application string was always just "chrome" and used only | 811 // Originally, the application string was always just "chrome" and used only |
| 812 // so that we had *something* to search for since GNOME Keyring won't search | 812 // so that we had *something* to search for since GNOME Keyring won't search |
| 813 // for nothing. Now we use it to distinguish passwords for different profiles. | 813 // for nothing. Now we use it to distinguish passwords for different profiles. |
| 814 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_); | 814 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_); |
| 815 } | 815 } |
| OLD | NEW |