Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/toolkit/components/url-classifier/nsUrlClassifierDBService.h
Line
Count
Source (jump to first uncovered line)
1
//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-/
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#ifndef nsUrlClassifierDBService_h_
7
#define nsUrlClassifierDBService_h_
8
9
#include <nsISupportsUtils.h>
10
11
#include "nsID.h"
12
#include "nsInterfaceHashtable.h"
13
#include "nsIObserver.h"
14
#include "nsUrlClassifierPrefixSet.h"
15
#include "nsIUrlClassifierHashCompleter.h"
16
#include "nsIUrlListManager.h"
17
#include "nsIUrlClassifierDBService.h"
18
#include "nsIUrlClassifierInfo.h"
19
#include "nsIURIClassifier.h"
20
#include "nsToolkitCompsCID.h"
21
#include "nsICryptoHMAC.h"
22
#include "mozilla/Attributes.h"
23
#include "mozilla/Mutex.h"
24
#include "mozilla/TimeStamp.h"
25
26
#include "Entries.h"
27
#include "LookupCache.h"
28
#include "HashStore.h"
29
30
// GCC < 6.1 workaround, see bug 1329593
31
#if defined(XP_WIN) && defined(__MINGW32__)
32
#define GCC_MANGLING_WORKAROUND __stdcall
33
#else
34
#define GCC_MANGLING_WORKAROUND
35
#endif
36
37
// The hash length for a domain key.
38
#define DOMAIN_LENGTH 4
39
40
// The hash length of a partial hash entry.
41
#define PARTIAL_LENGTH 4
42
43
// The hash length of a complete hash entry.
44
#define COMPLETE_LENGTH 32
45
46
// Prefs for implementing nsIURIClassifier to block page loads
47
0
#define CHECK_MALWARE_PREF      "browser.safebrowsing.malware.enabled"
48
0
#define CHECK_MALWARE_DEFAULT   false
49
50
0
#define CHECK_PHISHING_PREF     "browser.safebrowsing.phishing.enabled"
51
0
#define CHECK_PHISHING_DEFAULT  false
52
53
0
#define CHECK_BLOCKED_PREF      "browser.safebrowsing.blockedURIs.enabled"
54
0
#define CHECK_BLOCKED_DEFAULT   false
55
56
// Comma-separated lists
57
0
#define MALWARE_TABLE_PREF              "urlclassifier.malwareTable"
58
0
#define PHISH_TABLE_PREF                "urlclassifier.phishTable"
59
0
#define TRACKING_TABLE_PREF             "urlclassifier.trackingTable"
60
0
#define TRACKING_TABLE_TEST_ENTRIES_PREF "urlclassifier.trackingTable.testEntries"
61
0
#define TRACKING_WHITELIST_TABLE_PREF   "urlclassifier.trackingWhitelistTable"
62
0
#define TRACKING_WHITELIST_TABLE_TEST_ENTRIES_PREF "urlclassifier.trackingWhitelistTable.testEntries"
63
0
#define BLOCKED_TABLE_PREF              "urlclassifier.blockedTable"
64
0
#define DOWNLOAD_BLOCK_TABLE_PREF       "urlclassifier.downloadBlockTable"
65
0
#define DOWNLOAD_ALLOW_TABLE_PREF       "urlclassifier.downloadAllowTable"
66
0
#define DISALLOW_COMPLETION_TABLE_PREF  "urlclassifier.disallow_completions"
67
0
#define PASSWORD_ALLOW_TABLE_PREF       "urlclassifier.passwordAllowTable"
68
69
using namespace mozilla::safebrowsing;
70
71
class nsUrlClassifierDBServiceWorker;
72
class nsIThread;
73
class nsIURI;
74
class UrlClassifierDBServiceWorkerProxy;
75
namespace mozilla {
76
namespace safebrowsing {
77
class Classifier;
78
class ProtocolParser;
79
80
nsresult
81
TablesToResponse(const nsACString& tables);
82
83
} // namespace safebrowsing
84
} // namespace mozilla
85
86
// This is a proxy class that just creates a background thread and delegates
87
// calls to the background thread.
88
class nsUrlClassifierDBService final : public nsIUrlClassifierDBService,
89
                                       public nsIURIClassifier,
90
                                       public nsIUrlClassifierInfo,
91
                                       public nsIObserver
92
{
93
public:
94
  // This is thread safe. It throws an exception if the thread is busy.
95
  nsUrlClassifierDBService();
96
97
  nsresult Init();
98
99
  static nsUrlClassifierDBService* GetInstance(nsresult *result);
100
101
  NS_DECLARE_STATIC_IID_ACCESSOR(NS_URLCLASSIFIERDBSERVICE_CID)
102
103
  NS_DECL_THREADSAFE_ISUPPORTS
104
  NS_DECL_NSIURLCLASSIFIERDBSERVICE
105
  NS_DECL_NSIURICLASSIFIER
106
  NS_DECL_NSIURLCLASSIFIERINFO
107
  NS_DECL_NSIOBSERVER
108
109
  bool CanComplete(const nsACString &tableName);
110
  bool GetCompleter(const nsACString& tableName,
111
                    nsIUrlClassifierHashCompleter** completer);
112
  nsresult CacheCompletions(const mozilla::safebrowsing::ConstCacheResultArray& results);
113
114
  static nsIThread* BackgroundThread();
115
116
  static bool ShutdownHasStarted();
117
118
private:
119
120
  const nsTArray<nsCString> kObservedPrefs = {
121
    NS_LITERAL_CSTRING(CHECK_MALWARE_PREF),
122
    NS_LITERAL_CSTRING(CHECK_PHISHING_PREF),
123
    NS_LITERAL_CSTRING(CHECK_BLOCKED_PREF),
124
    NS_LITERAL_CSTRING(MALWARE_TABLE_PREF),
125
    NS_LITERAL_CSTRING(PHISH_TABLE_PREF),
126
    NS_LITERAL_CSTRING(TRACKING_TABLE_PREF),
127
    NS_LITERAL_CSTRING(TRACKING_TABLE_TEST_ENTRIES_PREF),
128
    NS_LITERAL_CSTRING(TRACKING_WHITELIST_TABLE_PREF),
129
    NS_LITERAL_CSTRING(TRACKING_WHITELIST_TABLE_TEST_ENTRIES_PREF),
130
    NS_LITERAL_CSTRING(BLOCKED_TABLE_PREF),
131
    NS_LITERAL_CSTRING(DOWNLOAD_BLOCK_TABLE_PREF),
132
    NS_LITERAL_CSTRING(DOWNLOAD_ALLOW_TABLE_PREF),
133
    NS_LITERAL_CSTRING(DISALLOW_COMPLETION_TABLE_PREF)
134
  };
135
136
  // No subclassing
137
  ~nsUrlClassifierDBService();
138
139
  // Disallow copy constructor
140
  nsUrlClassifierDBService(nsUrlClassifierDBService&);
141
142
  nsresult LookupURI(nsIPrincipal* aPrincipal,
143
                     const nsACString& tables,
144
                     const nsTArray<nsCString>& extraTablesByPrefs,
145
                     const nsTArray<nsCString>& extraEntriesByPrefs,
146
                     nsIUrlClassifierCallback* c,
147
                     bool forceCheck, bool *didCheck);
148
149
  // Post an event to worker thread to release objects when receive 'quit-application'
150
  nsresult PreShutdown();
151
152
  // Close db connection and join the background thread if it exists.
153
  nsresult Shutdown();
154
155
  nsresult ReadTablesFromPrefs();
156
157
  RefPtr<nsUrlClassifierDBServiceWorker> mWorker;
158
  RefPtr<UrlClassifierDBServiceWorkerProxy> mWorkerProxy;
159
160
  nsInterfaceHashtable<nsCStringHashKey, nsIUrlClassifierHashCompleter> mCompleters;
161
162
  // TRUE if the nsURIClassifier implementation should check for malware
163
  // uris on document loads.
164
  bool mCheckMalware;
165
166
  // TRUE if the nsURIClassifier implementation should check for phishing
167
  // uris on document loads.
168
  bool mCheckPhishing;
169
170
  // TRUE if the nsURIClassifier implementation should check for blocked
171
  // uris on document loads.
172
  bool mCheckBlockedURIs;
173
174
  // TRUE if a BeginUpdate() has been called without an accompanying
175
  // CancelUpdate()/FinishUpdate().  This is used to prevent competing
176
  // updates, not to determine whether an update is still being
177
  // processed.
178
  bool mInUpdate;
179
180
  // The list of tables that can use the default hash completer object.
181
  nsTArray<nsCString> mGethashTables;
182
183
  // The list of tables that should never be hash completed.
184
  nsTArray<nsCString> mDisallowCompletionsTables;
185
186
  // Comma-separated list of tables to use in lookups.
187
  nsCString mTrackingProtectionTables;
188
  nsCString mBaseTables;
189
190
  // Comma-separated hosts set by prefs to use in lookups.
191
  nsCString mTrackingProtectionWhitelistExtraEntriesByPrefs;
192
  nsCString mTrackingProtectionBlacklistExtraEntriesByPrefs;
193
194
  // Thread that we do the updates on.
195
  static nsIThread* gDbBackgroundThread;
196
};
197
198
class nsUrlClassifierDBServiceWorker final : public nsIUrlClassifierDBService
199
{
200
public:
201
  nsUrlClassifierDBServiceWorker();
202
203
  NS_DECL_THREADSAFE_ISUPPORTS
204
  NS_DECL_NSIURLCLASSIFIERDBSERVICE
205
206
  nsresult Init(uint32_t aGethashNoise,
207
                nsCOMPtr<nsIFile> aCacheDir,
208
                nsUrlClassifierDBService* aDBService);
209
210
  // Queue a lookup for the worker to perform, called in the main thread.
211
  // tables is a comma-separated list of tables to query
212
  nsresult QueueLookup(const nsACString& lookupKey,
213
                       const nsACString& tables,
214
                       nsIUrlClassifierLookupCallback* callback);
215
216
  // Handle any queued-up lookups.  We call this function during long-running
217
  // update operations to prevent lookups from blocking for too long.
218
  nsresult HandlePendingLookups();
219
220
  // Perform a blocking classifier lookup for a given url. Can be called on
221
  // either the main thread or the worker thread.
222
  nsresult DoLocalLookup(const nsACString& spec,
223
                         const nsACString& tables,
224
                         LookupResultArray& results);
225
226
  // Open the DB connection
227
  nsresult GCC_MANGLING_WORKAROUND OpenDb();
228
229
  // Provide a way to forcibly close the db connection.
230
  nsresult GCC_MANGLING_WORKAROUND CloseDb();
231
232
  nsresult GCC_MANGLING_WORKAROUND PreShutdown();
233
234
  nsresult CacheCompletions(const ConstCacheResultArray& aEntries);
235
236
  // Used to probe the state of the worker thread. When the update begins,
237
  // mUpdateObserver will be set. When the update finished, mUpdateObserver
238
  // will be nulled out in NotifyUpdateObserver.
239
0
  bool IsBusyUpdating() const { return !!mUpdateObserver; }
240
241
  // Check the DB ready state of the worker thread
242
0
  bool IsDBOpened() const { return !!mClassifier; }
243
244
  // Delegate Classifier to disable async update. If there is an
245
  // ongoing update on the update thread, we will be blocked until
246
  // the background update is done and callback is fired.
247
  // Should be called on the worker thread.
248
  void FlushAndDisableAsyncUpdate();
249
250
  // A synchronous call to get cache information for the given table.
251
  // This is only used by about:url-classifier now.
252
  nsresult GetCacheInfo(const nsACString& aTable,
253
                        nsIUrlClassifierCacheInfo** aCache);
254
private:
255
  // No subclassing
256
  ~nsUrlClassifierDBServiceWorker();
257
258
  // Disallow copy constructor
259
  nsUrlClassifierDBServiceWorker(nsUrlClassifierDBServiceWorker&);
260
261
  nsresult NotifyUpdateObserver(nsresult aUpdateStatus);
262
263
  // Reset the in-progress update stream
264
  void ResetStream();
265
266
  // Reset the in-progress update
267
  void ResetUpdate();
268
269
  // Perform a classifier lookup for a given url.
270
  nsresult DoLookup(const nsACString& spec,
271
                    const nsACString& tables,
272
                    nsIUrlClassifierLookupCallback* c);
273
274
  nsresult AddNoise(const Prefix aPrefix,
275
                    const nsCString tableName,
276
                    uint32_t aCount,
277
                    LookupResultArray& results);
278
279
  nsresult CacheResultToTableUpdate(RefPtr<const CacheResult> aCacheResult,
280
                                    RefPtr<TableUpdate> aUpdate);
281
282
  bool IsSameAsLastResults(const ConstCacheResultArray& aResult) const;
283
284
  RefPtr<mozilla::safebrowsing::Classifier> mClassifier;
285
  // The class that actually parses the update chunks.
286
  mozilla::UniquePtr<ProtocolParser> mProtocolParser;
287
288
  // Directory where to store the SB databases.
289
  nsCOMPtr<nsIFile> mCacheDir;
290
291
  RefPtr<nsUrlClassifierDBService> mDBService;
292
293
  TableUpdateArray mTableUpdates;
294
295
  uint32_t mUpdateWaitSec;
296
297
  // Stores the last results that triggered a table update.
298
  ConstCacheResultArray mLastResults;
299
300
  nsresult mUpdateStatus;
301
  nsTArray<nsCString> mUpdateTables;
302
303
  nsCOMPtr<nsIUrlClassifierUpdateObserver> mUpdateObserver;
304
  bool mInStream;
305
306
  // The number of noise entries to add to the set of lookup results.
307
  uint32_t mGethashNoise;
308
309
  // Pending lookups are stored in a queue for processing.  The queue
310
  // is protected by mPendingLookupLock.
311
  mozilla::Mutex mPendingLookupLock;
312
313
  class PendingLookup {
314
  public:
315
    mozilla::TimeStamp mStartTime;
316
    nsCString mKey;
317
    nsCString mTables;
318
    nsCOMPtr<nsIUrlClassifierLookupCallback> mCallback;
319
  };
320
321
  // list of pending lookups
322
  nsTArray<PendingLookup> mPendingLookups;
323
324
#ifdef MOZ_SAFEBROWSING_DUMP_FAILED_UPDATES
325
  // The raw update response for debugging.
326
  nsCString mRawTableUpdates;
327
#endif
328
};
329
330
NS_DEFINE_STATIC_IID_ACCESSOR(nsUrlClassifierDBService, NS_URLCLASSIFIERDBSERVICE_CID)
331
332
#endif // nsUrlClassifierDBService_h_