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

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

Issue 245563005: Passwords PSL Matching on Gnome: overwrite realm and origin (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comment about AddLogin added Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/password_manager/native_backend_gnome_x_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 form->blacklisted_by_user = uint_attr_map["blacklisted_by_user"]; 136 form->blacklisted_by_user = uint_attr_map["blacklisted_by_user"];
137 form->type = static_cast<PasswordForm::Type>(uint_attr_map["type"]); 137 form->type = static_cast<PasswordForm::Type>(uint_attr_map["type"]);
138 form->times_used = uint_attr_map["times_used"]; 138 form->times_used = uint_attr_map["times_used"];
139 form->scheme = static_cast<PasswordForm::Scheme>(uint_attr_map["scheme"]); 139 form->scheme = static_cast<PasswordForm::Scheme>(uint_attr_map["scheme"]);
140 140
141 return form.Pass(); 141 return form.Pass();
142 } 142 }
143 143
144 // Parse all the results from the given GList into a PasswordFormList, and free 144 // Parse all the results from the given GList into a PasswordFormList, and free
145 // the GList. PasswordForms are allocated on the heap, and should be deleted by 145 // the GList. PasswordForms are allocated on the heap, and should be deleted by
146 // the consumer. If not empty, |filter_by_signon_realm| is used to filter out 146 // the consumer. If not NULL, |lookup_form| is used to filter out results --
147 // results -- only credentials with signon realms passing the PSL matching 147 // only credentials with signon realms passing the PSL matching (done by
148 // (done by |helper|) against |filter_by_signon_realm| will be kept. 148 // |helper|) against |lookup_form->signon_realm| will be kept. PSL matched
149 // results get their signon_realm, origin, and action rewritten to those of
150 // |lookup_form_|, with the original signon_realm saved into the result's
151 // original_signon_realm data member.
149 void ConvertFormList(GList* found, 152 void ConvertFormList(GList* found,
150 const std::string& filter_by_signon_realm, 153 const PasswordForm* lookup_form,
151 const PSLMatchingHelper& helper, 154 const PSLMatchingHelper& helper,
152 NativeBackendGnome::PasswordFormList* forms) { 155 NativeBackendGnome::PasswordFormList* forms) {
153 PSLMatchingHelper::PSLDomainMatchMetric psl_domain_match_metric = 156 PSLMatchingHelper::PSLDomainMatchMetric psl_domain_match_metric =
154 PSLMatchingHelper::PSL_DOMAIN_MATCH_NONE; 157 PSLMatchingHelper::PSL_DOMAIN_MATCH_NONE;
155 for (GList* element = g_list_first(found); element != NULL; 158 for (GList* element = g_list_first(found); element != NULL;
156 element = g_list_next(element)) { 159 element = g_list_next(element)) {
157 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); 160 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data);
158 GnomeKeyringAttributeList* attrs = data->attributes; 161 GnomeKeyringAttributeList* attrs = data->attributes;
159 162
160 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs)); 163 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs));
161 if (form) { 164 if (form) {
162 if (!filter_by_signon_realm.empty() && 165 if (lookup_form && form->signon_realm != lookup_form->signon_realm) {
163 form->signon_realm != filter_by_signon_realm) {
164 // This is not an exact match, we try PSL matching. 166 // This is not an exact match, we try PSL matching.
165 if (!(PSLMatchingHelper::IsPublicSuffixDomainMatch( 167 if (!(PSLMatchingHelper::IsPublicSuffixDomainMatch(
166 filter_by_signon_realm, form->signon_realm))) { 168 lookup_form->signon_realm, form->signon_realm))) {
167 continue; 169 continue;
168 } 170 }
169 psl_domain_match_metric = PSLMatchingHelper::PSL_DOMAIN_MATCH_FOUND; 171 psl_domain_match_metric = PSLMatchingHelper::PSL_DOMAIN_MATCH_FOUND;
170 form->original_signon_realm = form->signon_realm; 172 form->original_signon_realm = form->signon_realm;
173 form->signon_realm = lookup_form->signon_realm;
174 form->origin = lookup_form->origin;
175 form->action = lookup_form->action;
171 } 176 }
172 if (data->secret) { 177 if (data->secret) {
173 form->password_value = UTF8ToUTF16(data->secret); 178 form->password_value = UTF8ToUTF16(data->secret);
174 } else { 179 } else {
175 LOG(WARNING) << "Unable to access password from list element!"; 180 LOG(WARNING) << "Unable to access password from list element!";
176 } 181 }
177 forms->push_back(form.release()); 182 forms->push_back(form.release());
178 } else { 183 } else {
179 LOG(WARNING) << "Could not initialize PasswordForm from attributes!"; 184 LOG(WARNING) << "Could not initialize PasswordForm from attributes!";
180 } 185 }
181 } 186 }
182 if (!filter_by_signon_realm.empty()) { 187 if (lookup_form) {
183 UMA_HISTOGRAM_ENUMERATION( 188 UMA_HISTOGRAM_ENUMERATION(
184 "PasswordManager.PslDomainMatchTriggering", 189 "PasswordManager.PslDomainMatchTriggering",
185 helper.IsMatchingEnabled() 190 helper.IsMatchingEnabled()
186 ? psl_domain_match_metric 191 ? psl_domain_match_metric
187 : PSLMatchingHelper::PSL_DOMAIN_MATCH_DISABLED, 192 : PSLMatchingHelper::PSL_DOMAIN_MATCH_DISABLED,
188 PSLMatchingHelper::PSL_DOMAIN_MATCH_COUNT); 193 PSLMatchingHelper::PSL_DOMAIN_MATCH_COUNT);
189 } 194 }
190 } 195 }
191 196
192 // Schema is analagous to the fields in PasswordForm. 197 // Schema is analagous to the fields in PasswordForm.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 285
281 // All these callbacks are called on UI thread. 286 // All these callbacks are called on UI thread.
282 static void OnOperationDone(GnomeKeyringResult result, gpointer data); 287 static void OnOperationDone(GnomeKeyringResult result, gpointer data);
283 288
284 static void OnOperationGetList(GnomeKeyringResult result, GList* list, 289 static void OnOperationGetList(GnomeKeyringResult result, GList* list,
285 gpointer data); 290 gpointer data);
286 291
287 base::WaitableEvent event_; 292 base::WaitableEvent event_;
288 GnomeKeyringResult result_; 293 GnomeKeyringResult result_;
289 NativeBackendGnome::PasswordFormList forms_; 294 NativeBackendGnome::PasswordFormList forms_;
290 // Two additional arguments to OnOperationGetList: 295 // If the credential search is specified by a single form and needs to use PSL
291 // If the credential search is related to a particular form, 296 // matching, then the specifying form is stored in |lookup_form_|. If PSL
292 // |original_signon_realm_| contains the signon realm of that form. It is used 297 // matching is used to find a result, then the results signon realm, origin
293 // to filter the relevant results out of all the found ones. 298 // and action are stored are replaced by those of |lookup_form_|.
294 std::string original_signon_realm_; 299 // Additionally, |lookup_form_->signon_realm| is also used to narrow down the
300 // found logins to those which indeed PSL-match the look-up. And finally,
301 // |lookup_form_| set to NULL means that PSL matching is not required.
302 scoped_ptr<PasswordForm> lookup_form_;
295 const PSLMatchingHelper helper_; 303 const PSLMatchingHelper helper_;
296 }; 304 };
297 305
298 void GKRMethod::AddLogin(const PasswordForm& form, const char* app_string) { 306 void GKRMethod::AddLogin(const PasswordForm& form, const char* app_string) {
299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
300 time_t date_created = form.date_created.ToTimeT(); 308 time_t date_created = form.date_created.ToTimeT();
301 // If we are asked to save a password with 0 date, use the current time. 309 // If we are asked to save a password with 0 date, use the current time.
302 // We don't want to actually save passwords as though on January 1, 1970. 310 // We don't want to actually save passwords as though on January 1, 1970.
303 if (!date_created) 311 if (!date_created)
304 date_created = time(NULL); 312 date_created = time(NULL);
(...skipping 19 matching lines...) Expand all
324 "type", form.type, 332 "type", form.type,
325 "times_used", form.times_used, 333 "times_used", form.times_used,
326 "scheme", form.scheme, 334 "scheme", form.scheme,
327 "application", app_string, 335 "application", app_string,
328 NULL); 336 NULL);
329 } 337 }
330 338
331 void GKRMethod::AddLoginSearch(const PasswordForm& form, 339 void GKRMethod::AddLoginSearch(const PasswordForm& form,
332 const char* app_string) { 340 const char* app_string) {
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
334 original_signon_realm_ = form.signon_realm; 342 lookup_form_.reset(NULL);
335 // Search GNOME Keyring for matching passwords to update. 343 // Search GNOME Keyring for matching passwords to update.
336 ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); 344 ScopedAttributeList attrs(gnome_keyring_attribute_list_new());
337 AppendString(&attrs, "origin_url", form.origin.spec()); 345 AppendString(&attrs, "origin_url", form.origin.spec());
338 AppendString(&attrs, "username_element", UTF16ToUTF8(form.username_element)); 346 AppendString(&attrs, "username_element", UTF16ToUTF8(form.username_element));
339 AppendString(&attrs, "username_value", UTF16ToUTF8(form.username_value)); 347 AppendString(&attrs, "username_value", UTF16ToUTF8(form.username_value));
340 AppendString(&attrs, "password_element", UTF16ToUTF8(form.password_element)); 348 AppendString(&attrs, "password_element", UTF16ToUTF8(form.password_element));
341 AppendString(&attrs, "submit_element", UTF16ToUTF8(form.submit_element)); 349 AppendString(&attrs, "submit_element", UTF16ToUTF8(form.submit_element));
342 AppendString(&attrs, "signon_realm", form.signon_realm); 350 AppendString(&attrs, "signon_realm", form.signon_realm);
343 AppendString(&attrs, "application", app_string); 351 AppendString(&attrs, "application", app_string);
344 gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET, 352 gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET,
345 attrs.get(), 353 attrs.get(),
346 OnOperationGetList, 354 OnOperationGetList,
347 /*data=*/this, 355 /*data=*/this,
348 /*destroy_data=*/NULL); 356 /*destroy_data=*/NULL);
349 } 357 }
350 358
351 void GKRMethod::UpdateLoginSearch(const PasswordForm& form, 359 void GKRMethod::UpdateLoginSearch(const PasswordForm& form,
352 const char* app_string) { 360 const char* app_string) {
353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
354 original_signon_realm_ = form.signon_realm; 362 lookup_form_.reset(NULL);
355 // Search GNOME Keyring for matching passwords to update. 363 // Search GNOME Keyring for matching passwords to update.
356 ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); 364 ScopedAttributeList attrs(gnome_keyring_attribute_list_new());
357 AppendString(&attrs, "origin_url", form.origin.spec()); 365 AppendString(&attrs, "origin_url", form.origin.spec());
358 AppendString(&attrs, "username_element", UTF16ToUTF8(form.username_element)); 366 AppendString(&attrs, "username_element", UTF16ToUTF8(form.username_element));
359 AppendString(&attrs, "username_value", UTF16ToUTF8(form.username_value)); 367 AppendString(&attrs, "username_value", UTF16ToUTF8(form.username_value));
360 AppendString(&attrs, "password_element", UTF16ToUTF8(form.password_element)); 368 AppendString(&attrs, "password_element", UTF16ToUTF8(form.password_element));
361 AppendString(&attrs, "signon_realm", form.signon_realm); 369 AppendString(&attrs, "signon_realm", form.signon_realm);
362 AppendString(&attrs, "application", app_string); 370 AppendString(&attrs, "application", app_string);
363 gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET, 371 gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET,
364 attrs.get(), 372 attrs.get(),
(...skipping 16 matching lines...) Expand all
381 "username_value", UTF16ToUTF8(form.username_value).c_str(), 389 "username_value", UTF16ToUTF8(form.username_value).c_str(),
382 "password_element", UTF16ToUTF8(form.password_element).c_str(), 390 "password_element", UTF16ToUTF8(form.password_element).c_str(),
383 "submit_element", UTF16ToUTF8(form.submit_element).c_str(), 391 "submit_element", UTF16ToUTF8(form.submit_element).c_str(),
384 "signon_realm", form.signon_realm.c_str(), 392 "signon_realm", form.signon_realm.c_str(),
385 "application", app_string, 393 "application", app_string,
386 NULL); 394 NULL);
387 } 395 }
388 396
389 void GKRMethod::GetLogins(const PasswordForm& form, const char* app_string) { 397 void GKRMethod::GetLogins(const PasswordForm& form, const char* app_string) {
390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 398 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
391 original_signon_realm_ = form.signon_realm; 399 lookup_form_.reset(new PasswordForm(form));
392 // Search GNOME Keyring for matching passwords. 400 // Search GNOME Keyring for matching passwords.
393 ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); 401 ScopedAttributeList attrs(gnome_keyring_attribute_list_new());
394 if (!helper_.ShouldPSLDomainMatchingApply( 402 if (!helper_.ShouldPSLDomainMatchingApply(
395 PSLMatchingHelper::GetRegistryControlledDomain( 403 PSLMatchingHelper::GetRegistryControlledDomain(
396 GURL(form.signon_realm)))) { 404 GURL(form.signon_realm)))) {
397 AppendString(&attrs, "signon_realm", form.signon_realm); 405 AppendString(&attrs, "signon_realm", form.signon_realm);
398 } 406 }
399 AppendString(&attrs, "application", app_string); 407 AppendString(&attrs, "application", app_string);
400 gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET, 408 gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET,
401 attrs.get(), 409 attrs.get(),
402 OnOperationGetList, 410 OnOperationGetList,
403 /*data=*/this, 411 /*data=*/this,
404 /*destroy_data=*/NULL); 412 /*destroy_data=*/NULL);
405 } 413 }
406 414
407 void GKRMethod::GetLoginsList(uint32_t blacklisted_by_user, 415 void GKRMethod::GetLoginsList(uint32_t blacklisted_by_user,
408 const char* app_string) { 416 const char* app_string) {
409 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
410 original_signon_realm_.clear(); 418 lookup_form_.reset(NULL);
411 // Search GNOME Keyring for matching passwords. 419 // Search GNOME Keyring for matching passwords.
412 ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); 420 ScopedAttributeList attrs(gnome_keyring_attribute_list_new());
413 AppendUint32(&attrs, "blacklisted_by_user", blacklisted_by_user); 421 AppendUint32(&attrs, "blacklisted_by_user", blacklisted_by_user);
414 AppendString(&attrs, "application", app_string); 422 AppendString(&attrs, "application", app_string);
415 gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET, 423 gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET,
416 attrs.get(), 424 attrs.get(),
417 OnOperationGetList, 425 OnOperationGetList,
418 /*data=*/this, 426 /*data=*/this,
419 /*destroy_data=*/NULL); 427 /*destroy_data=*/NULL);
420 } 428 }
421 429
422 void GKRMethod::GetAllLogins(const char* app_string) { 430 void GKRMethod::GetAllLogins(const char* app_string) {
423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 431 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
424 original_signon_realm_.clear(); 432 lookup_form_.reset(NULL);
425 // We need to search for something, otherwise we get no results - so 433 // We need to search for something, otherwise we get no results - so
426 // we search for the fixed application string. 434 // we search for the fixed application string.
427 ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); 435 ScopedAttributeList attrs(gnome_keyring_attribute_list_new());
428 AppendString(&attrs, "application", app_string); 436 AppendString(&attrs, "application", app_string);
429 gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET, 437 gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET,
430 attrs.get(), 438 attrs.get(),
431 OnOperationGetList, 439 OnOperationGetList,
432 /*data=*/this, 440 /*data=*/this,
433 /*destroy_data=*/NULL); 441 /*destroy_data=*/NULL);
434 } 442 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 } 490 }
483 491
484 // static 492 // static
485 void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list, 493 void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list,
486 gpointer data) { 494 gpointer data) {
487 GKRMethod* method = static_cast<GKRMethod*>(data); 495 GKRMethod* method = static_cast<GKRMethod*>(data);
488 method->result_ = result; 496 method->result_ = result;
489 method->forms_.clear(); 497 method->forms_.clear();
490 // |list| will be freed after this callback returns, so convert it now. 498 // |list| will be freed after this callback returns, so convert it now.
491 ConvertFormList( 499 ConvertFormList(
492 list, method->original_signon_realm_, method->helper_, &method->forms_); 500 list, method->lookup_form_.get(), method->helper_, &method->forms_);
493 method->original_signon_realm_.clear(); 501 method->lookup_form_.reset(NULL);
494 method->event_.Signal(); 502 method->event_.Signal();
495 } 503 }
496 504
497 } // namespace 505 } // namespace
498 506
499 NativeBackendGnome::NativeBackendGnome(LocalProfileId id) 507 NativeBackendGnome::NativeBackendGnome(LocalProfileId id)
500 : profile_id_(id) { 508 : profile_id_(id) {
501 app_string_ = GetProfileSpecificAppString(); 509 app_string_ = GetProfileSpecificAppString();
502 } 510 }
503 511
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 } 736 }
729 return true; 737 return true;
730 } 738 }
731 739
732 std::string NativeBackendGnome::GetProfileSpecificAppString() const { 740 std::string NativeBackendGnome::GetProfileSpecificAppString() const {
733 // Originally, the application string was always just "chrome" and used only 741 // Originally, the application string was always just "chrome" and used only
734 // so that we had *something* to search for since GNOME Keyring won't search 742 // so that we had *something* to search for since GNOME Keyring won't search
735 // for nothing. Now we use it to distinguish passwords for different profiles. 743 // for nothing. Now we use it to distinguish passwords for different profiles.
736 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_); 744 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_);
737 } 745 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/password_manager/native_backend_gnome_x_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698