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

Unified Diff: chrome/browser/password_manager/login_database.cc

Issue 15660018: [autofill] Add support for PSL domain matching for password autofill. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments from isherman and aurimas Created 7 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/password_manager/login_database.cc
diff --git a/chrome/browser/password_manager/login_database.cc b/chrome/browser/password_manager/login_database.cc
index 43277284086113507ec2f82e0ab5d249c1e825d6..8c01bd59af9dc532e5ce01e59d076493fa3508c2 100644
--- a/chrome/browser/password_manager/login_database.cc
+++ b/chrome/browser/password_manager/login_database.cc
@@ -7,14 +7,18 @@
#include <algorithm>
#include <limits>
+#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/pickle.h"
+#include "base/string_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time.h"
+#include "chrome/common/chrome_switches.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "sql/statement.h"
#include "sql/transaction.h"
@@ -45,6 +49,13 @@ enum LoginTableColumns {
COLUMN_TIMES_USED
};
+std::string GetRegistryControlledDomain(const std::string& signon_realm_str) {
+ const GURL signon_realm(signon_realm_str);
+ return net::registry_controlled_domains::GetDomainAndRegistry(
+ signon_realm,
+ net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+}
+
} // namespace
LoginDatabase::LoginDatabase() {
@@ -100,6 +111,10 @@ bool LoginDatabase::Init(const base::FilePath& db_path) {
db_.Close();
return false;
}
+
+ public_suffix_domain_matching_ = CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnablePasswordAutofillPublicSuffixDomainMatching);
+
return true;
}
@@ -357,19 +372,63 @@ bool LoginDatabase::GetLogins(const PasswordForm& form,
std::vector<PasswordForm*>* forms) const {
DCHECK(forms);
// You *must* change LoginTableColumns if this query changes.
- sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
- "SELECT origin_url, action_url, "
+ const std::string sql_query = "SELECT origin_url, action_url, "
"username_element, username_value, "
"password_element, password_value, submit_element, "
"signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
"scheme, password_type, possible_usernames, times_used "
- "FROM logins WHERE signon_realm == ? "));
- s.BindString(0, form.signon_realm);
+ "FROM logins WHERE signon_realm == ? ";
+ sql::Statement s;
+ if (public_suffix_domain_matching_) {
+ const std::string extended_sql_query =
+ sql_query + "OR signon_realm REGEXP ? ";
+ // TODO(nyquist) Re-enable usage of cached statements if possible.
+ // s.Assign(db_.GetCachedStatement(SQL_FROM_HERE, sql_query.c_str()));
+ s.Assign(db_.GetUniqueStatement(extended_sql_query.c_str()));
+ std::string domain = GetRegistryControlledDomain(form.signon_realm);
+ // We need to escape ., - and _ in the domain. Since the domain has already
palmer 2013/06/11 18:55:45 The comment doesn't match the code --- you don't e
nyquist 2013/06/11 23:54:43 I don't think _ has to be escaped in regexp. Updat
+ // been sanitized using GURL, we do not need to escape any other characters.
+ ReplaceChars(domain, ".", "\\.", &domain);
+ ReplaceChars(domain, "-", "\\-", &domain);
+ // For a domain such as foo.bar, this regexp will match domains for http
+ // and https and on the form: http://foo.bar/, http://www.foo.bar/,
+ // http://www.mobile.foo.bar/. It will not match http://notfoo.bar/.
+ // It also matches any port, such as http://foo.bar:8080/.
+ std::string regexp =
+ "^((http|https):\\/\\/)([\\w\\-_]+\\.)*" + domain + "(:\\d+)?\\/$";
palmer 2013/06/11 18:55:45 It doesn't feel right to match loosely on the port
nyquist 2013/06/11 23:54:43 Made this more strict. Now both scheme and port ha
+ s.BindString(0, form.signon_realm);
+ s.BindString(1, regexp);
+ } else {
+ s.Assign(db_.GetCachedStatement(SQL_FROM_HERE, sql_query.c_str()));
+ s.BindString(0, form.signon_realm);
+ }
while (s.Step()) {
scoped_ptr<PasswordForm> new_form(new PasswordForm());
if (!InitPasswordFormFromStatement(new_form.get(), s))
return false;
+ if (public_suffix_domain_matching_) {
+ const std::string found_registry_controlled_domain =
+ GetRegistryControlledDomain(new_form->signon_realm);
+ const std::string form_registry_controlled_domain =
+ GetRegistryControlledDomain(form.signon_realm);
+ if (found_registry_controlled_domain != form_registry_controlled_domain) {
+ // The database returned results that should not match. Skipping result.
+ continue;
+ }
+ if (form.signon_realm != new_form->signon_realm) {
+ // This is not a perfect match, so we need to create a new valid result.
+ // We do this by copying over origin, signon realm and action from the
+ // observed form and setting the original signon realm to what we found
+ // in the database. We use the fact that |original_signon_realm| is
+ // non-empty to communicate that this match was found using public
+ // suffix matching.
+ new_form->original_signon_realm = new_form->signon_realm;
+ new_form->origin = form.origin;
+ new_form->signon_realm = form.signon_realm;
+ new_form->action = form.action;
+ }
+ }
forms->push_back(new_form.release());
}
return s.Succeeded();

Powered by Google App Engine
This is Rietveld 408576698