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

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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 158
159 return form.Pass(); 159 return form.Pass();
160 } 160 }
161 161
162 // Parse all the results from the given GList into a 162 // Returns all the results from |found|. If not NULL, |lookup_form| is used to
163 // ScopedVector<autofill::PasswordForm>, and free the GList. PasswordForms are 163 // filter out results -- only credentials with signon realms passing the PSL
164 // allocated on the heap, and should be deleted by the consumer. If not NULL, 164 // matching against |lookup_form->signon_realm| will be kept. PSL matched
165 // |lookup_form| is used to filter out results -- only credentials with signon 165 // results get their signon_realm, origin, and action rewritten to those of
166 // realms passing the PSL matching against |lookup_form->signon_realm| will be 166 // |lookup_form_|, with the original signon_realm saved into the result's
167 // kept. PSL matched results get their signon_realm, origin, and action 167 // original_signon_realm data member.
168 // rewritten to those of |lookup_form_|, with the original signon_realm saved 168 ScopedVector<autofill::PasswordForm> ConvertFormList(
169 // into the result's original_signon_realm data member. 169 GList* found,
170 void ConvertFormList(GList* found, 170 const PasswordForm* lookup_form) {
171 const PasswordForm* lookup_form, 171 ScopedVector<autofill::PasswordForm> forms;
172 ScopedVector<autofill::PasswordForm>* forms) {
173 password_manager::PSLDomainMatchMetric psl_domain_match_metric = 172 password_manager::PSLDomainMatchMetric psl_domain_match_metric =
174 password_manager::PSL_DOMAIN_MATCH_NONE; 173 password_manager::PSL_DOMAIN_MATCH_NONE;
175 for (GList* element = g_list_first(found); element != NULL; 174 for (GList* element = g_list_first(found); element != NULL;
176 element = g_list_next(element)) { 175 element = g_list_next(element)) {
177 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); 176 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data);
178 GnomeKeyringAttributeList* attrs = data->attributes; 177 GnomeKeyringAttributeList* attrs = data->attributes;
179 178
180 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs)); 179 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs));
181 if (form) { 180 if (form) {
182 if (lookup_form && form->signon_realm != lookup_form->signon_realm) { 181 if (lookup_form && form->signon_realm != lookup_form->signon_realm) {
183 // This is not an exact match, we try PSL matching. 182 // This is not an exact match, we try PSL matching.
184 if (lookup_form->scheme != PasswordForm::SCHEME_HTML || 183 if (lookup_form->scheme != PasswordForm::SCHEME_HTML ||
185 form->scheme != PasswordForm::SCHEME_HTML || 184 form->scheme != PasswordForm::SCHEME_HTML ||
186 !(password_manager::IsPublicSuffixDomainMatch( 185 !(password_manager::IsPublicSuffixDomainMatch(
187 lookup_form->signon_realm, form->signon_realm))) { 186 lookup_form->signon_realm, form->signon_realm))) {
188 continue; 187 continue;
189 } 188 }
190 psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND; 189 psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND;
191 form->original_signon_realm = form->signon_realm; 190 form->original_signon_realm = form->signon_realm;
192 form->signon_realm = lookup_form->signon_realm; 191 form->signon_realm = lookup_form->signon_realm;
193 form->origin = lookup_form->origin; 192 form->origin = lookup_form->origin;
194 form->action = lookup_form->action; 193 form->action = lookup_form->action;
195 } 194 }
196 if (data->secret) { 195 if (data->secret) {
197 form->password_value = UTF8ToUTF16(data->secret); 196 form->password_value = UTF8ToUTF16(data->secret);
198 } else { 197 } else {
199 LOG(WARNING) << "Unable to access password from list element!"; 198 LOG(WARNING) << "Unable to access password from list element!";
200 } 199 }
201 forms->push_back(form.release()); 200 forms.push_back(form.release());
202 } else { 201 } else {
203 LOG(WARNING) << "Could not initialize PasswordForm from attributes!"; 202 LOG(WARNING) << "Could not initialize PasswordForm from attributes!";
204 } 203 }
205 } 204 }
206 if (lookup_form) { 205 if (lookup_form) {
207 const GURL signon_realm(lookup_form->signon_realm); 206 const GURL signon_realm(lookup_form->signon_realm);
208 std::string registered_domain = 207 std::string registered_domain =
209 password_manager::GetRegistryControlledDomain(signon_realm); 208 password_manager::GetRegistryControlledDomain(signon_realm);
210 UMA_HISTOGRAM_ENUMERATION( 209 UMA_HISTOGRAM_ENUMERATION(
211 "PasswordManager.PslDomainMatchTriggering", 210 "PasswordManager.PslDomainMatchTriggering",
212 password_manager::ShouldPSLDomainMatchingApply(registered_domain) 211 password_manager::ShouldPSLDomainMatchingApply(registered_domain)
213 ? psl_domain_match_metric 212 ? psl_domain_match_metric
214 : password_manager::PSL_DOMAIN_MATCH_NOT_USED, 213 : password_manager::PSL_DOMAIN_MATCH_NOT_USED,
215 password_manager::PSL_DOMAIN_MATCH_COUNT); 214 password_manager::PSL_DOMAIN_MATCH_COUNT);
216 } 215 }
216 return forms.Pass();
217 } 217 }
218 218
219 // Schema is analagous to the fields in PasswordForm. 219 // Schema is analagous to the fields in PasswordForm.
220 // TODO(gcasto): Adding 'form_data' would be nice, but we would need to 220 // TODO(gcasto): Adding 'form_data' would be nice, but we would need to
221 // serialize in a way that is guaranteed to not have any embedded NULLs. Pickle 221 // serialize in a way that is guaranteed to not have any embedded NULLs. Pickle
222 // doesn't make this guarantee, so we just don't serialize this field. Since 222 // doesn't make this guarantee, so we just don't serialize this field. Since
223 // it's only used to crowd source data collection it doesn't matter that much 223 // it's only used to crowd source data collection it doesn't matter that much
224 // if it's not available on this platform. 224 // if it's not available on this platform.
225 const GnomeKeyringPasswordSchema kGnomeSchema = { 225 const GnomeKeyringPasswordSchema kGnomeSchema = {
226 GNOME_KEYRING_ITEM_GENERIC_SECRET, { 226 GNOME_KEYRING_ITEM_GENERIC_SECRET, {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 void UpdateLoginSearch(const PasswordForm& form, const char* app_string); 276 void UpdateLoginSearch(const PasswordForm& form, const char* app_string);
277 void RemoveLogin(const PasswordForm& form, const char* app_string); 277 void RemoveLogin(const PasswordForm& form, const char* app_string);
278 void GetLogins(const PasswordForm& form, const char* app_string); 278 void GetLogins(const PasswordForm& form, const char* app_string);
279 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string); 279 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string);
280 void GetAllLogins(const char* app_string); 280 void GetAllLogins(const char* app_string);
281 281
282 // Use after AddLogin, RemoveLogin. 282 // Use after AddLogin, RemoveLogin.
283 GnomeKeyringResult WaitResult(); 283 GnomeKeyringResult WaitResult();
284 284
285 // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList, 285 // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList,
286 // GetAllLogins. 286 // GetAllLogins. Replaces the content of |forms| with found logins.
287 GnomeKeyringResult WaitResult(ScopedVector<autofill::PasswordForm>* forms); 287 GnomeKeyringResult WaitResult(ScopedVector<autofill::PasswordForm>* forms);
288 288
289 private: 289 private:
290 struct GnomeKeyringAttributeListFreeDeleter { 290 struct GnomeKeyringAttributeListFreeDeleter {
291 inline void operator()(void* list) const { 291 inline void operator()(void* list) const {
292 gnome_keyring_attribute_list_free( 292 gnome_keyring_attribute_list_free(
293 static_cast<GnomeKeyringAttributeList*>(list)); 293 static_cast<GnomeKeyringAttributeList*>(list));
294 } 294 }
295 }; 295 };
296 296
297 typedef scoped_ptr<GnomeKeyringAttributeList, 297 typedef scoped_ptr<GnomeKeyringAttributeList,
298 GnomeKeyringAttributeListFreeDeleter> ScopedAttributeList; 298 GnomeKeyringAttributeListFreeDeleter> ScopedAttributeList;
299 299
300 // Helper methods to abbreviate Gnome Keyring long API names. 300 // Helper methods to abbreviate Gnome Keyring long API names.
301 static void AppendString(ScopedAttributeList* list, 301 static void AppendString(ScopedAttributeList* list,
302 const char* name, 302 const char* name,
303 const char* value); 303 const char* value);
304 static void AppendString(ScopedAttributeList* list, 304 static void AppendString(ScopedAttributeList* list,
305 const char* name, 305 const char* name,
306 const std::string& value); 306 const std::string& value);
307 static void AppendUint32(ScopedAttributeList* list, 307 static void AppendUint32(ScopedAttributeList* list,
308 const char* name, 308 const char* name,
309 guint32 value); 309 guint32 value);
310 310
311 // All these callbacks are called on UI thread. 311 // All these callbacks are called on UI thread.
312 static void OnOperationDone(GnomeKeyringResult result, gpointer data); 312 static void OnOperationDone(GnomeKeyringResult result, gpointer data);
313 313
314 // This is marked as static, but acts on the GKRMethod instance pointed to by
315 // |data|. Saves the result to |result_|. If the result is OK, overwrites
316 // |forms_| with the found credentials. Clears |forms_| otherwise.
314 static void OnOperationGetList(GnomeKeyringResult result, GList* list, 317 static void OnOperationGetList(GnomeKeyringResult result, GList* list,
315 gpointer data); 318 gpointer data);
316 319
317 base::WaitableEvent event_; 320 base::WaitableEvent event_;
318 GnomeKeyringResult result_; 321 GnomeKeyringResult result_;
319 ScopedVector<autofill::PasswordForm> forms_; 322 ScopedVector<autofill::PasswordForm> forms_;
320 // If the credential search is specified by a single form and needs to use PSL 323 // If the credential search is specified by a single form and needs to use PSL
321 // matching, then the specifying form is stored in |lookup_form_|. If PSL 324 // matching, then the specifying form is stored in |lookup_form_|. If PSL
322 // matching is used to find a result, then the results signon realm, origin 325 // matching is used to find a result, then the results signon realm, origin
323 // and action are stored are replaced by those of |lookup_form_|. 326 // and action are stored are replaced by those of |lookup_form_|.
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 GnomeKeyringResult GKRMethod::WaitResult() { 476 GnomeKeyringResult GKRMethod::WaitResult() {
474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
475 event_.Wait(); 478 event_.Wait();
476 return result_; 479 return result_;
477 } 480 }
478 481
479 GnomeKeyringResult GKRMethod::WaitResult( 482 GnomeKeyringResult GKRMethod::WaitResult(
480 ScopedVector<autofill::PasswordForm>* forms) { 483 ScopedVector<autofill::PasswordForm>* forms) {
481 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 484 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
482 event_.Wait(); 485 event_.Wait();
483 if (forms->empty()) { 486 forms->swap(forms_);
vabr (Chromium) 2015/02/11 17:19:14 https://codereview.chromium.org/7712024 introduced
484 // Normal case. Avoid extra allocation by swapping.
485 forms->swap(forms_);
486 } else {
487 // Rare case. Append forms_ to *forms.
488 forms->insert(forms->end(), forms_.begin(), forms_.end());
489 forms_.weak_clear();
490 }
491 return result_; 487 return result_;
492 } 488 }
493 489
494 // static 490 // static
495 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list, 491 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list,
496 const char* name, 492 const char* name,
497 const char* value) { 493 const char* value) {
498 gnome_keyring_attribute_list_append_string(list->get(), name, value); 494 gnome_keyring_attribute_list_append_string(list->get(), name, value);
499 } 495 }
500 496
(...skipping 18 matching lines...) Expand all
519 method->event_.Signal(); 515 method->event_.Signal();
520 } 516 }
521 517
522 // static 518 // static
523 void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list, 519 void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list,
524 gpointer data) { 520 gpointer data) {
525 GKRMethod* method = static_cast<GKRMethod*>(data); 521 GKRMethod* method = static_cast<GKRMethod*>(data);
526 method->result_ = result; 522 method->result_ = result;
527 method->forms_.clear(); 523 method->forms_.clear();
528 // |list| will be freed after this callback returns, so convert it now. 524 // |list| will be freed after this callback returns, so convert it now.
529 ConvertFormList(list, method->lookup_form_.get(), &method->forms_); 525 if (result == GNOME_KEYRING_RESULT_OK)
526 method->forms_ = ConvertFormList(list, method->lookup_form_.get());
530 method->lookup_form_.reset(NULL); 527 method->lookup_form_.reset(NULL);
531 method->event_.Signal(); 528 method->event_.Signal();
532 } 529 }
533 530
534 } // namespace 531 } // namespace
535 532
536 NativeBackendGnome::NativeBackendGnome(LocalProfileId id) 533 NativeBackendGnome::NativeBackendGnome(LocalProfileId id)
537 : profile_id_(id) { 534 : profile_id_(id) {
538 app_string_ = GetProfileSpecificAppString(); 535 app_string_ = GetProfileSpecificAppString();
539 } 536 }
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 702
706 bool NativeBackendGnome::GetBlacklistLogins( 703 bool NativeBackendGnome::GetBlacklistLogins(
707 ScopedVector<autofill::PasswordForm>* forms) { 704 ScopedVector<autofill::PasswordForm>* forms) {
708 return GetLoginsList(false, forms); 705 return GetLoginsList(false, forms);
709 } 706 }
710 707
711 bool NativeBackendGnome::GetLoginsList( 708 bool NativeBackendGnome::GetLoginsList(
712 bool autofillable, 709 bool autofillable,
713 ScopedVector<autofill::PasswordForm>* forms) { 710 ScopedVector<autofill::PasswordForm>* forms) {
714 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 711 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
712 forms->clear();
715 713
716 uint32_t blacklisted_by_user = !autofillable; 714 uint32_t blacklisted_by_user = !autofillable;
717 715
718 GKRMethod method; 716 GKRMethod method;
719 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 717 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
720 base::Bind(&GKRMethod::GetLoginsList, 718 base::Bind(&GKRMethod::GetLoginsList,
721 base::Unretained(&method), 719 base::Unretained(&method),
722 blacklisted_by_user, app_string_.c_str())); 720 blacklisted_by_user, app_string_.c_str()));
723 GnomeKeyringResult result = method.WaitResult(forms); 721 GnomeKeyringResult result = method.WaitResult(forms);
724 if (result == GNOME_KEYRING_RESULT_NO_MATCH) 722 if (result == GNOME_KEYRING_RESULT_NO_MATCH)
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 } 799 }
802 return ok; 800 return ok;
803 } 801 }
804 802
805 std::string NativeBackendGnome::GetProfileSpecificAppString() const { 803 std::string NativeBackendGnome::GetProfileSpecificAppString() const {
806 // Originally, the application string was always just "chrome" and used only 804 // Originally, the application string was always just "chrome" and used only
807 // so that we had *something* to search for since GNOME Keyring won't search 805 // so that we had *something* to search for since GNOME Keyring won't search
808 // for nothing. Now we use it to distinguish passwords for different profiles. 806 // for nothing. Now we use it to distinguish passwords for different profiles.
809 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_); 807 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_);
810 } 808 }
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/native_backend_gnome_x.h ('k') | chrome/browser/password_manager/native_backend_kwallet_x.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698