Bug 842828: Clean up urlclassifier.gethashtables preferences (r=gcp)

* * *
Bug 842828: Mark attributes of nsIApplicationReputationQuery as readonly, remove unused field (r=mossop)
* * *
Bug 842828: Check local list to suppress remote lookups (r=paolo)
This commit is contained in:
Monica Chew 2013-09-26 06:51:59 -07:00
parent 83e3f07339
commit a1caaa978a
18 changed files with 456 additions and 345 deletions

View File

@ -330,9 +330,6 @@ pref("urlclassifier.alternate_error_page", "blocked");
// The number of random entries to send with a gethash request.
pref("urlclassifier.gethashnoise", 4);
// The list of tables that use the gethash request to confirm partial results.
pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// If an urlclassifier table has not been updated in this number of seconds,
// a gethash request will be forced to check that the result is still in
// the database.

View File

@ -803,9 +803,6 @@ pref("urlclassifier.alternate_error_page", "blocked");
// The number of random entries to send with a gethash request.
pref("urlclassifier.gethashnoise", 4);
// The list of tables that use the gethash request to confirm partial results.
pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// If an urlclassifier table has not been updated in this number of seconds,
// a gethash request will be forced to check that the result is still in
// the database.

View File

@ -607,9 +607,6 @@ pref("urlclassifier.alternate_error_page", "blocked");
// The number of random entries to send with a gethash request.
pref("urlclassifier.gethashnoise", 4);
// The list of tables that use the gethash request to confirm partial results.
pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// If an urlclassifier table has not been updated in this number of seconds,
// a gethash request will be forced to check that the result is still in
// the database.

View File

@ -600,9 +600,6 @@ pref("urlclassifier.alternate_error_page", "blocked");
// The number of random entries to send with a gethash request.
pref("urlclassifier.gethashnoise", 4);
// The list of tables that use the gethash request to confirm partial results.
pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// If an urlclassifier table has not been updated in this number of seconds,
// a gethash request will be forced to check that the result is still in
// the database.

View File

@ -4429,3 +4429,9 @@ pref("dom.telephony.enabled", false);
// DOM Inter-App Communication API.
pref("dom.inter-app-communication-api.enabled", false);
// The tables used for Safebrowsing phishing and malware checks.
pref("urlclassifier.malware_table", "goog-malware-shavar");
pref("urlclassifier.phish_table", "goog-phish-shavar");
pref("urlclassifier.download_block_table", "goog-badbinurl-shavar");
pref("urlclassifier.download_allow_table", "goog-downloadwhite-digest256");

View File

@ -175,12 +175,6 @@
{ 0xf3dcf644, 0x79e8, 0x4f59, { 0xa1, 0xbb, 0x87, 0x84, 0x54, 0x48, 0x8e, 0xf9 } }
#endif
#define NS_APPLICATION_REPUTATION_QUERY_CONTRACTID \
"@mozilla.org/downloads/application-reputation-query;1"
#define NS_APPLICATION_REPUTATION_QUERY_CID \
{ 0x857da2c0, 0xcfe5, 0x11e2, { 0x8b, 0x8b, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }
#define NS_APPLICATION_REPUTATION_SERVICE_CONTRACTID \
"@mozilla.org/downloads/application-reputation-service;1"

View File

@ -26,6 +26,7 @@
#include "nsTypeAheadFind.h"
#ifdef MOZ_URL_CLASSIFIER
#include "ApplicationReputation.h"
#include "nsUrlClassifierDBService.h"
#include "nsUrlClassifierStreamUpdater.h"
#include "nsUrlClassifierUtils.h"
@ -33,7 +34,6 @@
#endif
#include "nsBrowserStatusFilter.h"
#include "ApplicationReputation.h"
/////////////////////////////////////////////////////////////////////////////
@ -55,6 +55,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsDownloadProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTypeAheadFind)
#ifdef MOZ_URL_CLASSIFIER
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ApplicationReputationService,
ApplicationReputationService::GetSingleton)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUrlClassifierPrefixSet)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUrlClassifierStreamUpdater)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUrlClassifierUtils, Init)
@ -79,16 +81,11 @@ nsUrlClassifierDBServiceConstructor(nsISupports *aOuter, REFNSIID aIID,
}
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR(ApplicationReputationQuery)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ApplicationReputationService,
ApplicationReputationService::GetSingleton)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBrowserStatusFilter)
#if defined(USE_MOZ_UPDATER)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUpdateProcessor)
#endif
NS_DEFINE_NAMED_CID(NS_APPLICATION_REPUTATION_QUERY_CID);
NS_DEFINE_NAMED_CID(NS_APPLICATION_REPUTATION_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_TOOLKIT_APPSTARTUP_CID);
NS_DEFINE_NAMED_CID(NS_USERINFO_CID);
NS_DEFINE_NAMED_CID(NS_ALERTSSERVICE_CID);
@ -101,6 +98,7 @@ NS_DEFINE_NAMED_CID(NS_DOWNLOAD_CID);
NS_DEFINE_NAMED_CID(NS_FIND_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_TYPEAHEADFIND_CID);
#ifdef MOZ_URL_CLASSIFIER
NS_DEFINE_NAMED_CID(NS_APPLICATION_REPUTATION_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_URLCLASSIFIERPREFIXSET_CID);
NS_DEFINE_NAMED_CID(NS_URLCLASSIFIERDBSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_URLCLASSIFIERSTREAMUPDATER_CID);
@ -113,8 +111,6 @@ NS_DEFINE_NAMED_CID(NS_UPDATEPROCESSOR_CID);
#endif
static const mozilla::Module::CIDEntry kToolkitCIDs[] = {
{ &kNS_APPLICATION_REPUTATION_QUERY_CID, false, NULL, ApplicationReputationQueryConstructor },
{ &kNS_APPLICATION_REPUTATION_SERVICE_CID, false, NULL, ApplicationReputationServiceConstructor },
{ &kNS_TOOLKIT_APPSTARTUP_CID, false, NULL, nsAppStartupConstructor },
{ &kNS_USERINFO_CID, false, NULL, nsUserInfoConstructor },
{ &kNS_ALERTSSERVICE_CID, false, NULL, nsAlertsServiceConstructor },
@ -127,6 +123,7 @@ static const mozilla::Module::CIDEntry kToolkitCIDs[] = {
{ &kNS_FIND_SERVICE_CID, false, NULL, nsFindServiceConstructor },
{ &kNS_TYPEAHEADFIND_CID, false, NULL, nsTypeAheadFindConstructor },
#ifdef MOZ_URL_CLASSIFIER
{ &kNS_APPLICATION_REPUTATION_SERVICE_CID, false, NULL, ApplicationReputationServiceConstructor },
{ &kNS_URLCLASSIFIERPREFIXSET_CID, false, NULL, nsUrlClassifierPrefixSetConstructor },
{ &kNS_URLCLASSIFIERDBSERVICE_CID, false, NULL, nsUrlClassifierDBServiceConstructor },
{ &kNS_URLCLASSIFIERSTREAMUPDATER_CID, false, NULL, nsUrlClassifierStreamUpdaterConstructor },
@ -141,8 +138,6 @@ static const mozilla::Module::CIDEntry kToolkitCIDs[] = {
};
static const mozilla::Module::ContractIDEntry kToolkitContracts[] = {
{ NS_APPLICATION_REPUTATION_QUERY_CONTRACTID, &kNS_APPLICATION_REPUTATION_QUERY_CID },
{ NS_APPLICATION_REPUTATION_SERVICE_CONTRACTID, &kNS_APPLICATION_REPUTATION_SERVICE_CID },
{ NS_APPSTARTUP_CONTRACTID, &kNS_TOOLKIT_APPSTARTUP_CID },
{ NS_USERINFO_CONTRACTID, &kNS_USERINFO_CID },
{ NS_ALERTSERVICE_CONTRACTID, &kNS_ALERTSSERVICE_CID },
@ -155,6 +150,7 @@ static const mozilla::Module::ContractIDEntry kToolkitContracts[] = {
{ NS_FIND_SERVICE_CONTRACTID, &kNS_FIND_SERVICE_CID },
{ NS_TYPEAHEADFIND_CONTRACTID, &kNS_TYPEAHEADFIND_CID },
#ifdef MOZ_URL_CLASSIFIER
{ NS_APPLICATION_REPUTATION_SERVICE_CONTRACTID, &kNS_APPLICATION_REPUTATION_SERVICE_CID },
{ NS_URLCLASSIFIERPREFIXSET_CONTRACTID, &kNS_URLCLASSIFIERPREFIXSET_CID },
{ NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &kNS_URLCLASSIFIERDBSERVICE_CID },
{ NS_URICLASSIFIERSERVICE_CONTRACTID, &kNS_URLCLASSIFIERDBSERVICE_CID },

View File

@ -11,12 +11,13 @@
#include "nsIChannel.h"
#include "nsIHttpChannel.h"
#include "nsIIOService.h"
#include "nsIObserverService.h"
#include "nsIPrefService.h"
#include "nsIScriptSecurityManager.h"
#include "nsIStreamListener.h"
#include "nsIStringStream.h"
#include "nsIUploadChannel2.h"
#include "nsIURI.h"
#include "nsIUrlClassifierDBService.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
@ -25,6 +26,7 @@
#include "nsDebug.h"
#include "nsError.h"
#include "nsNetCID.h"
#include "nsReadableUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "nsThreadUtils.h"
@ -38,79 +40,117 @@ using mozilla::Preferences;
#define PREF_SB_APP_REP_URL "browser.safebrowsing.appRepURL"
#define PREF_SB_MALWARE_ENABLED "browser.safebrowsing.malware.enabled"
#define PREF_GENERAL_LOCALE "general.useragent.locale"
#define PREF_DOWNLOAD_BLOCK_TABLE "urlclassifier.download_block_table"
#define PREF_DOWNLOAD_ALLOW_TABLE "urlclassifier.download_allow_table"
NS_IMPL_ISUPPORTS1(ApplicationReputationService, nsIApplicationReputationService)
/**
* Keep track of pending lookups. Once the ApplicationReputationService creates
* this, it is guaranteed to call mCallback. This class is private to
* ApplicationReputationService.
*/
class PendingLookup MOZ_FINAL :
public nsIStreamListener,
public nsIUrlClassifierCallback {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIURLCLASSIFIERCALLBACK
PendingLookup(nsIApplicationReputationQuery* aQuery,
nsIApplicationReputationCallback* aCallback);
~PendingLookup();
ApplicationReputationService* ApplicationReputationService::gApplicationReputationService = nullptr;
private:
nsCOMPtr<nsIApplicationReputationQuery> mQuery;
nsCOMPtr<nsIApplicationReputationCallback> mCallback;
/**
* The response from the application reputation query. This is read in chunks
* as part of our nsIStreamListener implementation and may contain embedded
* NULLs.
*/
nsCString mResponse;
/**
* Clean up and call the callback. PendingLookup must not be used after this
* function is called.
*/
nsresult OnComplete(bool shouldBlock, nsresult rv);
/**
* Wrapper function for nsIStreamListener.onStopRequest to make it easy to
* guarantee calling the callback
*/
nsresult OnStopRequestInternal(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aResult,
bool* aShouldBlock);
/**
* Sends a query to the remote application reputation service. Returns NS_OK
* on success.
*/
nsresult SendRemoteQuery();
};
ApplicationReputationService *
ApplicationReputationService::GetSingleton()
{
if (gApplicationReputationService) {
NS_ADDREF(gApplicationReputationService);
return gApplicationReputationService;
}
NS_IMPL_ISUPPORTS3(PendingLookup,
nsIStreamListener,
nsIRequestObserver,
nsIUrlClassifierCallback)
gApplicationReputationService = new ApplicationReputationService();
if (gApplicationReputationService) {
NS_ADDREF(gApplicationReputationService);
}
return gApplicationReputationService;
PendingLookup::PendingLookup(nsIApplicationReputationQuery* aQuery,
nsIApplicationReputationCallback* aCallback) :
mQuery(aQuery),
mCallback(aCallback) {
}
ApplicationReputationService::ApplicationReputationService() { }
ApplicationReputationService::~ApplicationReputationService() { }
PendingLookup::~PendingLookup() {
}
nsresult
PendingLookup::OnComplete(bool shouldBlock, nsresult rv) {
nsresult res = mCallback->OnComplete(shouldBlock, rv);
return res;
}
////////////////////////////////////////////////////////////////////////////////
//// nsIUrlClassifierCallback
NS_IMETHODIMP
ApplicationReputationService::QueryReputation(
nsIApplicationReputationQuery* aQuery,
nsIApplicationReputationCallback* aCallback) {
NS_ENSURE_ARG_POINTER(aQuery);
NS_ENSURE_ARG_POINTER(aCallback);
PendingLookup::HandleEvent(const nsACString& tables) {
// HandleEvent is guaranteed to call the callback if either the URL can be
// classified locally, or if there is an error sending the remote lookup.
// Allow listing trumps block listing.
nsCString allow_list;
Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE, &allow_list);
if (FindInReadable(tables, allow_list)) {
return OnComplete(false, NS_OK);
}
nsresult rv = QueryReputationInternal(aQuery, aCallback);
nsCString block_list;
Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE, &block_list);
if (FindInReadable(tables, block_list)) {
return OnComplete(true, NS_OK);
}
nsresult rv = SendRemoteQuery();
if (NS_FAILED(rv)) {
aCallback->OnComplete(false, rv);
aCallback = nullptr;
return OnComplete(false, rv);
}
return NS_OK;
}
nsresult
ApplicationReputationService::QueryReputationInternal(
nsIApplicationReputationQuery* aQuery,
nsIApplicationReputationCallback* aCallback) {
nsresult rv;
aQuery->SetCallback(aCallback);
// If malware checks aren't enabled, don't query application reputation.
if (!Preferences::GetBool(PREF_SB_MALWARE_ENABLED, false)) {
return NS_ERROR_NOT_AVAILABLE;
}
// If there is no service URL for querying application reputation, abort.
nsCString serviceUrl;
NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_SB_APP_REP_URL, &serviceUrl),
NS_ERROR_NOT_AVAILABLE);
if (serviceUrl.EqualsLiteral("")) {
return NS_ERROR_NOT_AVAILABLE;
}
PendingLookup::SendRemoteQuery() {
// We did not find a local result, so fire off the query to the application
// reputation service.
safe_browsing::ClientDownloadRequest req;
nsCOMPtr<nsIURI> uri;
nsresult rv;
rv = mQuery->GetSourceURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
nsCString spec;
nsCOMPtr<nsIURI> aURI;
rv = aQuery->GetSourceURI(getter_AddRefs(aURI));
rv = uri->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
// If the URI hasn't been set, bail
NS_ENSURE_STATE(aURI);
rv = aURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
req.set_url(spec.get());
uint32_t fileSize;
rv = aQuery->GetFileSize(&fileSize);
rv = mQuery->GetFileSize(&fileSize);
NS_ENSURE_SUCCESS(rv, rv);
req.set_length(fileSize);
// We have no way of knowing whether or not a user initiated the download.
@ -121,11 +161,11 @@ ApplicationReputationService::QueryReputationInternal(
NS_ERROR_NOT_AVAILABLE);
req.set_locale(locale.get());
nsCString sha256Hash;
rv = aQuery->GetSha256Hash(sha256Hash);
rv = mQuery->GetSha256Hash(sha256Hash);
NS_ENSURE_SUCCESS(rv, rv);
req.mutable_digests()->set_sha256(sha256Hash.Data());
nsString fileName;
rv = aQuery->GetSuggestedFileName(fileName);
rv = mQuery->GetSuggestedFileName(fileName);
NS_ENSURE_SUCCESS(rv, rv);
req.set_file_basename(NS_ConvertUTF16toUTF8(fileName).get());
@ -150,6 +190,9 @@ ApplicationReputationService::QueryReputationInternal(
// Set up the channel to transmit the request to the service.
nsCOMPtr<nsIChannel> channel;
nsCString serviceUrl;
NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_SB_APP_REP_URL, &serviceUrl),
NS_ERROR_NOT_AVAILABLE);
rv = ios->NewChannel(serviceUrl, nullptr, nullptr, getter_AddRefs(channel));
NS_ENSURE_SUCCESS(rv, rv);
@ -171,96 +214,14 @@ ApplicationReputationService::QueryReputationInternal(
NS_LITERAL_CSTRING("POST"), false);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStreamListener> listener = do_QueryInterface(aQuery, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = channel->AsyncOpen(listener, nullptr);
rv = channel->AsyncOpen(this, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMPL_ISUPPORTS3(ApplicationReputationQuery,
nsIApplicationReputationQuery,
nsIStreamListener,
nsIRequestObserver)
ApplicationReputationQuery::ApplicationReputationQuery() :
mURI(nullptr),
mFileSize(0),
mCallback(nullptr) {
}
ApplicationReputationQuery::~ApplicationReputationQuery() {
}
NS_IMETHODIMP
ApplicationReputationQuery::GetSourceURI(nsIURI** aURI) {
*aURI = mURI;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
ApplicationReputationQuery::SetSourceURI(nsIURI* aURI) {
mURI = aURI;
return NS_OK;
}
NS_IMETHODIMP
ApplicationReputationQuery::GetSuggestedFileName(
nsAString& aSuggestedFileName) {
aSuggestedFileName = mSuggestedFileName;
return NS_OK;
}
NS_IMETHODIMP
ApplicationReputationQuery::SetSuggestedFileName(
const nsAString& aSuggestedFileName) {
mSuggestedFileName = aSuggestedFileName;
return NS_OK;
}
NS_IMETHODIMP
ApplicationReputationQuery::GetFileSize(uint32_t* aFileSize) {
*aFileSize = mFileSize;
return NS_OK;
}
NS_IMETHODIMP
ApplicationReputationQuery::SetFileSize(uint32_t aFileSize) {
mFileSize = aFileSize;
return NS_OK;
}
NS_IMETHODIMP
ApplicationReputationQuery::GetSha256Hash(nsACString& aSha256Hash) {
aSha256Hash = mSha256Hash;
return NS_OK;
}
NS_IMETHODIMP
ApplicationReputationQuery::SetSha256Hash(const nsACString& aSha256Hash) {
mSha256Hash = aSha256Hash;
return NS_OK;
}
NS_IMETHODIMP
ApplicationReputationQuery::GetCallback(
nsIApplicationReputationCallback** aCallback) {
*aCallback = mCallback;
return NS_OK;
}
NS_IMETHODIMP
ApplicationReputationQuery::SetCallback(
nsIApplicationReputationCallback* aCallback) {
mCallback = aCallback;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
//// nsIStreamListener
static NS_METHOD
AppendSegmentToString(nsIInputStream* inputStream,
void *closure,
@ -275,40 +236,39 @@ AppendSegmentToString(nsIInputStream* inputStream,
}
NS_IMETHODIMP
ApplicationReputationQuery::OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aStream,
uint64_t offset,
uint32_t count) {
PendingLookup::OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aStream,
uint64_t offset,
uint32_t count) {
uint32_t read;
return aStream->ReadSegments(AppendSegmentToString, &mResponse, count, &read);
}
NS_IMETHODIMP
ApplicationReputationQuery::OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext) {
PendingLookup::OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext) {
return NS_OK;
}
NS_IMETHODIMP
ApplicationReputationQuery::OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aResult) {
PendingLookup::OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aResult) {
NS_ENSURE_STATE(mCallback);
bool shouldBlock = false;
nsresult rv = OnStopRequestInternal(aRequest, aContext, aResult,
&shouldBlock);
mCallback->OnComplete(shouldBlock, rv);
mCallback = nullptr;
OnComplete(shouldBlock, rv);
return rv;
}
nsresult
ApplicationReputationQuery::OnStopRequestInternal(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aResult,
bool* aShouldBlock) {
PendingLookup::OnStopRequestInternal(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aResult,
bool* aShouldBlock) {
*aShouldBlock = false;
nsresult rv;
nsCOMPtr<nsIHttpChannel> channel = do_QueryInterface(aRequest, &rv);
@ -337,3 +297,98 @@ ApplicationReputationQuery::OnStopRequestInternal(nsIRequest *aRequest,
return NS_OK;
}
NS_IMPL_ISUPPORTS1(ApplicationReputationService,
nsIApplicationReputationService)
ApplicationReputationService*
ApplicationReputationService::gApplicationReputationService = nullptr;
ApplicationReputationService*
ApplicationReputationService::GetSingleton()
{
if (gApplicationReputationService) {
NS_ADDREF(gApplicationReputationService);
return gApplicationReputationService;
}
// We're not initialized yet.
gApplicationReputationService = new ApplicationReputationService();
if (gApplicationReputationService) {
NS_ADDREF(gApplicationReputationService);
}
return gApplicationReputationService;
}
ApplicationReputationService::ApplicationReputationService() :
mDBService(nullptr),
mSecurityManager(nullptr) {
}
ApplicationReputationService::~ApplicationReputationService() {
}
NS_IMETHODIMP
ApplicationReputationService::QueryReputation(
nsIApplicationReputationQuery* aQuery,
nsIApplicationReputationCallback* aCallback) {
NS_ENSURE_ARG_POINTER(aQuery);
NS_ENSURE_ARG_POINTER(aCallback);
nsresult rv = QueryReputationInternal(aQuery, aCallback);
if (NS_FAILED(rv)) {
aCallback->OnComplete(false, rv);
}
return NS_OK;
}
nsresult ApplicationReputationService::QueryReputationInternal(
nsIApplicationReputationQuery* aQuery,
nsIApplicationReputationCallback* aCallback) {
// Lazily instantiate mDBService and mSecurityManager
nsresult rv;
if (!mDBService) {
mDBService = do_GetService(NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!mSecurityManager) {
mSecurityManager = do_GetService("@mozilla.org/scriptsecuritymanager;1",
&rv);
NS_ENSURE_SUCCESS(rv, rv);
}
// If malware checks aren't enabled, don't query application reputation.
if (!Preferences::GetBool(PREF_SB_MALWARE_ENABLED, false)) {
return NS_ERROR_NOT_AVAILABLE;
}
// If there is no service URL for querying application reputation, abort.
nsCString serviceUrl;
NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_SB_APP_REP_URL, &serviceUrl),
NS_ERROR_NOT_AVAILABLE);
if (serviceUrl.EqualsLiteral("")) {
return NS_ERROR_NOT_AVAILABLE;
}
// Create a new pending lookup.
nsRefPtr<PendingLookup> lookup(new PendingLookup(aQuery, aCallback));
NS_ENSURE_STATE(lookup);
nsCOMPtr<nsIURI> uri;
rv = aQuery->GetSourceURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
// If the URI hasn't been set, bail
NS_ENSURE_STATE(uri);
nsCOMPtr<nsIPrincipal> principal;
// In nsIUrlClassifierDBService.lookup, the only use of the principal is to
// wrap the URI. nsISecurityManager.getNoAppCodebasePrincipal is the easiest
// way to wrap a URI inside a principal, since principals can't be
// constructed.
rv = mSecurityManager->GetNoAppCodebasePrincipal(uri,
getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
// Check local lists to see if the URI has already been whitelisted or
// blacklisted.
return mDBService->Lookup(principal, lookup);
}

View File

@ -15,11 +15,10 @@
#include "nsCOMPtr.h"
#include "nsString.h"
class nsIApplicationReputationListener;
class nsIChannel;
class nsIObserverService;
class nsIRequest;
class PRLogModuleInfo;
class nsIUrlClassifierDBService;
class nsIScriptSecurityManager;
class PendingLookup;
class ApplicationReputationService MOZ_FINAL :
public nsIApplicationReputationService {
@ -35,10 +34,16 @@ private:
* Global singleton object for holding this factory service.
*/
static ApplicationReputationService* gApplicationReputationService;
/**
* Keeps track of services used to query the local database of URLs.
*/
nsCOMPtr<nsIUrlClassifierDBService> mDBService;
nsCOMPtr<nsIScriptSecurityManager> mSecurityManager;
/**
* This is a singleton, so disallow construction.
*/
ApplicationReputationService();
~ApplicationReputationService();
/**
* Wrapper function for QueryReputation that makes it easier to ensure the
* callback is called.
@ -46,53 +51,4 @@ private:
nsresult QueryReputationInternal(nsIApplicationReputationQuery* aQuery,
nsIApplicationReputationCallback* aCallback);
};
/**
* This class implements nsIApplicationReputation. See the
* nsIApplicationReputation.idl for details. ApplicationReputation also
* implements nsIStreamListener because it calls nsIChannel->AsyncOpen.
*/
class ApplicationReputationQuery MOZ_FINAL :
public nsIApplicationReputationQuery,
public nsIStreamListener {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIAPPLICATIONREPUTATIONQUERY
ApplicationReputationQuery();
~ApplicationReputationQuery();
private:
/**
* Corresponding member variables for the attributes in the IDL.
*/
nsString mSuggestedFileName;
nsCOMPtr<nsIURI> mURI;
uint32_t mFileSize;
nsCString mSha256Hash;
/**
* The callback for the request.
*/
nsCOMPtr<nsIApplicationReputationCallback> mCallback;
/**
* The response from the application reputation query. This is read in chunks
* as part of our nsIStreamListener implementation and may contain embedded
* NULLs.
*/
nsCString mResponse;
/**
* Wrapper function for nsIStreamListener.onStopRequest to make it easy to
* guarantee calling the callback
*/
nsresult OnStopRequestInternal(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aResult,
bool* aShouldBlock);
};
#endif /* ApplicationReputation_h__ */

View File

@ -19,10 +19,14 @@ MODULE = 'downloads'
CPP_SOURCES += [
'SQLFunctions.cpp',
'nsDownloadManager.cpp',
'ApplicationReputation.cpp',
'csd.pb.cc'
]
if CONFIG['MOZ_URL_CLASSIFIER']:
CPP_SOURCES += [
'ApplicationReputation.cpp',
'csd.pb.cc'
]
if CONFIG['OS_ARCH'] == 'WINNT':
CPP_SOURCES += [
'nsDownloadScanner.cpp',

View File

@ -43,12 +43,12 @@ interface nsIApplicationReputationService : nsISupports {
* downloaded file. nsIApplicationReputationService.Start() may only be called
* once with a single query.
*/
[scriptable, uuid(857da2c0-cfe5-11e2-8b8b-0800200c9a66)]
[scriptable, uuid(5a054991-e489-4a1c-a0aa-ea7c69b20e3d)]
interface nsIApplicationReputationQuery : nsISupports {
/*
* The nsIURI from which the file was downloaded. This may not be null.
*/
attribute nsIURI sourceURI;
readonly attribute nsIURI sourceURI;
/*
* The target filename for the downloaded file, as inferred from the source
@ -56,24 +56,19 @@ interface nsIApplicationReputationQuery : nsISupports {
* is not set by the caller, it will be passed as an empty string but the
* query won't produce any useful information.
*/
attribute AString suggestedFileName;
readonly attribute AString suggestedFileName;
/*
* The size of the downloaded file in bytes.
*/
attribute unsigned long fileSize;
readonly attribute unsigned long fileSize;
/*
* The SHA256 hash of the downloaded file in raw bytes. If this is not set by
* the caller, it will be passed as an empty string but the query won't
* produce any useful information.
*/
attribute ACString sha256Hash;
/**
* The callback object listening to this query.
*/
attribute nsIApplicationReputationCallback callback;
readonly attribute ACString sha256Hash;
};
[scriptable, function, uuid(9a228470-cfe5-11e2-8b8b-0800200c9a66)]

View File

@ -0,0 +1,2 @@
a:5:32:32
<EFBFBD><EFBFBD>_H<EFBFBD>^<5E>a<EFBFBD>7<EFBFBD><37>]<5D>=#<23>nm<6E><6D><EFBFBD><EFBFBD>n<EFBFBD><6E>o<EFBFBD><6F>Q<EFBFBD>

View File

@ -7,13 +7,47 @@
Cu.import('resource://gre/modules/NetUtil.jsm');
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const ApplicationReputationQuery = Components.Constructor(
"@mozilla.org/downloads/application-reputation-query;1",
"nsIApplicationReputationQuery");
const gAppRep = Cc["@mozilla.org/downloads/application-reputation-service;1"].
getService(Ci.nsIApplicationReputationService);
let gHttpServ = null;
let gTables = {};
function readFileToString(aFilename) {
let f = do_get_file(aFilename);
let stream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
stream.init(f, -1, 0, 0);
let buf = NetUtil.readInputStreamToString(stream, stream.available());
return buf;
}
// Registers a table for which to serve update chunks. Returns a promise that
// resolves when that chunk has been downloaded.
function registerTableUpdate(aTable, aFilename) {
// If we haven't been given an update for this table yet, add it to the map
if (!(aTable in gTables)) {
gTables[aTable] = [];
}
// The number of chunks associated with this table.
let numChunks = gTables[aTable].length + 1;
let redirectPath = "/" + aTable + "-" + numChunks;
let redirectUrl = "localhost:4444" + redirectPath;
// Store redirect url for that table so we can return it later when we
// process an update request.
gTables[aTable].push(redirectUrl);
gHttpServ.registerPathHandler(redirectPath, function(request, response) {
do_print("Mock safebrowsing server handling request for " + redirectPath);
let contents = readFileToString(aFilename);
do_print("Length of " + aFilename + ": " + contents.length);
response.setHeader("Content-Type",
"application/vnd.google.safebrowsing-update", false);
response.setStatusLine(request.httpVersion, 200, "OK");
response.bodyOutputStream.write(contents, contents.length);
});
}
function run_test() {
// Set up a local HTTP server to return bad verdicts.
@ -49,13 +83,16 @@ function run_test() {
request.bodyInputStream,
request.bodyInputStream.available());
do_print("Request length: " + buf.length);
// A garbage response.
// A garbage response. By default this produces NS_CANNOT_CONVERT_DATA as
// the callback status.
let blob = "this is not a serialized protocol buffer";
// We can't actually parse the protocol buffer here, so just switch on the
// length instead of inspecting the contents.
if (buf.length == 35) {
// evil.com
blob = createVerdict(true);
} else if (buf.length == 38) {
// mozilla.com
blob = createVerdict(false);
}
response.bodyOutputStream.write(blob, blob.length);
@ -67,11 +104,10 @@ function run_test() {
}
add_test(function test_shouldBlock() {
let query = new ApplicationReputationQuery();
query.sourceURI = createURI("http://evil.com");
query.fileSize = 12;
gAppRep.queryReputation(query, function onComplete(aShouldBlock, aStatus) {
gAppRep.queryReputation({
sourceURI: createURI("http://evil.com"),
fileSize: 12,
}, function onComplete(aShouldBlock, aStatus) {
do_check_true(aShouldBlock);
do_check_eq(Cr.NS_OK, aStatus);
run_next_test();
@ -79,35 +115,21 @@ add_test(function test_shouldBlock() {
});
add_test(function test_shouldNotBlock() {
let query = new ApplicationReputationQuery();
query.sourceURI = createURI("http://mozilla.com");
query.fileSize = 12;
gAppRep.queryReputation(query, function onComplete(aShouldBlock, aStatus) {
gAppRep.queryReputation({
sourceURI: createURI("http://mozilla.com"),
fileSize: 12,
}, function onComplete(aShouldBlock, aStatus) {
do_check_eq(Cr.NS_OK, aStatus);
do_check_false(aShouldBlock);
run_next_test();
});
});
add_test(function test_garbage() {
let query = new ApplicationReputationQuery();
query.sourceURI = createURI("http://thisisagarbageurl.com");
query.fileSize = 12;
gAppRep.queryReputation(query, function onComplete(aShouldBlock, aStatus) {
// We should be getting the garbage response.
do_check_eq(Cr.NS_ERROR_CANNOT_CONVERT_DATA, aStatus);
do_check_false(aShouldBlock);
run_next_test();
});
});
add_test(function test_nullSourceURI() {
let query = new ApplicationReputationQuery();
query.fileSize = 12;
// No source URI
gAppRep.queryReputation(query, function onComplete(aShouldBlock, aStatus) {
gAppRep.queryReputation({
// No source URI
fileSize: 12,
}, function onComplete(aShouldBlock, aStatus) {
do_check_eq(Cr.NS_ERROR_UNEXPECTED, aStatus);
do_check_false(aShouldBlock);
run_next_test();
@ -115,10 +137,11 @@ add_test(function test_nullSourceURI() {
});
add_test(function test_nullCallback() {
let query = new ApplicationReputationQuery();
query.fileSize = 12;
try {
gAppRep.queryReputation(query, null);
gAppRep.queryReputation({
sourceURI: createURI("http://example.com"),
fileSize: 12,
}, null);
do_throw("Callback cannot be null");
} catch (ex if ex.result == Cr.NS_ERROR_INVALID_POINTER) {
run_next_test();
@ -127,13 +150,92 @@ add_test(function test_nullCallback() {
add_test(function test_disabled() {
Services.prefs.setCharPref("browser.safebrowsing.appRepURL", "");
let query = new ApplicationReputationQuery();
query.sourceURI = createURI("http://example.com");
query.fileSize = 12;
gAppRep.queryReputation(query, function onComplete(aShouldBlock, aStatus) {
gAppRep.queryReputation({
sourceURI: createURI("http://example.com"),
fileSize: 12,
}, function onComplete(aShouldBlock, aStatus) {
// We should be getting NS_ERROR_NOT_AVAILABLE if the service is disabled
do_check_eq(Cr.NS_ERROR_NOT_AVAILABLE, aStatus);
do_check_false(aShouldBlock);
run_next_test();
});
});
add_test(function test_garbage() {
Services.prefs.setCharPref("browser.safebrowsing.appRepURL",
"http://localhost:4444/download");
gAppRep.queryReputation({
sourceURI: createURI("http://whitelisted.com"),
fileSize: 12,
}, function onComplete(aShouldBlock, aStatus) {
// We should be getting the garbage response.
do_check_eq(Cr.NS_ERROR_CANNOT_CONVERT_DATA, aStatus);
do_check_false(aShouldBlock);
run_next_test();
});
});
// Set up the local whitelist.
add_test(function test_local_list() {
// Construct a response with redirect urls.
function processUpdateRequest() {
let response = "n:1000\n";
for (let table in gTables) {
response += "i:" + table + "\n";
for (let i = 0; i < gTables[table].length; ++i) {
response += "u:" + gTables[table][i] + "\n";
}
}
do_print("Returning update response: " + response);
return response;
}
gHttpServ.registerPathHandler("/downloads", function(request, response) {
let buf = NetUtil.readInputStreamToString(request.bodyInputStream,
request.bodyInputStream.available());
let blob = processUpdateRequest();
response.setHeader("Content-Type",
"application/vnd.google.safebrowsing-update", false);
response.setStatusLine(request.httpVersion, 200, "OK");
response.bodyOutputStream.write(blob, blob.length);
});
let streamUpdater = Cc["@mozilla.org/url-classifier/streamupdater;1"]
.getService(Ci.nsIUrlClassifierStreamUpdater);
streamUpdater.updateUrl = "http://localhost:4444/downloads";
// Load up some update chunks for the safebrowsing server to serve. This
// particular chunk contains the hash of whitelisted.com/.
registerTableUpdate("goog-downloadwhite-digest256", "data/digest.chunk");
// Download some updates, and don't continue until the downloads are done.
function updateSuccess(aEvent) {
// Timeout of n:1000 is constructed in processUpdateRequest above and
// passed back in the callback in nsIUrlClassifierStreamUpdater on success.
do_check_eq("1000", aEvent);
do_print("All data processed");
run_next_test();
}
// Just throw if we ever get an update or download error.
function handleError(aEvent) {
do_throw("We didn't download or update correctly: " + aEvent);
}
streamUpdater.downloadUpdates(
"goog-downloadwhite-digest256",
"goog-downloadwhite-digest256;\n", "",
updateSuccess, handleError, handleError);
});
// After being whitelisted, we shouldn't throw.
add_test(function test_local_whitelist() {
Services.prefs.setCharPref("browser.safebrowsing.appRepURL",
"http://localhost:4444/download");
gAppRep.queryReputation({
sourceURI: createURI("http://whitelisted.com"),
fileSize: 12,
}, function onComplete(aShouldBlock, aStatus) {
// We would get garbage if this query made it to the remote server.
do_check_eq(Cr.NS_OK, aStatus);
do_check_false(aShouldBlock);
run_next_test();
});
});

View File

@ -8,6 +8,7 @@ support-files =
downloads_manifest.js
empty_downloads.rdf
test_downloads.manifest
data/digest.chunk
[test_app_rep.js]
[test_bug_382825.js]

View File

@ -10,8 +10,12 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
const [phishingList, malwareList] =
Services.prefs.getCharPref("urlclassifier.gethashtables").split(",").map(function(value) value.trim());
const phishingList = Services.prefs.getCharPref("urlclassifier.phish_table");
const malwareList = Services.prefs.getCharPref("urlclassifier.malware_table");
const downloadBlockList =
Services.prefs.getCharPref("urlclassifier.download_block_table");
const downloadAllowList =
Services.prefs.getCharPref("urlclassifier.download_allow_table");
var debug = false;
function log(...stuff) {
@ -39,6 +43,8 @@ this.SafeBrowsing = {
getService(Ci.nsIUrlListManager);
listManager.registerTable(phishingList, false);
listManager.registerTable(malwareList, false);
listManager.registerTable(downloadBlockList, false);
listManager.registerTable(downloadAllowList, false);
this.addMozEntries();
this.controlUpdateChecking();

View File

@ -48,9 +48,14 @@ EXTRA_JS_MODULES += [
'SafeBrowsing.jsm',
]
EXPORTS += [
'Entries.h',
'LookupCache.h',
'nsUrlClassifierPrefixSet.h',
]
FAIL_ON_WARNINGS = True
LIBXUL_LIBRARY = True
MSVC_ENABLE_PGO = True

View File

@ -33,6 +33,7 @@
#include "mozilla/Atomics.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Mutex.h"
#include "mozilla/Preferences.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Telemetry.h"
#include "prlog.h"
@ -68,7 +69,10 @@ PRLogModuleInfo *gUrlClassifierDbServiceLog = nullptr;
#define GETHASH_NOISE_PREF "urlclassifier.gethashnoise"
#define GETHASH_NOISE_DEFAULT 4
#define GETHASH_TABLES_PREF "urlclassifier.gethashtables"
#define MALWARE_TABLE_PREF "urlclassifier.malware_table"
#define PHISH_TABLE_PREF "urlclassifier.phish_table"
#define DOWNLOAD_BLOCK_TABLE_PREF "urlclassifier.download_block_table"
#define DOWNLOAD_ALLOW_TABLE_PREF "urlclassifier.download_allow_table"
#define CONFIRM_AGE_PREF "urlclassifier.max-complete-age"
#define CONFIRM_AGE_DEFAULT_SEC (45 * 60)
@ -1115,43 +1119,34 @@ nsUrlClassifierDBService::Init()
gUrlClassifierDbServiceLog = PR_NewLogModule("UrlClassifierDbService");
#endif
nsresult rv;
// Retrieve all the preferences.
mCheckMalware = Preferences::GetBool(CHECK_MALWARE_PREF,
CHECK_MALWARE_DEFAULT);
mCheckPhishing = Preferences::GetBool(CHECK_PHISHING_PREF,
CHECK_PHISHING_DEFAULT);
uint32_t gethashNoise = Preferences::GetUint(GETHASH_NOISE_PREF,
GETHASH_NOISE_DEFAULT);
gFreshnessGuarantee = Preferences::GetInt(CONFIRM_AGE_PREF,
CONFIRM_AGE_DEFAULT_SEC);
mGethashTables.AppendElement(Preferences::GetCString(PHISH_TABLE_PREF));
mGethashTables.AppendElement(Preferences::GetCString(MALWARE_TABLE_PREF));
mGethashTables.AppendElement(Preferences::GetCString(
DOWNLOAD_BLOCK_TABLE_PREF));
mGethashTables.AppendElement(Preferences::GetCString(
DOWNLOAD_ALLOW_TABLE_PREF));
// Should we check document loads for malware URIs?
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
uint32_t gethashNoise = 0;
if (prefs) {
bool tmpbool;
rv = prefs->GetBoolPref(CHECK_MALWARE_PREF, &tmpbool);
mCheckMalware = NS_SUCCEEDED(rv) ? tmpbool : CHECK_MALWARE_DEFAULT;
prefs->AddObserver(CHECK_MALWARE_PREF, this, false);
rv = prefs->GetBoolPref(CHECK_PHISHING_PREF, &tmpbool);
mCheckPhishing = NS_SUCCEEDED(rv) ? tmpbool : CHECK_PHISHING_DEFAULT;
prefs->AddObserver(CHECK_PHISHING_PREF, this, false);
int32_t tmpint;
rv = prefs->GetIntPref(GETHASH_NOISE_PREF, &tmpint);
gethashNoise = (NS_SUCCEEDED(rv) && tmpint >= 0) ?
static_cast<uint32_t>(tmpint) : GETHASH_NOISE_DEFAULT;
nsXPIDLCString tmpstr;
if (NS_SUCCEEDED(prefs->GetCharPref(GETHASH_TABLES_PREF, getter_Copies(tmpstr)))) {
SplitTables(tmpstr, mGethashWhitelist);
}
prefs->AddObserver(GETHASH_TABLES_PREF, this, false);
rv = prefs->GetIntPref(CONFIRM_AGE_PREF, &tmpint);
gFreshnessGuarantee = NS_SUCCEEDED(rv) ? tmpint : CONFIRM_AGE_DEFAULT_SEC;
prefs->AddObserver(CONFIRM_AGE_PREF, this, false);
}
// Do we *really* need to be able to change all of these at runtime?
Preferences::AddStrongObserver(this, CHECK_MALWARE_PREF);
Preferences::AddStrongObserver(this, CHECK_PHISHING_PREF);
Preferences::AddStrongObserver(this, GETHASH_NOISE_PREF);
Preferences::AddStrongObserver(this, CONFIRM_AGE_PREF);
Preferences::AddStrongObserver(this, PHISH_TABLE_PREF);
Preferences::AddStrongObserver(this, MALWARE_TABLE_PREF);
Preferences::AddStrongObserver(this, DOWNLOAD_BLOCK_TABLE_PREF);
Preferences::AddStrongObserver(this, DOWNLOAD_ALLOW_TABLE_PREF);
// Force PSM loading on main thread
nsresult rv;
nsCOMPtr<nsICryptoHash> acryptoHash = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
@ -1429,7 +1424,7 @@ nsUrlClassifierDBService::GetCompleter(const nsACString &tableName,
return true;
}
if (!mGethashWhitelist.Contains(tableName)) {
if (!mGethashTables.Contains(tableName)) {
return false;
}
@ -1446,23 +1441,26 @@ nsUrlClassifierDBService::Observe(nsISupports *aSubject, const char *aTopic,
nsCOMPtr<nsIPrefBranch> prefs(do_QueryInterface(aSubject, &rv));
NS_ENSURE_SUCCESS(rv, rv);
if (NS_LITERAL_STRING(CHECK_MALWARE_PREF).Equals(aData)) {
bool tmpbool;
rv = prefs->GetBoolPref(CHECK_MALWARE_PREF, &tmpbool);
mCheckMalware = NS_SUCCEEDED(rv) ? tmpbool : CHECK_MALWARE_DEFAULT;
mCheckMalware = Preferences::GetBool(CHECK_MALWARE_PREF,
CHECK_MALWARE_DEFAULT);
} else if (NS_LITERAL_STRING(CHECK_PHISHING_PREF).Equals(aData)) {
bool tmpbool;
rv = prefs->GetBoolPref(CHECK_PHISHING_PREF, &tmpbool);
mCheckPhishing = NS_SUCCEEDED(rv) ? tmpbool : CHECK_PHISHING_DEFAULT;
} else if (NS_LITERAL_STRING(GETHASH_TABLES_PREF).Equals(aData)) {
mGethashWhitelist.Clear();
nsXPIDLCString val;
if (NS_SUCCEEDED(prefs->GetCharPref(GETHASH_TABLES_PREF, getter_Copies(val)))) {
SplitTables(val, mGethashWhitelist);
}
mCheckPhishing = Preferences::GetBool(CHECK_PHISHING_PREF,
CHECK_PHISHING_DEFAULT);
} else if (NS_LITERAL_STRING(PHISH_TABLE_PREF).Equals(aData) ||
NS_LITERAL_STRING(MALWARE_TABLE_PREF).Equals(aData) ||
NS_LITERAL_STRING(DOWNLOAD_BLOCK_TABLE_PREF).Equals(aData) ||
NS_LITERAL_STRING(DOWNLOAD_ALLOW_TABLE_PREF).Equals(aData)) {
// Just read everything again.
mGethashTables.Clear();
mGethashTables.AppendElement(Preferences::GetCString(PHISH_TABLE_PREF));
mGethashTables.AppendElement(Preferences::GetCString(MALWARE_TABLE_PREF));
mGethashTables.AppendElement(Preferences::GetCString(
DOWNLOAD_BLOCK_TABLE_PREF));
mGethashTables.AppendElement(Preferences::GetCString(
DOWNLOAD_ALLOW_TABLE_PREF));
} else if (NS_LITERAL_STRING(CONFIRM_AGE_PREF).Equals(aData)) {
int32_t tmpint;
rv = prefs->GetIntPref(CONFIRM_AGE_PREF, &tmpint);
gFreshnessGuarantee = NS_SUCCEEDED(rv) ? tmpint : CONFIRM_AGE_DEFAULT_SEC;
gFreshnessGuarantee = Preferences::GetInt(CONFIRM_AGE_PREF,
CONFIRM_AGE_DEFAULT_SEC);
}
} else if (!strcmp(aTopic, "profile-before-change") ||
!strcmp(aTopic, "xpcom-shutdown-threads")) {
@ -1489,7 +1487,10 @@ nsUrlClassifierDBService::Shutdown()
if (prefs) {
prefs->RemoveObserver(CHECK_MALWARE_PREF, this);
prefs->RemoveObserver(CHECK_PHISHING_PREF, this);
prefs->RemoveObserver(GETHASH_TABLES_PREF, this);
prefs->RemoveObserver(PHISH_TABLE_PREF, this);
prefs->RemoveObserver(MALWARE_TABLE_PREF, this);
prefs->RemoveObserver(DOWNLOAD_BLOCK_TABLE_PREF, this);
prefs->RemoveObserver(DOWNLOAD_ALLOW_TABLE_PREF, this);
prefs->RemoveObserver(CONFIRM_AGE_PREF, this);
}

View File

@ -101,7 +101,7 @@ private:
bool mInUpdate;
// The list of tables that can use the default hash completer object.
nsTArray<nsCString> mGethashWhitelist;
nsTArray<nsCString> mGethashTables;
// Thread that we do the updates on.
static nsIThread* gDbBackgroundThread;