1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/safe_browsing/test_safe_browsing_database_helper.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/location.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/strings/stringprintf.h"
15 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
16 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
17 #include "components/safe_browsing/core/db/v4_database.h"
18 #include "components/safe_browsing/core/db/v4_protocol_manager_util.h"
19 #include "components/safe_browsing/core/db/v4_test_util.h"
20 #include "components/security_interstitials/core/unsafe_resource.h"
21
22 namespace {
23
24 // UI manager that never actually shows any interstitials, but emulates as if
25 // the user chose to proceed through them.
26 class FakeSafeBrowsingUIManager
27 : public safe_browsing::TestSafeBrowsingUIManager {
28 public:
FakeSafeBrowsingUIManager()29 FakeSafeBrowsingUIManager() {}
30
31 protected:
~FakeSafeBrowsingUIManager()32 ~FakeSafeBrowsingUIManager() override {}
33
DisplayBlockingPage(const UnsafeResource & resource)34 void DisplayBlockingPage(const UnsafeResource& resource) override {
35 resource.callback_thread->PostTask(
36 FROM_HERE, base::BindOnce(resource.callback, true /* proceed */,
37 true /* showed_interstitial */));
38 }
39
40 private:
41 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingUIManager);
42 };
43
44 } // namespace
45
46 // This class automatically inserts lists into the store map when initializing
47 // the test database.
48 class InsertingDatabaseFactory : public safe_browsing::TestV4DatabaseFactory {
49 public:
InsertingDatabaseFactory(safe_browsing::TestV4StoreFactory * store_factory,const std::vector<safe_browsing::ListIdentifier> & lists_to_insert)50 explicit InsertingDatabaseFactory(
51 safe_browsing::TestV4StoreFactory* store_factory,
52 const std::vector<safe_browsing::ListIdentifier>& lists_to_insert)
53 : lists_to_insert_(lists_to_insert), store_factory_(store_factory) {}
54
Create(const scoped_refptr<base::SequencedTaskRunner> & db_task_runner,std::unique_ptr<safe_browsing::StoreMap> store_map)55 std::unique_ptr<safe_browsing::V4Database> Create(
56 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
57 std::unique_ptr<safe_browsing::StoreMap> store_map) override {
58 const base::FilePath base_store_path(FILE_PATH_LITERAL("UrlDb.store"));
59 for (const auto& id : lists_to_insert_) {
60 if (!base::Contains(*store_map, id)) {
61 const base::FilePath store_path =
62 base_store_path.InsertBeforeExtensionASCII(base::StringPrintf(
63 " (%d)", base::GetUniquePathNumber(base_store_path)));
64 (*store_map)[id] =
65 store_factory_->CreateV4Store(db_task_runner, store_path);
66 }
67 }
68
69 for (const auto& it : *store_map)
70 lists_.push_back(it.first);
71 return safe_browsing::TestV4DatabaseFactory::Create(db_task_runner,
72 std::move(store_map));
73 }
74
lists()75 const std::vector<safe_browsing::ListIdentifier> lists() { return lists_; }
76
77 private:
78 std::vector<safe_browsing::ListIdentifier> lists_to_insert_;
79 std::vector<safe_browsing::ListIdentifier> lists_;
80 safe_browsing::TestV4StoreFactory* store_factory_;
81 };
82
TestSafeBrowsingDatabaseHelper()83 TestSafeBrowsingDatabaseHelper::TestSafeBrowsingDatabaseHelper()
84 : TestSafeBrowsingDatabaseHelper(
85 std::make_unique<
86 safe_browsing::TestV4GetHashProtocolManagerFactory>(),
87 std::vector<safe_browsing::ListIdentifier>()) {}
88
TestSafeBrowsingDatabaseHelper(std::unique_ptr<safe_browsing::TestV4GetHashProtocolManagerFactory> v4_get_hash_factory,std::vector<safe_browsing::ListIdentifier> lists_to_insert)89 TestSafeBrowsingDatabaseHelper::TestSafeBrowsingDatabaseHelper(
90 std::unique_ptr<safe_browsing::TestV4GetHashProtocolManagerFactory>
91 v4_get_hash_factory,
92 std::vector<safe_browsing::ListIdentifier> lists_to_insert)
93 : v4_get_hash_factory_(v4_get_hash_factory.get()) {
94 sb_factory_ =
95 std::make_unique<safe_browsing::TestSafeBrowsingServiceFactory>();
96 sb_factory_->SetTestUIManager(new FakeSafeBrowsingUIManager());
97 sb_factory_->UseV4LocalDatabaseManager();
98 safe_browsing::SafeBrowsingService::RegisterFactory(sb_factory_.get());
99
100 auto store_factory = std::make_unique<safe_browsing::TestV4StoreFactory>();
101 auto v4_db_factory = std::make_unique<InsertingDatabaseFactory>(
102 store_factory.get(), lists_to_insert);
103
104 v4_db_factory_ = v4_db_factory.get();
105
106 safe_browsing::V4Database::RegisterStoreFactoryForTest(
107 std::move(store_factory));
108 safe_browsing::V4Database::RegisterDatabaseFactoryForTest(
109 std::move(v4_db_factory));
110
111 if (v4_get_hash_factory) {
112 safe_browsing::V4GetHashProtocolManager::RegisterFactory(
113 std::move(v4_get_hash_factory));
114 }
115 }
116
~TestSafeBrowsingDatabaseHelper()117 TestSafeBrowsingDatabaseHelper::~TestSafeBrowsingDatabaseHelper() {
118 safe_browsing::V4GetHashProtocolManager::RegisterFactory(nullptr);
119 safe_browsing::V4Database::RegisterDatabaseFactoryForTest(nullptr);
120 safe_browsing::V4Database::RegisterStoreFactoryForTest(nullptr);
121 safe_browsing::SafeBrowsingService::RegisterFactory(nullptr);
122 }
123
AddFullHashToDbAndFullHashCache(const GURL & bad_url,const safe_browsing::ListIdentifier & list_id,const safe_browsing::ThreatMetadata & threat_metadata)124 void TestSafeBrowsingDatabaseHelper::AddFullHashToDbAndFullHashCache(
125 const GURL& bad_url,
126 const safe_browsing::ListIdentifier& list_id,
127 const safe_browsing::ThreatMetadata& threat_metadata) {
128 // Should only be called if we are mocking the v4 hash factory.
129 DCHECK(v4_get_hash_factory_);
130
131 LocallyMarkPrefixAsBad(bad_url, list_id);
132
133 safe_browsing::FullHashInfo full_hash_info =
134 GetFullHashInfoWithMetadata(bad_url, list_id, threat_metadata);
135 v4_get_hash_factory_->AddToFullHashCache(full_hash_info);
136 }
137
LocallyMarkPrefixAsBad(const GURL & url,const safe_browsing::ListIdentifier & list_id)138 void TestSafeBrowsingDatabaseHelper::LocallyMarkPrefixAsBad(
139 const GURL& url,
140 const safe_browsing::ListIdentifier& list_id) {
141 safe_browsing::FullHash full_hash =
142 safe_browsing::V4ProtocolManagerUtil::GetFullHash(url);
143 v4_db_factory_->MarkPrefixAsBad(list_id, full_hash);
144 }
145
HasListSynced(const safe_browsing::ListIdentifier & list_id)146 bool TestSafeBrowsingDatabaseHelper::HasListSynced(
147 const safe_browsing::ListIdentifier& list_id) {
148 return base::Contains(v4_db_factory_->lists(), list_id);
149 }
150