/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=2 sts=2 ts=8 et 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/. */
// Put CachedPrefs in anonymous namespace to avoid any collision from outside of // this file. namespace {
/** * It is not recommended to read from Preference everytime a channel is * connected. * That is not fast and we should cache preference values and reuse them
*/ class CachedPrefs final { public: static CachedPrefs* GetInstance();
void nsChannelClassifier::Start() {
nsresult rv = StartInternal(); if (NS_FAILED(rv)) { // If we aren't getting a callback for any reason, assume a good verdict and // make sure we resume the channel if necessary.
OnClassifyComplete(NS_OK, ""_ns, ""_ns, ""_ns);
}
}
nsresult nsChannelClassifier::StartInternal() { // Should only be called in the parent process.
MOZ_ASSERT(XRE_IsParentProcess());
// Don't bother to run the classifier on a load that has already failed. // (this might happen after a redirect)
nsresult status;
mChannel->GetStatus(&status); if (NS_FAILED(status)) return status;
// Don't bother to run the classifier on a cached load that was // previously classified as good. if (HasBeenClassified(mChannel)) { return NS_ERROR_UNEXPECTED;
}
bool expectCallback; if (UC_LOG_ENABLED()) {
nsCOMPtr<nsIURI> principalURI;
nsCString spec;
principal->GetAsciiSpec(spec);
spec.Truncate(std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(
("nsChannelClassifier::StartInternal - classifying principal %s on " "channel %p [this=%p]",
spec.get(), mChannel.get(), this));
} // The classify is running in parent process, no need to give a valid event // target
rv = uriClassifier->Classify(principal, this, &expectCallback); if (NS_FAILED(rv)) { return rv;
}
if (expectCallback) { // Suspend the channel, it will be resumed when we get the classifier // callback.
rv = mChannel->Suspend(); if (NS_FAILED(rv)) { // Some channels (including nsJSChannel) fail on Suspend. This // shouldn't be fatal, but will prevent malware from being // blocked on these channels.
UC_LOG_WARN(
("nsChannelClassifier::StartInternal - couldn't suspend channel " "[this=%p]", this)); return rv;
}
// Note in the cache entry that this URL was classified, so that future // cached loads don't need to be checked. void nsChannelClassifier::MarkEntryClassified(nsresult status) { // Should only be called in the parent process.
MOZ_ASSERT(XRE_IsParentProcess());
// Don't cache tracking classifications because we support allowlisting. if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status) ||
mIsAllowListed) { return;
}
if (UC_LOG_ENABLED()) {
nsAutoCString errorName;
GetErrorName(status, errorName);
nsCOMPtr<nsIURI> uri;
mChannel->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetAsciiSpec(spec);
spec.Truncate(std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(
("nsChannelClassifier::MarkEntryClassified - result is %s " "for uri %s [this=%p, channel=%p]",
errorName.get(), spec.get(), this, mChannel.get()));
}
nsCOMPtr<nsICachingChannel> cachingChannel = do_QueryInterface(mChannel); if (!cachingChannel) { return;
}
nsCOMPtr<nsISupports> cacheToken;
cachingChannel->GetCacheToken(getter_AddRefs(cacheToken)); if (!cacheToken) { return;
}
nsCOMPtr<nsICacheEntry> cacheEntry = do_QueryInterface(cacheToken); if (!cacheEntry) { return;
}
bool nsChannelClassifier::HasBeenClassified(nsIChannel* aChannel) { // Should only be called in the parent process.
MOZ_ASSERT(XRE_IsParentProcess());
nsCOMPtr<nsICachingChannel> cachingChannel = do_QueryInterface(aChannel); if (!cachingChannel) { returnfalse;
}
// Only check the tag if we are loading from the cache without // validation. bool fromCache; if (NS_FAILED(cachingChannel->IsFromCache(&fromCache)) || !fromCache) { returnfalse;
}
nsCOMPtr<nsISupports> cacheToken;
cachingChannel->GetCacheToken(getter_AddRefs(cacheToken)); if (!cacheToken) { returnfalse;
}
nsCOMPtr<nsICacheEntry> cacheEntry = do_QueryInterface(cacheToken); if (!cacheEntry) { returnfalse;
}
NS_IMETHODIMP
nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode, const nsACString& aList, const nsACString& aProvider, const nsACString& aFullHash) { // Should only be called in the parent process.
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(
!UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode));
if (mSuspendedChannel) {
MarkEntryClassified(aErrorCode);
if (NS_FAILED(aErrorCode)) { if (UC_LOG_ENABLED()) {
nsAutoCString errorName;
GetErrorName(aErrorCode, errorName);
// Channel will be cancelled (page element blocked) due to Safe Browsing. // Do update the security state of the document and fire a security // change event.
UrlClassifierCommon::SetBlockedContent(mChannel, aErrorCode, aList,
aProvider, aFullHash);
/////////////////////////////////////////////////////////////////////////////// // nsIObserver implementation
NS_IMETHODIMP
nsChannelClassifier::Observe(nsISupports* aSubject, constchar* aTopic, const char16_t* aData) { if (!strcmp(aTopic, "profile-change-net-teardown")) { // If we aren't getting a callback for any reason, make sure // we resume the channel.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.