/* -*- 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 http://mozilla.org/MPL/2.0/. */ #include "ThirdPartyUtil.h" #include "nsNetCID.h" #include "nsNetUtil.h" #include "nsIChannel.h" #include "nsIServiceManager.h" #include "nsIHttpChannelInternal.h" #include "nsPIDOMWindow.h" #include "nsIDOMWindow.h" #include "nsILoadContext.h" #include "nsIPrincipal.h" #include "nsIScriptObjectPrincipal.h" #include "nsIURI.h" #include "nsThreadUtils.h" #include "mozilla/Logging.h" NS_IMPL_ISUPPORTS(ThirdPartyUtil, mozIThirdPartyUtil) // // MOZ_LOG=thirdPartyUtil:5 // static mozilla::LazyLogModule gThirdPartyLog("thirdPartyUtil"); #undef LOG #define LOG(args) MOZ_LOG(gThirdPartyLog, mozilla::LogLevel::Debug, args) nsresult ThirdPartyUtil::Init() { NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_NOT_AVAILABLE); nsresult rv; mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv); return rv; } // Determine if aFirstDomain is a different base domain to aSecondURI; or, if // the concept of base domain does not apply, determine if the two hosts are not // string-identical. nsresult ThirdPartyUtil::IsThirdPartyInternal(const nsCString& aFirstDomain, nsIURI* aSecondURI, bool* aResult) { if (!aSecondURI) { return NS_ERROR_INVALID_ARG; } // Get the base domain for aSecondURI. nsCString secondDomain; nsresult rv = GetBaseDomain(aSecondURI, secondDomain); LOG(("ThirdPartyUtil::IsThirdPartyInternal %s =? %s", aFirstDomain.get(), secondDomain.get())); if (NS_FAILED(rv)) return rv; // Check strict equality. *aResult = aFirstDomain != secondDomain; return NS_OK; } // Get the URI associated with a window. NS_IMETHODIMP ThirdPartyUtil::GetURIFromWindow(mozIDOMWindowProxy* aWin, nsIURI** result) { nsresult rv; nsCOMPtr scriptObjPrin = do_QueryInterface(aWin); if (!scriptObjPrin) { return NS_ERROR_INVALID_ARG; } nsIPrincipal* prin = scriptObjPrin->GetPrincipal(); if (!prin) { return NS_ERROR_INVALID_ARG; } if (prin->GetIsNullPrincipal()) { LOG(("ThirdPartyUtil::GetURIFromWindow can't use null principal\n")); return NS_ERROR_INVALID_ARG; } rv = prin->GetURI(result); return rv; } // Determine if aFirstURI is third party with respect to aSecondURI. See docs // for mozIThirdPartyUtil. NS_IMETHODIMP ThirdPartyUtil::IsThirdPartyURI(nsIURI* aFirstURI, nsIURI* aSecondURI, bool* aResult) { NS_ENSURE_ARG(aFirstURI); NS_ENSURE_ARG(aSecondURI); NS_ASSERTION(aResult, "null outparam pointer"); nsCString firstHost; nsresult rv = GetBaseDomain(aFirstURI, firstHost); if (NS_FAILED(rv)) return rv; return IsThirdPartyInternal(firstHost, aSecondURI, aResult); } // Determine if any URI of the window hierarchy of aWindow is foreign with // respect to aSecondURI. See docs for mozIThirdPartyUtil. NS_IMETHODIMP ThirdPartyUtil::IsThirdPartyWindow(mozIDOMWindowProxy* aWindow, nsIURI* aURI, bool* aResult) { NS_ENSURE_ARG(aWindow); NS_ASSERTION(aResult, "null outparam pointer"); bool result; // Get the URI of the window, and its base domain. nsresult rv; nsCOMPtr currentURI; rv = GetURIFromWindow(aWindow, getter_AddRefs(currentURI)); if (NS_FAILED(rv)) return rv; nsCString bottomDomain; rv = GetBaseDomain(currentURI, bottomDomain); if (NS_FAILED(rv)) return rv; if (aURI) { // Determine whether aURI is foreign with respect to currentURI. rv = IsThirdPartyInternal(bottomDomain, aURI, &result); if (NS_FAILED(rv)) return rv; if (result) { *aResult = true; return NS_OK; } } nsCOMPtr current = nsPIDOMWindowOuter::From(aWindow), parent; nsCOMPtr parentURI; do { // We use GetScriptableParent rather than GetParent because we consider //