Bug 1514202 - Port flash url-classifier to nsIUrlClassifierFeature - part 1 - Flash feature, r=dimi, r=edgar, r=valentin

This commit is contained in:
Andrea Marchesini 2019-01-04 14:45:42 +01:00
Родитель b68f36a865
Коммит e34612e16e
42 изменённых файлов: 829 добавлений и 183 удалений

Просмотреть файл

@ -6,13 +6,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PContent;
include PURLClassifierInfo;
using refcounted class nsIURI from "mozilla/ipc/URIUtils.h";
namespace mozilla {
namespace dom {
struct URLClassifierLocalResult
{
nsIURI uri;
nsCString featureName;
nsCString matchingList;
};

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/dom/PURLClassifierChild.h"
#include "mozilla/dom/PURLClassifierLocalChild.h"
#include "mozilla/ipc/URIUtils.h"
#include "mozilla/net/UrlClassifierFeatureResult.h"
#include "nsIURIClassifier.h"
#include "nsIUrlClassifierFeature.h"
@ -63,8 +64,14 @@ class URLClassifierLocalChild : public PURLClassifierLocalChild {
continue;
}
RefPtr<nsIURI> uri = result.uri();
if (NS_WARN_IF(!uri)) {
continue;
}
RefPtr<net::UrlClassifierFeatureResult> r =
new net::UrlClassifierFeatureResult(feature, result.matchingList());
new net::UrlClassifierFeatureResult(uri, feature,
result.matchingList());
finalResults.AppendElement(r);
break;
}

Просмотреть файл

@ -53,8 +53,8 @@ class IPCFeature final : public nsIUrlClassifierFeature {
public:
NS_DECL_ISUPPORTS
explicit IPCFeature(const IPCURLClassifierFeature& aFeature)
: mIPCFeature(aFeature) {}
IPCFeature(nsIURI* aURI, const IPCURLClassifierFeature& aFeature)
: mURI(aURI), mIPCFeature(aFeature) {}
NS_IMETHOD
GetName(nsACString& aName) override {
@ -102,9 +102,22 @@ class IPCFeature final : public nsIUrlClassifierFeature {
return NS_OK;
}
NS_IMETHOD
GetURIByListType(nsIChannel* aChannel,
nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) override {
NS_ENSURE_ARG_POINTER(aURI);
// This method should not be called, but we have a URI, let's return it.
nsCOMPtr<nsIURI> uri = mURI;
uri.forget(aURI);
return NS_OK;
}
private:
~IPCFeature() = default;
nsCOMPtr<nsIURI> mURI;
IPCURLClassifierFeature mIPCFeature;
};
@ -130,7 +143,7 @@ mozilla::ipc::IPCResult URLClassifierLocalParent::StartClassify(
nsTArray<RefPtr<nsIUrlClassifierFeature>> features;
for (const IPCURLClassifierFeature& feature : aFeatures) {
features.AppendElement(new IPCFeature(feature));
features.AppendElement(new IPCFeature(aURI, feature));
}
// Doesn't matter if we pass blacklist, whitelist or any other list.
@ -154,6 +167,8 @@ URLClassifierLocalParent::OnClassifyComplete(
net::UrlClassifierFeatureResult* r =
static_cast<net::UrlClassifierFeatureResult*>(result);
ipcResult->uri() = r->URI();
r->Feature()->GetName(ipcResult->featureName());
ipcResult->matchingList() = r->List();
}

Просмотреть файл

@ -1940,6 +1940,22 @@ VARCACHE_PREF(
)
#undef PREF_VALUE
//---------------------------------------------------------------------------
// Plugins prefs
//---------------------------------------------------------------------------
VARCACHE_PREF(
"plugins.flashBlock.enabled",
plugins_flashBlock_enabled,
bool, false
)
VARCACHE_PREF(
"plugins.http_https_only",
plugins_http_https_only,
bool, true
)
//---------------------------------------------------------------------------
// Reporting API
//---------------------------------------------------------------------------

Просмотреть файл

@ -5655,9 +5655,6 @@ pref("urlclassifier.flashSubDocTable", "block-flashsubdoc-digest256");
pref("urlclassifier.flashSubDocExceptTable", "except-flashsubdoc-digest256");
pref("urlclassifier.flashInfobarTable", "except-flashinfobar-digest256");
pref("plugins.http_https_only", true);
pref("plugins.flashBlock.enabled", false);
// Turn off Spatial navigation by default.
pref("snav.enabled", false);

Просмотреть файл

@ -52,6 +52,13 @@ SimpleChannelParent::NotifyTrackingResource(bool aIsThirdParty) {
return NS_OK;
}
NS_IMETHODIMP
SimpleChannelParent::NotifyFlashPluginStateChanged(
nsIHttpChannel::FlashPluginState aState) {
// Nothing to do.
return NS_OK;
}
NS_IMETHODIMP
SimpleChannelParent::SetClassifierMatchedInfo(const nsACString& aList,
const nsACString& aProvider,

Просмотреть файл

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIStreamListener.idl"
#include "nsIHttpChannel.idl"
interface nsITabParent;
@ -46,6 +47,11 @@ interface nsIParentChannel : nsIStreamListener
*/
[noscript] void notifyTrackingCookieBlocked(in uint32_t aRejectedReason);
/**
* Called to notify the HttpChannelChild that flash plugin state has changed.
*/
[noscript] void notifyFlashPluginStateChanged(in nsIHttpChannel_FlashPluginState aState);
/**
* Called to set matched information when URL matches SafeBrowsing list.
* @param aList

Просмотреть файл

@ -10,6 +10,7 @@
#include "ipc/IPCMessageUtils.h"
#include "nsExceptionHandler.h"
#include "nsIHttpChannel.h"
#include "nsPrintfCString.h"
#include "nsString.h"
#include "prio.h"
@ -179,6 +180,12 @@ struct ParamTraits<mozilla::net::ResourceTimingStruct> {
}
};
template <>
struct ParamTraits<nsIHttpChannel::FlashPluginState>
: public ContiguousEnumSerializerInclusive<
nsIHttpChannel::FlashPluginState, nsIHttpChannel::FlashPluginUnknown,
nsIHttpChannel::FlashPluginLastValue> {};
} // namespace IPC
#endif // mozilla_net_NeckoMessageUtils_h

Просмотреть файл

@ -52,6 +52,13 @@ DataChannelParent::NotifyTrackingResource(bool aIsThirdParty) {
return NS_OK;
}
NS_IMETHODIMP
DataChannelParent::NotifyFlashPluginStateChanged(
nsIHttpChannel::FlashPluginState aState) {
// Nothing to do.
return NS_OK;
}
NS_IMETHODIMP
DataChannelParent::SetClassifierMatchedInfo(const nsACString &aList,
const nsACString &aProvider,

Просмотреть файл

@ -52,6 +52,13 @@ FileChannelParent::NotifyTrackingResource(bool aIsThirdParty) {
return NS_OK;
}
NS_IMETHODIMP
FileChannelParent::NotifyFlashPluginStateChanged(
nsIHttpChannel::FlashPluginState aState) {
// Nothing to do.
return NS_OK;
}
NS_IMETHODIMP
FileChannelParent::SetClassifierMatchedInfo(const nsACString &aList,
const nsACString &aProvider,

Просмотреть файл

@ -523,6 +523,13 @@ FTPChannelParent::NotifyTrackingResource(bool aIsThirdParty) {
return NS_OK;
}
NS_IMETHODIMP
FTPChannelParent::NotifyFlashPluginStateChanged(
nsIHttpChannel::FlashPluginState aState) {
// One day, this should probably be filled in.
return NS_OK;
}
NS_IMETHODIMP
FTPChannelParent::SetClassifierMatchedInfo(const nsACString& aList,
const nsACString& aProvider,

Просмотреть файл

@ -358,6 +358,25 @@ IPCResult HttpBackgroundChannelChild::RecvNotifyTrackingResource(
return IPC_OK();
}
IPCResult HttpBackgroundChannelChild::RecvNotifyFlashPluginStateChanged(
const nsIHttpChannel::FlashPluginState& aState) {
LOG(
("HttpBackgroundChannelChild::RecvNotifyFlashPluginStateChanged "
"[this=%p]\n",
this));
MOZ_ASSERT(OnSocketThread());
if (NS_WARN_IF(!mChannelChild)) {
return IPC_OK();
}
// NotifyFlashPluginStateChanged has no order dependency to OnStartRequest.
// It this be handled as soon as possible
mChannelChild->ProcessNotifyFlashPluginStateChanged(aState);
return IPC_OK();
}
IPCResult HttpBackgroundChannelChild::RecvSetClassifierMatchedInfo(
const ClassifierInfo& info) {
LOG(("HttpBackgroundChannelChild::RecvSetClassifierMatchedInfo [this=%p]\n",

Просмотреть файл

@ -72,6 +72,9 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
IPCResult RecvNotifyTrackingResource(const bool& aIsThirdParty) override;
IPCResult RecvNotifyFlashPluginStateChanged(
const nsIHttpChannel::FlashPluginState& aState) override;
IPCResult RecvSetClassifierMatchedInfo(const ClassifierInfo& info) override;
void ActorDestroy(ActorDestroyReason aWhy) override;

Просмотреть файл

@ -426,6 +426,37 @@ bool HttpBackgroundChannelParent::OnNotifyTrackingResource(bool aIsThirdParty) {
return SendNotifyTrackingResource(aIsThirdParty);
}
bool HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged(
nsIHttpChannel::FlashPluginState aState) {
LOG(
("HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged "
"[this=%p]\n",
this));
AssertIsInMainProcess();
if (NS_WARN_IF(!mIPCOpened)) {
return false;
}
if (!IsOnBackgroundThread()) {
MutexAutoLock lock(mBgThreadMutex);
RefPtr<HttpBackgroundChannelParent> self = this;
nsresult rv = mBackgroundThread->Dispatch(
NS_NewRunnableFunction(
"net::HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged",
[self, aState]() {
self->OnNotifyFlashPluginStateChanged(aState);
}),
NS_DISPATCH_NORMAL);
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
return NS_SUCCEEDED(rv);
}
return SendNotifyFlashPluginStateChanged(aState);
}
bool HttpBackgroundChannelParent::OnSetClassifierMatchedInfo(
const nsACString& aList, const nsACString& aProvider,
const nsACString& aFullHash) {

Просмотреть файл

@ -75,6 +75,9 @@ class HttpBackgroundChannelParent final : public PHttpBackgroundChannelParent {
// To send NotifyTrackingResource message over background channel.
bool OnNotifyTrackingResource(bool aIsThirdParty);
// To send NotifyFlashPluginStateChanged message over background channel.
bool OnNotifyFlashPluginStateChanged(nsIHttpChannel::FlashPluginState aState);
// To send SetClassifierMatchedInfo message over background channel.
bool OnSetClassifierMatchedInfo(const nsACString& aList,
const nsACString& aProvider,

Просмотреть файл

@ -168,6 +168,7 @@ HttpBaseChannel::HttpBaseChannel()
mCanceled(false),
mIsFirstPartyTrackingResource(false),
mIsThirdPartyTrackingResource(false),
mFlashPluginState(nsIHttpChannel::FlashPluginUnknown),
mLoadFlags(LOAD_NORMAL),
mCaps(0),
mClassOfService(0),
@ -319,6 +320,12 @@ void HttpBaseChannel::SetIsTrackingResource(bool aIsThirdParty) {
}
}
void HttpBaseChannel::SetFlashPluginState(
nsIHttpChannel::FlashPluginState aState) {
LOG(("HttpBaseChannel::SetFlashPluginState %p", this));
mFlashPluginState = aState;
}
nsresult HttpBaseChannel::Init(nsIURI* aURI, uint32_t aCaps,
nsProxyInfo* aProxyInfo,
uint32_t aProxyResolveFlags, nsIURI* aProxyURI,
@ -1485,6 +1492,13 @@ HttpBaseChannel::GetIsThirdPartyTrackingResource(bool* aIsTrackingResource) {
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetFlashPluginState(nsIHttpChannel::FlashPluginState* aState) {
uint32_t flashPluginState = mFlashPluginState;
*aState = (nsIHttpChannel::FlashPluginState)flashPluginState;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::OverrideTrackingFlagsForDocumentCookieAccessor(
nsIHttpChannel* aDocumentChannel) {

Просмотреть файл

@ -238,6 +238,8 @@ class HttpBaseChannel : public nsHashPropertyBag,
bool *aIsTrackingResource) override;
NS_IMETHOD OverrideTrackingFlagsForDocumentCookieAccessor(
nsIHttpChannel *aDocumentChannel) override;
NS_IMETHOD GetFlashPluginState(
nsIHttpChannel::FlashPluginState *aState) override;
// nsIHttpChannelInternal
NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI) override;
@ -413,6 +415,8 @@ class HttpBaseChannel : public nsHashPropertyBag,
void SetIsTrackingResource(bool aIsThirdParty);
void SetFlashPluginState(nsIHttpChannel::FlashPluginState aState);
const uint64_t &ChannelId() const { return mChannelId; }
void InternalSetUploadStream(nsIInputStream *uploadStream) {
@ -647,6 +651,7 @@ class HttpBaseChannel : public nsHashPropertyBag,
Atomic<bool, ReleaseAcquire> mCanceled;
Atomic<bool, ReleaseAcquire> mIsFirstPartyTrackingResource;
Atomic<bool, ReleaseAcquire> mIsThirdPartyTrackingResource;
Atomic<uint32_t, ReleaseAcquire> mFlashPluginState;
uint32_t mLoadFlags;
uint32_t mCaps;

Просмотреть файл

@ -1862,6 +1862,15 @@ void HttpChannelChild::ProcessNotifyTrackingResource(bool aIsThirdParty) {
SetIsTrackingResource(aIsThirdParty);
}
void HttpChannelChild::ProcessNotifyFlashPluginStateChanged(
nsIHttpChannel::FlashPluginState aState) {
LOG(("HttpChannelChild::ProcessNotifyFlashPluginStateChanged [this=%p]\n",
this));
MOZ_ASSERT(OnSocketThread());
SetFlashPluginState(aState);
}
void HttpChannelChild::FlushedForDiversion() {
LOG(("HttpChannelChild::FlushedForDiversion [this=%p]\n", this));
MOZ_RELEASE_ASSERT(mDivertingToParent);

Просмотреть файл

@ -265,6 +265,8 @@ class HttpChannelChild final : public PHttpChannelChild,
void ProcessNotifyCookieAllowed();
void ProcessNotifyTrackingCookieBlocked(uint32_t aRejectedReason);
void ProcessNotifyTrackingResource(bool aIsThirdParty);
void ProcessNotifyFlashPluginStateChanged(
nsIHttpChannel::FlashPluginState aState);
void ProcessSetClassifierMatchedInfo(const nsCString& aList,
const nsCString& aProvider,
const nsCString& aFullHash);

Просмотреть файл

@ -1826,6 +1826,17 @@ HttpChannelParent::NotifyTrackingResource(bool aIsThirdParty) {
return NS_OK;
}
NS_IMETHODIMP
HttpChannelParent::NotifyFlashPluginStateChanged(
nsIHttpChannel::FlashPluginState aState) {
LOG(("HttpChannelParent::NotifyFlashPluginStateChanged [this=%p]\n", this));
if (!mIPCClosed) {
MOZ_ASSERT(mBgParent);
Unused << mBgParent->OnNotifyFlashPluginStateChanged(aState);
}
return NS_OK;
}
NS_IMETHODIMP
HttpChannelParent::Delete() {
if (!mIPCClosed) Unused << DoSendDeleteSelf();

Просмотреть файл

@ -88,6 +88,12 @@ NullHttpChannel::GetIsTrackingResource(bool *aIsTrackingResource) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NullHttpChannel::GetFlashPluginState(
nsIHttpChannel::FlashPluginState *aResult) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NullHttpChannel::GetIsThirdPartyTrackingResource(bool *aIsTrackingResource) {
return NS_ERROR_NOT_IMPLEMENTED;

Просмотреть файл

@ -13,6 +13,7 @@ include "mozilla/net/NeckoMessageUtils.h";
using class nsHttpHeaderArray from "nsHttpHeaderArray.h";
using struct mozilla::net::ResourceTimingStruct from "mozilla/net/TimingStruct.h";
using nsIHttpChannel::FlashPluginState from "mozilla/net/NeckoMessageUtils.h";
namespace mozilla {
namespace net {
@ -66,6 +67,10 @@ child:
// protection list.
async NotifyTrackingResource(bool aIsThirdParty);
// Tell the child that the current channel's document is not allowed to load
// flash content.
async NotifyFlashPluginStateChanged(FlashPluginState aState);
// Tell the child information of matched URL againts SafeBrowsing list
async SetClassifierMatchedInfo(ClassifierInfo info);

Просмотреть файл

@ -495,6 +495,20 @@ interface nsIHttpChannel : nsIChannel
*/
[infallible] readonly attribute boolean isThirdPartyTrackingResource;
/**
* Returns the allowing status for flash plugin for this channel.
*/
cenum FlashPluginState : 8 {
FlashPluginUnknown = 0,
FlashPluginAllowed = 1,
FlashPluginDenied = 2,
FlashPluginDeniedInSubdocuments = 3,
// Keep this equal to the last value.
FlashPluginLastValue = 3,
};
[infallible] readonly attribute nsIHttpChannel_FlashPluginState flashPluginState;
/**
* This method is used by the document.cookie call site in order
* to override the tracking status of an HTTP channel. This should

Просмотреть файл

@ -765,6 +765,13 @@ nsViewSourceChannel::GetIsTrackingResource(bool *aIsTrackingResource) {
: mHttpChannel->GetIsTrackingResource(aIsTrackingResource);
}
NS_IMETHODIMP
nsViewSourceChannel::GetFlashPluginState(
nsIHttpChannel::FlashPluginState *aResult) {
return !mHttpChannel ? NS_ERROR_NULL_POINTER
: mHttpChannel->GetFlashPluginState(aResult);
}
NS_IMETHODIMP
nsViewSourceChannel::GetIsThirdPartyTrackingResource(
bool *aIsTrackingResource) {

Просмотреть файл

@ -24,6 +24,74 @@ namespace net {
namespace {
// When we do blacklist/whitelist classification, from a list of features, we
// need to aggregate them per URI, because not all the features work with the
// same channel's URI.
// This struct contains only the features able to deal with a particular URI.
// See more in GetFeatureTasks().
struct FeatureTask {
nsCOMPtr<nsIURI> mURI;
// Let's use RefPtr<> here, because this needs to be used with methods which
// require it.
nsTArray<RefPtr<nsIUrlClassifierFeature>> mFeatures;
};
// Features are able to classify particular URIs from a channel. For instance,
// tracking-annotation feature uses the top-level URI to whitelist the current
// channel's URI; flash feature always uses the channel's URI. Because of
// this, this function aggregates feature per URI in an array of FeatureTask
// object.
nsresult GetFeatureTasks(
nsIChannel* aChannel,
const nsTArray<nsCOMPtr<nsIUrlClassifierFeature>>& aFeatures,
nsIUrlClassifierFeature::listType aListType,
nsTArray<FeatureTask>& aTasks) {
MOZ_ASSERT(!aFeatures.IsEmpty());
// Let's unify features per nsIURI.
for (nsIUrlClassifierFeature* feature : aFeatures) {
nsCOMPtr<nsIURI> uri;
nsresult rv =
feature->GetURIByListType(aChannel, aListType, getter_AddRefs(uri));
if (NS_WARN_IF(NS_FAILED(rv)) || !uri) {
if (UC_LOG_ENABLED()) {
nsAutoCString errorName;
GetErrorName(rv, errorName);
UC_LOG(
("GetFeatureTasks got an unexpected error (rv=%s) while trying to "
"create a whitelist URI. Allowing tracker.",
errorName.get()));
}
return rv;
}
MOZ_ASSERT(uri);
bool found = false;
for (FeatureTask& task : aTasks) {
bool equal = false;
rv = task.mURI->Equals(uri, &equal);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (equal) {
task.mFeatures.AppendElement(feature);
found = true;
break;
}
}
if (!found) {
FeatureTask* task = aTasks.AppendElement();
task->mURI = uri;
task->mFeatures.AppendElement(feature);
}
}
return NS_OK;
}
nsresult TrackerFound(
const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aResults,
nsIChannel* aChannel, const std::function<void()>& aCallback) {
@ -48,81 +116,6 @@ nsresult TrackerFound(
return NS_OK;
}
nsresult CreateWhiteListURI(nsIChannel* aChannel, nsIURI** aURI) {
MOZ_ASSERT(aChannel);
MOZ_ASSERT(aURI);
nsresult rv;
nsCOMPtr<nsIHttpChannelInternal> chan = do_QueryInterface(aChannel, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (!chan) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIURI> topWinURI;
rv = chan->GetTopWindowURI(getter_AddRefs(topWinURI));
NS_ENSURE_SUCCESS(rv, rv);
if (!topWinURI) {
if (UC_LOG_ENABLED()) {
nsresult rv;
nsCOMPtr<nsIHttpChannel> httpChan = do_QueryInterface(aChannel, &rv);
nsCOMPtr<nsIURI> uri;
rv = httpChan->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetAsciiSpec(spec);
spec.Truncate(
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(
("CreateWhiteListURI: No window URI associated with %s", spec.get()));
}
return NS_OK;
}
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> chanPrincipal;
rv = securityManager->GetChannelURIPrincipal(aChannel,
getter_AddRefs(chanPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
// Craft a whitelist URL like "toplevel.page/?resource=third.party.domain"
nsAutoCString pageHostname, resourceDomain;
rv = topWinURI->GetHost(pageHostname);
NS_ENSURE_SUCCESS(rv, rv);
rv = chanPrincipal->GetBaseDomain(resourceDomain);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString whitelistEntry = NS_LITERAL_CSTRING("http://") + pageHostname +
NS_LITERAL_CSTRING("/?resource=") +
resourceDomain;
UC_LOG(("CreateWhiteListURI: Looking for %s in the whitelist (channel=%p)",
whitelistEntry.get(), aChannel));
nsCOMPtr<nsIURI> whitelistURI;
rv = NS_NewURI(getter_AddRefs(whitelistURI), whitelistEntry);
NS_ENSURE_SUCCESS(rv, rv);
whitelistURI.forget(aURI);
return NS_OK;
}
nsresult IsTrackerWhitelisted(
nsIURI* aWhiteListURI,
const nsTArray<RefPtr<nsIUrlClassifierFeature>>& aFeatures,
nsIUrlClassifierFeatureCallback* aCallback) {
MOZ_ASSERT(aWhiteListURI);
MOZ_ASSERT(!aFeatures.IsEmpty());
MOZ_ASSERT(aCallback);
nsresult rv;
nsCOMPtr<nsIURIClassifier> uriClassifier =
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return uriClassifier->AsyncClassifyLocalWithFeatures(
aWhiteListURI, aFeatures, nsIUrlClassifierFeature::whitelist, aCallback);
}
// This class is designed to get the results of checking whitelist.
class WhitelistClassifierCallback final
: public nsIUrlClassifierFeatureCallback {
@ -131,25 +124,34 @@ class WhitelistClassifierCallback final
NS_DECL_NSIURLCLASSIFIERFEATURECALLBACK
WhitelistClassifierCallback(
nsIChannel* aChannel, nsIURI* aURI,
nsIChannel* aChannel,
const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aBlacklistResults,
std::function<void()>& aCallback)
: mChannel(aChannel),
mURI(aURI),
mTaskCount(0),
mBlacklistResults(aBlacklistResults),
mChannelCallback(aCallback) {
MOZ_ASSERT(mChannel);
MOZ_ASSERT(mURI);
MOZ_ASSERT(!mBlacklistResults.IsEmpty());
}
void SetTaskCount(uint32_t aTaskCount) {
MOZ_ASSERT(aTaskCount > 0);
mTaskCount = aTaskCount;
}
private:
~WhitelistClassifierCallback() = default;
nsresult OnClassifyCompleteInternal();
nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsIURI> mURI;
uint32_t mTaskCount;
nsTArray<RefPtr<nsIUrlClassifierFeatureResult>> mBlacklistResults;
std::function<void()> mChannelCallback;
nsTArray<RefPtr<nsIUrlClassifierFeatureResult>> mWhitelistResults;
};
NS_IMPL_ISUPPORTS(WhitelistClassifierCallback, nsIUrlClassifierFeatureCallback)
@ -157,18 +159,33 @@ NS_IMPL_ISUPPORTS(WhitelistClassifierCallback, nsIUrlClassifierFeatureCallback)
NS_IMETHODIMP
WhitelistClassifierCallback::OnClassifyComplete(
const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aWhitelistResults) {
MOZ_ASSERT(mTaskCount > 0);
UC_LOG(("WhitelistClassifierCallback[%p]:OnClassifyComplete channel=%p", this,
mChannel.get()));
mWhitelistResults.AppendElements(aWhitelistResults);
if (--mTaskCount) {
// More callbacks will come.
return NS_OK;
}
return OnClassifyCompleteInternal();
}
nsresult WhitelistClassifierCallback::OnClassifyCompleteInternal() {
nsTArray<RefPtr<nsIUrlClassifierFeatureResult>> remainingResults;
for (nsIUrlClassifierFeatureResult* blacklistResult : mBlacklistResults) {
nsIUrlClassifierFeature* blacklistFeature =
static_cast<UrlClassifierFeatureResult*>(blacklistResult)->Feature();
UrlClassifierFeatureResult* result =
static_cast<UrlClassifierFeatureResult*>(blacklistResult);
nsIUrlClassifierFeature* blacklistFeature = result->Feature();
MOZ_ASSERT(blacklistFeature);
bool found = false;
for (nsIUrlClassifierFeatureResult* whitelistResult : aWhitelistResults) {
for (nsIUrlClassifierFeatureResult* whitelistResult : mWhitelistResults) {
// We can do pointer comparison because Features are singletons.
if (static_cast<UrlClassifierFeatureResult*>(whitelistResult)
->Feature() == blacklistFeature) {
@ -188,13 +205,12 @@ WhitelistClassifierCallback::OnClassifyComplete(
continue;
}
if (nsContentUtils::IsURIInList(mURI, skipList)) {
if (nsContentUtils::IsURIInList(result->URI(), skipList)) {
if (UC_LOG_ENABLED()) {
nsCString spec = mURI->GetSpecOrDefault();
UC_LOG(
("WhitelistClassifierCallback[%p]::OnClassifyComplete uri %s found "
"in skiplist",
this, spec.get()));
("WhitelistClassifierCallback[%p]::OnClassifyComplete uri found in "
"skiplist",
this));
}
continue;
@ -207,13 +223,10 @@ WhitelistClassifierCallback::OnClassifyComplete(
if (remainingResults.IsEmpty()) {
if (UC_LOG_ENABLED()) {
nsCString spec = mURI->GetSpecOrDefault();
spec.Truncate(
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(
("WhitelistClassifierCallback[%p]::OnClassifyComplete uri %s fully "
("WhitelistClassifierCallback[%p]::OnClassifyComplete uri fully "
"whitelisted",
this, spec.get()));
this));
}
mChannelCallback();
@ -221,12 +234,10 @@ WhitelistClassifierCallback::OnClassifyComplete(
}
if (UC_LOG_ENABLED()) {
nsCString spec = mURI->GetSpecOrDefault();
spec.Truncate(std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(
("WhitelistClassifierCallback[%p]::OnClassifyComplete "
"channel[%p] uri=%s, should not be whitelisted",
this, mChannel.get(), spec.get()));
("WhitelistClassifierCallback[%p]::OnClassifyComplete channel[%p] "
"should not be whitelisted",
this, mChannel.get()));
}
return TrackerFound(remainingResults, mChannel, mChannelCallback);
@ -239,19 +250,29 @@ class BlacklistClassifierCallback final
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIURLCLASSIFIERFEATURECALLBACK
BlacklistClassifierCallback(nsIChannel* aChannel, nsIURI* aURI,
BlacklistClassifierCallback(nsIChannel* aChannel,
std::function<void()>&& aCallback)
: mChannel(aChannel), mURI(aURI), mChannelCallback(std::move(aCallback)) {
: mChannel(aChannel),
mTaskCount(0),
mChannelCallback(std::move(aCallback)) {
MOZ_ASSERT(mChannel);
MOZ_ASSERT(mURI);
}
void SetTaskCount(uint32_t aTaskCount) {
MOZ_ASSERT(aTaskCount > 0);
mTaskCount = aTaskCount;
}
private:
~BlacklistClassifierCallback() = default;
nsresult OnClassifyCompleteInternal();
nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsIURI> mURI;
uint32_t mTaskCount;
std::function<void()> mChannelCallback;
nsTArray<RefPtr<nsIUrlClassifierFeatureResult>> mResults;
};
NS_IMPL_ISUPPORTS(BlacklistClassifierCallback, nsIUrlClassifierFeatureCallback)
@ -259,18 +280,29 @@ NS_IMPL_ISUPPORTS(BlacklistClassifierCallback, nsIUrlClassifierFeatureCallback)
NS_IMETHODIMP
BlacklistClassifierCallback::OnClassifyComplete(
const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aResults) {
UC_LOG(("BlacklistClassifierCallback[%p]:OnClassifyComplete", this));
MOZ_ASSERT(mTaskCount > 0);
UC_LOG(("BlacklistClassifierCallback[%p]:OnClassifyComplete - remaining %d",
this, mTaskCount));
mResults.AppendElements(aResults);
if (--mTaskCount) {
// More callbacks will come.
return NS_OK;
}
return OnClassifyCompleteInternal();
}
nsresult BlacklistClassifierCallback::OnClassifyCompleteInternal() {
// All good! The URL has not been classified.
if (aResults.IsEmpty()) {
if (mResults.IsEmpty()) {
if (UC_LOG_ENABLED()) {
nsCString spec = mURI->GetSpecOrDefault();
spec.Truncate(
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(
("BlacklistClassifierCallback[%p]::OnClassifyComplete uri %s not "
"found in blacklist",
this, spec.get()));
("BlacklistClassifierCallback[%p]::OnClassifyComplete uri not found "
"in blacklist",
this));
}
mChannelCallback();
@ -278,63 +310,79 @@ BlacklistClassifierCallback::OnClassifyComplete(
}
if (UC_LOG_ENABLED()) {
nsCString spec = mURI->GetSpecOrDefault();
spec.Truncate(std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(
("BlacklistClassifierCallback[%p]::OnClassifyComplete uri %s is in "
("BlacklistClassifierCallback[%p]::OnClassifyComplete uri is in "
"blacklist. Start checking whitelist.",
this, spec.get()));
this));
}
nsCOMPtr<nsIURI> whitelistURI;
nsresult rv = CreateWhiteListURI(mChannel, getter_AddRefs(whitelistURI));
if (NS_FAILED(rv)) {
nsAutoCString errorName;
GetErrorName(rv, errorName);
NS_WARNING(
nsPrintfCString("BlacklistClassifierCallback[%p]:OnClassifyComplete "
"got an unexpected error (rv=%s) while trying to "
"create a whitelist URI. Allowing tracker.",
this, errorName.get())
.get());
return TrackerFound(aResults, mChannel, mChannelCallback);
nsTArray<nsCOMPtr<nsIUrlClassifierFeature>> features;
for (nsIUrlClassifierFeatureResult* result : mResults) {
features.AppendElement(
static_cast<UrlClassifierFeatureResult*>(result)->Feature());
}
if (!whitelistURI) {
nsTArray<FeatureTask> tasks;
nsresult rv = GetFeatureTasks(mChannel, features,
nsIUrlClassifierFeature::whitelist, tasks);
if (NS_WARN_IF(NS_FAILED(rv))) {
return TrackerFound(mResults, mChannel, mChannelCallback);
}
if (tasks.IsEmpty()) {
UC_LOG(
("BlacklistClassifierCallback[%p]:OnClassifyComplete could not create "
"a whitelist URI. Ignoring whitelist.",
this));
return TrackerFound(aResults, mChannel, mChannelCallback);
return TrackerFound(mResults, mChannel, mChannelCallback);
}
nsCOMPtr<nsIUrlClassifierFeatureCallback> callback =
new WhitelistClassifierCallback(mChannel, mURI, aResults,
mChannelCallback);
RefPtr<WhitelistClassifierCallback> callback =
new WhitelistClassifierCallback(mChannel, mResults, mChannelCallback);
// xpcom parser creates array of interfaces using RefPtr<>.
nsTArray<RefPtr<nsIUrlClassifierFeature>> refPtrFeatures;
for (nsIUrlClassifierFeatureResult* result : aResults) {
refPtrFeatures.AppendElement(
static_cast<UrlClassifierFeatureResult*>(result)->Feature());
}
nsCOMPtr<nsIURIClassifier> uriClassifier =
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = IsTrackerWhitelisted(whitelistURI, refPtrFeatures, callback);
if (NS_WARN_IF(NS_FAILED(rv))) {
if (UC_LOG_ENABLED()) {
nsAutoCString errorName;
GetErrorName(rv, errorName);
UC_LOG(
("BlacklistClassifierCallback[%p]:OnClassifyComplete "
"IsTrackerWhitelisted has failed with rv=%s.",
this, errorName.get()));
uint32_t pendingCallbacks = 0;
for (FeatureTask& task : tasks) {
rv = uriClassifier->AsyncClassifyLocalWithFeatures(
task.mURI, task.mFeatures, nsIUrlClassifierFeature::whitelist,
callback);
if (NS_WARN_IF(NS_FAILED(rv))) {
if (UC_LOG_ENABLED()) {
nsAutoCString errorName;
GetErrorName(rv, errorName);
UC_LOG((
"BlacklistClassifierCallback[%p]:OnClassifyComplete Failed "
"calling AsyncClassifyLocalWithFeatures with rv=%s. Let's move on.",
this, errorName.get()));
}
continue;
}
return TrackerFound(aResults, mChannel, mChannelCallback);
++pendingCallbacks;
}
// All the AsyncClassifyLocalWithFeatures() calls return error. We do not
// expect callbacks.
if (pendingCallbacks == 0) {
if (UC_LOG_ENABLED()) {
UC_LOG(
("BlacklistClassifierCallback[%p]:OnClassifyComplete All "
"AsyncClassifyLocalWithFeatures() calls return errors. We cannot "
"continue.",
this));
}
return TrackerFound(mResults, mChannel, mChannelCallback);
}
// Nothing else do here. Let's wait for the WhitelistClassifierCallback.
callback->SetTaskCount(pendingCallbacks);
return NS_OK;
}
@ -349,44 +397,62 @@ BlacklistClassifierCallback::OnClassifyComplete(
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIURI> uri;
nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
if (NS_FAILED(rv) || !uri) {
return rv;
}
// We need to obtain the list of nsIUrlClassifierFeature objects able to
// classify this channel. If the list is empty, we do an early return.
nsTArray<nsCOMPtr<nsIUrlClassifierFeature>> features;
UrlClassifierFeatureFactory::GetFeaturesFromChannel(aChannel, features);
if (features.IsEmpty()) {
UC_LOG(("AsyncUrlChannelClassifier: Feature list is empty for channel %p",
aChannel));
UC_LOG(
("AsyncUrlChannelClassifier: Nothing to do for channel %p", aChannel));
return NS_ERROR_FAILURE;
}
nsTArray<FeatureTask> tasks;
nsresult rv = GetFeatureTasks(aChannel, features,
nsIUrlClassifierFeature::blacklist, tasks);
if (NS_WARN_IF(NS_FAILED(rv)) || tasks.IsEmpty()) {
return rv;
}
MOZ_ASSERT(!tasks.IsEmpty());
nsCOMPtr<nsIURIClassifier> uriClassifier =
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIUrlClassifierFeatureCallback> callback =
new BlacklistClassifierCallback(aChannel, uri, std::move(aCallback));
RefPtr<BlacklistClassifierCallback> callback =
new BlacklistClassifierCallback(aChannel, std::move(aCallback));
if (UC_LOG_ENABLED()) {
nsCString spec = uri->GetSpecOrDefault();
spec.Truncate(std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(("AsyncUrlChannelClassifier: Checking blacklist for uri=%s\n",
spec.get()));
uint32_t pendingCallbacks = 0;
for (FeatureTask& task : tasks) {
if (UC_LOG_ENABLED()) {
nsCString spec = task.mURI->GetSpecOrDefault();
spec.Truncate(
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(("AsyncUrlChannelClassifier: Checking blacklist for uri=%s\n",
spec.get()));
}
rv = uriClassifier->AsyncClassifyLocalWithFeatures(
task.mURI, task.mFeatures, nsIUrlClassifierFeature::blacklist,
callback);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
++pendingCallbacks;
}
// xpcom parser creates array of interfaces using RefPtr<>.
nsTArray<RefPtr<nsIUrlClassifierFeature>> refPtrFeatures;
for (nsIUrlClassifierFeature* feature : features) {
refPtrFeatures.AppendElement(feature);
// All the AsyncClassifyLocalWithFeatures() calls return error. We do not
// expect callbacks.
if (pendingCallbacks == 0) {
return NS_ERROR_FAILURE;
}
return uriClassifier->AsyncClassifyLocalWithFeatures(
uri, refPtrFeatures, nsIUrlClassifierFeature::blacklist, callback);
callback->SetTaskCount(pendingCallbacks);
return NS_OK;
}
} // namespace net

Просмотреть файл

@ -244,5 +244,66 @@ UrlClassifierCommon::ShouldEnableTrackingProtectionOrAnnotation(
return NS_OK;
}
/* static */ nsresult UrlClassifierCommon::CreatePairwiseWhiteListURI(
nsIChannel* aChannel, nsIURI** aURI) {
MOZ_ASSERT(aChannel);
MOZ_ASSERT(aURI);
nsresult rv;
nsCOMPtr<nsIHttpChannelInternal> chan = do_QueryInterface(aChannel, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (!chan) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIURI> topWinURI;
rv = chan->GetTopWindowURI(getter_AddRefs(topWinURI));
NS_ENSURE_SUCCESS(rv, rv);
if (!topWinURI) {
if (UC_LOG_ENABLED()) {
nsresult rv;
nsCOMPtr<nsIHttpChannel> httpChan = do_QueryInterface(aChannel, &rv);
nsCOMPtr<nsIURI> uri;
rv = httpChan->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetAsciiSpec(spec);
spec.Truncate(
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(("CreatePairwiseWhiteListURI: No window URI associated with %s",
spec.get()));
}
return NS_OK;
}
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> chanPrincipal;
rv = securityManager->GetChannelURIPrincipal(aChannel,
getter_AddRefs(chanPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
// Craft a whitelist URL like "toplevel.page/?resource=third.party.domain"
nsAutoCString pageHostname, resourceDomain;
rv = topWinURI->GetHost(pageHostname);
NS_ENSURE_SUCCESS(rv, rv);
rv = chanPrincipal->GetBaseDomain(resourceDomain);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString whitelistEntry = NS_LITERAL_CSTRING("http://") + pageHostname +
NS_LITERAL_CSTRING("/?resource=") +
resourceDomain;
UC_LOG(
("CreatePairwiseWhiteListURI: Looking for %s in the whitelist "
"(channel=%p)",
whitelistEntry.get(), aChannel));
nsCOMPtr<nsIURI> whitelistURI;
rv = NS_NewURI(getter_AddRefs(whitelistURI), whitelistEntry);
NS_ENSURE_SUCCESS(rv, rv);
whitelistURI.forget(aURI);
return NS_OK;
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -41,6 +41,11 @@ class UrlClassifierCommon final {
const nsACString& aList,
const nsACString& aProvider,
const nsACString& aFullHash);
// Use this function only when you are looking for a pairwise whitelist uri
// with the format: http://toplevel.page/?resource=channel.uri.domain
static nsresult CreatePairwiseWhiteListURI(nsIChannel* aChannel,
nsIURI** aURI);
};
} // namespace net

Просмотреть файл

@ -7,6 +7,7 @@
#include "mozilla/net/UrlClassifierFeatureFactory.h"
// List of Features
#include "UrlClassifierFeatureFlash.h"
#include "UrlClassifierFeatureLoginReputation.h"
#include "UrlClassifierFeatureTrackingProtection.h"
#include "UrlClassifierFeatureTrackingAnnotation.h"
@ -22,6 +23,7 @@ namespace net {
return;
}
UrlClassifierFeatureFlash::Initialize();
UrlClassifierFeatureTrackingAnnotation::Initialize();
UrlClassifierFeatureTrackingProtection::Initialize();
}
@ -32,6 +34,7 @@ namespace net {
return;
}
UrlClassifierFeatureFlash::Shutdown();
UrlClassifierFeatureLoginReputation::MaybeShutdown();
UrlClassifierFeatureTrackingAnnotation::Shutdown();
UrlClassifierFeatureTrackingProtection::Shutdown();
@ -61,6 +64,11 @@ namespace net {
if (feature) {
aFeatures.AppendElement(feature);
}
// Flash
nsTArray<nsCOMPtr<nsIUrlClassifierFeature>> flashFeatures;
UrlClassifierFeatureFlash::MaybeCreate(aChannel, flashFeatures);
aFeatures.AppendElements(flashFeatures);
}
/* static */

Просмотреть файл

@ -0,0 +1,155 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "UrlClassifierFeatureFlash.h"
#include "mozilla/net/HttpBaseChannel.h"
#include "nsScriptSecurityManager.h"
#include "nsQueryObject.h"
namespace mozilla {
namespace net {
namespace {
struct FlashFeatures {
const char* mName;
const char* mBlacklistPrefTables;
const char* mWhitelistPrefTables;
bool mSubdocumentOnly;
nsIHttpChannel::FlashPluginState mFlashPluginState;
RefPtr<UrlClassifierFeatureFlash> mFeature;
};
static FlashFeatures sFlashFeaturesMap[] = {
{"flash-deny", "urlclassifier.flashTable", "urlclassifier.flashExceptTable",
false, nsIHttpChannel::FlashPluginDenied},
{"flash-allow", "urlclassifier.flashAllowTable",
"urlclassifier.flashAllowExceptTable", false,
nsIHttpChannel::FlashPluginAllowed},
{"flash-deny-subdoc", "urlclassifier.flashSubDocTable",
"urlclassifier.flashSubDocExceptTable", true,
nsIHttpChannel::FlashPluginDeniedInSubdocuments},
};
} // namespace
UrlClassifierFeatureFlash::UrlClassifierFeatureFlash(uint32_t aId)
: UrlClassifierFeatureBase(
nsDependentCString(sFlashFeaturesMap[aId].mName),
nsDependentCString(sFlashFeaturesMap[aId].mBlacklistPrefTables),
nsDependentCString(sFlashFeaturesMap[aId].mWhitelistPrefTables),
EmptyCString(), // aPrefBlacklistHosts
EmptyCString(), // aPrefWhitelistHosts
EmptyCString(), // aPrefBlacklistTableName
EmptyCString(), // aPrefWhitelistTableName
EmptyCString()) // aPrefSkipHosts
,
mFlashPluginState(sFlashFeaturesMap[aId].mFlashPluginState) {
static_assert(nsIHttpChannel::FlashPluginDeniedInSubdocuments ==
nsIHttpChannel::FlashPluginLastValue,
"nsIHttpChannel::FlashPluginLastValue is out-of-sync!");
}
/* static */ void UrlClassifierFeatureFlash::Initialize() {
uint32_t numFeatures =
(sizeof(sFlashFeaturesMap) / sizeof(sFlashFeaturesMap[0]));
for (uint32_t i = 0; i < numFeatures; ++i) {
MOZ_ASSERT(!sFlashFeaturesMap[i].mFeature);
sFlashFeaturesMap[i].mFeature = new UrlClassifierFeatureFlash(i);
sFlashFeaturesMap[i].mFeature->InitializePreferences();
}
}
/* static */ void UrlClassifierFeatureFlash::Shutdown() {
uint32_t numFeatures =
(sizeof(sFlashFeaturesMap) / sizeof(sFlashFeaturesMap[0]));
for (uint32_t i = 0; i < numFeatures; ++i) {
MOZ_ASSERT(sFlashFeaturesMap[i].mFeature);
sFlashFeaturesMap[i].mFeature->ShutdownPreferences();
sFlashFeaturesMap[i].mFeature = nullptr;
}
}
/* static */ void UrlClassifierFeatureFlash::MaybeCreate(
nsIChannel* aChannel,
nsTArray<nsCOMPtr<nsIUrlClassifierFeature>>& aFeatures) {
// All disabled.
if (!StaticPrefs::plugins_flashBlock_enabled()) {
return;
}
// We use Flash feature just for document loading.
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
nsContentPolicyType contentPolicyType =
loadInfo ? loadInfo->GetExternalContentPolicyType()
: nsIContentPolicy::TYPE_INVALID;
if (contentPolicyType != nsIContentPolicy::TYPE_DOCUMENT &&
contentPolicyType != nsIContentPolicy::TYPE_SUBDOCUMENT) {
return;
}
// Only allow plugins for documents from an HTTP/HTTPS origin.
if (StaticPrefs::plugins_http_https_only()) {
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
if (!httpChannel) {
return;
}
}
uint32_t numFeatures =
(sizeof(sFlashFeaturesMap) / sizeof(sFlashFeaturesMap[0]));
for (uint32_t i = 0; i < numFeatures; ++i) {
MOZ_ASSERT(sFlashFeaturesMap[i].mFeature);
if (!sFlashFeaturesMap[i].mSubdocumentOnly ||
contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) {
aFeatures.AppendElement(sFlashFeaturesMap[i].mFeature);
}
}
}
NS_IMETHODIMP
UrlClassifierFeatureFlash::ProcessChannel(nsIChannel* aChannel,
const nsACString& aList,
bool* aShouldContinue) {
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aShouldContinue);
// This is not a blocking feature.
*aShouldContinue = true;
UC_LOG(("UrlClassifierFeatureFlash::ProcessChannel, annotating channel[%p]",
aChannel));
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(aChannel, parentChannel);
if (parentChannel) {
// This channel is a parent-process proxy for a child process
// request. We should notify the child process as well.
parentChannel->NotifyFlashPluginStateChanged(mFlashPluginState);
}
RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(aChannel);
if (httpChannel) {
httpChannel->SetFlashPluginState(mFlashPluginState);
}
return NS_OK;
}
NS_IMETHODIMP
UrlClassifierFeatureFlash::GetURIByListType(
nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) {
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aURI);
// Here we return the channel's URI always.
return aChannel->GetURI(aURI);
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_UrlClassifierFeatureFlash_h
#define mozilla_UrlClassifierFeatureFlash_h
#include "UrlClassifierFeatureBase.h"
namespace mozilla {
namespace net {
class UrlClassifierFeatureFlash final : public UrlClassifierFeatureBase {
public:
static void Initialize();
static void Shutdown();
static void MaybeCreate(
nsIChannel* aChannel,
nsTArray<nsCOMPtr<nsIUrlClassifierFeature>>& aFeatures);
NS_IMETHOD
ProcessChannel(nsIChannel* aChannel, const nsACString& aList,
bool* aShouldContinue) override;
NS_IMETHOD GetURIByListType(nsIChannel* aChannel,
nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) override;
private:
explicit UrlClassifierFeatureFlash(uint32_t aId);
nsIHttpChannel::FlashPluginState mFlashPluginState;
};
} // namespace net
} // namespace mozilla
#endif // mozilla_UrlClassifierFeatureFlash_h

Просмотреть файл

@ -93,5 +93,18 @@ UrlClassifierFeatureLoginReputation::HasHostInPreferences(
aHost, aListType, aPrefTableName, aResult);
}
NS_IMETHODIMP
UrlClassifierFeatureLoginReputation::GetURIByListType(
nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) {
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aURI);
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist,
"UrlClassifierFeatureLoginReputation is meant to be used just to "
"whitelist URLs");
return aChannel->GetURI(aURI);
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -37,6 +37,10 @@ class UrlClassifierFeatureLoginReputation final
NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList,
bool* aShouldContinue) override;
NS_IMETHOD GetURIByListType(nsIChannel* aChannel,
nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) override;
private:
UrlClassifierFeatureLoginReputation();
};

Просмотреть файл

@ -10,11 +10,19 @@ namespace mozilla {
namespace net {
UrlClassifierFeatureResult::UrlClassifierFeatureResult(
nsIUrlClassifierFeature* aFeature, const nsACString& aList)
: mFeature(aFeature), mList(aList) {}
nsIURI* aURI, nsIUrlClassifierFeature* aFeature, const nsACString& aList)
: mURI(aURI), mFeature(aFeature), mList(aList) {}
UrlClassifierFeatureResult::~UrlClassifierFeatureResult() = default;
NS_IMETHODIMP
UrlClassifierFeatureResult::GetUri(nsIURI** aURI) {
NS_ENSURE_ARG_POINTER(aURI);
nsCOMPtr<nsIURI> uri = mURI;
uri.forget(aURI);
return NS_OK;
}
NS_IMETHODIMP
UrlClassifierFeatureResult::GetFeature(nsIUrlClassifierFeature** aFeature) {
NS_ENSURE_ARG_POINTER(aFeature);

Просмотреть файл

@ -10,6 +10,8 @@
#include "nsIUrlClassifierFeature.h"
#include "nsString.h"
class nsIURI;
namespace mozilla {
namespace net {
@ -18,9 +20,11 @@ class UrlClassifierFeatureResult final : public nsIUrlClassifierFeatureResult {
NS_DECL_ISUPPORTS
NS_DECL_NSIURLCLASSIFIERFEATURERESULT
UrlClassifierFeatureResult(nsIUrlClassifierFeature* aFeature,
UrlClassifierFeatureResult(nsIURI* aURI, nsIUrlClassifierFeature* aFeature,
const nsACString& aList);
nsIURI* URI() const { return mURI; }
nsIUrlClassifierFeature* Feature() const { return mFeature; }
// Comma separated list of tables.
@ -30,6 +34,7 @@ class UrlClassifierFeatureResult final : public nsIUrlClassifierFeatureResult {
~UrlClassifierFeatureResult();
private:
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIUrlClassifierFeature> mFeature;
const nsCString mList;
};

Просмотреть файл

@ -201,5 +201,20 @@ UrlClassifierFeatureTrackingAnnotation::ProcessChannel(nsIChannel* aChannel,
return NS_OK;
}
NS_IMETHODIMP
UrlClassifierFeatureTrackingAnnotation::GetURIByListType(
nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) {
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aURI);
if (aListType == nsIUrlClassifierFeature::blacklist) {
return aChannel->GetURI(aURI);
}
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist);
return UrlClassifierCommon::CreatePairwiseWhiteListURI(aChannel, aURI);
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -27,6 +27,10 @@ class UrlClassifierFeatureTrackingAnnotation final
NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList,
bool* aShouldContinue) override;
NS_IMETHOD GetURIByListType(nsIChannel* aChannel,
nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) override;
private:
UrlClassifierFeatureTrackingAnnotation();
};

Просмотреть файл

@ -130,5 +130,20 @@ UrlClassifierFeatureTrackingProtection::ProcessChannel(nsIChannel* aChannel,
return NS_OK;
}
NS_IMETHODIMP
UrlClassifierFeatureTrackingProtection::GetURIByListType(
nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) {
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aURI);
if (aListType == nsIUrlClassifierFeature::blacklist) {
return aChannel->GetURI(aURI);
}
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist);
return UrlClassifierCommon::CreatePairwiseWhiteListURI(aChannel, aURI);
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -27,6 +27,10 @@ class UrlClassifierFeatureTrackingProtection final
NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList,
bool* aShouldContinue) override;
NS_IMETHOD GetURIByListType(nsIChannel* aChannel,
nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) override;
private:
UrlClassifierFeatureTrackingProtection();
};

Просмотреть файл

@ -23,6 +23,7 @@ UNIFIED_SOURCES += [
'UrlClassifierCommon.cpp',
'UrlClassifierFeatureBase.cpp',
'UrlClassifierFeatureFactory.cpp',
'UrlClassifierFeatureFlash.cpp',
'UrlClassifierFeatureLoginReputation.cpp',
'UrlClassifierFeatureResult.cpp',
'UrlClassifierFeatureTrackingAnnotation.cpp',

Просмотреть файл

@ -11,6 +11,7 @@
[ref] native StringArrayRef(nsTArray<nsCString>);
interface nsIChannel;
interface nsIURI;
/**
* A single URLClassifier feature.
@ -62,6 +63,14 @@ interface nsIUrlClassifierFeature : nsISupports
* processing other features.
*/
[noscript] boolean processChannel(in nsIChannel aChannel, in ACString aList);
/**
* Features can work with different URLs from a channel (channel url, or
* top-level, or something else). This method returns what we need to use for
* the current list.
*/
[noscript] nsIURI getURIByListType(in nsIChannel channel,
in nsIUrlClassifierFeature_listType listType);
};
/**
@ -71,6 +80,8 @@ interface nsIUrlClassifierFeature : nsISupports
[builtinclass, scriptable, uuid(ccb88140-5d66-4873-9815-a1b98d6cdc92)]
interface nsIUrlClassifierFeatureResult : nsISupports
{
readonly attribute nsIURI uri;
readonly attribute nsIUrlClassifierFeature feature;
// Comma separate tables or preferences.

Просмотреть файл

@ -127,11 +127,12 @@ class FeatureHolder final {
};
static already_AddRefed<FeatureHolder> Create(
const nsTArray<RefPtr<nsIUrlClassifierFeature>>& aFeatures,
nsIURI* aURI, const nsTArray<RefPtr<nsIUrlClassifierFeature>>& aFeatures,
nsIUrlClassifierFeature::listType aListType) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aURI);
RefPtr<FeatureHolder> holder = new FeatureHolder();
RefPtr<FeatureHolder> holder = new FeatureHolder(aURI);
for (nsIUrlClassifierFeature* feature : aFeatures) {
FeatureData* featureData = holder->mFeatureData.AppendElement();
@ -202,20 +203,24 @@ class FeatureHolder final {
}
RefPtr<mozilla::net::UrlClassifierFeatureResult> result =
new mozilla::net::UrlClassifierFeatureResult(featureData.mFeature,
list);
new mozilla::net::UrlClassifierFeatureResult(
mURI, featureData.mFeature, list);
aResults.AppendElement(result);
}
}
private:
FeatureHolder() { MOZ_ASSERT(NS_IsMainThread()); }
explicit FeatureHolder(nsIURI* aURI) : mURI(aURI) {
MOZ_ASSERT(NS_IsMainThread());
}
~FeatureHolder() {
for (FeatureData& featureData : mFeatureData) {
NS_ReleaseOnMainThreadSystemGroup("FeatureHolder:mFeatureData",
featureData.mFeature.forget());
}
NS_ReleaseOnMainThreadSystemGroup("FeatureHolder:mURI", mURI.forget());
}
TableData* GetOrCreateTableData(const nsACString& aTable) {
@ -230,6 +235,7 @@ class FeatureHolder final {
return tableData;
}
nsCOMPtr<nsIURI> mURI;
nsTArray<FeatureData> mFeatureData;
nsTArray<RefPtr<TableData>> mTableData;
};
@ -300,6 +306,13 @@ class DummyFeature final : public nsIUrlClassifierFeature {
return NS_OK;
}
NS_IMETHODIMP
GetURIByListType(nsIChannel* aChannel,
nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) override {
return NS_ERROR_NOT_IMPLEMENTED;
}
private:
~DummyFeature() = default;
@ -2839,7 +2852,8 @@ nsUrlClassifierDBService::AsyncClassifyLocalWithFeatures(
auto startTime = TimeStamp::Now(); // For telemetry.
// Let's keep the features alive and release them on the correct thread.
RefPtr<FeatureHolder> holder = FeatureHolder::Create(aFeatures, aListType);
RefPtr<FeatureHolder> holder =
FeatureHolder::Create(aURI, aFeatures, aListType);
if (NS_WARN_IF(!holder)) {
return NS_ERROR_FAILURE;
}
@ -2905,7 +2919,8 @@ bool nsUrlClassifierDBService::AsyncClassifyLocalWithFeaturesUsingPreferences(
LOG(("URI found in preferences. Table: %s", tableName.get()));
RefPtr<mozilla::net::UrlClassifierFeatureResult> result =
new mozilla::net::UrlClassifierFeatureResult(feature, tableName);
new mozilla::net::UrlClassifierFeatureResult(aURI, feature,
tableName);
results.AppendElement(result);
}
}

Просмотреть файл

@ -416,6 +416,12 @@ NS_IMETHODIMP nsExtProtocolChannel::NotifyTrackingResource(bool aIsThirdParty) {
return NS_OK;
}
NS_IMETHODIMP nsExtProtocolChannel::NotifyFlashPluginStateChanged(
nsIHttpChannel::FlashPluginState aState) {
// nothing to do
return NS_OK;
}
NS_IMETHODIMP nsExtProtocolChannel::Delete() {
// nothing to do
return NS_OK;