mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Backed out 3 changesets (bug 1879181
) for causing gtest failures on ContentAnalysisTest.
Backed out changeset b2407a14159f (bug1879181
) Backed out changeset 78303b2900e9 (bug1879181
) Backed out changeset 25521d09c1de (bug1879181
)
This commit is contained in:
parent
a6c8604fef
commit
0f00df454f
@ -1192,22 +1192,6 @@
|
||||
value: "path_user"
|
||||
mirror: never
|
||||
|
||||
# Space-separated list of regexs that are compared to URLs of resources
|
||||
# being checked by content-analysis. Resources that match are not checked
|
||||
# and are always permitted.
|
||||
- name: browser.contentanalysis.allow_url_regex_list
|
||||
type: String
|
||||
value: ""
|
||||
mirror: never
|
||||
|
||||
# Space-separated list of regexs that are compared to URLs of resources
|
||||
# being checked by content-analysis. Resources that match are not checked
|
||||
# and are always denied.
|
||||
- name: browser.contentanalysis.deny_url_regex_list
|
||||
type: String
|
||||
value: ""
|
||||
mirror: never
|
||||
|
||||
# Should CA ignore the system setting and use silent notifications?
|
||||
- name: browser.contentanalysis.silent_notifications
|
||||
type: bool
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "GMPUtils.h" // ToHexString
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/Services.h"
|
||||
@ -29,7 +28,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include <windows.h>
|
||||
@ -58,8 +56,6 @@ const char* kIsPerUserPref = "browser.contentanalysis.is_per_user";
|
||||
const char* kPipePathNamePref = "browser.contentanalysis.pipe_path_name";
|
||||
const char* kDefaultAllowPref = "browser.contentanalysis.default_allow";
|
||||
const char* kClientSignature = "browser.contentanalysis.client_signature";
|
||||
const char* kAllowUrlPref = "browser.contentanalysis.allow_url_regex_list";
|
||||
const char* kDenyUrlPref = "browser.contentanalysis.deny_url_regex_list";
|
||||
|
||||
nsresult MakePromise(JSContext* aCx, RefPtr<mozilla::dom::Promise>* aPromise) {
|
||||
nsIGlobalObject* go = xpc::CurrentNativeGlobal(aCx);
|
||||
@ -484,7 +480,8 @@ static void LogRequest(
|
||||
}
|
||||
|
||||
ContentAnalysisResponse::ContentAnalysisResponse(
|
||||
content_analysis::sdk::ContentAnalysisResponse&& aResponse) {
|
||||
content_analysis::sdk::ContentAnalysisResponse&& aResponse)
|
||||
: mHasAcknowledged(false) {
|
||||
mAction = Action::eUnspecified;
|
||||
for (const auto& result : aResponse.results()) {
|
||||
if (!result.has_status() ||
|
||||
@ -512,7 +509,7 @@ ContentAnalysisResponse::ContentAnalysisResponse(
|
||||
|
||||
ContentAnalysisResponse::ContentAnalysisResponse(
|
||||
Action aAction, const nsACString& aRequestToken)
|
||||
: mAction(aAction), mRequestToken(aRequestToken) {}
|
||||
: mAction(aAction), mRequestToken(aRequestToken), mHasAcknowledged(false) {}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<ContentAnalysisResponse> ContentAnalysisResponse::FromProtobuf(
|
||||
@ -701,122 +698,6 @@ NS_IMETHODIMP ContentAnalysisResult::GetShouldAllowContent(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void ContentAnalysis::EnsureParsedUrlFilters() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mParsedUrlLists) {
|
||||
return;
|
||||
}
|
||||
|
||||
mParsedUrlLists = true;
|
||||
nsAutoCString allowList;
|
||||
MOZ_ALWAYS_SUCCEEDS(Preferences::GetCString(kAllowUrlPref, allowList));
|
||||
for (const nsACString& regexSubstr : allowList.Split(u' ')) {
|
||||
if (!regexSubstr.IsEmpty()) {
|
||||
auto flatStr = PromiseFlatCString(regexSubstr);
|
||||
const char* regex = flatStr.get();
|
||||
LOGD("CA will allow URLs that match %s", regex);
|
||||
mAllowUrlList.push_back(std::regex(regex));
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoCString denyList;
|
||||
MOZ_ALWAYS_SUCCEEDS(Preferences::GetCString(kDenyUrlPref, denyList));
|
||||
for (const nsACString& regexSubstr : denyList.Split(u' ')) {
|
||||
if (!regexSubstr.IsEmpty()) {
|
||||
auto flatStr = PromiseFlatCString(regexSubstr);
|
||||
const char* regex = flatStr.get();
|
||||
LOGD("CA will block URLs that match %s", regex);
|
||||
mDenyUrlList.push_back(std::regex(regex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentAnalysis::UrlFilterResult ContentAnalysis::FilterByUrlLists(
|
||||
nsIContentAnalysisRequest* aRequest) {
|
||||
EnsureParsedUrlFilters();
|
||||
|
||||
nsIURI* nsiUrl = nullptr;
|
||||
MOZ_ALWAYS_SUCCEEDS(aRequest->GetUrl(&nsiUrl));
|
||||
nsCString urlString;
|
||||
nsresult rv = nsiUrl->GetSpec(urlString);
|
||||
NS_ENSURE_SUCCESS(rv, UrlFilterResult::eDeny);
|
||||
MOZ_ASSERT(!urlString.IsEmpty());
|
||||
std::string url = urlString.BeginReading();
|
||||
size_t count = 0;
|
||||
for (const auto& denyFilter : mDenyUrlList) {
|
||||
if (std::regex_search(url, denyFilter)) {
|
||||
LOGD("Denying CA request : Deny filter %zu matched url %s", count,
|
||||
url.c_str());
|
||||
return UrlFilterResult::eDeny;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
UrlFilterResult result = UrlFilterResult::eCheck;
|
||||
for (const auto& allowFilter : mAllowUrlList) {
|
||||
if (std::regex_match(url, allowFilter)) {
|
||||
LOGD("CA request : Allow filter %zu matched %s", count, url.c_str());
|
||||
result = UrlFilterResult::eAllow;
|
||||
break;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
|
||||
// The rest only applies to download resources.
|
||||
nsIContentAnalysisRequest::AnalysisType analysisType;
|
||||
MOZ_ALWAYS_SUCCEEDS(aRequest->GetAnalysisType(&analysisType));
|
||||
if (analysisType != ContentAnalysisRequest::AnalysisType::eFileDownloaded) {
|
||||
MOZ_ASSERT(result == UrlFilterResult::eCheck ||
|
||||
result == UrlFilterResult::eAllow);
|
||||
LOGD("CA request filter result: %s",
|
||||
result == UrlFilterResult::eCheck ? "check" : "allow");
|
||||
return result;
|
||||
}
|
||||
|
||||
nsTArray<RefPtr<nsIClientDownloadResource>> resources;
|
||||
MOZ_ALWAYS_SUCCEEDS(aRequest->GetResources(resources));
|
||||
for (size_t resourceIdx = 0; resourceIdx < resources.Length();
|
||||
/* noop */) {
|
||||
auto& resource = resources[resourceIdx];
|
||||
nsAutoString nsUrl;
|
||||
MOZ_ALWAYS_SUCCEEDS(resource->GetUrl(nsUrl));
|
||||
std::string url = NS_ConvertUTF16toUTF8(nsUrl).get();
|
||||
count = 0;
|
||||
for (auto& denyFilter : mDenyUrlList) {
|
||||
if (std::regex_search(url, denyFilter)) {
|
||||
LOGD(
|
||||
"Denying CA request : Deny filter %zu matched download resource "
|
||||
"at url %s",
|
||||
count, url.c_str());
|
||||
return UrlFilterResult::eDeny;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
bool removed = false;
|
||||
for (auto& allowFilter : mAllowUrlList) {
|
||||
if (std::regex_search(url, allowFilter)) {
|
||||
LOGD(
|
||||
"CA request : Allow filter %zu matched download resource "
|
||||
"at url %s",
|
||||
count, url.c_str());
|
||||
resources.RemoveElementAt(resourceIdx);
|
||||
removed = true;
|
||||
break;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
if (!removed) {
|
||||
++resourceIdx;
|
||||
}
|
||||
}
|
||||
|
||||
// Check unless all were allowed.
|
||||
return resources.Length() ? UrlFilterResult::eCheck : UrlFilterResult::eAllow;
|
||||
}
|
||||
|
||||
NS_IMPL_CLASSINFO(ContentAnalysisRequest, nullptr, 0, {0});
|
||||
NS_IMPL_ISUPPORTS_CI(ContentAnalysisRequest, nsIContentAnalysisRequest);
|
||||
NS_IMPL_CLASSINFO(ContentAnalysisResponse, nullptr, 0, {0});
|
||||
@ -985,8 +866,6 @@ nsresult ContentAnalysis::RunAnalyzeRequestTask(
|
||||
const RefPtr<nsIContentAnalysisRequest>& aRequest, bool aAutoAcknowledge,
|
||||
int64_t aRequestCount,
|
||||
const RefPtr<nsIContentAnalysisCallback>& aCallback) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
auto callbackCopy = aCallback;
|
||||
auto se = MakeScopeExit([&] {
|
||||
@ -996,51 +875,24 @@ nsresult ContentAnalysis::RunAnalyzeRequestTask(
|
||||
}
|
||||
});
|
||||
|
||||
nsCString requestToken;
|
||||
rv = aRequest->GetRequestToken(requestToken);
|
||||
content_analysis::sdk::ContentAnalysisRequest pbRequest;
|
||||
rv =
|
||||
ConvertToProtobuf(aRequest, GetUserActionId(), aRequestCount, &pbRequest);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCString requestToken;
|
||||
nsMainThreadPtrHandle<nsIContentAnalysisCallback> callbackHolderCopy(
|
||||
new nsMainThreadPtrHolder<nsIContentAnalysisCallback>(
|
||||
"content analysis callback", aCallback));
|
||||
CallbackData callbackData(std::move(callbackHolderCopy), aAutoAcknowledge);
|
||||
rv = aRequest->GetRequestToken(requestToken);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
{
|
||||
auto lock = mCallbackMap.Lock();
|
||||
lock->InsertOrUpdate(requestToken, std::move(callbackData));
|
||||
}
|
||||
|
||||
// Check URLs of requested info against
|
||||
// browser.contentanalysis.allow_url_regex_list/deny_url_regex_list.
|
||||
// Build the list once since creating regexs is slow.
|
||||
// URLs that match the allow list are removed from the check. There is
|
||||
// only one URL in all cases except downloads. If all contents are removed
|
||||
// or the page URL is allowed (for downloads) then the operation is allowed.
|
||||
// URLs that match the deny list block the entire operation.
|
||||
// If the request is completely covered by this filter then flag it as
|
||||
// not needing to send an Acknowledge.
|
||||
auto filterResult = FilterByUrlLists(aRequest);
|
||||
if (filterResult == ContentAnalysis::UrlFilterResult::eDeny) {
|
||||
LOGD("Blocking request due to deny URL filter.");
|
||||
auto response = ContentAnalysisResponse::FromAction(
|
||||
nsIContentAnalysisResponse::Action::eBlock, requestToken);
|
||||
response->DoNotAcknowledge();
|
||||
IssueResponse(response);
|
||||
return NS_OK;
|
||||
} else if (filterResult == ContentAnalysis::UrlFilterResult::eAllow) {
|
||||
LOGD("Allowing request -- all operations match allow URL filter.");
|
||||
auto response = ContentAnalysisResponse::FromAction(
|
||||
nsIContentAnalysisResponse::Action::eAllow, requestToken);
|
||||
response->DoNotAcknowledge();
|
||||
IssueResponse(response);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LOGD("Issuing ContentAnalysisRequest for token %s", requestToken.get());
|
||||
|
||||
content_analysis::sdk::ContentAnalysisRequest pbRequest;
|
||||
rv =
|
||||
ConvertToProtobuf(aRequest, GetUserActionId(), aRequestCount, &pbRequest);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
LogRequest(&pbRequest);
|
||||
|
||||
mCaClientPromise->Then(
|
||||
@ -1142,77 +994,77 @@ void ContentAnalysis::DoAnalyzeRequest(
|
||||
LOGE("Content analysis got invalid response!");
|
||||
return;
|
||||
}
|
||||
nsCString responseRequestToken;
|
||||
nsresult requestRv = response->GetRequestToken(responseRequestToken);
|
||||
if (NS_FAILED(requestRv)) {
|
||||
LOGE(
|
||||
"Content analysis couldn't get request token "
|
||||
"from response!");
|
||||
return;
|
||||
}
|
||||
|
||||
owner->IssueResponse(response);
|
||||
Maybe<CallbackData> maybeCallbackData;
|
||||
{
|
||||
auto callbackMap = owner->mCallbackMap.Lock();
|
||||
maybeCallbackData = callbackMap->Extract(responseRequestToken);
|
||||
}
|
||||
if (maybeCallbackData.isNothing()) {
|
||||
LOGD(
|
||||
"Content analysis did not find callback for "
|
||||
"token %s",
|
||||
responseRequestToken.get());
|
||||
return;
|
||||
}
|
||||
response->SetOwner(owner);
|
||||
if (maybeCallbackData->Canceled()) {
|
||||
// request has already been cancelled, so there's
|
||||
// nothing to do
|
||||
LOGD(
|
||||
"Content analysis got response but ignoring "
|
||||
"because it was already cancelled for token %s",
|
||||
responseRequestToken.get());
|
||||
// Note that we always acknowledge here, even if
|
||||
// autoAcknowledge isn't set, since we raise an exception
|
||||
// at the caller on cancellation.
|
||||
auto acknowledgement = MakeRefPtr<ContentAnalysisAcknowledgement>(
|
||||
nsIContentAnalysisAcknowledgement::Result::eTooLate,
|
||||
nsIContentAnalysisAcknowledgement::FinalAction::eBlock);
|
||||
response->Acknowledge(acknowledgement);
|
||||
return;
|
||||
}
|
||||
|
||||
LOGD(
|
||||
"Content analysis resolving response promise for "
|
||||
"token %s",
|
||||
responseRequestToken.get());
|
||||
nsIContentAnalysisResponse::Action action = response->GetAction();
|
||||
nsCOMPtr<nsIObserverService> obsServ =
|
||||
mozilla::services::GetObserverService();
|
||||
if (action == nsIContentAnalysisResponse::Action::eWarn) {
|
||||
{
|
||||
auto warnResponseDataMap = owner->mWarnResponseDataMap.Lock();
|
||||
warnResponseDataMap->InsertOrUpdate(
|
||||
responseRequestToken,
|
||||
WarnResponseData(std::move(*maybeCallbackData), response));
|
||||
}
|
||||
obsServ->NotifyObservers(response, "dlp-response", nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
obsServ->NotifyObservers(response, "dlp-response", nullptr);
|
||||
if (maybeCallbackData->AutoAcknowledge()) {
|
||||
auto acknowledgement = MakeRefPtr<ContentAnalysisAcknowledgement>(
|
||||
nsIContentAnalysisAcknowledgement::Result::eSuccess,
|
||||
ConvertResult(action));
|
||||
response->Acknowledge(acknowledgement);
|
||||
}
|
||||
|
||||
nsMainThreadPtrHandle<nsIContentAnalysisCallback> callbackHolder =
|
||||
maybeCallbackData->TakeCallbackHolder();
|
||||
callbackHolder->ContentResult(response);
|
||||
}));
|
||||
}
|
||||
|
||||
void ContentAnalysis::IssueResponse(RefPtr<ContentAnalysisResponse>& response) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsCString responseRequestToken;
|
||||
nsresult requestRv = response->GetRequestToken(responseRequestToken);
|
||||
if (NS_FAILED(requestRv)) {
|
||||
LOGE("Content analysis couldn't get request token from response!");
|
||||
return;
|
||||
}
|
||||
|
||||
Maybe<CallbackData> maybeCallbackData;
|
||||
{
|
||||
auto callbackMap = mCallbackMap.Lock();
|
||||
maybeCallbackData = callbackMap->Extract(responseRequestToken);
|
||||
}
|
||||
if (maybeCallbackData.isNothing()) {
|
||||
LOGD("Content analysis did not find callback for token %s",
|
||||
responseRequestToken.get());
|
||||
return;
|
||||
}
|
||||
response->SetOwner(this);
|
||||
if (maybeCallbackData->Canceled()) {
|
||||
// request has already been cancelled, so there's
|
||||
// nothing to do
|
||||
LOGD(
|
||||
"Content analysis got response but ignoring "
|
||||
"because it was already cancelled for token %s",
|
||||
responseRequestToken.get());
|
||||
// Note that we always acknowledge here, even if
|
||||
// autoAcknowledge isn't set, since we raise an exception
|
||||
// at the caller on cancellation.
|
||||
auto acknowledgement = MakeRefPtr<ContentAnalysisAcknowledgement>(
|
||||
nsIContentAnalysisAcknowledgement::Result::eTooLate,
|
||||
nsIContentAnalysisAcknowledgement::FinalAction::eBlock);
|
||||
response->Acknowledge(acknowledgement);
|
||||
return;
|
||||
}
|
||||
|
||||
LOGD("Content analysis resolving response promise for token %s",
|
||||
responseRequestToken.get());
|
||||
nsIContentAnalysisResponse::Action action = response->GetAction();
|
||||
nsCOMPtr<nsIObserverService> obsServ =
|
||||
mozilla::services::GetObserverService();
|
||||
if (action == nsIContentAnalysisResponse::Action::eWarn) {
|
||||
{
|
||||
auto warnResponseDataMap = mWarnResponseDataMap.Lock();
|
||||
warnResponseDataMap->InsertOrUpdate(
|
||||
responseRequestToken,
|
||||
WarnResponseData(std::move(*maybeCallbackData), response));
|
||||
}
|
||||
obsServ->NotifyObservers(response, "dlp-response", nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
obsServ->NotifyObservers(response, "dlp-response", nullptr);
|
||||
if (maybeCallbackData->AutoAcknowledge()) {
|
||||
auto acknowledgement = MakeRefPtr<ContentAnalysisAcknowledgement>(
|
||||
nsIContentAnalysisAcknowledgement::Result::eSuccess,
|
||||
ConvertResult(action));
|
||||
response->Acknowledge(acknowledgement);
|
||||
}
|
||||
|
||||
nsMainThreadPtrHandle<nsIContentAnalysisCallback> callbackHolder =
|
||||
maybeCallbackData->TakeCallbackHolder();
|
||||
callbackHolder->ContentResult(response);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentAnalysis::AnalyzeContentRequest(nsIContentAnalysisRequest* aRequest,
|
||||
bool aAutoAcknowledge, JSContext* aCx,
|
||||
@ -1366,10 +1218,6 @@ ContentAnalysisResponse::Acknowledge(
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mHasAcknowledged = true;
|
||||
|
||||
if (mDoNotAcknowledge) {
|
||||
return NS_OK;
|
||||
}
|
||||
return mOwner->RunAcknowledgeTask(aAcknowledgement, mRequestToken);
|
||||
};
|
||||
|
||||
|
@ -7,25 +7,15 @@
|
||||
#define mozilla_contentanalysis_h
|
||||
|
||||
#include "mozilla/DataMutex.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "nsIContentAnalysis.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTHashMap.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
class nsIPrincipal;
|
||||
class ContentAnalysisTest;
|
||||
|
||||
namespace mozilla::dom {
|
||||
class DataTransfer;
|
||||
class WindowGlobalParent;
|
||||
} // namespace mozilla::dom
|
||||
|
||||
namespace content_analysis::sdk {
|
||||
class Client;
|
||||
class ContentAnalysisRequest;
|
||||
@ -85,8 +75,6 @@ class ContentAnalysisRequest final : public nsIContentAnalysisRequest {
|
||||
nsString mOperationDisplayString;
|
||||
|
||||
RefPtr<dom::WindowGlobalParent> mWindowGlobalParent;
|
||||
|
||||
friend class ::ContentAnalysisTest;
|
||||
};
|
||||
|
||||
#define CONTENTANALYSIS_IID \
|
||||
@ -128,14 +116,6 @@ class ContentAnalysis final : public nsIContentAnalysis {
|
||||
nsCString aRequestToken,
|
||||
content_analysis::sdk::ContentAnalysisRequest&& aRequest,
|
||||
const std::shared_ptr<content_analysis::sdk::Client>& aClient);
|
||||
void IssueResponse(RefPtr<ContentAnalysisResponse>& response);
|
||||
|
||||
// Did the URL filter completely handle the request or do we need to check
|
||||
// with the agent.
|
||||
enum UrlFilterResult { eCheck, eDeny, eAllow };
|
||||
|
||||
UrlFilterResult FilterByUrlLists(nsIContentAnalysisRequest* aRequest);
|
||||
void EnsureParsedUrlFilters();
|
||||
|
||||
using ClientPromise =
|
||||
MozPromise<std::shared_ptr<content_analysis::sdk::Client>, nsresult,
|
||||
@ -178,12 +158,7 @@ class ContentAnalysis final : public nsIContentAnalysis {
|
||||
};
|
||||
DataMutex<nsTHashMap<nsCString, WarnResponseData>> mWarnResponseDataMap;
|
||||
|
||||
std::vector<std::regex> mAllowUrlList;
|
||||
std::vector<std::regex> mDenyUrlList;
|
||||
bool mParsedUrlLists;
|
||||
|
||||
friend class ContentAnalysisResponse;
|
||||
friend class ::ContentAnalysisTest;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(ContentAnalysis, CONTENTANALYSIS_IID)
|
||||
@ -197,7 +172,6 @@ class ContentAnalysisResponse final : public nsIContentAnalysisResponse {
|
||||
Action aAction, const nsACString& aRequestToken);
|
||||
|
||||
void SetOwner(RefPtr<ContentAnalysis> aOwner);
|
||||
void DoNotAcknowledge() { mDoNotAcknowledge = true; }
|
||||
|
||||
private:
|
||||
~ContentAnalysisResponse() = default;
|
||||
@ -223,11 +197,7 @@ class ContentAnalysisResponse final : public nsIContentAnalysisResponse {
|
||||
RefPtr<ContentAnalysis> mOwner;
|
||||
|
||||
// Whether the response has been acknowledged
|
||||
bool mHasAcknowledged = false;
|
||||
|
||||
// If true, the request was completely handled by URL filter lists, so it
|
||||
// was not sent to the agent and should not send an Acknowledge.
|
||||
bool mDoNotAcknowledge = false;
|
||||
bool mHasAcknowledged;
|
||||
|
||||
friend class ContentAnalysis;
|
||||
};
|
||||
|
@ -6,110 +6,127 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "ContentAnalysis.h"
|
||||
#include "mozilla/CmdLineAndEnvUtils.h"
|
||||
#include "content_analysis/sdk/analysis_client.h"
|
||||
#include "TestContentAnalysis.h"
|
||||
#include <processenv.h>
|
||||
#include <synchapi.h>
|
||||
|
||||
const char* kAllowUrlPref = "browser.contentanalysis.allow_url_regex_list";
|
||||
const char* kDenyUrlPref = "browser.contentanalysis.deny_url_regex_list";
|
||||
using namespace content_analysis::sdk;
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::contentanalysis;
|
||||
|
||||
class ContentAnalysisTest : public testing::Test {
|
||||
protected:
|
||||
ContentAnalysisTest() {
|
||||
nsCOMPtr<nsIContentAnalysis> caSvc =
|
||||
do_GetService("@mozilla.org/contentanalysis;1");
|
||||
MOZ_ASSERT(caSvc);
|
||||
mContentAnalysis = static_cast<ContentAnalysis*>(caSvc.get());
|
||||
MozAgentInfo LaunchAgentNormal(const wchar_t* aToBlock) {
|
||||
nsString cmdLineArguments;
|
||||
if (aToBlock && aToBlock[0] != 0) {
|
||||
cmdLineArguments.Append(L" --toblock=.*");
|
||||
cmdLineArguments.Append(aToBlock);
|
||||
cmdLineArguments.Append(L".*");
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
mContentAnalysis->mParsedUrlLists = false;
|
||||
mContentAnalysis->mAllowUrlList = {};
|
||||
mContentAnalysis->mDenyUrlList = {};
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(Preferences::SetCString(kAllowUrlPref, ""));
|
||||
MOZ_ALWAYS_SUCCEEDS(Preferences::SetCString(kDenyUrlPref, ""));
|
||||
}
|
||||
|
||||
already_AddRefed<nsIContentAnalysisRequest> CreateRequest(const char* aUrl) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
MOZ_ALWAYS_SUCCEEDS(NS_NewURI(getter_AddRefs(uri), aUrl));
|
||||
// We will only use the URL and, implicitly, the analysisType
|
||||
// (behavior differs for download vs other types).
|
||||
return RefPtr(new ContentAnalysisRequest(
|
||||
nsIContentAnalysisRequest::AnalysisType::eFileTransfer,
|
||||
EmptyString(), false, EmptyCString(), uri,
|
||||
nsIContentAnalysisRequest::OperationType::eDroppedText,
|
||||
nullptr))
|
||||
.forget();
|
||||
}
|
||||
|
||||
RefPtr<ContentAnalysis> mContentAnalysis;
|
||||
|
||||
// Proxies for private members of ContentAnalysis. TEST_F
|
||||
// creates new subclasses -- they do not inherit `friend`s.
|
||||
// (FRIEND_TEST is another more verbose solution.)
|
||||
using UrlFilterResult = ContentAnalysis::UrlFilterResult;
|
||||
UrlFilterResult FilterByUrlLists(nsIContentAnalysisRequest* aReq) {
|
||||
return mContentAnalysis->FilterByUrlLists(aReq);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(ContentAnalysisTest, AllowUrlList) {
|
||||
// using UrlFilterResult = ContentAnalysis::UrlFilterResult;
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
Preferences::SetCString(kAllowUrlPref, ".*\\.org/match.*"));
|
||||
RefPtr<nsIContentAnalysisRequest> car =
|
||||
CreateRequest("https://example.org/matchme/");
|
||||
ASSERT_EQ(FilterByUrlLists(car), UrlFilterResult::eAllow);
|
||||
car = CreateRequest("https://example.com/matchme/");
|
||||
ASSERT_EQ(FilterByUrlLists(car), UrlFilterResult::eCheck);
|
||||
cmdLineArguments.Append(L" --user");
|
||||
cmdLineArguments.Append(L" --path=");
|
||||
nsString pipeName;
|
||||
GeneratePipeName(L"contentanalysissdk-gtest-", pipeName);
|
||||
cmdLineArguments.Append(pipeName);
|
||||
MozAgentInfo agentInfo;
|
||||
LaunchAgentWithCommandLineArguments(cmdLineArguments, pipeName, agentInfo);
|
||||
return agentInfo;
|
||||
}
|
||||
|
||||
TEST_F(ContentAnalysisTest, MultipleAllowUrlList) {
|
||||
MOZ_ALWAYS_SUCCEEDS(Preferences::SetCString(
|
||||
kAllowUrlPref, ".*\\.org/match.* .*\\.net/match.*"));
|
||||
RefPtr<nsIContentAnalysisRequest> car =
|
||||
CreateRequest("https://example.org/matchme/");
|
||||
ASSERT_EQ(FilterByUrlLists(car), UrlFilterResult::eAllow);
|
||||
car = CreateRequest("https://example.net/matchme/");
|
||||
ASSERT_EQ(FilterByUrlLists(car), UrlFilterResult::eAllow);
|
||||
car = CreateRequest("https://example.com/matchme/");
|
||||
ASSERT_EQ(FilterByUrlLists(car), UrlFilterResult::eCheck);
|
||||
TEST(ContentAnalysis, TextShouldNotBeBlocked)
|
||||
{
|
||||
auto MozAgentInfo = LaunchAgentNormal(L"block");
|
||||
// Exit the test early if the process failed to launch
|
||||
ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL);
|
||||
ASSERT_NE(nullptr, MozAgentInfo.client.get());
|
||||
|
||||
ContentAnalysisRequest request;
|
||||
request.set_request_token("request token");
|
||||
request.set_text_content("should succeed");
|
||||
ContentAnalysisResponse response;
|
||||
ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response));
|
||||
ASSERT_STREQ("request token", response.request_token().c_str());
|
||||
ASSERT_EQ(1, response.results().size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS,
|
||||
response.results().Get(0).status());
|
||||
ASSERT_EQ(0, response.results().Get(0).triggered_rules_size());
|
||||
|
||||
BOOL terminateResult =
|
||||
::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0);
|
||||
ASSERT_NE(FALSE, terminateResult)
|
||||
<< "Failed to terminate content_analysis_sdk_agent process";
|
||||
}
|
||||
|
||||
TEST_F(ContentAnalysisTest, DenyUrlList) {
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
Preferences::SetCString(kDenyUrlPref, ".*\\.com/match.*"));
|
||||
RefPtr<nsIContentAnalysisRequest> car =
|
||||
CreateRequest("https://example.org/matchme/");
|
||||
ASSERT_EQ(FilterByUrlLists(car), UrlFilterResult::eCheck);
|
||||
car = CreateRequest("https://example.com/matchme/");
|
||||
ASSERT_EQ(FilterByUrlLists(car), UrlFilterResult::eDeny);
|
||||
TEST(ContentAnalysis, TextShouldBeBlocked)
|
||||
{
|
||||
auto MozAgentInfo = LaunchAgentNormal(L"block");
|
||||
// Exit the test early if the process failed to launch
|
||||
ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL);
|
||||
ASSERT_NE(nullptr, MozAgentInfo.client.get());
|
||||
|
||||
ContentAnalysisRequest request;
|
||||
request.set_request_token("request token");
|
||||
request.set_text_content("should be blocked");
|
||||
ContentAnalysisResponse response;
|
||||
ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response));
|
||||
ASSERT_STREQ("request token", response.request_token().c_str());
|
||||
ASSERT_EQ(1, response.results().size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS,
|
||||
response.results().Get(0).status());
|
||||
ASSERT_EQ(1, response.results().Get(0).triggered_rules_size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_TriggeredRule_Action_BLOCK,
|
||||
response.results().Get(0).triggered_rules(0).action());
|
||||
|
||||
BOOL terminateResult =
|
||||
::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0);
|
||||
ASSERT_NE(FALSE, terminateResult)
|
||||
<< "Failed to terminate content_analysis_sdk_agent process";
|
||||
}
|
||||
|
||||
TEST_F(ContentAnalysisTest, MultipleDenyUrlList) {
|
||||
MOZ_ALWAYS_SUCCEEDS(Preferences::SetCString(
|
||||
kDenyUrlPref, ".*\\.com/match.* .*\\.biz/match.*"));
|
||||
RefPtr<nsIContentAnalysisRequest> car =
|
||||
CreateRequest("https://example.org/matchme/");
|
||||
ASSERT_EQ(FilterByUrlLists(car), UrlFilterResult::eCheck);
|
||||
car = CreateRequest("https://example.com/matchme/");
|
||||
ASSERT_EQ(FilterByUrlLists(car), UrlFilterResult::eDeny);
|
||||
car = CreateRequest("https://example.biz/matchme/");
|
||||
ASSERT_EQ(FilterByUrlLists(car), UrlFilterResult::eDeny);
|
||||
TEST(ContentAnalysis, FileShouldNotBeBlocked)
|
||||
{
|
||||
auto MozAgentInfo = LaunchAgentNormal(L"block");
|
||||
// Exit the test early if the process failed to launch
|
||||
ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL);
|
||||
ASSERT_NE(nullptr, MozAgentInfo.client.get());
|
||||
|
||||
ContentAnalysisRequest request;
|
||||
request.set_request_token("request token");
|
||||
request.set_file_path("..\\..\\_tests\\gtest\\allowedFile.txt");
|
||||
ContentAnalysisResponse response;
|
||||
ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response));
|
||||
ASSERT_STREQ("request token", response.request_token().c_str());
|
||||
ASSERT_EQ(1, response.results().size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS,
|
||||
response.results().Get(0).status());
|
||||
ASSERT_EQ(0, response.results().Get(0).triggered_rules_size());
|
||||
|
||||
BOOL terminateResult =
|
||||
::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0);
|
||||
ASSERT_NE(FALSE, terminateResult)
|
||||
<< "Failed to terminate content_analysis_sdk_agent process";
|
||||
}
|
||||
|
||||
TEST_F(ContentAnalysisTest, DenyOverridesAllowUrlList) {
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
Preferences::SetCString(kAllowUrlPref, ".*\\.org/match.*"));
|
||||
MOZ_ALWAYS_SUCCEEDS(Preferences::SetCString(kDenyUrlPref, ".*.org/match.*"));
|
||||
RefPtr<nsIContentAnalysisRequest> car =
|
||||
CreateRequest("https://example.org/matchme/");
|
||||
ASSERT_EQ(FilterByUrlLists(car), UrlFilterResult::eDeny);
|
||||
TEST(ContentAnalysis, FileShouldBeBlocked)
|
||||
{
|
||||
auto MozAgentInfo = LaunchAgentNormal(L"block");
|
||||
// Exit the test early if the process failed to launch
|
||||
ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL);
|
||||
ASSERT_NE(nullptr, MozAgentInfo.client.get());
|
||||
|
||||
ContentAnalysisRequest request;
|
||||
request.set_request_token("request token");
|
||||
request.set_file_path("..\\..\\_tests\\gtest\\blockedFile.txt");
|
||||
ContentAnalysisResponse response;
|
||||
ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response));
|
||||
ASSERT_STREQ("request token", response.request_token().c_str());
|
||||
ASSERT_EQ(1, response.results().size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS,
|
||||
response.results().Get(0).status());
|
||||
ASSERT_EQ(1, response.results().Get(0).triggered_rules_size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_TriggeredRule_Action_BLOCK,
|
||||
response.results().Get(0).triggered_rules(0).action());
|
||||
|
||||
BOOL terminateResult =
|
||||
::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0);
|
||||
ASSERT_NE(FALSE, terminateResult)
|
||||
<< "Failed to terminate content_analysis_sdk_agent process";
|
||||
}
|
||||
|
@ -1,132 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/CmdLineAndEnvUtils.h"
|
||||
#include "content_analysis/sdk/analysis_client.h"
|
||||
#include "TestContentAnalysisAgent.h"
|
||||
#include <processenv.h>
|
||||
#include <synchapi.h>
|
||||
|
||||
using namespace content_analysis::sdk;
|
||||
|
||||
MozAgentInfo LaunchAgentNormal(const wchar_t* aToBlock) {
|
||||
nsString cmdLineArguments;
|
||||
if (aToBlock && aToBlock[0] != 0) {
|
||||
cmdLineArguments.Append(L" --toblock=.*");
|
||||
cmdLineArguments.Append(aToBlock);
|
||||
cmdLineArguments.Append(L".*");
|
||||
}
|
||||
cmdLineArguments.Append(L" --user");
|
||||
cmdLineArguments.Append(L" --path=");
|
||||
nsString pipeName;
|
||||
GeneratePipeName(L"contentanalysissdk-gtest-", pipeName);
|
||||
cmdLineArguments.Append(pipeName);
|
||||
MozAgentInfo agentInfo;
|
||||
LaunchAgentWithCommandLineArguments(cmdLineArguments, pipeName, agentInfo);
|
||||
return agentInfo;
|
||||
}
|
||||
|
||||
TEST(ContentAnalysisAgent, TextShouldNotBeBlocked)
|
||||
{
|
||||
auto MozAgentInfo = LaunchAgentNormal(L"block");
|
||||
// Exit the test early if the process failed to launch
|
||||
ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL);
|
||||
ASSERT_NE(nullptr, MozAgentInfo.client.get());
|
||||
|
||||
ContentAnalysisRequest request;
|
||||
request.set_request_token("request token");
|
||||
request.set_text_content("should succeed");
|
||||
ContentAnalysisResponse response;
|
||||
ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response));
|
||||
ASSERT_STREQ("request token", response.request_token().c_str());
|
||||
ASSERT_EQ(1, response.results().size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS,
|
||||
response.results().Get(0).status());
|
||||
ASSERT_EQ(0, response.results().Get(0).triggered_rules_size());
|
||||
|
||||
BOOL terminateResult =
|
||||
::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0);
|
||||
ASSERT_NE(FALSE, terminateResult)
|
||||
<< "Failed to terminate content_analysis_sdk_agent process";
|
||||
}
|
||||
|
||||
TEST(ContentAnalysisAgent, TextShouldBeBlocked)
|
||||
{
|
||||
auto MozAgentInfo = LaunchAgentNormal(L"block");
|
||||
// Exit the test early if the process failed to launch
|
||||
ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL);
|
||||
ASSERT_NE(nullptr, MozAgentInfo.client.get());
|
||||
|
||||
ContentAnalysisRequest request;
|
||||
request.set_request_token("request token");
|
||||
request.set_text_content("should be blocked");
|
||||
ContentAnalysisResponse response;
|
||||
ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response));
|
||||
ASSERT_STREQ("request token", response.request_token().c_str());
|
||||
ASSERT_EQ(1, response.results().size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS,
|
||||
response.results().Get(0).status());
|
||||
ASSERT_EQ(1, response.results().Get(0).triggered_rules_size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_TriggeredRule_Action_BLOCK,
|
||||
response.results().Get(0).triggered_rules(0).action());
|
||||
|
||||
BOOL terminateResult =
|
||||
::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0);
|
||||
ASSERT_NE(FALSE, terminateResult)
|
||||
<< "Failed to terminate content_analysis_sdk_agent process";
|
||||
}
|
||||
|
||||
TEST(ContentAnalysisAgent, FileShouldNotBeBlocked)
|
||||
{
|
||||
auto MozAgentInfo = LaunchAgentNormal(L"block");
|
||||
// Exit the test early if the process failed to launch
|
||||
ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL);
|
||||
ASSERT_NE(nullptr, MozAgentInfo.client.get());
|
||||
|
||||
ContentAnalysisRequest request;
|
||||
request.set_request_token("request token");
|
||||
request.set_file_path("..\\..\\_tests\\gtest\\allowedFile.txt");
|
||||
ContentAnalysisResponse response;
|
||||
ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response));
|
||||
ASSERT_STREQ("request token", response.request_token().c_str());
|
||||
ASSERT_EQ(1, response.results().size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS,
|
||||
response.results().Get(0).status());
|
||||
ASSERT_EQ(0, response.results().Get(0).triggered_rules_size());
|
||||
|
||||
BOOL terminateResult =
|
||||
::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0);
|
||||
ASSERT_NE(FALSE, terminateResult)
|
||||
<< "Failed to terminate content_analysis_sdk_agent process";
|
||||
}
|
||||
|
||||
TEST(ContentAnalysisAgent, FileShouldBeBlocked)
|
||||
{
|
||||
auto MozAgentInfo = LaunchAgentNormal(L"block");
|
||||
// Exit the test early if the process failed to launch
|
||||
ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL);
|
||||
ASSERT_NE(nullptr, MozAgentInfo.client.get());
|
||||
|
||||
ContentAnalysisRequest request;
|
||||
request.set_request_token("request token");
|
||||
request.set_file_path("..\\..\\_tests\\gtest\\blockedFile.txt");
|
||||
ContentAnalysisResponse response;
|
||||
ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response));
|
||||
ASSERT_STREQ("request token", response.request_token().c_str());
|
||||
ASSERT_EQ(1, response.results().size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS,
|
||||
response.results().Get(0).status());
|
||||
ASSERT_EQ(1, response.results().Get(0).triggered_rules_size());
|
||||
ASSERT_EQ(ContentAnalysisResponse_Result_TriggeredRule_Action_BLOCK,
|
||||
response.results().Get(0).triggered_rules(0).action());
|
||||
|
||||
BOOL terminateResult =
|
||||
::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0);
|
||||
ASSERT_NE(FALSE, terminateResult)
|
||||
<< "Failed to terminate content_analysis_sdk_agent process";
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/CmdLineAndEnvUtils.h"
|
||||
#include "content_analysis/sdk/analysis_client.h"
|
||||
#include "TestContentAnalysisAgent.h"
|
||||
#include "TestContentAnalysis.h"
|
||||
#include <processenv.h>
|
||||
#include <synchapi.h>
|
||||
#include <windows.h>
|
||||
|
@ -3,7 +3,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "TestContentAnalysisAgent.h"
|
||||
#include "TestContentAnalysis.h"
|
||||
#include <combaseapi.h>
|
||||
#include <pathcch.h>
|
||||
#include <shlwapi.h>
|
||||
|
@ -12,10 +12,6 @@ LOCAL_INCLUDES += [
|
||||
if CONFIG["OS_TARGET"] == "WINNT":
|
||||
UNIFIED_SOURCES += [
|
||||
"TestContentAnalysis.cpp",
|
||||
]
|
||||
SOURCES += [
|
||||
# Agent SDK usings conflicts with Gecko usings
|
||||
"TestContentAnalysisAgent.cpp",
|
||||
"TestContentAnalysisMisbehaving.cpp",
|
||||
"TestContentAnalysisUtils.cpp",
|
||||
]
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "mozilla/BackgroundHangMonitor.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||
#include "mozilla/dom/Directory.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/ipc/UtilityProcessManager.h"
|
||||
|
Loading…
Reference in New Issue
Block a user