mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1180088 - Use origin-based permission check on parent side for signed packaged web app. r=kanru.
This commit is contained in:
parent
2f629074a5
commit
e8a186056f
@ -97,6 +97,8 @@
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/WebBrowserPersistLocalDocument.h"
|
||||
|
||||
#include "nsPrincipal.h"
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsXULPopupManager.h"
|
||||
#endif
|
||||
@ -278,13 +280,20 @@ nsFrameLoader::LoadURI(nsIURI* aURI)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::SwitchProcessAndLoadURI(nsIURI* aURI)
|
||||
nsFrameLoader::SwitchProcessAndLoadURI(nsIURI* aURI, const nsACString& aPackageId)
|
||||
{
|
||||
nsCOMPtr<nsIURI> URIToLoad = aURI;
|
||||
RefPtr<TabParent> tp = nullptr;
|
||||
|
||||
nsCString signedPkgOrigin;
|
||||
if (!aPackageId.IsEmpty()) {
|
||||
// Only when aPackageId is not empty would signed package origin
|
||||
// be meaningful.
|
||||
nsPrincipal::GetOriginForURI(aURI, signedPkgOrigin);
|
||||
}
|
||||
|
||||
MutableTabContext context;
|
||||
nsresult rv = GetNewTabContext(&context);
|
||||
nsresult rv = GetNewTabContext(&context, signedPkgOrigin, aPackageId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<Element> ownerElement = mOwnerContent;
|
||||
@ -3031,7 +3040,9 @@ nsFrameLoader::MaybeUpdatePrimaryTabParent(TabParentChange aChange)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext)
|
||||
nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
|
||||
const nsACString& aSignedPkgOriginNoSuffix,
|
||||
const nsACString& aPackageId)
|
||||
{
|
||||
nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
|
||||
nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
|
||||
@ -3051,7 +3062,11 @@ nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext)
|
||||
}
|
||||
attrs.mAppId = appId;
|
||||
|
||||
bool tabContextUpdated = aTabContext->SetTabContext(ownApp, containingApp, attrs);
|
||||
// Populate packageId to signedPkg.
|
||||
attrs.mSignedPkg = NS_ConvertUTF8toUTF16(aPackageId);
|
||||
|
||||
bool tabContextUpdated = aTabContext->SetTabContext(ownApp, containingApp,
|
||||
attrs, aSignedPkgOriginNoSuffix);
|
||||
NS_ENSURE_STATE(tabContextUpdated);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -318,7 +318,9 @@ private:
|
||||
|
||||
void InitializeBrowserAPI();
|
||||
|
||||
nsresult GetNewTabContext(mozilla::dom::MutableTabContext* aTabContext);
|
||||
nsresult GetNewTabContext(mozilla::dom::MutableTabContext* aTabContext,
|
||||
const nsACString& aSignedPkgNoSuffix = EmptyCString(),
|
||||
const nsACString& aPackageId = EmptyCString());
|
||||
|
||||
enum TabParentChange {
|
||||
eTabParentRemoved,
|
||||
|
@ -16,7 +16,7 @@ interface nsIDOMElement;
|
||||
interface nsITabParent;
|
||||
interface nsILoadContext;
|
||||
|
||||
[scriptable, builtinclass, uuid(c6e00815-b7a1-4544-b309-a85b86cb1747)]
|
||||
[scriptable, builtinclass, uuid(1645af04-1bc7-4363-8f2c-eb9679220ab1)]
|
||||
interface nsIFrameLoader : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -52,10 +52,11 @@ interface nsIFrameLoader : nsISupports
|
||||
/**
|
||||
* Loads the specified URI in this frame but using a different process.
|
||||
* Behaves identically to loadURI, except that this method only works
|
||||
* with remote frame.
|
||||
* with remote frame. For a signed package, we need to specifiy the
|
||||
* package identifier.
|
||||
* Throws an exception with non-remote frames.
|
||||
*/
|
||||
void switchProcessAndLoadURI(in nsIURI aURI);
|
||||
void switchProcessAndLoadURI(in nsIURI aURI, in ACString aPackageId);
|
||||
|
||||
/**
|
||||
* Puts the frameloader in prerendering mode.
|
||||
|
@ -30,7 +30,7 @@
|
||||
.QueryInterface(Ci.nsIFrameLoaderOwner)
|
||||
.frameLoader;
|
||||
var uri = SpecialPowers.Services.io.newURI(url, null, null);
|
||||
fl.switchProcessAndLoadURI(uri);
|
||||
fl.switchProcessAndLoadURI(uri, "");
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
|
@ -35,6 +35,12 @@ class nsIPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
#if DEUBG
|
||||
#define LOG(args...) printf_stderr(args)
|
||||
#else
|
||||
#define LOG(...)
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_CHILD_PERMISSIONS
|
||||
|
||||
static bool
|
||||
@ -118,11 +124,52 @@ AssertAppStatus(PBrowserParent* aActor,
|
||||
return CheckAppStatusHelper(app, aStatus);
|
||||
}
|
||||
|
||||
// A general purpose helper function to check permission against the origin
|
||||
// rather than mozIApplication.
|
||||
static bool
|
||||
CheckOriginPermission(const nsACString& aOrigin, const char* aPermission)
|
||||
{
|
||||
LOG("CheckOriginPermission: %s, %s\n", nsCString(aOrigin).get(), aPermission);
|
||||
|
||||
nsIScriptSecurityManager *securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
securityManager->CreateCodebasePrincipalFromOrigin(aOrigin,
|
||||
getter_AddRefs(principal));
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
|
||||
NS_ENSURE_TRUE(permMgr, false);
|
||||
|
||||
uint32_t perm;
|
||||
nsresult rv = permMgr->TestExactPermissionFromPrincipal(principal, aPermission, &perm);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
LOG("Permission %s for %s: %d\n", aPermission, nsCString(aOrigin).get(), perm);
|
||||
return nsIPermissionManager::ALLOW_ACTION == perm;
|
||||
}
|
||||
|
||||
bool
|
||||
AssertAppProcess(TabContext& aContext,
|
||||
AssertAppProcessType aType,
|
||||
const char* aCapability)
|
||||
{
|
||||
const mozilla::OriginAttributes& attr = aContext.OriginAttributesRef();
|
||||
nsCString suffix;
|
||||
attr.CreateSuffix(suffix);
|
||||
|
||||
if (!aContext.SignedPkgOriginNoSuffix().IsEmpty()) {
|
||||
LOG("TabContext owning signed package origin: %s, originAttr; %s\n",
|
||||
nsCString(aContext.SignedPkgOriginNoSuffix()).get(),
|
||||
suffix.get());
|
||||
}
|
||||
|
||||
// Do a origin-based permission check if the TabContext owns a signed package.
|
||||
if (!aContext.SignedPkgOriginNoSuffix().IsEmpty() &&
|
||||
(ASSERT_APP_HAS_PERMISSION == aType || ASSERT_APP_PROCESS_PERMISSION == aType)) {
|
||||
nsCString origin = aContext.SignedPkgOriginNoSuffix() + suffix;
|
||||
return CheckOriginPermission(origin, aCapability);
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIApplication> app = aContext.GetOwnOrContainingApp();
|
||||
return CheckAppTypeHelper(app, aType, aCapability, aContext.IsBrowserElement());
|
||||
|
@ -37,6 +37,11 @@ struct FrameIPCTabContext
|
||||
|
||||
// The ID of the app containing this app/browser frame, if applicable.
|
||||
uint32_t frameOwnerAppId;
|
||||
|
||||
// The origin without originAttribute suffix for a signed package.
|
||||
// This value would be empty if the TabContext doesn't own a signed
|
||||
// package.
|
||||
nsCString signedPkgOriginNoSuffix;
|
||||
};
|
||||
|
||||
// IPCTabContext is an analog to mozilla::dom::TabContext. Both specify an
|
||||
|
@ -158,11 +158,17 @@ TabContext::OriginAttributesRef() const
|
||||
return mOriginAttributes;
|
||||
}
|
||||
|
||||
const nsACString&
|
||||
TabContext::SignedPkgOriginNoSuffix() const
|
||||
{
|
||||
return mSignedPkgOriginNoSuffix;
|
||||
}
|
||||
|
||||
bool
|
||||
TabContext::SetTabContext(mozIApplication* aOwnApp,
|
||||
mozIApplication* aAppFrameOwnerApp,
|
||||
const OriginAttributes& aOriginAttributes)
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const nsACString& aSignedPkgOriginNoSuffix)
|
||||
{
|
||||
NS_ENSURE_FALSE(mInitialized, false);
|
||||
|
||||
@ -192,6 +198,7 @@ TabContext::SetTabContext(mozIApplication* aOwnApp,
|
||||
mContainingAppId = containingAppId;
|
||||
mOwnApp = aOwnApp;
|
||||
mContainingApp = aAppFrameOwnerApp;
|
||||
mSignedPkgOriginNoSuffix = aSignedPkgOriginNoSuffix;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -200,7 +207,9 @@ TabContext::AsIPCTabContext() const
|
||||
{
|
||||
nsAutoCString originSuffix;
|
||||
mOriginAttributes.CreateSuffix(originSuffix);
|
||||
return IPCTabContext(FrameIPCTabContext(originSuffix, mContainingAppId));
|
||||
return IPCTabContext(FrameIPCTabContext(originSuffix,
|
||||
mContainingAppId,
|
||||
mSignedPkgOriginNoSuffix));
|
||||
}
|
||||
|
||||
static already_AddRefed<mozIApplication>
|
||||
@ -221,6 +230,7 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
|
||||
uint32_t containingAppId = NO_APP_ID;
|
||||
OriginAttributes originAttributes = OriginAttributes();
|
||||
nsAutoCString originSuffix;
|
||||
nsAutoCString signedPkgOriginNoSuffix;
|
||||
|
||||
const IPCTabContextUnion& contextUnion = aParams.contextUnion();
|
||||
switch(contextUnion.type()) {
|
||||
@ -276,6 +286,7 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
|
||||
contextUnion.get_FrameIPCTabContext();
|
||||
|
||||
containingAppId = ipcContext.frameOwnerAppId();
|
||||
signedPkgOriginNoSuffix = ipcContext.signedPkgOriginNoSuffix();
|
||||
originSuffix = ipcContext.originSuffix();
|
||||
originAttributes.PopulateFromSuffix(originSuffix);
|
||||
break;
|
||||
@ -305,7 +316,8 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
|
||||
bool rv;
|
||||
rv = mTabContext.SetTabContext(ownApp,
|
||||
containingApp,
|
||||
originAttributes);
|
||||
originAttributes,
|
||||
signedPkgOriginNoSuffix);
|
||||
if (!rv) {
|
||||
mInvalidReason = "Couldn't initialize TabContext.";
|
||||
}
|
||||
|
@ -110,6 +110,12 @@ public:
|
||||
*/
|
||||
const OriginAttributes& OriginAttributesRef() const;
|
||||
|
||||
/**
|
||||
* Returns the origin associated with the tab (w/o suffix) if this tab owns
|
||||
* a signed packaged content.
|
||||
*/
|
||||
const nsACString& SignedPkgOriginNoSuffix() const;
|
||||
|
||||
protected:
|
||||
friend class MaybeInvalidTabContext;
|
||||
|
||||
@ -136,7 +142,8 @@ protected:
|
||||
*/
|
||||
bool SetTabContext(mozIApplication* aOwnApp,
|
||||
mozIApplication* aAppFrameOwnerApp,
|
||||
const OriginAttributes& aOriginAttributes);
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const nsACString& aSignedPkgOriginNoSuffix);
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -167,6 +174,13 @@ private:
|
||||
*/
|
||||
OriginAttributes mOriginAttributes;
|
||||
|
||||
/**
|
||||
* The signed package origin without suffix. Since the signed packaged
|
||||
* web content is always loaded in a separate process, it makes sense
|
||||
* that we store this immutable value in TabContext. If the TabContext
|
||||
* doesn't own a signed package, this value would be empty.
|
||||
*/
|
||||
nsCString mSignedPkgOriginNoSuffix;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -184,11 +198,13 @@ public:
|
||||
|
||||
bool SetTabContext(mozIApplication* aOwnApp,
|
||||
mozIApplication* aAppFrameOwnerApp,
|
||||
const OriginAttributes& aOriginAttributes)
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const nsACString& aSignedPkgOriginNoSuffix = EmptyCString())
|
||||
{
|
||||
return TabContext::SetTabContext(aOwnApp,
|
||||
aAppFrameOwnerApp,
|
||||
aOriginAttributes);
|
||||
aOriginAttributes,
|
||||
aSignedPkgOriginNoSuffix);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -518,7 +518,8 @@ TabParent::ShouldSwitchProcess(nsIChannel* aChannel)
|
||||
}
|
||||
|
||||
void
|
||||
TabParent::OnStartSignedPackageRequest(nsIChannel* aChannel)
|
||||
TabParent::OnStartSignedPackageRequest(nsIChannel* aChannel,
|
||||
const nsACString& aPackageId)
|
||||
{
|
||||
if (!ShouldSwitchProcess(aChannel)) {
|
||||
return;
|
||||
@ -537,7 +538,7 @@ TabParent::OnStartSignedPackageRequest(nsIChannel* aChannel)
|
||||
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
||||
NS_ENSURE_TRUE_VOID(frameLoader);
|
||||
|
||||
nsresult rv = frameLoader->SwitchProcessAndLoadURI(uri);
|
||||
nsresult rv = frameLoader->SwitchProcessAndLoadURI(uri, aPackageId);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to switch process.");
|
||||
}
|
||||
|
@ -456,7 +456,8 @@ public:
|
||||
|
||||
// Called by HttpChannelParent. The function may use a new process to
|
||||
// reload the URI associated with the given channel.
|
||||
void OnStartSignedPackageRequest(nsIChannel* aChannel);
|
||||
void OnStartSignedPackageRequest(nsIChannel* aChannel,
|
||||
const nsACString& aPackageId);
|
||||
|
||||
protected:
|
||||
bool ReceiveMessage(const nsString& aMessage,
|
||||
|
@ -1057,7 +1057,7 @@ NS_IMETHODIMP
|
||||
HttpChannelParent::OnStartSignedPackageRequest(const nsACString& aPackageId)
|
||||
{
|
||||
if (mTabParent) {
|
||||
mTabParent->OnStartSignedPackageRequest(mChannel);
|
||||
mTabParent->OnStartSignedPackageRequest(mChannel, aPackageId);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user