Index: chrome/browser/password_manager/native_backend_gnome_x.cc |
diff --git a/chrome/browser/password_manager/native_backend_gnome_x.cc b/chrome/browser/password_manager/native_backend_gnome_x.cc |
index 788858d95365d6aacaeb5bdb1cde25a3b4e3bd17..bc37e2422cdc6fca2f630b0aac26f4815bbc5274 100644 |
--- a/chrome/browser/password_manager/native_backend_gnome_x.cc |
+++ b/chrome/browser/password_manager/native_backend_gnome_x.cc |
@@ -13,6 +13,7 @@ |
#include "base/basictypes.h" |
#include "base/logging.h" |
+#include "base/metrics/histogram.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/strings/string_piece.h" |
#include "base/strings/string_util.h" |
@@ -20,6 +21,7 @@ |
#include "base/strings/utf_string_conversions.h" |
#include "base/synchronization/waitable_event.h" |
#include "base/time/time.h" |
+#include "chrome/browser/password_manager/psl_matching_helper.h" |
#include "components/autofill/core/common/password_form.h" |
#include "content/public/browser/browser_thread.h" |
@@ -137,9 +139,15 @@ PasswordForm* FormFromAttributes(GnomeKeyringAttributeList* attrs) { |
// Parse all the results from the given GList into a PasswordFormList, and free |
// the GList. PasswordForms are allocated on the heap, and should be deleted by |
-// the consumer. |
+// the consumer. If not empty, |filter_by_signon_realm| is used to filter out |
+// results -- only credentials with signon realms passing the PSL matching |
+// (done by |helper|) against |filter_by_signon_realm| will be kept. |
void ConvertFormList(GList* found, |
+ const std::string& filter_by_signon_realm, |
+ const PSLMatchingHelper& helper, |
NativeBackendGnome::PasswordFormList* forms) { |
+ PSLMatchingHelper::PSLDomainMatchMetric psl_domain_match_metric = |
+ PSLMatchingHelper::PSL_DOMAIN_MATCH_NONE; |
for (GList* element = g_list_first(found); element != NULL; |
element = g_list_next(element)) { |
GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); |
@@ -147,6 +155,16 @@ void ConvertFormList(GList* found, |
PasswordForm* form = FormFromAttributes(attrs); |
if (form) { |
+ if (!filter_by_signon_realm.empty() && |
+ form->signon_realm != filter_by_signon_realm) { |
+ // This is not an exact match, we try PSL matching. |
+ if (!(PSLMatchingHelper::IsPublicSuffixDomainMatch( |
+ filter_by_signon_realm, form->signon_realm))) { |
+ continue; |
+ } |
+ psl_domain_match_metric = PSLMatchingHelper::PSL_DOMAIN_MATCH_FOUND; |
+ form->original_signon_realm = form->signon_realm; |
+ } |
if (data->secret) { |
form->password_value = UTF8ToUTF16(data->secret); |
} else { |
@@ -157,6 +175,14 @@ void ConvertFormList(GList* found, |
LOG(WARNING) << "Could not initialize PasswordForm from attributes!"; |
} |
} |
+ if (!filter_by_signon_realm.empty()) { |
+ UMA_HISTOGRAM_ENUMERATION( |
+ "PasswordManager.PslDomainMatchTriggering", |
+ helper.IsMatchingEnabled() |
+ ? psl_domain_match_metric |
+ : PSLMatchingHelper::PSL_DOMAIN_MATCH_DISABLED, |
+ PSLMatchingHelper::PSL_DOMAIN_MATCH_COUNT); |
+ } |
} |
// Schema is analagous to the fields in PasswordForm. |
@@ -250,6 +276,12 @@ class GKRMethod : public GnomeKeyringLoader { |
base::WaitableEvent event_; |
GnomeKeyringResult result_; |
NativeBackendGnome::PasswordFormList forms_; |
+ // Two additional arguments to OnOperationGetList: |
+ // If the credential search is related to a particular form, |
+ // |original_signon_realm_| contains the signon realm of that form. It is used |
+ // to filter the relevant results out of all the found ones. |
+ std::string original_signon_realm_; |
+ const PSLMatchingHelper helper_; |
}; |
void GKRMethod::AddLogin(const PasswordForm& form, const char* app_string) { |
@@ -286,6 +318,7 @@ void GKRMethod::AddLogin(const PasswordForm& form, const char* app_string) { |
void GKRMethod::AddLoginSearch(const PasswordForm& form, |
const char* app_string) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ original_signon_realm_ = form.signon_realm; |
// Search GNOME Keyring for matching passwords to update. |
ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); |
AppendString(&attrs, "origin_url", form.origin.spec()); |
@@ -305,6 +338,7 @@ void GKRMethod::AddLoginSearch(const PasswordForm& form, |
void GKRMethod::UpdateLoginSearch(const PasswordForm& form, |
const char* app_string) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ original_signon_realm_ = form.signon_realm; |
// Search GNOME Keyring for matching passwords to update. |
ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); |
AppendString(&attrs, "origin_url", form.origin.spec()); |
@@ -341,9 +375,14 @@ void GKRMethod::RemoveLogin(const PasswordForm& form, const char* app_string) { |
void GKRMethod::GetLogins(const PasswordForm& form, const char* app_string) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ original_signon_realm_ = form.signon_realm; |
// Search GNOME Keyring for matching passwords. |
ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); |
- AppendString(&attrs, "signon_realm", form.signon_realm); |
+ if (!helper_.ShouldPSLDomainMatchingApply( |
+ PSLMatchingHelper::GetRegistryControlledDomain( |
+ GURL(form.signon_realm)))) { |
+ AppendString(&attrs, "signon_realm", form.signon_realm); |
+ } |
AppendString(&attrs, "application", app_string); |
gnome_keyring_find_items(GNOME_KEYRING_ITEM_GENERIC_SECRET, |
attrs.get(), |
@@ -355,6 +394,7 @@ void GKRMethod::GetLogins(const PasswordForm& form, const char* app_string) { |
void GKRMethod::GetLoginsList(uint32_t blacklisted_by_user, |
const char* app_string) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ original_signon_realm_.clear(); |
// Search GNOME Keyring for matching passwords. |
ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); |
AppendUint32(&attrs, "blacklisted_by_user", blacklisted_by_user); |
@@ -368,6 +408,7 @@ void GKRMethod::GetLoginsList(uint32_t blacklisted_by_user, |
void GKRMethod::GetAllLogins(const char* app_string) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ original_signon_realm_.clear(); |
// We need to search for something, otherwise we get no results - so |
// we search for the fixed application string. |
ScopedAttributeList attrs(gnome_keyring_attribute_list_new()); |
@@ -434,7 +475,9 @@ void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list, |
method->result_ = result; |
method->forms_.clear(); |
// |list| will be freed after this callback returns, so convert it now. |
- ConvertFormList(list, &method->forms_); |
+ ConvertFormList( |
+ list, method->original_signon_realm_, method->helper_, &method->forms_); |
+ method->original_signon_realm_.clear(); |
method->event_.Signal(); |
} |