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

Side by Side Diff: chrome/browser/password_manager/native_backend_gnome_x.cc

Issue 906973007: PasswordStore: Clean up expectations about rewriting vectors of forms (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 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 unified diff | Download patch
OLDNEW
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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
162 return form.Pass(); 162 return form.Pass();
163 } 163 }
164 164
165 // Parse all the results from the given GList into a 165 // Returns all the results from |found|. If not NULL, |lookup_form| is used to
engedy 2015/02/25 15:17:48 Phrasing suggestion: Converts native credentials i
vabr (Chromium) 2015/03/09 10:56:18 Done.
engedy 2015/03/09 13:33:17 I am not sure, but the original comment mentioned
166 // ScopedVector<autofill::PasswordForm>, and free the GList. PasswordForms are 166 // filter out results -- only credentials with signon realms passing the PSL
167 // allocated on the heap, and should be deleted by the consumer. If not NULL, 167 // matching against |lookup_form->signon_realm| will be kept. PSL matched
168 // |lookup_form| is used to filter out results -- only credentials with signon 168 // results get their signon_realm, origin, and action rewritten to those of
169 // realms passing the PSL matching against |lookup_form->signon_realm| will be 169 // |lookup_form_|, with the original signon_realm saved into the result's
170 // kept. PSL matched results get their signon_realm, origin, and action 170 // original_signon_realm data member.
171 // rewritten to those of |lookup_form_|, with the original signon_realm saved 171 ScopedVector<autofill::PasswordForm> ConvertFormList(
172 // into the result's original_signon_realm data member. 172 GList* found,
173 void ConvertFormList(GList* found, 173 const PasswordForm* lookup_form) {
174 const PasswordForm* lookup_form, 174 ScopedVector<autofill::PasswordForm> forms;
175 ScopedVector<autofill::PasswordForm>* forms) {
176 password_manager::PSLDomainMatchMetric psl_domain_match_metric = 175 password_manager::PSLDomainMatchMetric psl_domain_match_metric =
177 password_manager::PSL_DOMAIN_MATCH_NONE; 176 password_manager::PSL_DOMAIN_MATCH_NONE;
178 for (GList* element = g_list_first(found); element; 177 for (GList* element = g_list_first(found); element;
179 element = g_list_next(element)) { 178 element = g_list_next(element)) {
180 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); 179 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data);
181 GnomeKeyringAttributeList* attrs = data->attributes; 180 GnomeKeyringAttributeList* attrs = data->attributes;
182 181
183 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs)); 182 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs));
184 if (form) { 183 if (form) {
185 if (lookup_form && form->signon_realm != lookup_form->signon_realm) { 184 if (lookup_form && form->signon_realm != lookup_form->signon_realm) {
186 // This is not an exact match, we try PSL matching. 185 // This is not an exact match, we try PSL matching.
187 if (lookup_form->scheme != PasswordForm::SCHEME_HTML || 186 if (lookup_form->scheme != PasswordForm::SCHEME_HTML ||
188 form->scheme != PasswordForm::SCHEME_HTML || 187 form->scheme != PasswordForm::SCHEME_HTML ||
189 !(password_manager::IsPublicSuffixDomainMatch( 188 !(password_manager::IsPublicSuffixDomainMatch(
190 lookup_form->signon_realm, form->signon_realm))) { 189 lookup_form->signon_realm, form->signon_realm))) {
191 continue; 190 continue;
192 } 191 }
193 psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND; 192 psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND;
194 form->original_signon_realm = form->signon_realm; 193 form->original_signon_realm = form->signon_realm;
195 form->signon_realm = lookup_form->signon_realm; 194 form->signon_realm = lookup_form->signon_realm;
196 form->origin = lookup_form->origin; 195 form->origin = lookup_form->origin;
197 form->action = lookup_form->action; 196 form->action = lookup_form->action;
198 } 197 }
199 if (data->secret) { 198 if (data->secret) {
200 form->password_value = UTF8ToUTF16(data->secret); 199 form->password_value = UTF8ToUTF16(data->secret);
201 } else { 200 } else {
202 LOG(WARNING) << "Unable to access password from list element!"; 201 LOG(WARNING) << "Unable to access password from list element!";
203 } 202 }
204 forms->push_back(form.release()); 203 forms.push_back(form.release());
205 } else { 204 } else {
206 LOG(WARNING) << "Could not initialize PasswordForm from attributes!"; 205 LOG(WARNING) << "Could not initialize PasswordForm from attributes!";
207 } 206 }
208 } 207 }
209 if (lookup_form) { 208 if (lookup_form) {
210 const GURL signon_realm(lookup_form->signon_realm); 209 const GURL signon_realm(lookup_form->signon_realm);
211 std::string registered_domain = 210 std::string registered_domain =
212 password_manager::GetRegistryControlledDomain(signon_realm); 211 password_manager::GetRegistryControlledDomain(signon_realm);
213 UMA_HISTOGRAM_ENUMERATION( 212 UMA_HISTOGRAM_ENUMERATION(
214 "PasswordManager.PslDomainMatchTriggering", 213 "PasswordManager.PslDomainMatchTriggering",
215 password_manager::ShouldPSLDomainMatchingApply(registered_domain) 214 password_manager::ShouldPSLDomainMatchingApply(registered_domain)
216 ? psl_domain_match_metric 215 ? psl_domain_match_metric
217 : password_manager::PSL_DOMAIN_MATCH_NOT_USED, 216 : password_manager::PSL_DOMAIN_MATCH_NOT_USED,
218 password_manager::PSL_DOMAIN_MATCH_COUNT); 217 password_manager::PSL_DOMAIN_MATCH_COUNT);
219 } 218 }
219 return forms.Pass();
220 } 220 }
221 221
222 // Schema is analagous to the fields in PasswordForm. 222 // Schema is analagous to the fields in PasswordForm.
223 // TODO(gcasto): Adding 'form_data' would be nice, but we would need to 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 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 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 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. 227 // if it's not available on this platform.
228 const GnomeKeyringPasswordSchema kGnomeSchema = { 228 const GnomeKeyringPasswordSchema kGnomeSchema = {
229 GNOME_KEYRING_ITEM_GENERIC_SECRET, { 229 GNOME_KEYRING_ITEM_GENERIC_SECRET, {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 void UpdateLoginSearch(const PasswordForm& form, const char* app_string); 280 void UpdateLoginSearch(const PasswordForm& form, const char* app_string);
281 void RemoveLogin(const PasswordForm& form, const char* app_string); 281 void RemoveLogin(const PasswordForm& form, const char* app_string);
282 void GetLogins(const PasswordForm& form, const char* app_string); 282 void GetLogins(const PasswordForm& form, const char* app_string);
283 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string); 283 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string);
284 void GetAllLogins(const char* app_string); 284 void GetAllLogins(const char* app_string);
285 285
286 // Use after AddLogin, RemoveLogin. 286 // Use after AddLogin, RemoveLogin.
287 GnomeKeyringResult WaitResult(); 287 GnomeKeyringResult WaitResult();
288 288
289 // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList, 289 // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList,
290 // GetAllLogins. 290 // GetAllLogins. Replaces the content of |forms| with found logins.
291 GnomeKeyringResult WaitResult(ScopedVector<autofill::PasswordForm>* forms); 291 GnomeKeyringResult WaitResult(ScopedVector<autofill::PasswordForm>* forms);
292 292
293 private: 293 private:
294 struct GnomeKeyringAttributeListFreeDeleter { 294 struct GnomeKeyringAttributeListFreeDeleter {
295 inline void operator()(void* list) const { 295 inline void operator()(void* list) const {
296 gnome_keyring_attribute_list_free( 296 gnome_keyring_attribute_list_free(
297 static_cast<GnomeKeyringAttributeList*>(list)); 297 static_cast<GnomeKeyringAttributeList*>(list));
298 } 298 }
299 }; 299 };
300 300
301 typedef scoped_ptr<GnomeKeyringAttributeList, 301 typedef scoped_ptr<GnomeKeyringAttributeList,
302 GnomeKeyringAttributeListFreeDeleter> ScopedAttributeList; 302 GnomeKeyringAttributeListFreeDeleter> ScopedAttributeList;
303 303
304 // Helper methods to abbreviate Gnome Keyring long API names. 304 // Helper methods to abbreviate Gnome Keyring long API names.
305 static void AppendString(ScopedAttributeList* list, 305 static void AppendString(ScopedAttributeList* list,
306 const char* name, 306 const char* name,
307 const char* value); 307 const char* value);
308 static void AppendString(ScopedAttributeList* list, 308 static void AppendString(ScopedAttributeList* list,
309 const char* name, 309 const char* name,
310 const std::string& value); 310 const std::string& value);
311 static void AppendUint32(ScopedAttributeList* list, 311 static void AppendUint32(ScopedAttributeList* list,
312 const char* name, 312 const char* name,
313 guint32 value); 313 guint32 value);
314 314
315 // All these callbacks are called on UI thread. 315 // All these callbacks are called on UI thread.
316 static void OnOperationDone(GnomeKeyringResult result, gpointer data); 316 static void OnOperationDone(GnomeKeyringResult result, gpointer data);
317 317
318 // This is marked as static, but acts on the GKRMethod instance pointed to by
engedy 2015/02/25 15:17:47 Phrasing suggestion: s/GKRMethod instance pointed
vabr (Chromium) 2015/03/09 10:56:18 Done.
319 // |data|. Saves the result to |result_|. If the result is OK, overwrites
engedy 2015/02/25 15:17:47 Nit: |result|.
vabr (Chromium) 2015/03/09 10:56:18 Done.
320 // |forms_| with the found credentials. Clears |forms_| otherwise.
318 static void OnOperationGetList(GnomeKeyringResult result, GList* list, 321 static void OnOperationGetList(GnomeKeyringResult result, GList* list,
319 gpointer data); 322 gpointer data);
320 323
321 base::WaitableEvent event_; 324 base::WaitableEvent event_;
322 GnomeKeyringResult result_; 325 GnomeKeyringResult result_;
323 ScopedVector<autofill::PasswordForm> forms_; 326 ScopedVector<autofill::PasswordForm> forms_;
324 // If the credential search is specified by a single form and needs to use PSL 327 // If the credential search is specified by a single form and needs to use PSL
325 // matching, then the specifying form is stored in |lookup_form_|. If PSL 328 // matching, then the specifying form is stored in |lookup_form_|. If PSL
326 // matching is used to find a result, then the results signon realm, origin 329 // matching is used to find a result, then the results signon realm, origin
327 // and action are stored are replaced by those of |lookup_form_|. 330 // and action are stored are replaced by those of |lookup_form_|.
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 GnomeKeyringResult GKRMethod::WaitResult() { 481 GnomeKeyringResult GKRMethod::WaitResult() {
479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 482 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
480 event_.Wait(); 483 event_.Wait();
481 return result_; 484 return result_;
482 } 485 }
483 486
484 GnomeKeyringResult GKRMethod::WaitResult( 487 GnomeKeyringResult GKRMethod::WaitResult(
485 ScopedVector<autofill::PasswordForm>* forms) { 488 ScopedVector<autofill::PasswordForm>* forms) {
486 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 489 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
487 event_.Wait(); 490 event_.Wait();
488 if (forms->empty()) { 491 forms->swap(forms_);
vabr (Chromium) 2015/02/24 18:06:21 https://codereview.chromium.org/7712024 introduced
489 // Normal case. Avoid extra allocation by swapping.
490 forms->swap(forms_);
491 } else {
492 // Rare case. Append forms_ to *forms.
493 forms->insert(forms->end(), forms_.begin(), forms_.end());
494 forms_.weak_clear();
495 }
496 return result_; 492 return result_;
497 } 493 }
498 494
499 // static 495 // static
500 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list, 496 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list,
501 const char* name, 497 const char* name,
502 const char* value) { 498 const char* value) {
503 gnome_keyring_attribute_list_append_string(list->get(), name, value); 499 gnome_keyring_attribute_list_append_string(list->get(), name, value);
504 } 500 }
505 501
(...skipping 18 matching lines...) Expand all
524 method->event_.Signal(); 520 method->event_.Signal();
525 } 521 }
526 522
527 // static 523 // static
528 void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list, 524 void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list,
529 gpointer data) { 525 gpointer data) {
530 GKRMethod* method = static_cast<GKRMethod*>(data); 526 GKRMethod* method = static_cast<GKRMethod*>(data);
531 method->result_ = result; 527 method->result_ = result;
532 method->forms_.clear(); 528 method->forms_.clear();
533 // |list| will be freed after this callback returns, so convert it now. 529 // |list| will be freed after this callback returns, so convert it now.
534 ConvertFormList(list, method->lookup_form_.get(), &method->forms_); 530 if (result == GNOME_KEYRING_RESULT_OK)
531 method->forms_ = ConvertFormList(list, method->lookup_form_.get());
535 method->lookup_form_.reset(); 532 method->lookup_form_.reset();
536 method->event_.Signal(); 533 method->event_.Signal();
537 } 534 }
538 535
539 } // namespace 536 } // namespace
540 537
541 NativeBackendGnome::NativeBackendGnome(LocalProfileId id) 538 NativeBackendGnome::NativeBackendGnome(LocalProfileId id)
542 : profile_id_(id) { 539 : profile_id_(id) {
543 app_string_ = GetProfileSpecificAppString(); 540 app_string_ = GetProfileSpecificAppString();
544 } 541 }
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 707
711 bool NativeBackendGnome::GetBlacklistLogins( 708 bool NativeBackendGnome::GetBlacklistLogins(
712 ScopedVector<autofill::PasswordForm>* forms) { 709 ScopedVector<autofill::PasswordForm>* forms) {
713 return GetLoginsList(false, forms); 710 return GetLoginsList(false, forms);
714 } 711 }
715 712
716 bool NativeBackendGnome::GetLoginsList( 713 bool NativeBackendGnome::GetLoginsList(
717 bool autofillable, 714 bool autofillable,
718 ScopedVector<autofill::PasswordForm>* forms) { 715 ScopedVector<autofill::PasswordForm>* forms) {
719 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 716 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
717 forms->clear();
engedy 2015/02/25 15:17:48 I think this is not needed, WaitResult will always
vabr (Chromium) 2015/03/09 10:56:18 Done.
720 718
721 uint32_t blacklisted_by_user = !autofillable; 719 uint32_t blacklisted_by_user = !autofillable;
722 720
723 GKRMethod method; 721 GKRMethod method;
724 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 722 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
725 base::Bind(&GKRMethod::GetLoginsList, 723 base::Bind(&GKRMethod::GetLoginsList,
726 base::Unretained(&method), 724 base::Unretained(&method),
727 blacklisted_by_user, app_string_.c_str())); 725 blacklisted_by_user, app_string_.c_str()));
728 GnomeKeyringResult result = method.WaitResult(forms); 726 GnomeKeyringResult result = method.WaitResult(forms);
729 if (result == GNOME_KEYRING_RESULT_NO_MATCH) 727 if (result == GNOME_KEYRING_RESULT_NO_MATCH)
(...skipping 23 matching lines...) Expand all
753 } 751 }
754 return true; 752 return true;
755 } 753 }
756 754
757 bool NativeBackendGnome::GetLoginsBetween( 755 bool NativeBackendGnome::GetLoginsBetween(
758 base::Time get_begin, 756 base::Time get_begin,
759 base::Time get_end, 757 base::Time get_end,
760 TimestampToCompare date_to_compare, 758 TimestampToCompare date_to_compare,
761 ScopedVector<autofill::PasswordForm>* forms) { 759 ScopedVector<autofill::PasswordForm>* forms) {
762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 760 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
763 // We could walk the list and add items as we find them, but it is much 761 // We could walk the list and add items as we find them, but it is much
engedy 2015/02/25 15:17:48 Need to clear |forms| here.
vabr (Chromium) 2015/03/09 10:56:18 Done.
764 // easier to build the list and then filter the results. 762 // easier to build the list and then filter the results.
765 ScopedVector<autofill::PasswordForm> all_forms; 763 ScopedVector<autofill::PasswordForm> all_forms;
766 if (!GetAllLogins(&all_forms)) 764 if (!GetAllLogins(&all_forms))
767 return false; 765 return false;
768 766
769 base::Time autofill::PasswordForm::*date_member = 767 base::Time autofill::PasswordForm::*date_member =
770 date_to_compare == CREATION_TIMESTAMP 768 date_to_compare == CREATION_TIMESTAMP
771 ? &autofill::PasswordForm::date_created 769 ? &autofill::PasswordForm::date_created
772 : &autofill::PasswordForm::date_synced; 770 : &autofill::PasswordForm::date_synced;
773 for (auto& saved_form : all_forms) { 771 for (auto& saved_form : all_forms) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 } 804 }
807 return ok; 805 return ok;
808 } 806 }
809 807
810 std::string NativeBackendGnome::GetProfileSpecificAppString() const { 808 std::string NativeBackendGnome::GetProfileSpecificAppString() const {
811 // Originally, the application string was always just "chrome" and used only 809 // 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 810 // 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. 811 // for nothing. Now we use it to distinguish passwords for different profiles.
814 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_); 812 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_);
815 } 813 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698