mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
83e3f07339
commit
a1caaa978a
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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");
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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 },
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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',
|
||||
|
@ -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)]
|
||||
|
2
toolkit/components/downloads/test/unit/data/digest.chunk
Normal file
2
toolkit/components/downloads/test/unit/data/digest.chunk
Normal 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>
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
@ -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]
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user