Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/net/sqlite_server_bound_cert_store.h" | 5 #include "chrome/browser/net/sqlite_server_bound_cert_store.h" |
| 6 | 6 |
| 7 #include <list> | 7 #include <list> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/file_path.h" | 11 #include "base/file_path.h" |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 16 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
| 17 #include "base/threading/thread_restrictions.h" | 17 #include "base/threading/thread_restrictions.h" |
| 18 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" | 18 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" |
| 19 #include "chrome/browser/net/clear_on_exit_policy.h" | |
| 19 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 20 #include "net/base/ssl_client_cert_type.h" | 21 #include "net/base/ssl_client_cert_type.h" |
| 21 #include "net/base/x509_certificate.h" | 22 #include "net/base/x509_certificate.h" |
| 22 #include "sql/meta_table.h" | 23 #include "sql/meta_table.h" |
| 23 #include "sql/statement.h" | 24 #include "sql/statement.h" |
| 24 #include "sql/transaction.h" | 25 #include "sql/transaction.h" |
| 25 | 26 |
| 26 using content::BrowserThread; | 27 using content::BrowserThread; |
| 27 | 28 |
| 28 // This class is designed to be shared between any calling threads and the | 29 // This class is designed to be shared between any calling threads and the |
| 29 // database thread. It batches operations and commits them on a timer. | 30 // database thread. It batches operations and commits them on a timer. |
| 30 class SQLiteServerBoundCertStore::Backend | 31 class SQLiteServerBoundCertStore::Backend |
| 31 : public base::RefCountedThreadSafe<SQLiteServerBoundCertStore::Backend> { | 32 : public base::RefCountedThreadSafe<SQLiteServerBoundCertStore::Backend> { |
| 32 public: | 33 public: |
| 33 explicit Backend(const FilePath& path) | 34 Backend(const FilePath& path, ClearOnExitPolicy* clear_on_exit_policy) |
| 34 : path_(path), | 35 : path_(path), |
| 35 db_(NULL), | 36 db_(NULL), |
| 36 num_pending_(0), | 37 num_pending_(0), |
| 37 clear_local_state_on_exit_(false) { | 38 clear_local_state_on_exit_(false), |
| 39 clear_on_exit_policy_(clear_on_exit_policy) { | |
| 38 } | 40 } |
| 39 | 41 |
| 40 // Creates or load the SQLite database. | 42 // Creates or load the SQLite database. |
| 41 bool Load( | 43 bool Load( |
| 42 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs); | 44 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs); |
| 43 | 45 |
| 44 // Batch a server bound cert addition. | 46 // Batch a server bound cert addition. |
| 45 void AddServerBoundCert( | 47 void AddServerBoundCert( |
| 46 const net::DefaultServerBoundCertStore::ServerBoundCert& cert); | 48 const net::DefaultServerBoundCertStore::ServerBoundCert& cert); |
| 47 | 49 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 private: | 97 private: |
| 96 // Batch a server bound cert operation (add or delete) | 98 // Batch a server bound cert operation (add or delete) |
| 97 void BatchOperation( | 99 void BatchOperation( |
| 98 PendingOperation::OperationType op, | 100 PendingOperation::OperationType op, |
| 99 const net::DefaultServerBoundCertStore::ServerBoundCert& cert); | 101 const net::DefaultServerBoundCertStore::ServerBoundCert& cert); |
| 100 // Commit our pending operations to the database. | 102 // Commit our pending operations to the database. |
| 101 void Commit(); | 103 void Commit(); |
| 102 // Close() executed on the background thread. | 104 // Close() executed on the background thread. |
| 103 void InternalBackgroundClose(); | 105 void InternalBackgroundClose(); |
| 104 | 106 |
| 107 void DeleteCertificatesOnShutdown(); | |
| 108 | |
| 105 FilePath path_; | 109 FilePath path_; |
| 106 scoped_ptr<sql::Connection> db_; | 110 scoped_ptr<sql::Connection> db_; |
| 107 sql::MetaTable meta_table_; | 111 sql::MetaTable meta_table_; |
| 108 | 112 |
| 109 typedef std::list<PendingOperation*> PendingOperationsList; | 113 typedef std::list<PendingOperation*> PendingOperationsList; |
| 110 PendingOperationsList pending_; | 114 PendingOperationsList pending_; |
| 111 PendingOperationsList::size_type num_pending_; | 115 PendingOperationsList::size_type num_pending_; |
| 112 // True if the persistent store should be deleted upon destruction. | 116 // True if the persistent store should be deleted upon destruction. |
| 113 bool clear_local_state_on_exit_; | 117 bool clear_local_state_on_exit_; |
| 114 // Guard |pending_|, |num_pending_| and |clear_local_state_on_exit_|. | 118 // Guard |pending_|, |num_pending_| and |clear_local_state_on_exit_|. |
| 115 base::Lock lock_; | 119 base::Lock lock_; |
| 116 | 120 |
| 121 scoped_refptr<ClearOnExitPolicy> clear_on_exit_policy_; | |
| 122 | |
| 117 DISALLOW_COPY_AND_ASSIGN(Backend); | 123 DISALLOW_COPY_AND_ASSIGN(Backend); |
| 118 }; | 124 }; |
| 119 | 125 |
| 120 // Version number of the database. | 126 // Version number of the database. |
| 121 static const int kCurrentVersionNumber = 4; | 127 static const int kCurrentVersionNumber = 4; |
| 122 static const int kCompatibleVersionNumber = 1; | 128 static const int kCompatibleVersionNumber = 1; |
| 123 | 129 |
| 124 namespace { | 130 namespace { |
| 125 | 131 |
| 126 // Initializes the certs table, returning true on success. | 132 // Initializes the certs table, returning true on success. |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 BrowserThread::PostTask( | 462 BrowserThread::PostTask( |
| 457 BrowserThread::DB, FROM_HERE, | 463 BrowserThread::DB, FROM_HERE, |
| 458 base::Bind(&Backend::InternalBackgroundClose, this)); | 464 base::Bind(&Backend::InternalBackgroundClose, this)); |
| 459 } | 465 } |
| 460 | 466 |
| 461 void SQLiteServerBoundCertStore::Backend::InternalBackgroundClose() { | 467 void SQLiteServerBoundCertStore::Backend::InternalBackgroundClose() { |
| 462 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 463 // Commit any pending operations | 469 // Commit any pending operations |
| 464 Commit(); | 470 Commit(); |
| 465 | 471 |
| 472 if (!clear_local_state_on_exit_ && clear_on_exit_policy_.get() && | |
| 473 clear_on_exit_policy_->HasClearOnExitOrigins()) { | |
| 474 DeleteCertificatesOnShutdown(); | |
| 475 } | |
| 476 | |
| 466 db_.reset(); | 477 db_.reset(); |
| 467 | 478 |
| 468 if (clear_local_state_on_exit_) | 479 if (clear_local_state_on_exit_) |
| 469 file_util::Delete(path_, false); | 480 file_util::Delete(path_, false); |
| 470 } | 481 } |
| 471 | 482 |
| 483 void SQLiteServerBoundCertStore::Backend::DeleteCertificatesOnShutdown() { | |
| 484 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | |
| 485 | |
| 486 if (!db_.get()) | |
| 487 return; | |
| 488 | |
| 489 sql::Statement select_smt(db_->GetCachedStatement( | |
|
erikwright (departed)
2012/05/29 13:09:03
Can you comment on the difference between the cook
jochen (gone - plz use gerrit)
2012/05/30 11:28:42
I expect less data in the store (there's only one
| |
| 490 SQL_FROM_HERE, "SELECT origin FROM origin_bound_certs")); | |
| 491 if (!select_smt.is_valid()) { | |
| 492 LOG(WARNING) << "Unable to delete certificates on shutdown."; | |
| 493 return; | |
| 494 } | |
| 495 | |
| 496 std::vector<std::string> origins_to_delete; | |
| 497 while (select_smt.Step()) { | |
| 498 std::string origin = select_smt.ColumnString(0); | |
| 499 if (!clear_on_exit_policy_->ShouldClearOriginOnExit(origin, true)) | |
| 500 continue; | |
| 501 origins_to_delete.push_back(origin); | |
| 502 } | |
| 503 | |
| 504 if (origins_to_delete.empty()) | |
| 505 return; | |
| 506 | |
| 507 sql::Statement del_smt(db_->GetCachedStatement( | |
| 508 SQL_FROM_HERE, "DELETE FROM origin_bound_certs WHERE origin=?")); | |
| 509 if (!del_smt.is_valid()) { | |
| 510 LOG(WARNING) << "Unable to delete certificates on shutdown."; | |
| 511 return; | |
| 512 } | |
| 513 | |
| 514 sql::Transaction transaction(db_.get()); | |
| 515 if (!transaction.Begin()) { | |
| 516 LOG(WARNING) << "Unable to delete certificates on shutdown."; | |
| 517 return; | |
| 518 } | |
| 519 | |
| 520 for (unsigned i = 0; i < origins_to_delete.size(); ++i) { | |
| 521 del_smt.Reset(true); | |
| 522 del_smt.BindString(0, origins_to_delete[i]); | |
| 523 if (!del_smt.Run()) | |
| 524 NOTREACHED() << "Could not delete a certificate from the DB."; | |
| 525 } | |
| 526 | |
| 527 if (!transaction.Commit()) | |
| 528 LOG(WARNING) << "Unable to delete certificates on shutdown."; | |
| 529 } | |
| 530 | |
| 472 void SQLiteServerBoundCertStore::Backend::SetClearLocalStateOnExit( | 531 void SQLiteServerBoundCertStore::Backend::SetClearLocalStateOnExit( |
| 473 bool clear_local_state) { | 532 bool clear_local_state) { |
| 474 base::AutoLock locked(lock_); | 533 base::AutoLock locked(lock_); |
| 475 clear_local_state_on_exit_ = clear_local_state; | 534 clear_local_state_on_exit_ = clear_local_state; |
| 476 } | 535 } |
| 477 | 536 |
| 478 SQLiteServerBoundCertStore::SQLiteServerBoundCertStore(const FilePath& path) | 537 SQLiteServerBoundCertStore::SQLiteServerBoundCertStore( |
| 479 : backend_(new Backend(path)) { | 538 const FilePath& path, |
| 539 ClearOnExitPolicy* clear_on_exit_policy) | |
| 540 : backend_(new Backend(path, clear_on_exit_policy)) { | |
| 480 } | 541 } |
| 481 | 542 |
| 482 bool SQLiteServerBoundCertStore::Load( | 543 bool SQLiteServerBoundCertStore::Load( |
| 483 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs) { | 544 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs) { |
| 484 return backend_->Load(certs); | 545 return backend_->Load(certs); |
| 485 } | 546 } |
| 486 | 547 |
| 487 void SQLiteServerBoundCertStore::AddServerBoundCert( | 548 void SQLiteServerBoundCertStore::AddServerBoundCert( |
| 488 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) { | 549 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) { |
| 489 if (backend_.get()) | 550 if (backend_.get()) |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 510 } | 571 } |
| 511 | 572 |
| 512 SQLiteServerBoundCertStore::~SQLiteServerBoundCertStore() { | 573 SQLiteServerBoundCertStore::~SQLiteServerBoundCertStore() { |
| 513 if (backend_.get()) { | 574 if (backend_.get()) { |
| 514 backend_->Close(); | 575 backend_->Close(); |
| 515 // Release our reference, it will probably still have a reference if the | 576 // Release our reference, it will probably still have a reference if the |
| 516 // background thread has not run Close() yet. | 577 // background thread has not run Close() yet. |
| 517 backend_ = NULL; | 578 backend_ = NULL; |
| 518 } | 579 } |
| 519 } | 580 } |
| OLD | NEW |