зеркало из https://github.com/mozilla/gecko-dev.git
Bug 904298 - Implement mozilla::{AssertAppPrincipal,CheckPermission}. r=sicking
This commit is contained in:
Родитель
3da424dcdb
Коммит
ae48603c29
|
@ -6,15 +6,26 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "AppProcessChecker.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#ifdef MOZ_CHILD_PERMISSIONS
|
||||
#include "ContentParent.h"
|
||||
#include "mozIApplication.h"
|
||||
#include "mozilla/hal_sandbox/PHalParent.h"
|
||||
#include "nsIAppsService.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "TabParent.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::hal_sandbox;
|
||||
using namespace mozilla::services;
|
||||
#else
|
||||
class PContentParent;
|
||||
class nsIPrincipal;
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -126,6 +137,99 @@ AssertAppProcess(PHalParent* aActor,
|
|||
return AssertAppProcess(aActor->Manager(), aType, aCapability);
|
||||
}
|
||||
|
||||
bool
|
||||
AssertAppPrincipal(PContentParent* aActor,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
if (!aPrincipal) {
|
||||
NS_WARNING("Principal is invalid, killing app process");
|
||||
static_cast<ContentParent*>(aActor)->KillHard();
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t principalAppId = aPrincipal->GetAppId();
|
||||
bool inBrowserElement = aPrincipal->GetIsInBrowserElement();
|
||||
|
||||
// Check if the permission's appId matches a child we manage.
|
||||
const InfallibleTArray<PBrowserParent*>& browsers =
|
||||
aActor->ManagedPBrowserParent();
|
||||
for (uint32_t i = 0; i < browsers.Length(); ++i) {
|
||||
TabParent* tab = static_cast<TabParent*>(browsers[i]);
|
||||
if (tab->OwnOrContainingAppId() == principalAppId) {
|
||||
// If the child only runs inBrowserElement content and the principal claims
|
||||
// it's not in a browser element, it's lying.
|
||||
if (!tab->IsBrowserElement() || inBrowserElement) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NS_WARNING("Principal is invalid, killing app process");
|
||||
static_cast<ContentParent*>(aActor)->KillHard();
|
||||
return false;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIPrincipal>
|
||||
GetAppPrincipal(uint32_t aAppId)
|
||||
{
|
||||
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
|
||||
|
||||
nsIURI* uri;
|
||||
nsresult rv = appsService->GetManifestURLByLocalId(aAppId);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
|
||||
|
||||
nsIPrincipal* appPrincipal;
|
||||
rv = secMan->GetAppCodebasePrincipal(uri, aAppId, false, &appPrincipal);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
return appPrincipal;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
CheckPermission(PContentParent* aActor,
|
||||
nsIPrincipal* aPrincipal,
|
||||
const char* aPermission)
|
||||
{
|
||||
if (!AssertAppPrincipal(aActor, aPrincipal)) {
|
||||
return nsIPermissionManager::DENY_ACTION;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> pm =
|
||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(pm, nsIPermissionManager::DENY_ACTION);
|
||||
|
||||
// Make sure that `aPermission' is an app permission before checking the origin.
|
||||
nsCOMPtr<nsIPrincipal> appPrincipal = GetAppPrincipal(aPrincipal->GetAppId());
|
||||
uint32_t appPerm = nsIPermissionManager::UNKNOWN_ACTION;
|
||||
nsresult rv = pm->TestExactPermissionFromPrincipal(appPrincipal, aPermission, &appPerm);
|
||||
NS_ENSURE_SUCCESS(rv, nsIPermissionManager::UNKNOWN_ACTION);
|
||||
if (appPerm == nsIPermissionManager::UNKNOWN_ACTION ||
|
||||
appPerm == nsIPermissionManager::DENY_ACTION) {
|
||||
return appPerm;
|
||||
}
|
||||
|
||||
uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
|
||||
rv = pm->TestExactPermissionFromPrincipal(aPrincipal, aPermission, &permission);
|
||||
NS_ENSURE_SUCCESS(rv, nsIPermissionManager::UNKNOWN_ACTION);
|
||||
if (permission == nsIPermissionManager::UNKNOWN_ACTION ||
|
||||
permission == nsIPermissionManager::DENY_ACTION) {
|
||||
return permission;
|
||||
}
|
||||
|
||||
if (appPerm == PROMPT_ACTION || permission == PROMPT_ACTION) {
|
||||
return PROMPT_ACTION;
|
||||
}
|
||||
|
||||
if (appPerm == ALLOW_ACTION || permission == ALLOW_ACTION) {
|
||||
return ALLOW_ACTION;
|
||||
}
|
||||
|
||||
NS_RUNTIMEABORT("Invalid permission value");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool
|
||||
|
@ -167,6 +271,21 @@ AssertAppProcess(mozilla::hal_sandbox::PHalParent* aActor,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AssertAppPrincipal(PContentParent* aActor,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
CheckPermission(PContentParent*,
|
||||
nsIPrincipal*,
|
||||
const char*)
|
||||
{
|
||||
return nsIPermissionManager::ALLOW_ACTION;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#ifndef mozilla_AppProcessChecker_h
|
||||
#define mozilla_AppProcessChecker_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class nsIPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
|
@ -66,6 +70,21 @@ AssertAppProcess(mozilla::hal_sandbox::PHalParent* aActor,
|
|||
// return AssertAppProcess(aActor->Manager(), aType);
|
||||
// }
|
||||
|
||||
bool
|
||||
AssertAppPrincipal(mozilla::dom::PContentParent* aParent,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
/**
|
||||
* Check if the specified principal is valid, and return the saved permission
|
||||
* value for permission `aPermission' on that principal.
|
||||
* See nsIPermissionManager.idl for possible return values.
|
||||
*
|
||||
* nsIPermissionManager::UNKNOWN_ACTION is retuned if the principal is invalid.
|
||||
*/
|
||||
uint32_t
|
||||
CheckPermission(mozilla::dom::PContentParent* aParent,
|
||||
nsIPrincipal* aPrincipal, const char* aPermission);
|
||||
|
||||
/**
|
||||
* Inline function for asserting the process's permission.
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче