Bug 1161831 - Implement moz-extension protocol. r=bz,r=billm,sr=mcmanus

The heavy lifting all happened in the previous patch, so this is easy now.
This commit is contained in:
Bobby Holley 2015-07-19 18:42:16 -07:00
parent 12ea1bf6fe
commit f925835ed9
9 changed files with 123 additions and 1 deletions

View File

@ -11,7 +11,7 @@
* This interface allows the security manager to query custom per-addon security
* policy.
*/
[scriptable,uuid(fedf126c-988e-42df-82c9-f2ac99cd65f3)]
[scriptable,uuid(3ec203f8-2bd0-4f4c-8f99-f9f056221231)]
interface nsIAddonPolicyService : nsISupports
{
/**
@ -19,4 +19,9 @@ interface nsIAddonPolicyService : nsISupports
* data from |aURI|.
*/
boolean addonMayLoadURI(in AString aAddonId, in nsIURI aURI);
/**
* Returns true if a given extension:// URI is web-accessible.
*/
boolean extensionURILoadableByAnyone(in nsIURI aURI);
};

View File

@ -745,6 +745,16 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
// the methods that work on chains of nested URIs and they will only look
// at the flags for our one URI.
// Special case: moz-extension has a whitelist of URIs that are loadable by
// anyone.
if (targetScheme.EqualsLiteral("moz-extension") && GetAddonPolicyService()) {
bool loadable = false;
rv = GetAddonPolicyService()->ExtensionURILoadableByAnyone(targetBaseURI, &loadable);
if (NS_SUCCEEDED(rv) && loadable) {
return NS_OK;
}
}
// Check for system target URI
rv = DenyAccessIfURIHasFlags(targetBaseURI,
nsIProtocolHandler::URI_DANGEROUS_TO_LOAD);

View File

@ -8,10 +8,15 @@
#define nsScriptSecurityManager_h__
#include "nsIScriptSecurityManager.h"
#include "nsIAddonPolicyService.h"
#include "mozilla/Maybe.h"
#include "nsIAddonPolicyService.h"
#include "nsIPrincipal.h"
#include "nsCOMPtr.h"
#include "nsIChannelEventSink.h"
#include "nsIObserver.h"
#include "nsServiceManagerUtils.h"
#include "plstr.h"
#include "js/TypeDecls.h"
@ -124,6 +129,17 @@ private:
// policy machinery will be removed soon.
nsCOMPtr<nsIDomainPolicy> mDomainPolicy;
// Cached addon policy service. We can't generate this in Init() because
// that's too early to get a service.
mozilla::Maybe<nsCOMPtr<nsIAddonPolicyService>> mAddonPolicyService;
nsIAddonPolicyService* GetAddonPolicyService()
{
if (mAddonPolicyService.isNothing()) {
mAddonPolicyService.emplace(do_GetService("@mozilla.org/addons/policy-service;1"));
}
return mAddonPolicyService.ref();
}
static bool sStrictFileOriginPolicy;
static nsIIOService *sIOService;

View File

@ -637,6 +637,14 @@
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_EXTENSIONPROTOCOLHANDLER_CID \
{ /* aea16cd0-f020-4138-b068-0716c4a15b5a */ \
0xaea16cd0, \
0xf020, \
0x4138, \
{0xb0, 0x68, 0x07, 0x16, 0xc4, 0xa1, 0x5b, 0x5a} \
}
#define NS_SUBSTITUTINGURL_CID \
{ 0xdea9657c, \
0x18cf, \

View File

@ -272,10 +272,12 @@ namespace net {
#ifdef NECKO_PROTOCOL_res
// resource
#include "nsResProtocolHandler.h"
#include "ExtensionProtocolHandler.h"
#include "SubstitutingProtocolHandler.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsResProtocolHandler, Init)
namespace mozilla {
NS_GENERIC_FACTORY_CONSTRUCTOR(ExtensionProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(SubstitutingURL)
} // namespace mozilla
#endif
@ -760,6 +762,7 @@ NS_DEFINE_NAMED_CID(NS_FTPPROTOCOLHANDLER_CID);
#endif
#ifdef NECKO_PROTOCOL_res
NS_DEFINE_NAMED_CID(NS_RESPROTOCOLHANDLER_CID);
NS_DEFINE_NAMED_CID(NS_EXTENSIONPROTOCOLHANDLER_CID);
NS_DEFINE_NAMED_CID(NS_SUBSTITUTINGURL_CID);
#endif
NS_DEFINE_NAMED_CID(NS_ABOUTPROTOCOLHANDLER_CID);
@ -906,6 +909,7 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
#endif
#ifdef NECKO_PROTOCOL_res
{ &kNS_RESPROTOCOLHANDLER_CID, false, nullptr, nsResProtocolHandlerConstructor },
{ &kNS_EXTENSIONPROTOCOLHANDLER_CID, false, nullptr, mozilla::ExtensionProtocolHandlerConstructor },
{ &kNS_SUBSTITUTINGURL_CID, false, nullptr, mozilla::SubstitutingURLConstructor },
#endif
{ &kNS_ABOUTPROTOCOLHANDLER_CID, false, nullptr, nsAboutProtocolHandlerConstructor },
@ -1061,6 +1065,7 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
#endif
#ifdef NECKO_PROTOCOL_res
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "resource", &kNS_RESPROTOCOLHANDLER_CID },
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-extension", &kNS_EXTENSIONPROTOCOLHANDLER_CID },
#endif
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "about", &kNS_ABOUTPROTOCOLHANDLER_CID },
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-safe-about", &kNS_SAFEABOUTPROTOCOLHANDLER_CID },

View File

@ -0,0 +1,16 @@
/* -*- 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 "ExtensionProtocolHandler.h"
namespace mozilla {
NS_IMPL_QUERY_INTERFACE(ExtensionProtocolHandler, nsISubstitutingProtocolHandler,
nsIProtocolHandler, nsISupportsWeakReference)
NS_IMPL_ADDREF_INHERITED(ExtensionProtocolHandler, SubstitutingProtocolHandler)
NS_IMPL_RELEASE_INHERITED(ExtensionProtocolHandler, SubstitutingProtocolHandler)
} // namespace mozilla

View File

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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/. */
#ifndef ExtensionProtocolHandler_h___
#define ExtensionProtocolHandler_h___
#include "SubstitutingProtocolHandler.h"
#include "nsWeakReference.h"
namespace mozilla {
class ExtensionProtocolHandler final : public nsISubstitutingProtocolHandler,
public mozilla::SubstitutingProtocolHandler,
public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_FORWARD_NSIPROTOCOLHANDLER(mozilla::SubstitutingProtocolHandler::)
NS_FORWARD_NSISUBSTITUTINGPROTOCOLHANDLER(mozilla::SubstitutingProtocolHandler::)
// In general a moz-extension URI is only loadable by chrome, but a whitelisted
// subset are web-accessible (see nsIAddonPolicyService).
ExtensionProtocolHandler()
: SubstitutingProtocolHandler("moz-extension", URI_STD | URI_DANGEROUS_TO_LOAD | URI_IS_LOCAL_RESOURCE)
{}
protected:
~ExtensionProtocolHandler() {}
};
} // namespace mozilla
#endif /* ExtensionProtocolHandler_h___ */

View File

@ -12,6 +12,7 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'necko_res'
SOURCES += [
'ExtensionProtocolHandler.cpp',
'nsResProtocolHandler.cpp',
'SubstitutingProtocolHandler.cpp',
]

View File

@ -66,6 +66,21 @@ AddonPolicyService.prototype = {
return cb ? cb(aURI) : false;
},
/*
* Invokes a callback (if any) to determine if an extension URI should be
* web-accessible.
*
* @see nsIAddonPolicyService.extensionURILoadableByAnyone
*/
extensionURILoadableByAnyone(aURI) {
if (aURI.scheme != "moz-extension") {
throw new TypeError("non-extension URI passed");
}
let cb = this.extensionURILoadCallback;
return cb ? cb(aURI) : false;
},
/*
* Sets the callbacks used in addonMayLoadURI above. Not accessible over
* XPCOM - callers should use .wrappedJSObject on the service to call it
@ -74,6 +89,17 @@ AddonPolicyService.prototype = {
setAddonLoadURICallback(aAddonId, aCallback) {
this.mayLoadURICallbacks[aAddonId] = aCallback;
},
/*
* Sets the callback used in extensionURILoadableByAnyone above. Not
* accessible over XPCOM - callers should use .wrappedJSObject on the
* service to call it directly.
*/
setExtensionURILoadCallback(aCallback) {
var old = this.extensionURILoadCallback;
this.extensionURILoadCallback = aCallback;
return old;
}
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RemoteTagServiceService, AddonPolicyService]);