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

Side by Side Diff: chrome/browser/extensions/activity_log/ad_network_database.cc

Issue 242303002: Add implementation for Ad Networks Database (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 8 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
OLDNEW
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 "chrome/browser/extensions/activity_log/ad_network_database.h" 5 #include "chrome/browser/extensions/activity_log/ad_network_database.h"
6 6
7 #include "base/basictypes.h"
7 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
9 #include "base/memory/ref_counted_memory.h"
10 #include "crypto/secure_hash.h"
11 #include "crypto/sha2.h"
12 #include "grit/browser_resources.h"
13 #include "ui/base/resource/resource_bundle.h"
14 #include "url/gurl.h"
8 15
9 namespace extensions { 16 namespace extensions {
10 17
11 namespace { 18 namespace {
12 19
20 // We use a hash size of 8 for these for three reasons.
21 // 1. It saves us a bit on space, and, since we have to store these in memory
22 // (reading from disk would be far too slow because these checks are
23 // performed synchronously), that space is important.
24 // 2. Since we don't store full hashes, reconstructing the list is more
25 // difficult. This may mean we get a few incorrect hits, but the security is
26 // worth the (very small) amount of noise.
27 // 3. It fits nicely into a int64.
28 const size_t kUrlHashSize = 8u;
29 COMPILE_ASSERT(kUrlHashSize <= sizeof(int64), url_hashes_must_fit_into_a_int64);
30
31 const size_t kChecksumHashSize = 32u;
32
33 class AdNetworkDatabaseImpl : public AdNetworkDatabase {
34 public:
35 AdNetworkDatabaseImpl();
36 virtual ~AdNetworkDatabaseImpl();
37
38 private:
39 // AdNetworkDatabase implementation.
40 virtual bool IsEnabled() const OVERRIDE { return enabled_; }
41 virtual bool IsAdNetwork(const GURL& url) const OVERRIDE;
42
43 // Initialize the AdNetworkDatabase. This means initializing the set of
44 // hashes from the shared memory. If this succeeds, |enabled_| will be set
45 // to true.
46 void Init();
47
48 // The set of partial hashes for known ad networks.
49 base::hash_set<int64> entries_;
50
51 // Whether or not the database is enabled. The database will not be enabled
52 // if Init() does not succeed in loading the hashes.
53 bool enabled_;
54 };
55
56 AdNetworkDatabaseImpl::AdNetworkDatabaseImpl() : enabled_(false) {
57 Init();
58 }
59
60 AdNetworkDatabaseImpl::~AdNetworkDatabaseImpl() {}
61
62 void AdNetworkDatabaseImpl::Init() {
63 base::RefCountedStaticMemory* entries_memory =
64 ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
65 IDR_AD_NETWORK_HASHES);
66
67 const size_t size = entries_memory->size();
68 const unsigned char* const front = entries_memory->front();
69 if (size < kChecksumHashSize ||
70 (size - kChecksumHashSize) % kUrlHashSize != 0) {
felt 2014/04/23 03:01:36 should this be a DCHECK?
Devlin 2014/04/23 18:16:55 Hmm... good question. If it were a normal file, t
71 return;
72 }
73
74 // The format of the data resource is fairly straight-forward:
75 // <32-bit checksum><list of 64-bit hashes of hosts>, with no linebreaks or
76 // other separations.
felt 2014/04/23 03:01:36 how are the list entries (the hashes) separated?
Devlin 2014/04/23 18:16:55 There's no deliminator between them, because they
felt 2014/04/23 20:15:22 ah right
77 scoped_ptr<crypto::SecureHash> hash(
78 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
79
80 hash->Update(front + kChecksumHashSize, size - kChecksumHashSize);
81 char hash_value[kChecksumHashSize];
82 hash->Finish(hash_value, kChecksumHashSize);
83 // If the checksum doesn't match, abort.
felt 2014/04/23 03:01:36 should this also be a DCHECK?
Devlin 2014/04/23 18:16:55 Done.
84 if (memcmp(hash_value, front, kChecksumHashSize) != 0)
85 return;
86
87 // Construct and insert all hashes.
88 for (const unsigned char* index = front + kChecksumHashSize;
89 index < front + size;
90 index += kUrlHashSize) {
91 int64 value = 0;
92 memcpy(&value, index, kUrlHashSize);
93 entries_.insert(value);
94 }
95
96 enabled_ = true;
97 }
98
99 bool AdNetworkDatabaseImpl::IsAdNetwork(const GURL& url) const {
100 int64 hash = 0;
101 crypto::SHA256HashString(url.host(), &hash, sizeof(hash));
102 return entries_.count(hash) != 0;
103 }
104
13 class AdNetworkDatabaseFactory { 105 class AdNetworkDatabaseFactory {
14 public: 106 public:
15 AdNetworkDatabaseFactory(); 107 AdNetworkDatabaseFactory();
16 ~AdNetworkDatabaseFactory(); 108 ~AdNetworkDatabaseFactory();
17 109
110 const AdNetworkDatabase* GetDatabase();
18 void SetDatabase(scoped_ptr<AdNetworkDatabase> database); 111 void SetDatabase(scoped_ptr<AdNetworkDatabase> database);
19 112
20 const AdNetworkDatabase* database() const { return database_.get(); }
21
22 private: 113 private:
23 scoped_ptr<AdNetworkDatabase> database_; 114 scoped_ptr<AdNetworkDatabase> database_;
24 }; 115 };
25 116
26 AdNetworkDatabaseFactory::AdNetworkDatabaseFactory() {} 117 AdNetworkDatabaseFactory::AdNetworkDatabaseFactory() {}
27 AdNetworkDatabaseFactory::~AdNetworkDatabaseFactory() {} 118 AdNetworkDatabaseFactory::~AdNetworkDatabaseFactory() {}
28 119
120 const AdNetworkDatabase* AdNetworkDatabaseFactory::GetDatabase() {
121 // Construct a new database, if we don't have one.
122 if (!database_.get())
123 database_.reset(new AdNetworkDatabaseImpl());
124
125 if (database_->IsEnabled())
126 return database_.get();
127
128 return NULL;
129 }
130
29 void AdNetworkDatabaseFactory::SetDatabase( 131 void AdNetworkDatabaseFactory::SetDatabase(
30 scoped_ptr<AdNetworkDatabase> database) { 132 scoped_ptr<AdNetworkDatabase> database) {
31 database_.reset(database.release()); 133 database_.reset(database.release());
32 } 134 }
33 135
34 base::LazyInstance<AdNetworkDatabaseFactory> g_factory = 136 base::LazyInstance<AdNetworkDatabaseFactory> g_factory =
35 LAZY_INSTANCE_INITIALIZER; 137 LAZY_INSTANCE_INITIALIZER;
36 138
37 } // namespace 139 } // namespace
38 140
39 AdNetworkDatabase::~AdNetworkDatabase() {} 141 AdNetworkDatabase::~AdNetworkDatabase() {}
40 142
41 // static 143 // static
42 const AdNetworkDatabase* AdNetworkDatabase::Get() { 144 const AdNetworkDatabase* AdNetworkDatabase::Get() {
43 return g_factory.Get().database(); 145 return g_factory.Get().GetDatabase();
44 } 146 }
45 147
46 // static 148 // static
47 void AdNetworkDatabase::SetForTesting(scoped_ptr<AdNetworkDatabase> database) { 149 void AdNetworkDatabase::SetForTesting(scoped_ptr<AdNetworkDatabase> database) {
48 g_factory.Get().SetDatabase(database.Pass()); 150 g_factory.Get().SetDatabase(database.Pass());
49 } 151 }
50 152
51 } // namespace extensions 153 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698