diff options
Diffstat (limited to 'toolkit/components/antitracking/PartitioningExceptionList.cpp')
-rw-r--r-- | toolkit/components/antitracking/PartitioningExceptionList.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/toolkit/components/antitracking/PartitioningExceptionList.cpp b/toolkit/components/antitracking/PartitioningExceptionList.cpp new file mode 100644 index 0000000000..f726a3b63a --- /dev/null +++ b/toolkit/components/antitracking/PartitioningExceptionList.cpp @@ -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 "PartitioningExceptionList.h" + +#include "AntiTrackingLog.h" +#include "nsContentUtils.h" + +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/StaticPtr.h" + +namespace mozilla { + +namespace { + +inline nsresult CreateExceptionListKey(const nsACString& aFirstPartyOrigin, + const nsACString& aThirdPartyOrigin, + nsACString& aExceptionListKey) { + MOZ_ASSERT(!aFirstPartyOrigin.IsEmpty()); + MOZ_ASSERT(!aThirdPartyOrigin.IsEmpty()); + + // Don't allow exceptions for everything + if (aFirstPartyOrigin.EqualsLiteral("*") && + aThirdPartyOrigin.EqualsLiteral("*")) { + return NS_ERROR_ILLEGAL_VALUE; + } + + aExceptionListKey.Assign(aFirstPartyOrigin); + aExceptionListKey.Append(","); + aExceptionListKey.Append(aThirdPartyOrigin); + + return NS_OK; +} + +inline nsresult CreateUnifiedOriginString(const nsACString& aInput, + nsACString& aOutput) { + nsCOMPtr<nsIURI> uri; + if (aInput.EqualsLiteral("*")) { + aOutput.AssignLiteral("*"); + return NS_OK; + } + nsresult rv = NS_NewURI(getter_AddRefs(uri), aInput); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + return nsContentUtils::GetASCIIOrigin(uri, aOutput); +} + +StaticRefPtr<PartitioningExceptionList> gPartitioningExceptionList; + +} // namespace + +NS_IMPL_ISUPPORTS(PartitioningExceptionList, + nsIPartitioningExceptionListObserver) + +bool PartitioningExceptionList::Check(const nsACString& aFirstPartyOrigin, + const nsACString& aThirdPartyOrigin) { + if (aFirstPartyOrigin.IsEmpty() || aThirdPartyOrigin.IsEmpty()) { + return false; + } + + LOG(("Check partitioning exception list for url %s and %s", + PromiseFlatCString(aFirstPartyOrigin).get(), + PromiseFlatCString(aThirdPartyOrigin).get())); + + nsAutoCString key, wildcardFirstPartyKey, wildcardThirdPartyKey; + CreateExceptionListKey(aFirstPartyOrigin, aThirdPartyOrigin, key); + CreateExceptionListKey("*"_ns, aThirdPartyOrigin, wildcardFirstPartyKey); + CreateExceptionListKey(aFirstPartyOrigin, "*"_ns, wildcardThirdPartyKey); + + if (GetOrCreate()->mExceptionList.Contains(key) || + GetOrCreate()->mExceptionList.Contains(wildcardFirstPartyKey) || + GetOrCreate()->mExceptionList.Contains(wildcardThirdPartyKey)) { + LOG(("URI is in exception list")); + return true; + } + + return false; +} + +PartitioningExceptionList* PartitioningExceptionList::GetOrCreate() { + if (!gPartitioningExceptionList) { + gPartitioningExceptionList = new PartitioningExceptionList(); + gPartitioningExceptionList->Init(); + + RunOnShutdown([&] { + gPartitioningExceptionList->Shutdown(); + gPartitioningExceptionList = nullptr; + }); + } + + return gPartitioningExceptionList; +} + +nsresult PartitioningExceptionList::Init() { + mService = + do_GetService("@mozilla.org/partitioning/exception-list-service;1"); + if (NS_WARN_IF(!mService)) { + return NS_ERROR_FAILURE; + } + + mService->RegisterAndRunExceptionListObserver(this); + return NS_OK; +} + +void PartitioningExceptionList::Shutdown() { + if (mService) { + mService->UnregisterExceptionListObserver(this); + mService = nullptr; + } + + mExceptionList.Clear(); +} + +NS_IMETHODIMP +PartitioningExceptionList::OnExceptionListUpdate(const nsACString& aList) { + mExceptionList.Clear(); + + nsresult rv; + for (const nsACString& item : aList.Split(';')) { + auto origins = item.Split(','); + auto originsIt = origins.begin(); + + nsAutoCString firstPartyOrigin; + rv = CreateUnifiedOriginString(*originsIt, firstPartyOrigin); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + ++originsIt; + + nsAutoCString thirdPartyOrigin; + rv = CreateUnifiedOriginString(*originsIt, thirdPartyOrigin); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + nsAutoCString key; + rv = CreateExceptionListKey(firstPartyOrigin, thirdPartyOrigin, key); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + LOG(("onExceptionListUpdate: %s", key.get())); + + mExceptionList.AppendElement(key); + } + + return NS_OK; +} + +} // namespace mozilla |