From 57dbd41b239dd6c17e15d4e9466b42fc2348ac50 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Mon, 15 Dec 2014 08:39:00 -0500 Subject: [PATCH] Bug 1107516 - Part 2: Add nsILoadGroup helpers to nsNetUtil.h. r=mcmanus --- netwerk/base/public/nsNetUtil.h | 14 +++++++ netwerk/base/src/nsNetUtil.cpp | 65 +++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index 77858ee03268..456222ab839d 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -992,6 +992,20 @@ NS_NewLoadGroup(nsILoadGroup **result, return rv; } +// Create a new nsILoadGroup that will match the given principal. +nsresult +NS_NewLoadGroup(nsILoadGroup** aResult, nsIPrincipal* aPrincipal); + +// Determine if the given loadGroup/principal pair will produce a principal +// with similar permissions when passed to NS_NewChannel(). This checks for +// things like making sure the appId and browser element flags match. Without +// an appropriate load group these values can be lost when getting the result +// principal back out of the channel. Null principals are also always allowed +// as they do not have permissions to actually use the load group. +bool +NS_LoadGroupMatchesPrincipal(nsILoadGroup* aLoadGroup, + nsIPrincipal* aPrincipal); + inline nsresult NS_NewDownloader(nsIStreamListener **result, nsIDownloadObserver *observer, diff --git a/netwerk/base/src/nsNetUtil.cpp b/netwerk/base/src/nsNetUtil.cpp index ee98c8dd15ba..03ba988d407e 100644 --- a/netwerk/base/src/nsNetUtil.cpp +++ b/netwerk/base/src/nsNetUtil.cpp @@ -4,6 +4,7 @@ * 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 "mozilla/LoadContext.h" #include "nsNetUtil.h" #include "nsHttp.h" @@ -16,3 +17,67 @@ bool NS_IsValidHTTPToken(const nsACString& aToken) { return mozilla::net::nsHttp::IsValidToken(aToken); } + +nsresult +NS_NewLoadGroup(nsILoadGroup** aResult, nsIPrincipal* aPrincipal) +{ + using mozilla::LoadContext; + nsresult rv; + + nsCOMPtr group = + do_CreateInstance(NS_LOADGROUP_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsRefPtr loadContext = new LoadContext(aPrincipal); + rv = group->SetNotificationCallbacks(loadContext); + NS_ENSURE_SUCCESS(rv, rv); + + group.forget(aResult); + return rv; +} + +bool +NS_LoadGroupMatchesPrincipal(nsILoadGroup* aLoadGroup, + nsIPrincipal* aPrincipal) +{ + if (!aPrincipal) { + return false; + } + + // If this is a null principal then the load group doesn't really matter. + // The principal will not be allowed to perform any actions that actually + // use the load group. Unconditionally treat null principals as a match. + bool isNullPrincipal; + nsresult rv = aPrincipal->GetIsNullPrincipal(&isNullPrincipal); + NS_ENSURE_SUCCESS(rv, false); + if (isNullPrincipal) { + return true; + } + + if (!aLoadGroup) { + return false; + } + + nsCOMPtr loadContext; + NS_QueryNotificationCallbacks(nullptr, aLoadGroup, NS_GET_IID(nsILoadContext), + getter_AddRefs(loadContext)); + NS_ENSURE_TRUE(loadContext, false); + + // Verify load context appId and browser flag match the principal + uint32_t contextAppId; + bool contextInBrowserElement; + rv = loadContext->GetAppId(&contextAppId); + NS_ENSURE_SUCCESS(rv, false); + rv = loadContext->GetIsInBrowserElement(&contextInBrowserElement); + NS_ENSURE_SUCCESS(rv, false); + + uint32_t principalAppId; + bool principalInBrowserElement; + rv = aPrincipal->GetAppId(&principalAppId); + NS_ENSURE_SUCCESS(rv, false); + rv = aPrincipal->GetIsInBrowserElement(&principalInBrowserElement); + NS_ENSURE_SUCCESS(rv, false); + + return contextAppId == principalAppId && + contextInBrowserElement == principalInBrowserElement; +}