зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1522265 - Moving malware, phishing and blocked URIs to features - part 3 - DBService updated, r=dimi
This commit is contained in:
Родитель
19c65633d3
Коммит
0b9a1617c2
|
@ -404,30 +404,6 @@ void Classifier::TableRequest(nsACString& aResult) {
|
|||
mIsTableRequestResultOutdated = false;
|
||||
}
|
||||
|
||||
nsresult Classifier::CheckURI(const nsACString& aSpec,
|
||||
const nsTArray<nsCString>& aTables,
|
||||
LookupResultArray& aResults) {
|
||||
Telemetry::AutoTimer<Telemetry::URLCLASSIFIER_CL_CHECK_TIME> timer;
|
||||
|
||||
// Get the set of fragments based on the url. This is necessary because we
|
||||
// only look up at most 5 URLs per aSpec, even if aSpec has more than 5
|
||||
// components.
|
||||
nsTArray<nsCString> fragments;
|
||||
nsresult rv = LookupCache::GetLookupFragments(aSpec, &fragments);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
LookupCacheArray cacheArray;
|
||||
for (const nsCString& table : aTables) {
|
||||
LookupResultArray results;
|
||||
rv = CheckURIFragments(fragments, table, results);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aResults.AppendElements(results);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Classifier::CheckURIFragments(
|
||||
const nsTArray<nsCString>& aSpecFragments, const nsACString& aTable,
|
||||
LookupResultArray& aResults) {
|
||||
|
|
|
@ -56,12 +56,6 @@ class Classifier {
|
|||
*/
|
||||
nsresult ActiveTables(nsTArray<nsCString>& aTables) const;
|
||||
|
||||
/**
|
||||
* Check a URL against the specified tables.
|
||||
*/
|
||||
nsresult CheckURI(const nsACString& aSpec, const nsTArray<nsCString>& tables,
|
||||
LookupResultArray& aResults);
|
||||
|
||||
/**
|
||||
* Check URL fragments against a specified table.
|
||||
* The fragments should be generated by |LookupCache::GetLookupFragments|
|
||||
|
|
|
@ -93,11 +93,9 @@ nsresult TablesToResponse(const nsACString& tables) {
|
|||
} // namespace safebrowsing
|
||||
} // namespace mozilla
|
||||
|
||||
namespace {
|
||||
|
||||
// This class holds a list of features, their tables, and it stores the lookup
|
||||
// results.
|
||||
class FeatureHolder final {
|
||||
class nsUrlClassifierDBService::FeatureHolder final {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FeatureHolder);
|
||||
|
||||
|
@ -107,7 +105,8 @@ class FeatureHolder final {
|
|||
|
||||
class TableData {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FeatureHolder::TableData);
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(
|
||||
nsUrlClassifierDBService::FeatureHolder::TableData);
|
||||
|
||||
explicit TableData(const nsACString& aTable) : mTable(aTable) {}
|
||||
|
||||
|
@ -158,6 +157,10 @@ class FeatureHolder final {
|
|||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aWorker);
|
||||
|
||||
mozilla::Telemetry::AutoTimer<
|
||||
mozilla::Telemetry::URLCLASSIFIER_CL_CHECK_TIME>
|
||||
timer;
|
||||
|
||||
// Get the set of fragments based on the url. This is necessary because we
|
||||
// only look up at most 5 URLs per aSpec, even if aSpec has more than 5
|
||||
// components.
|
||||
|
@ -206,6 +209,20 @@ class FeatureHolder final {
|
|||
}
|
||||
}
|
||||
|
||||
mozilla::UniquePtr<LookupResultArray> GetTableResults() const {
|
||||
mozilla::UniquePtr<LookupResultArray> results =
|
||||
mozilla::MakeUnique<LookupResultArray>();
|
||||
if (NS_WARN_IF(!results)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (TableData* tableData : mTableData) {
|
||||
results->AppendElements(tableData->mResults);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit FeatureHolder(nsIURI* aURI) : mURI(aURI) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -237,8 +254,6 @@ class FeatureHolder final {
|
|||
nsTArray<RefPtr<TableData>> mTableData;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::safebrowsing;
|
||||
|
||||
|
@ -294,20 +309,24 @@ nsresult nsUrlClassifierDBServiceWorker::Init(
|
|||
}
|
||||
|
||||
nsresult nsUrlClassifierDBServiceWorker::QueueLookup(
|
||||
const nsACString& spec, const nsACString& tables,
|
||||
nsIUrlClassifierLookupCallback* callback) {
|
||||
const nsACString& aKey,
|
||||
nsUrlClassifierDBService::FeatureHolder* aFeatureHolder,
|
||||
nsIUrlClassifierLookupCallback* aCallback) {
|
||||
MOZ_ASSERT(aFeatureHolder);
|
||||
MOZ_ASSERT(aCallback);
|
||||
|
||||
MutexAutoLock lock(mPendingLookupLock);
|
||||
if (gShuttingDownThread) {
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
PendingLookup* lookup = mPendingLookups.AppendElement(fallible);
|
||||
if (!lookup) return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (NS_WARN_IF(!lookup)) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
lookup->mStartTime = TimeStamp::Now();
|
||||
lookup->mKey = spec;
|
||||
lookup->mCallback = callback;
|
||||
lookup->mTables = tables;
|
||||
lookup->mKey = aKey;
|
||||
lookup->mCallback = aCallback;
|
||||
lookup->mFeatureHolder = aFeatureHolder;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -338,31 +357,6 @@ nsresult nsUrlClassifierDBServiceWorker::DoSingleLocalLookupWithURIFragments(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsUrlClassifierDBServiceWorker::DoLocalLookupWithURI(
|
||||
const nsACString& aSpec, const nsTArray<nsCString>& aTables,
|
||||
LookupResultArray& aResults) {
|
||||
if (gShuttingDownThread) {
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(
|
||||
!NS_IsMainThread(),
|
||||
"DoSingleLocalLookupWithURIFragments must be on background thread");
|
||||
|
||||
// Bail if we haven't been initialized on the background thread.
|
||||
if (!mClassifier) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsresult rv = mClassifier->CheckURI(aSpec, aTables, aResults);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
LOG(("Found %zu results.", aResults.Length()));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup up a key in the database is a two step process:
|
||||
*
|
||||
|
@ -375,7 +369,8 @@ nsresult nsUrlClassifierDBServiceWorker::DoLocalLookupWithURI(
|
|||
* "Simplified Regular Expression Lookup" section of the protocol doc.
|
||||
*/
|
||||
nsresult nsUrlClassifierDBServiceWorker::DoLookup(
|
||||
const nsACString& spec, const nsACString& tables,
|
||||
const nsACString& spec,
|
||||
nsUrlClassifierDBService::FeatureHolder* aFeatureHolder,
|
||||
nsIUrlClassifierLookupCallback* c) {
|
||||
if (gShuttingDownThread) {
|
||||
c->LookupComplete(nullptr);
|
||||
|
@ -387,25 +382,8 @@ nsresult nsUrlClassifierDBServiceWorker::DoLookup(
|
|||
clockStart = PR_IntervalNow();
|
||||
}
|
||||
|
||||
UniquePtr<LookupResultArray> results = MakeUnique<LookupResultArray>();
|
||||
if (!results) {
|
||||
c->LookupComplete(nullptr);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsTArray<nsCString> tableArray;
|
||||
Classifier::SplitTables(tables, tableArray);
|
||||
|
||||
nsresult rv = DoLocalLookupWithURI(spec, tableArray, *results);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_ASSERT(
|
||||
results->IsEmpty(),
|
||||
"DoLocalLookupWithURI() should not return any results if it fails.");
|
||||
c->LookupComplete(nullptr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
LOG(("Found %zu results.", results->Length()));
|
||||
nsresult rv = aFeatureHolder->DoLocalLookup(spec, this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
PRIntervalTime clockEnd = PR_IntervalNow();
|
||||
|
@ -413,6 +391,14 @@ nsresult nsUrlClassifierDBServiceWorker::DoLookup(
|
|||
PR_IntervalToMilliseconds(clockEnd - clockStart)));
|
||||
}
|
||||
|
||||
UniquePtr<LookupResultArray> results = aFeatureHolder->GetTableResults();
|
||||
if (NS_WARN_IF(!results)) {
|
||||
c->LookupComplete(nullptr);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
LOG(("Found %zu results.", results->Length()));
|
||||
|
||||
for (const RefPtr<const LookupResult> lookupResult : *results) {
|
||||
if (!lookupResult->Confirmed() &&
|
||||
mDBService->CanComplete(lookupResult->mTableName)) {
|
||||
|
@ -442,7 +428,7 @@ nsresult nsUrlClassifierDBServiceWorker::HandlePendingLookups() {
|
|||
mPendingLookups.RemoveElementAt(0);
|
||||
{
|
||||
MutexAutoUnlock unlock(mPendingLookupLock);
|
||||
DoLookup(lookup.mKey, lookup.mTables, lookup.mCallback);
|
||||
DoLookup(lookup.mKey, lookup.mFeatureHolder, lookup.mCallback);
|
||||
}
|
||||
double lookupTime = (TimeStamp::Now() - lookup.mStartTime).ToMilliseconds();
|
||||
Telemetry::Accumulate(Telemetry::URLCLASSIFIER_LOOKUP_TIME_2,
|
||||
|
@ -1617,72 +1603,15 @@ NS_INTERFACE_MAP_END
|
|||
return sUrlClassifierDBService;
|
||||
}
|
||||
|
||||
nsUrlClassifierDBService::nsUrlClassifierDBService()
|
||||
: mCheckMalware(CHECK_MALWARE_DEFAULT),
|
||||
mCheckPhishing(CHECK_PHISHING_DEFAULT),
|
||||
mCheckBlockedURIs(CHECK_BLOCKED_DEFAULT),
|
||||
mInUpdate(false) {}
|
||||
nsUrlClassifierDBService::nsUrlClassifierDBService() : mInUpdate(false) {}
|
||||
|
||||
nsUrlClassifierDBService::~nsUrlClassifierDBService() {
|
||||
sUrlClassifierDBService = nullptr;
|
||||
}
|
||||
|
||||
void AppendTables(const nsCString& aTables, nsCString& outTables) {
|
||||
if (!aTables.IsEmpty()) {
|
||||
if (!outTables.IsEmpty()) {
|
||||
outTables.Append(',');
|
||||
}
|
||||
outTables.Append(aTables);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsUrlClassifierDBService::ReadTablesFromPrefs() {
|
||||
mCheckMalware =
|
||||
Preferences::GetBool(CHECK_MALWARE_PREF, CHECK_MALWARE_DEFAULT);
|
||||
mCheckPhishing =
|
||||
Preferences::GetBool(CHECK_PHISHING_PREF, CHECK_PHISHING_DEFAULT);
|
||||
mCheckBlockedURIs =
|
||||
Preferences::GetBool(CHECK_BLOCKED_PREF, CHECK_BLOCKED_DEFAULT);
|
||||
|
||||
nsAutoCString allTables;
|
||||
nsresult nsUrlClassifierDBService::ReadDisallowCompletionsTablesFromPrefs() {
|
||||
nsAutoCString tables;
|
||||
|
||||
mBaseTables.Truncate();
|
||||
|
||||
Preferences::GetCString(PHISH_TABLE_PREF, allTables);
|
||||
if (mCheckPhishing) {
|
||||
AppendTables(allTables, mBaseTables);
|
||||
}
|
||||
|
||||
Preferences::GetCString(MALWARE_TABLE_PREF, tables);
|
||||
AppendTables(tables, allTables);
|
||||
if (mCheckMalware) {
|
||||
AppendTables(tables, mBaseTables);
|
||||
}
|
||||
|
||||
Preferences::GetCString(BLOCKED_TABLE_PREF, tables);
|
||||
AppendTables(tables, allTables);
|
||||
if (mCheckBlockedURIs) {
|
||||
AppendTables(tables, mBaseTables);
|
||||
}
|
||||
|
||||
Preferences::GetCString(DOWNLOAD_BLOCK_TABLE_PREF, tables);
|
||||
AppendTables(tables, allTables);
|
||||
|
||||
Preferences::GetCString(DOWNLOAD_ALLOW_TABLE_PREF, tables);
|
||||
AppendTables(tables, allTables);
|
||||
|
||||
Preferences::GetCString(PASSWORD_ALLOW_TABLE_PREF, tables);
|
||||
AppendTables(tables, allTables);
|
||||
|
||||
Preferences::GetCString(TRACKING_TABLE_PREF, tables);
|
||||
AppendTables(tables, allTables);
|
||||
|
||||
Preferences::GetCString(TRACKING_WHITELIST_TABLE_PREF, tables);
|
||||
AppendTables(tables, allTables);
|
||||
|
||||
Classifier::SplitTables(allTables, mGethashTables);
|
||||
|
||||
Preferences::GetCString(DISALLOW_COMPLETION_TABLE_PREF, tables);
|
||||
Classifier::SplitTables(tables, mDisallowCompletionsTables);
|
||||
|
||||
|
@ -1718,7 +1647,7 @@ nsresult nsUrlClassifierDBService::Init() {
|
|||
|
||||
sGethashNoise =
|
||||
Preferences::GetUint(GETHASH_NOISE_PREF, GETHASH_NOISE_DEFAULT);
|
||||
ReadTablesFromPrefs();
|
||||
ReadDisallowCompletionsTablesFromPrefs();
|
||||
nsresult rv;
|
||||
|
||||
{
|
||||
|
@ -1771,16 +1700,9 @@ nsresult nsUrlClassifierDBService::Init() {
|
|||
observerService->AddObserver(this, "quit-application", false);
|
||||
observerService->AddObserver(this, "profile-before-change", false);
|
||||
|
||||
// XXX: Do we *really* need to be able to change all of these at runtime?
|
||||
// Note: These observers should only be added when everything else above has
|
||||
// succeeded. Failing to do so can cause long shutdown times in certain
|
||||
// situations. See Bug 1247798 and Bug 1244803.
|
||||
Preferences::AddUintVarCache(&sGethashNoise, GETHASH_NOISE_PREF,
|
||||
GETHASH_NOISE_DEFAULT);
|
||||
|
||||
for (uint8_t i = 0; i < kObservedPrefs.Length(); i++) {
|
||||
Preferences::AddStrongObserver(this, kObservedPrefs[i]);
|
||||
}
|
||||
Preferences::AddStrongObserver(this, DISALLOW_COMPLETION_TABLE_PREF);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1789,8 +1711,30 @@ nsresult nsUrlClassifierDBService::Init() {
|
|||
NS_IMETHODIMP
|
||||
nsUrlClassifierDBService::Classify(nsIPrincipal* aPrincipal,
|
||||
nsIEventTarget* aEventTarget,
|
||||
nsIURIClassifierCallback* c, bool* result) {
|
||||
nsIURIClassifierCallback* c, bool* aResult) {
|
||||
NS_ENSURE_ARG(aPrincipal);
|
||||
NS_ENSURE_ARG(aResult);
|
||||
|
||||
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> permissionManager =
|
||||
services::GetPermissionManager();
|
||||
if (NS_WARN_IF(!permissionManager)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
uint32_t perm;
|
||||
nsresult rv = permissionManager->TestPermissionFromPrincipal(
|
||||
aPrincipal, "safe-browsing", &perm);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (perm == nsIPermissionManager::ALLOW_ACTION) {
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
using namespace mozilla::dom;
|
||||
|
@ -1799,7 +1743,7 @@ nsUrlClassifierDBService::Classify(nsIPrincipal* aPrincipal,
|
|||
MOZ_ASSERT(content);
|
||||
|
||||
auto actor = static_cast<URLClassifierChild*>(
|
||||
content->AllocPURLClassifierChild(IPC::Principal(aPrincipal), result));
|
||||
content->AllocPURLClassifierChild(IPC::Principal(aPrincipal), aResult));
|
||||
MOZ_ASSERT(actor);
|
||||
|
||||
if (aEventTarget) {
|
||||
|
@ -1813,8 +1757,8 @@ nsUrlClassifierDBService::Classify(nsIPrincipal* aPrincipal,
|
|||
content->SetEventTargetForActor(actor, systemGroupEventTarget);
|
||||
}
|
||||
if (!content->SendPURLClassifierConstructor(
|
||||
actor, IPC::Principal(aPrincipal), result)) {
|
||||
*result = false;
|
||||
actor, IPC::Principal(aPrincipal), aResult)) {
|
||||
*aResult = false;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -1824,24 +1768,46 @@ nsUrlClassifierDBService::Classify(nsIPrincipal* aPrincipal,
|
|||
|
||||
NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
if (!(mCheckMalware || mCheckPhishing || mCheckBlockedURIs)) {
|
||||
*result = false;
|
||||
nsTArray<RefPtr<nsIUrlClassifierFeature>> features;
|
||||
mozilla::net::UrlClassifierFeatureFactory::GetFeaturesNoChannel(features);
|
||||
if (features.IsEmpty()) {
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = aPrincipal->GetURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
|
||||
|
||||
// Let's keep the features alive and release them on the correct thread.
|
||||
RefPtr<FeatureHolder> holder =
|
||||
FeatureHolder::Create(uri, features, nsIUrlClassifierFeature::blacklist);
|
||||
if (NS_WARN_IF(!holder)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
uri = NS_GetInnermostURI(uri);
|
||||
NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoCString key;
|
||||
// Canonicalize the url
|
||||
nsCOMPtr<nsIUrlClassifierUtils> utilsService =
|
||||
do_GetService(NS_URLCLASSIFIERUTILS_CONTRACTID);
|
||||
rv = utilsService->GetKeyForURI(uri, key);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<nsUrlClassifierClassifyCallback> callback =
|
||||
new (fallible) nsUrlClassifierClassifyCallback(c);
|
||||
|
||||
if (!callback) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = LookupURI(aPrincipal, mBaseTables, callback, false, result);
|
||||
if (rv == NS_ERROR_MALFORMED_URI) {
|
||||
*result = false;
|
||||
// The URI had no hostname, don't try to classify it.
|
||||
return NS_OK;
|
||||
if (NS_WARN_IF(!callback)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// The rest is done async.
|
||||
rv = LookupURI(key, holder, callback);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2071,28 +2037,35 @@ nsUrlClassifierDBService::Lookup(nsIPrincipal* aPrincipal,
|
|||
nsIUrlClassifierCallback* c) {
|
||||
NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
bool dummy;
|
||||
return LookupURI(aPrincipal, tables, c, true, &dummy);
|
||||
}
|
||||
|
||||
nsresult nsUrlClassifierDBService::LookupURI(nsIPrincipal* aPrincipal,
|
||||
const nsACString& tables,
|
||||
nsIUrlClassifierCallback* c,
|
||||
bool forceLookup,
|
||||
bool* didLookup) {
|
||||
NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED);
|
||||
NS_ENSURE_ARG(aPrincipal);
|
||||
|
||||
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
|
||||
*didLookup = false;
|
||||
// FIXME: we don't call 'c' here!
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTArray<nsCString> tableArray;
|
||||
Classifier::SplitTables(tables, tableArray);
|
||||
|
||||
nsCOMPtr<nsIUrlClassifierFeature> feature;
|
||||
nsresult rv =
|
||||
CreateFeatureWithTables(NS_LITERAL_CSTRING("lookup"), tableArray,
|
||||
nsTArray<nsCString>(), getter_AddRefs(feature));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
|
||||
rv = aPrincipal->GetURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
|
||||
|
||||
nsTArray<RefPtr<nsIUrlClassifierFeature>> features;
|
||||
features.AppendElement(feature.get());
|
||||
|
||||
// Let's keep the features alive and release them on the correct thread.
|
||||
RefPtr<FeatureHolder> holder =
|
||||
FeatureHolder::Create(uri, features, nsIUrlClassifierFeature::blacklist);
|
||||
if (NS_WARN_IF(!holder)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
uri = NS_GetInnermostURI(uri);
|
||||
NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
|
||||
|
||||
|
@ -2101,44 +2074,31 @@ nsresult nsUrlClassifierDBService::LookupURI(nsIPrincipal* aPrincipal,
|
|||
nsCOMPtr<nsIUrlClassifierUtils> utilsService =
|
||||
do_GetService(NS_URLCLASSIFIERUTILS_CONTRACTID);
|
||||
rv = utilsService->GetKeyForURI(uri, key);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (forceLookup) {
|
||||
*didLookup = true;
|
||||
} else {
|
||||
nsCOMPtr<nsIPermissionManager> permissionManager =
|
||||
services::GetPermissionManager();
|
||||
if (NS_WARN_IF(!permissionManager)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return LookupURI(key, holder, c);
|
||||
}
|
||||
|
||||
uint32_t perm;
|
||||
rv = permissionManager->TestPermissionFromPrincipal(aPrincipal,
|
||||
"safe-browsing", &perm);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsresult nsUrlClassifierDBService::LookupURI(
|
||||
const nsACString& aKey, FeatureHolder* aHolder,
|
||||
nsIUrlClassifierCallback* aCallback) {
|
||||
MOZ_ASSERT(aHolder);
|
||||
MOZ_ASSERT(aCallback);
|
||||
|
||||
bool clean = (perm == nsIPermissionManager::ALLOW_ACTION);
|
||||
*didLookup = !clean;
|
||||
if (clean) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
NS_ENSURE_TRUE(gDbBackgroundThread, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// Create an nsUrlClassifierLookupCallback object. This object will
|
||||
// take care of confirming partial hash matches if necessary before
|
||||
// calling the client's callback.
|
||||
nsCOMPtr<nsIUrlClassifierLookupCallback> callback =
|
||||
new (fallible) nsUrlClassifierLookupCallback(this, c);
|
||||
if (!callback) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
new nsUrlClassifierLookupCallback(this, aCallback);
|
||||
|
||||
nsCOMPtr<nsIUrlClassifierLookupCallback> proxyCallback =
|
||||
new UrlClassifierLookupCallbackProxy(callback);
|
||||
|
||||
// Queue this lookup and call the lookup function to flush the queue if
|
||||
// necessary.
|
||||
rv = mWorker->QueueLookup(key, tables, proxyCallback);
|
||||
nsresult rv = mWorker->QueueLookup(aKey, aHolder, proxyCallback);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// This seems to just call HandlePendingLookups.
|
||||
|
@ -2307,8 +2267,7 @@ nsresult nsUrlClassifierDBService::CacheCompletions(
|
|||
}
|
||||
|
||||
bool nsUrlClassifierDBService::CanComplete(const nsACString& aTableName) {
|
||||
return mGethashTables.Contains(aTableName) &&
|
||||
!mDisallowCompletionsTables.Contains(aTableName);
|
||||
return !mDisallowCompletionsTables.Contains(aTableName);
|
||||
}
|
||||
|
||||
bool nsUrlClassifierDBService::GetCompleter(
|
||||
|
@ -2332,14 +2291,7 @@ NS_IMETHODIMP
|
|||
nsUrlClassifierDBService::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData) {
|
||||
if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefBranch> prefs(do_QueryInterface(aSubject, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
Unused << prefs;
|
||||
|
||||
if (kObservedPrefs.Contains(NS_ConvertUTF16toUTF8(aData))) {
|
||||
ReadTablesFromPrefs();
|
||||
}
|
||||
ReadDisallowCompletionsTablesFromPrefs();
|
||||
} else if (!strcmp(aTopic, "quit-application")) {
|
||||
// Tell the update thread to finish as soon as possible.
|
||||
gShuttingDownThread = true;
|
||||
|
@ -2389,9 +2341,7 @@ nsresult nsUrlClassifierDBService::Shutdown() {
|
|||
|
||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefs) {
|
||||
for (uint8_t i = 0; i < kObservedPrefs.Length(); i++) {
|
||||
prefs->RemoveObserver(kObservedPrefs[i], this);
|
||||
}
|
||||
prefs->RemoveObserver(DISALLOW_COMPLETION_TABLE_PREF, this);
|
||||
}
|
||||
|
||||
// 1. Synchronize with worker thread and update thread by
|
||||
|
|
|
@ -43,26 +43,8 @@
|
|||
// The hash length of a complete hash entry.
|
||||
#define COMPLETE_LENGTH 32
|
||||
|
||||
// Prefs for implementing nsIURIClassifier to block page loads
|
||||
#define CHECK_MALWARE_PREF "browser.safebrowsing.malware.enabled"
|
||||
#define CHECK_MALWARE_DEFAULT false
|
||||
|
||||
#define CHECK_PHISHING_PREF "browser.safebrowsing.phishing.enabled"
|
||||
#define CHECK_PHISHING_DEFAULT false
|
||||
|
||||
#define CHECK_BLOCKED_PREF "browser.safebrowsing.blockedURIs.enabled"
|
||||
#define CHECK_BLOCKED_DEFAULT false
|
||||
|
||||
// Comma-separated lists
|
||||
#define MALWARE_TABLE_PREF "urlclassifier.malwareTable"
|
||||
#define PHISH_TABLE_PREF "urlclassifier.phishTable"
|
||||
#define TRACKING_TABLE_PREF "urlclassifier.trackingTable"
|
||||
#define TRACKING_WHITELIST_TABLE_PREF "urlclassifier.trackingWhitelistTable"
|
||||
#define BLOCKED_TABLE_PREF "urlclassifier.blockedTable"
|
||||
#define DOWNLOAD_BLOCK_TABLE_PREF "urlclassifier.downloadBlockTable"
|
||||
#define DOWNLOAD_ALLOW_TABLE_PREF "urlclassifier.downloadAllowTable"
|
||||
#define DISALLOW_COMPLETION_TABLE_PREF "urlclassifier.disallow_completions"
|
||||
#define PASSWORD_ALLOW_TABLE_PREF "urlclassifier.passwordAllowTable"
|
||||
|
||||
using namespace mozilla::safebrowsing;
|
||||
|
||||
|
@ -96,6 +78,8 @@ class nsUrlClassifierDBService final : public nsIUrlClassifierDBService,
|
|||
friend class mozilla::net::AsyncUrlChannelClassifier;
|
||||
|
||||
public:
|
||||
class FeatureHolder;
|
||||
|
||||
// This is thread safe. It throws an exception if the thread is busy.
|
||||
nsUrlClassifierDBService();
|
||||
|
||||
|
@ -126,28 +110,14 @@ class nsUrlClassifierDBService final : public nsIUrlClassifierDBService,
|
|||
// it, please contact a safebrowsing/URL-Classifier peer.
|
||||
static nsUrlClassifierDBServiceWorker* GetWorker();
|
||||
|
||||
const nsTArray<nsCString> kObservedPrefs = {
|
||||
NS_LITERAL_CSTRING(CHECK_MALWARE_PREF),
|
||||
NS_LITERAL_CSTRING(CHECK_PHISHING_PREF),
|
||||
NS_LITERAL_CSTRING(CHECK_BLOCKED_PREF),
|
||||
NS_LITERAL_CSTRING(MALWARE_TABLE_PREF),
|
||||
NS_LITERAL_CSTRING(PHISH_TABLE_PREF),
|
||||
NS_LITERAL_CSTRING(TRACKING_TABLE_PREF),
|
||||
NS_LITERAL_CSTRING(TRACKING_WHITELIST_TABLE_PREF),
|
||||
NS_LITERAL_CSTRING(BLOCKED_TABLE_PREF),
|
||||
NS_LITERAL_CSTRING(DOWNLOAD_BLOCK_TABLE_PREF),
|
||||
NS_LITERAL_CSTRING(DOWNLOAD_ALLOW_TABLE_PREF),
|
||||
NS_LITERAL_CSTRING(DISALLOW_COMPLETION_TABLE_PREF)};
|
||||
|
||||
// No subclassing
|
||||
~nsUrlClassifierDBService();
|
||||
|
||||
// Disallow copy constructor
|
||||
nsUrlClassifierDBService(nsUrlClassifierDBService&);
|
||||
|
||||
nsresult LookupURI(nsIPrincipal* aPrincipal, const nsACString& tables,
|
||||
nsIUrlClassifierCallback* c, bool forceCheck,
|
||||
bool* didCheck);
|
||||
nsresult LookupURI(const nsACString& aKey, FeatureHolder* aHolder,
|
||||
nsIUrlClassifierCallback* c);
|
||||
|
||||
// Post an event to worker thread to release objects when receive
|
||||
// 'quit-application'
|
||||
|
@ -156,7 +126,7 @@ class nsUrlClassifierDBService final : public nsIUrlClassifierDBService,
|
|||
// Close db connection and join the background thread if it exists.
|
||||
nsresult Shutdown();
|
||||
|
||||
nsresult ReadTablesFromPrefs();
|
||||
nsresult ReadDisallowCompletionsTablesFromPrefs();
|
||||
|
||||
// This method checks if the classification can be done just using
|
||||
// preferences. It returns true if the operation has been completed.
|
||||
|
@ -171,33 +141,15 @@ class nsUrlClassifierDBService final : public nsIUrlClassifierDBService,
|
|||
nsInterfaceHashtable<nsCStringHashKey, nsIUrlClassifierHashCompleter>
|
||||
mCompleters;
|
||||
|
||||
// TRUE if the nsURIClassifier implementation should check for malware
|
||||
// uris on document loads.
|
||||
bool mCheckMalware;
|
||||
|
||||
// TRUE if the nsURIClassifier implementation should check for phishing
|
||||
// uris on document loads.
|
||||
bool mCheckPhishing;
|
||||
|
||||
// TRUE if the nsURIClassifier implementation should check for blocked
|
||||
// uris on document loads.
|
||||
bool mCheckBlockedURIs;
|
||||
|
||||
// TRUE if a BeginUpdate() has been called without an accompanying
|
||||
// CancelUpdate()/FinishUpdate(). This is used to prevent competing
|
||||
// updates, not to determine whether an update is still being
|
||||
// processed.
|
||||
bool mInUpdate;
|
||||
|
||||
// The list of tables that can use the default hash completer object.
|
||||
nsTArray<nsCString> mGethashTables;
|
||||
|
||||
// The list of tables that should never be hash completed.
|
||||
nsTArray<nsCString> mDisallowCompletionsTables;
|
||||
|
||||
// Comma-separated list of tables to use in lookups.
|
||||
nsCString mBaseTables;
|
||||
|
||||
// Thread that we do the updates on.
|
||||
static nsIThread* gDbBackgroundThread;
|
||||
};
|
||||
|
@ -213,9 +165,9 @@ class nsUrlClassifierDBServiceWorker final : public nsIUrlClassifierDBService {
|
|||
nsUrlClassifierDBService* aDBService);
|
||||
|
||||
// Queue a lookup for the worker to perform, called in the main thread.
|
||||
// tables is a comma-separated list of tables to query
|
||||
nsresult QueueLookup(const nsACString& lookupKey, const nsACString& tables,
|
||||
nsIUrlClassifierLookupCallback* callback);
|
||||
nsresult QueueLookup(const nsACString& aLookupKey,
|
||||
nsUrlClassifierDBService::FeatureHolder* aFeatureHolder,
|
||||
nsIUrlClassifierLookupCallback* aLallback);
|
||||
|
||||
// Handle any queued-up lookups. We call this function during long-running
|
||||
// update operations to prevent lookups from blocking for too long.
|
||||
|
@ -226,9 +178,6 @@ class nsUrlClassifierDBServiceWorker final : public nsIUrlClassifierDBService {
|
|||
nsresult DoSingleLocalLookupWithURIFragments(
|
||||
const nsTArray<nsCString>& aSpecFragments, const nsACString& aTable,
|
||||
LookupResultArray& aResults);
|
||||
nsresult DoLocalLookupWithURI(const nsACString& aSpec,
|
||||
const nsTArray<nsCString>& aTables,
|
||||
LookupResultArray& aResults);
|
||||
|
||||
// Open the DB connection
|
||||
nsresult GCC_MANGLING_WORKAROUND OpenDb();
|
||||
|
@ -275,7 +224,8 @@ class nsUrlClassifierDBServiceWorker final : public nsIUrlClassifierDBService {
|
|||
void ResetUpdate();
|
||||
|
||||
// Perform a classifier lookup for a given url.
|
||||
nsresult DoLookup(const nsACString& spec, const nsACString& tables,
|
||||
nsresult DoLookup(const nsACString& spec,
|
||||
nsUrlClassifierDBService::FeatureHolder* aFeatureHolder,
|
||||
nsIUrlClassifierLookupCallback* c);
|
||||
|
||||
nsresult AddNoise(const Prefix aPrefix, const nsCString tableName,
|
||||
|
@ -319,7 +269,7 @@ class nsUrlClassifierDBServiceWorker final : public nsIUrlClassifierDBService {
|
|||
public:
|
||||
mozilla::TimeStamp mStartTime;
|
||||
nsCString mKey;
|
||||
nsCString mTables;
|
||||
RefPtr<nsUrlClassifierDBService::FeatureHolder> mFeatureHolder;
|
||||
nsCOMPtr<nsIUrlClassifierLookupCallback> mCallback;
|
||||
};
|
||||
|
||||
|
|
|
@ -102,29 +102,6 @@ UrlClassifierDBServiceWorkerProxy::FinishStream() {
|
|||
return DispatchToWorkerThread(r);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierDBServiceWorkerProxy::DoLocalLookupRunnable::Run() {
|
||||
mTarget->DoLocalLookupWithURI(mSpec, mTables, mResults);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult UrlClassifierDBServiceWorkerProxy::DoLocalLookupWithURI(
|
||||
const nsACString& spec, const nsTArray<nsCString>& tables,
|
||||
LookupResultArray& results) const
|
||||
|
||||
{
|
||||
// Run synchronously on background thread. NS_DISPATCH_SYNC does *not* do
|
||||
// what we want -- it continues processing events on the main thread loop
|
||||
// before the Dispatch returns.
|
||||
nsCOMPtr<nsIRunnable> r =
|
||||
new DoLocalLookupRunnable(mTarget, spec, tables, results);
|
||||
nsIThread* t = nsUrlClassifierDBService::BackgroundThread();
|
||||
if (!t) return NS_ERROR_FAILURE;
|
||||
|
||||
mozilla::SyncRunnable::DispatchToThread(t, r);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierDBServiceWorkerProxy::FinishUpdate() {
|
||||
nsCOMPtr<nsIRunnable> r =
|
||||
|
|
|
@ -132,27 +132,6 @@ class UrlClassifierDBServiceWorkerProxy final
|
|||
const mozilla::safebrowsing::ConstCacheResultArray mEntries;
|
||||
};
|
||||
|
||||
class DoLocalLookupRunnable : public mozilla::Runnable {
|
||||
public:
|
||||
DoLocalLookupRunnable(nsUrlClassifierDBServiceWorker* aTarget,
|
||||
const nsACString& spec,
|
||||
const nsTArray<nsCString>& tables,
|
||||
mozilla::safebrowsing::LookupResultArray& results)
|
||||
: mozilla::Runnable(
|
||||
"UrlClassifierDBServiceWorkerProxy::DoLocalLookupRunnable"),
|
||||
mTarget(aTarget),
|
||||
mSpec(spec),
|
||||
mTables(tables),
|
||||
mResults(results) {}
|
||||
|
||||
NS_DECL_NSIRUNNABLE
|
||||
private:
|
||||
const RefPtr<nsUrlClassifierDBServiceWorker> mTarget;
|
||||
const nsCString mSpec;
|
||||
const nsTArray<nsCString> mTables;
|
||||
mozilla::safebrowsing::LookupResultArray& mResults;
|
||||
};
|
||||
|
||||
class ClearLastResultsRunnable : public mozilla::Runnable {
|
||||
public:
|
||||
explicit ClearLastResultsRunnable(nsUrlClassifierDBServiceWorker* aTarget)
|
||||
|
@ -205,10 +184,6 @@ class UrlClassifierDBServiceWorkerProxy final
|
|||
};
|
||||
|
||||
public:
|
||||
nsresult DoLocalLookupWithURI(
|
||||
const nsACString& spec, const nsTArray<nsCString>& tables,
|
||||
mozilla::safebrowsing::LookupResultArray& results) const;
|
||||
|
||||
nsresult OpenDb() const;
|
||||
nsresult CloseDb() const;
|
||||
nsresult PreShutdown() const;
|
||||
|
|
Загрузка…
Ссылка в новой задаче