| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/password_manager/core/browser/login_database.h" | 5 #include "components/password_manager/core/browser/login_database.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/debug/dump_without_crashing.h" | |
| 12 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
| 13 #include "base/logging.h" | 12 #include "base/logging.h" |
| 14 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 15 #include "base/pickle.h" | 14 #include "base/pickle.h" |
| 16 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 17 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 18 #include "components/autofill/core/common/password_form.h" | 17 #include "components/autofill/core/common/password_form.h" |
| 19 #include "google_apis/gaia/gaia_auth_util.h" | 18 #include "google_apis/gaia/gaia_auth_util.h" |
| 20 #include "google_apis/gaia/gaia_urls.h" | 19 #include "google_apis/gaia/gaia_urls.h" |
| 21 #include "sql/connection.h" | 20 #include "sql/connection.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 s->BindString(COLUMN_AVATAR_URL, form.avatar_url.spec()); | 110 s->BindString(COLUMN_AVATAR_URL, form.avatar_url.spec()); |
| 112 s->BindString(COLUMN_FEDERATION_URL, form.federation_url.spec()); | 111 s->BindString(COLUMN_FEDERATION_URL, form.federation_url.spec()); |
| 113 s->BindInt(COLUMN_IS_ZERO_CLICK, form.is_zero_click); | 112 s->BindInt(COLUMN_IS_ZERO_CLICK, form.is_zero_click); |
| 114 } | 113 } |
| 115 | 114 |
| 116 void AddCallback(int err, sql::Statement* /*stmt*/) { | 115 void AddCallback(int err, sql::Statement* /*stmt*/) { |
| 117 if (err == 19 /*SQLITE_CONSTRAINT*/) | 116 if (err == 19 /*SQLITE_CONSTRAINT*/) |
| 118 DLOG(WARNING) << "LoginDatabase::AddLogin updated an existing form"; | 117 DLOG(WARNING) << "LoginDatabase::AddLogin updated an existing form"; |
| 119 } | 118 } |
| 120 | 119 |
| 121 // http://crbug.com/404012. Let's see where the empty fields come from. | |
| 122 void CheckForEmptyUsernameAndPassword(const PasswordForm& form) { | |
| 123 if (form.username_value.empty() && form.password_value.empty()) | |
| 124 base::debug::DumpWithoutCrashing(); | |
| 125 } | |
| 126 | |
| 127 } // namespace | 120 } // namespace |
| 128 | 121 |
| 129 LoginDatabase::LoginDatabase() { | 122 LoginDatabase::LoginDatabase() { |
| 130 } | 123 } |
| 131 | 124 |
| 132 LoginDatabase::~LoginDatabase() { | 125 LoginDatabase::~LoginDatabase() { |
| 133 } | 126 } |
| 134 | 127 |
| 135 bool LoginDatabase::Init(const base::FilePath& db_path) { | 128 bool LoginDatabase::Init(const base::FilePath& db_path) { |
| 136 // Set pragmas for a small, private database (based on WebDatabase). | 129 // Set pragmas for a small, private database (based on WebDatabase). |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 break; | 345 break; |
| 353 } | 346 } |
| 354 } | 347 } |
| 355 } | 348 } |
| 356 UMA_HISTOGRAM_ENUMERATION("PasswordManager.SyncingAccountState", | 349 UMA_HISTOGRAM_ENUMERATION("PasswordManager.SyncingAccountState", |
| 357 2 * sync_username.empty() + syncing_account_saved, | 350 2 * sync_username.empty() + syncing_account_saved, |
| 358 4); | 351 4); |
| 359 } | 352 } |
| 360 | 353 |
| 361 PasswordStoreChangeList LoginDatabase::AddLogin(const PasswordForm& form) { | 354 PasswordStoreChangeList LoginDatabase::AddLogin(const PasswordForm& form) { |
| 362 CheckForEmptyUsernameAndPassword(form); | |
| 363 PasswordStoreChangeList list; | 355 PasswordStoreChangeList list; |
| 364 std::string encrypted_password; | 356 std::string encrypted_password; |
| 365 if (EncryptedString(form.password_value, &encrypted_password) != | 357 if (EncryptedString(form.password_value, &encrypted_password) != |
| 366 ENCRYPTION_RESULT_SUCCESS) | 358 ENCRYPTION_RESULT_SUCCESS) |
| 367 return list; | 359 return list; |
| 368 | 360 |
| 369 // You *must* change LoginTableColumns if this query changes. | 361 // You *must* change LoginTableColumns if this query changes. |
| 370 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, | 362 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, |
| 371 "INSERT INTO logins " | 363 "INSERT INTO logins " |
| 372 "(origin_url, action_url, username_element, username_value, " | 364 "(origin_url, action_url, username_element, username_value, " |
| (...skipping 23 matching lines...) Expand all Loading... |
| 396 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); | 388 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); |
| 397 BindAddStatement(form, encrypted_password, &s); | 389 BindAddStatement(form, encrypted_password, &s); |
| 398 if (s.Run()) { | 390 if (s.Run()) { |
| 399 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); | 391 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); |
| 400 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); | 392 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); |
| 401 } | 393 } |
| 402 return list; | 394 return list; |
| 403 } | 395 } |
| 404 | 396 |
| 405 PasswordStoreChangeList LoginDatabase::UpdateLogin(const PasswordForm& form) { | 397 PasswordStoreChangeList LoginDatabase::UpdateLogin(const PasswordForm& form) { |
| 406 CheckForEmptyUsernameAndPassword(form); | |
| 407 std::string encrypted_password; | 398 std::string encrypted_password; |
| 408 if (EncryptedString(form.password_value, &encrypted_password) != | 399 if (EncryptedString(form.password_value, &encrypted_password) != |
| 409 ENCRYPTION_RESULT_SUCCESS) | 400 ENCRYPTION_RESULT_SUCCESS) |
| 410 return PasswordStoreChangeList(); | 401 return PasswordStoreChangeList(); |
| 411 | 402 |
| 412 // Replacement is necessary to deal with updating imported credentials. See | 403 // Replacement is necessary to deal with updating imported credentials. See |
| 413 // crbug.com/349138 for details. | 404 // crbug.com/349138 for details. |
| 414 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, | 405 sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, |
| 415 "UPDATE OR REPLACE logins SET " | 406 "UPDATE OR REPLACE logins SET " |
| 416 "action_url = ?, " | 407 "action_url = ?, " |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 | 763 |
| 773 bool LoginDatabase::DeleteAndRecreateDatabaseFile() { | 764 bool LoginDatabase::DeleteAndRecreateDatabaseFile() { |
| 774 DCHECK(db_.is_open()); | 765 DCHECK(db_.is_open()); |
| 775 meta_table_.Reset(); | 766 meta_table_.Reset(); |
| 776 db_.Close(); | 767 db_.Close(); |
| 777 sql::Connection::Delete(db_path_); | 768 sql::Connection::Delete(db_path_); |
| 778 return Init(db_path_); | 769 return Init(db_path_); |
| 779 } | 770 } |
| 780 | 771 |
| 781 } // namespace password_manager | 772 } // namespace password_manager |
| OLD | NEW |