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

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

Issue 23857010: Revert "Revert 223907 "[password generation] Upload possible account cre..."" (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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/login_database_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/login_database.h" 5 #include "chrome/browser/password_manager/login_database.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/pickle.h" 14 #include "base/pickle.h"
15 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
16 #include "base/time/time.h" 16 #include "base/time/time.h"
17 #include "chrome/common/chrome_switches.h" 17 #include "chrome/common/chrome_switches.h"
18 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 18 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
19 #include "sql/connection.h" 19 #include "sql/connection.h"
20 #include "sql/statement.h" 20 #include "sql/statement.h"
21 #include "sql/transaction.h" 21 #include "sql/transaction.h"
22 22
23 using autofill::PasswordForm; 23 using autofill::PasswordForm;
24 24
25 static const int kCurrentVersionNumber = 3; 25 static const int kCurrentVersionNumber = 4;
26 static const int kCompatibleVersionNumber = 1; 26 static const int kCompatibleVersionNumber = 1;
27 27
28 namespace { 28 namespace {
29 29
30 // Convenience enum for interacting with SQL queries that use all the columns. 30 // Convenience enum for interacting with SQL queries that use all the columns.
31 enum LoginTableColumns { 31 enum LoginTableColumns {
32 COLUMN_ORIGIN_URL = 0, 32 COLUMN_ORIGIN_URL = 0,
33 COLUMN_ACTION_URL, 33 COLUMN_ACTION_URL,
34 COLUMN_USERNAME_ELEMENT, 34 COLUMN_USERNAME_ELEMENT,
35 COLUMN_USERNAME_VALUE, 35 COLUMN_USERNAME_VALUE,
36 COLUMN_PASSWORD_ELEMENT, 36 COLUMN_PASSWORD_ELEMENT,
37 COLUMN_PASSWORD_VALUE, 37 COLUMN_PASSWORD_VALUE,
38 COLUMN_SUBMIT_ELEMENT, 38 COLUMN_SUBMIT_ELEMENT,
39 COLUMN_SIGNON_REALM, 39 COLUMN_SIGNON_REALM,
40 COLUMN_SSL_VALID, 40 COLUMN_SSL_VALID,
41 COLUMN_PREFERRED, 41 COLUMN_PREFERRED,
42 COLUMN_DATE_CREATED, 42 COLUMN_DATE_CREATED,
43 COLUMN_BLACKLISTED_BY_USER, 43 COLUMN_BLACKLISTED_BY_USER,
44 COLUMN_SCHEME, 44 COLUMN_SCHEME,
45 COLUMN_PASSWORD_TYPE, 45 COLUMN_PASSWORD_TYPE,
46 COLUMN_POSSIBLE_USERNAMES, 46 COLUMN_POSSIBLE_USERNAMES,
47 COLUMN_TIMES_USED 47 COLUMN_TIMES_USED,
48 COLUMN_FORM_DATA
48 }; 49 };
49 50
50 // Using the public suffix list for matching the origin is only needed for 51 // Using the public suffix list for matching the origin is only needed for
51 // websites that do not have a single hostname for entering credentials. It 52 // websites that do not have a single hostname for entering credentials. It
52 // would be better for their users if they did, but until then we help them find 53 // would be better for their users if they did, but until then we help them find
53 // credentials across different hostnames. We know that accounts.google.com is 54 // credentials across different hostnames. We know that accounts.google.com is
54 // the only hostname we should be accepting credentials on for any domain under 55 // the only hostname we should be accepting credentials on for any domain under
55 // google.com, so we can apply a tighter policy for that domain. 56 // google.com, so we can apply a tighter policy for that domain.
56 // For owners of domains where a single hostname is always used when your 57 // For owners of domains where a single hostname is always used when your
57 // users are entering their credentials, please contact palmer@chromium.org, 58 // users are entering their credentials, please contact palmer@chromium.org,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 178
178 bool LoginDatabase::MigrateOldVersionsAsNeeded() { 179 bool LoginDatabase::MigrateOldVersionsAsNeeded() {
179 switch (meta_table_.GetVersionNumber()) { 180 switch (meta_table_.GetVersionNumber()) {
180 case 1: 181 case 1:
181 if (!db_.Execute("ALTER TABLE logins " 182 if (!db_.Execute("ALTER TABLE logins "
182 "ADD COLUMN password_type INTEGER") || 183 "ADD COLUMN password_type INTEGER") ||
183 !db_.Execute("ALTER TABLE logins " 184 !db_.Execute("ALTER TABLE logins "
184 "ADD COLUMN possible_usernames BLOB")) { 185 "ADD COLUMN possible_usernames BLOB")) {
185 return false; 186 return false;
186 } 187 }
188 // Fall through.
187 case 2: 189 case 2:
188 if (!db_.Execute("ALTER TABLE logins " 190 if (!db_.Execute("ALTER TABLE logins ADD COLUMN times_used INTEGER")) {
189 "ADD COLUMN times_used INTEGER")) {
190 return false; 191 return false;
191 } 192 }
192 break; 193 // Fall through.
194 case 3:
195 if (!db_.Execute("ALTER TABLE logins ADD COLUMN form_data BLOB")) {
196 return false;
197 }
198 // Fall through.
193 case kCurrentVersionNumber: 199 case kCurrentVersionNumber:
194 // Already up to date 200 // Already up to date
195 return true; 201 return true;
196 break;
197 default: 202 default:
198 NOTREACHED(); 203 NOTREACHED();
199 return false; 204 return false;
200 } 205 }
201 meta_table_.SetVersionNumber(kCurrentVersionNumber); 206 meta_table_.SetVersionNumber(kCurrentVersionNumber);
202 return true; 207 return true;
203 } 208 }
204 209
205 bool LoginDatabase::InitLoginsTable() { 210 bool LoginDatabase::InitLoginsTable() {
206 if (!db_.DoesTableExist("logins")) { 211 if (!db_.DoesTableExist("logins")) {
207 if (!db_.Execute("CREATE TABLE logins (" 212 if (!db_.Execute("CREATE TABLE logins ("
208 "origin_url VARCHAR NOT NULL, " 213 "origin_url VARCHAR NOT NULL, "
209 "action_url VARCHAR, " 214 "action_url VARCHAR, "
210 "username_element VARCHAR, " 215 "username_element VARCHAR, "
211 "username_value VARCHAR, " 216 "username_value VARCHAR, "
212 "password_element VARCHAR, " 217 "password_element VARCHAR, "
213 "password_value BLOB, " 218 "password_value BLOB, "
214 "submit_element VARCHAR, " 219 "submit_element VARCHAR, "
215 "signon_realm VARCHAR NOT NULL," 220 "signon_realm VARCHAR NOT NULL,"
216 "ssl_valid INTEGER NOT NULL," 221 "ssl_valid INTEGER NOT NULL,"
217 "preferred INTEGER NOT NULL," 222 "preferred INTEGER NOT NULL,"
218 "date_created INTEGER NOT NULL," 223 "date_created INTEGER NOT NULL,"
219 "blacklisted_by_user INTEGER NOT NULL," 224 "blacklisted_by_user INTEGER NOT NULL,"
220 "scheme INTEGER NOT NULL," 225 "scheme INTEGER NOT NULL,"
221 "password_type INTEGER," 226 "password_type INTEGER,"
222 "possible_usernames BLOB," 227 "possible_usernames BLOB,"
223 "times_used INTEGER," 228 "times_used INTEGER,"
229 "form_data BLOB,"
224 "UNIQUE " 230 "UNIQUE "
225 "(origin_url, username_element, " 231 "(origin_url, username_element, "
226 "username_value, password_element, " 232 "username_value, password_element, "
227 "submit_element, signon_realm))")) { 233 "submit_element, signon_realm))")) {
228 NOTREACHED(); 234 NOTREACHED();
229 return false; 235 return false;
230 } 236 }
231 if (!db_.Execute("CREATE INDEX logins_signon ON " 237 if (!db_.Execute("CREATE INDEX logins_signon ON "
232 "logins (signon_realm)")) { 238 "logins (signon_realm)")) {
233 NOTREACHED(); 239 NOTREACHED();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 std::string encrypted_password; 297 std::string encrypted_password;
292 if (!EncryptedString(form.password_value, &encrypted_password)) 298 if (!EncryptedString(form.password_value, &encrypted_password))
293 return false; 299 return false;
294 300
295 // You *must* change LoginTableColumns if this query changes. 301 // You *must* change LoginTableColumns if this query changes.
296 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, 302 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
297 "INSERT OR REPLACE INTO logins " 303 "INSERT OR REPLACE INTO logins "
298 "(origin_url, action_url, username_element, username_value, " 304 "(origin_url, action_url, username_element, username_value, "
299 " password_element, password_value, submit_element, " 305 " password_element, password_value, submit_element, "
300 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " 306 " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
301 " scheme, password_type, possible_usernames, times_used) " 307 " scheme, password_type, possible_usernames, times_used, form_data) "
302 "VALUES " 308 "VALUES "
303 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); 309 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
304 s.BindString(COLUMN_ORIGIN_URL, form.origin.spec()); 310 s.BindString(COLUMN_ORIGIN_URL, form.origin.spec());
305 s.BindString(COLUMN_ACTION_URL, form.action.spec()); 311 s.BindString(COLUMN_ACTION_URL, form.action.spec());
306 s.BindString16(COLUMN_USERNAME_ELEMENT, form.username_element); 312 s.BindString16(COLUMN_USERNAME_ELEMENT, form.username_element);
307 s.BindString16(COLUMN_USERNAME_VALUE, form.username_value); 313 s.BindString16(COLUMN_USERNAME_VALUE, form.username_value);
308 s.BindString16(COLUMN_PASSWORD_ELEMENT, form.password_element); 314 s.BindString16(COLUMN_PASSWORD_ELEMENT, form.password_element);
309 s.BindBlob(COLUMN_PASSWORD_VALUE, encrypted_password.data(), 315 s.BindBlob(COLUMN_PASSWORD_VALUE, encrypted_password.data(),
310 static_cast<int>(encrypted_password.length())); 316 static_cast<int>(encrypted_password.length()));
311 s.BindString16(COLUMN_SUBMIT_ELEMENT, form.submit_element); 317 s.BindString16(COLUMN_SUBMIT_ELEMENT, form.submit_element);
312 s.BindString(COLUMN_SIGNON_REALM, form.signon_realm); 318 s.BindString(COLUMN_SIGNON_REALM, form.signon_realm);
313 s.BindInt(COLUMN_SSL_VALID, form.ssl_valid); 319 s.BindInt(COLUMN_SSL_VALID, form.ssl_valid);
314 s.BindInt(COLUMN_PREFERRED, form.preferred); 320 s.BindInt(COLUMN_PREFERRED, form.preferred);
315 s.BindInt64(COLUMN_DATE_CREATED, form.date_created.ToTimeT()); 321 s.BindInt64(COLUMN_DATE_CREATED, form.date_created.ToTimeT());
316 s.BindInt(COLUMN_BLACKLISTED_BY_USER, form.blacklisted_by_user); 322 s.BindInt(COLUMN_BLACKLISTED_BY_USER, form.blacklisted_by_user);
317 s.BindInt(COLUMN_SCHEME, form.scheme); 323 s.BindInt(COLUMN_SCHEME, form.scheme);
318 s.BindInt(COLUMN_PASSWORD_TYPE, form.type); 324 s.BindInt(COLUMN_PASSWORD_TYPE, form.type);
319 Pickle pickle = SerializeVector(form.other_possible_usernames); 325 Pickle usernames_pickle = SerializeVector(form.other_possible_usernames);
320 s.BindBlob(COLUMN_POSSIBLE_USERNAMES, pickle.data(), pickle.size()); 326 s.BindBlob(COLUMN_POSSIBLE_USERNAMES,
327 usernames_pickle.data(),
328 usernames_pickle.size());
321 s.BindInt(COLUMN_TIMES_USED, form.times_used); 329 s.BindInt(COLUMN_TIMES_USED, form.times_used);
330 Pickle form_data_pickle;
331 autofill::SerializeFormData(form.form_data, &form_data_pickle);
332 s.BindBlob(COLUMN_FORM_DATA,
333 form_data_pickle.data(),
334 form_data_pickle.size());
322 335
323 return s.Run(); 336 return s.Run();
324 } 337 }
325 338
326 bool LoginDatabase::UpdateLogin(const PasswordForm& form, int* items_changed) { 339 bool LoginDatabase::UpdateLogin(const PasswordForm& form, int* items_changed) {
327 std::string encrypted_password; 340 std::string encrypted_password;
328 if (!EncryptedString(form.password_value, &encrypted_password)) 341 if (!EncryptedString(form.password_value, &encrypted_password))
329 return false; 342 return false;
330 343
331 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, 344 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 DCHECK((scheme_int >= 0) && (scheme_int <= PasswordForm::SCHEME_OTHER)); 437 DCHECK((scheme_int >= 0) && (scheme_int <= PasswordForm::SCHEME_OTHER));
425 form->scheme = static_cast<PasswordForm::Scheme>(scheme_int); 438 form->scheme = static_cast<PasswordForm::Scheme>(scheme_int);
426 int type_int = s.ColumnInt(COLUMN_PASSWORD_TYPE); 439 int type_int = s.ColumnInt(COLUMN_PASSWORD_TYPE);
427 DCHECK(type_int >= 0 && type_int <= PasswordForm::TYPE_GENERATED); 440 DCHECK(type_int >= 0 && type_int <= PasswordForm::TYPE_GENERATED);
428 form->type = static_cast<PasswordForm::Type>(type_int); 441 form->type = static_cast<PasswordForm::Type>(type_int);
429 Pickle pickle( 442 Pickle pickle(
430 static_cast<const char*>(s.ColumnBlob(COLUMN_POSSIBLE_USERNAMES)), 443 static_cast<const char*>(s.ColumnBlob(COLUMN_POSSIBLE_USERNAMES)),
431 s.ColumnByteLength(COLUMN_POSSIBLE_USERNAMES)); 444 s.ColumnByteLength(COLUMN_POSSIBLE_USERNAMES));
432 form->other_possible_usernames = DeserializeVector(pickle); 445 form->other_possible_usernames = DeserializeVector(pickle);
433 form->times_used = s.ColumnInt(COLUMN_TIMES_USED); 446 form->times_used = s.ColumnInt(COLUMN_TIMES_USED);
447 Pickle form_data_pickle(
448 static_cast<const char*>(s.ColumnBlob(COLUMN_FORM_DATA)),
449 s.ColumnByteLength(COLUMN_FORM_DATA));
450 PickleIterator form_data_iter(form_data_pickle);
451 autofill::DeserializeFormData(&form_data_iter, &form->form_data);
434 return true; 452 return true;
435 } 453 }
436 454
437 bool LoginDatabase::GetLogins(const PasswordForm& form, 455 bool LoginDatabase::GetLogins(const PasswordForm& form,
438 std::vector<PasswordForm*>* forms) const { 456 std::vector<PasswordForm*>* forms) const {
439 DCHECK(forms); 457 DCHECK(forms);
440 // You *must* change LoginTableColumns if this query changes. 458 // You *must* change LoginTableColumns if this query changes.
441 const std::string sql_query = "SELECT origin_url, action_url, " 459 const std::string sql_query = "SELECT origin_url, action_url, "
442 "username_element, username_value, " 460 "username_element, username_value, "
443 "password_element, password_value, submit_element, " 461 "password_element, password_value, submit_element, "
444 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " 462 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
445 "scheme, password_type, possible_usernames, times_used " 463 "scheme, password_type, possible_usernames, times_used, form_data "
446 "FROM logins WHERE signon_realm == ? "; 464 "FROM logins WHERE signon_realm == ? ";
447 sql::Statement s; 465 sql::Statement s;
448 const GURL signon_realm(form.signon_realm); 466 const GURL signon_realm(form.signon_realm);
449 std::string registered_domain = GetRegistryControlledDomain(signon_realm); 467 std::string registered_domain = GetRegistryControlledDomain(signon_realm);
450 if (public_suffix_domain_matching_ && 468 if (public_suffix_domain_matching_ &&
451 ShouldPSLDomainMatchingApply(registered_domain)) { 469 ShouldPSLDomainMatchingApply(registered_domain)) {
452 // We are extending the original SQL query with one that includes more 470 // We are extending the original SQL query with one that includes more
453 // possible matches based on public suffix domain matching. Using a regexp 471 // possible matches based on public suffix domain matching. Using a regexp
454 // here is just an optimization to not have to parse all the stored entries 472 // here is just an optimization to not have to parse all the stored entries
455 // in the |logins| table. The result (scheme, domain and port) is verified 473 // in the |logins| table. The result (scheme, domain and port) is verified
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 bool LoginDatabase::GetLoginsCreatedBetween( 532 bool LoginDatabase::GetLoginsCreatedBetween(
515 const base::Time begin, 533 const base::Time begin,
516 const base::Time end, 534 const base::Time end,
517 std::vector<autofill::PasswordForm*>* forms) const { 535 std::vector<autofill::PasswordForm*>* forms) const {
518 DCHECK(forms); 536 DCHECK(forms);
519 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, 537 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
520 "SELECT origin_url, action_url, " 538 "SELECT origin_url, action_url, "
521 "username_element, username_value, " 539 "username_element, username_value, "
522 "password_element, password_value, submit_element, " 540 "password_element, password_value, submit_element, "
523 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " 541 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
524 "scheme, password_type, possible_usernames, times_used " 542 "scheme, password_type, possible_usernames, times_used, form_data "
525 "FROM logins WHERE date_created >= ? AND date_created < ?" 543 "FROM logins WHERE date_created >= ? AND date_created < ?"
526 "ORDER BY origin_url")); 544 "ORDER BY origin_url"));
527 s.BindInt64(0, begin.ToTimeT()); 545 s.BindInt64(0, begin.ToTimeT());
528 s.BindInt64(1, end.is_null() ? std::numeric_limits<int64>::max() 546 s.BindInt64(1, end.is_null() ? std::numeric_limits<int64>::max()
529 : end.ToTimeT()); 547 : end.ToTimeT());
530 548
531 while (s.Step()) { 549 while (s.Step()) {
532 scoped_ptr<PasswordForm> new_form(new PasswordForm()); 550 scoped_ptr<PasswordForm> new_form(new PasswordForm());
533 if (!InitPasswordFormFromStatement(new_form.get(), s)) 551 if (!InitPasswordFormFromStatement(new_form.get(), s))
534 return false; 552 return false;
(...skipping 14 matching lines...) Expand all
549 567
550 bool LoginDatabase::GetAllLoginsWithBlacklistSetting( 568 bool LoginDatabase::GetAllLoginsWithBlacklistSetting(
551 bool blacklisted, std::vector<PasswordForm*>* forms) const { 569 bool blacklisted, std::vector<PasswordForm*>* forms) const {
552 DCHECK(forms); 570 DCHECK(forms);
553 // You *must* change LoginTableColumns if this query changes. 571 // You *must* change LoginTableColumns if this query changes.
554 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, 572 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
555 "SELECT origin_url, action_url, " 573 "SELECT origin_url, action_url, "
556 "username_element, username_value, " 574 "username_element, username_value, "
557 "password_element, password_value, submit_element, " 575 "password_element, password_value, submit_element, "
558 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " 576 "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, "
559 "scheme, password_type, possible_usernames, times_used " 577 "scheme, password_type, possible_usernames, times_used, form_data "
560 "FROM logins WHERE blacklisted_by_user == ? " 578 "FROM logins WHERE blacklisted_by_user == ? "
561 "ORDER BY origin_url")); 579 "ORDER BY origin_url"));
562 s.BindInt(0, blacklisted ? 1 : 0); 580 s.BindInt(0, blacklisted ? 1 : 0);
563 581
564 while (s.Step()) { 582 while (s.Step()) {
565 scoped_ptr<PasswordForm> new_form(new PasswordForm()); 583 scoped_ptr<PasswordForm> new_form(new PasswordForm());
566 if (!InitPasswordFormFromStatement(new_form.get(), s)) 584 if (!InitPasswordFormFromStatement(new_form.get(), s))
567 return false; 585 return false;
568 forms->push_back(new_form.release()); 586 forms->push_back(new_form.release());
569 } 587 }
(...skipping 19 matching lines...) Expand all
589 std::vector<string16> LoginDatabase::DeserializeVector(const Pickle& p) const { 607 std::vector<string16> LoginDatabase::DeserializeVector(const Pickle& p) const {
590 std::vector<string16> ret; 608 std::vector<string16> ret;
591 string16 str; 609 string16 str;
592 610
593 PickleIterator iterator(p); 611 PickleIterator iterator(p);
594 while (iterator.ReadString16(&str)) { 612 while (iterator.ReadString16(&str)) {
595 ret.push_back(str); 613 ret.push_back(str);
596 } 614 }
597 return ret; 615 return ret;
598 } 616 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/password_manager/login_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698