From edb1043b3e6f5f7e1e2c8c3046e6220e526f60cc Mon Sep 17 00:00:00 2001 From: William Chen Date: Mon, 30 Jul 2012 10:58:26 -0400 Subject: [PATCH] Bug 775377 - Modify nsIContentPermissionRequest to use nsIPrincipal instead of nsIURI. r=dougt+cjones --- b2g/components/ContentPermissionPrompt.js | 4 +- browser/components/nsBrowserGlue.js | 9 +-- dom/base/nsContentPermissionHelper.cpp | 38 +++++++---- dom/base/nsContentPermissionHelper.h | 15 ++-- dom/devicestorage/DeviceStorage.h | 3 +- dom/devicestorage/nsDeviceStorage.cpp | 44 ++++++------ dom/devicestorage/nsDeviceStorage.h | 5 +- .../base/nsIContentPermissionPrompt.idl | 8 +-- dom/ipc/Makefile.in | 2 + dom/ipc/PBrowser.ipdl | 19 +++++- dom/ipc/PermissionMessageUtils.cpp | 68 +++++++++++++++++++ dom/ipc/PermissionMessageUtils.h | 40 +++++++++++ dom/ipc/TabChild.cpp | 2 +- dom/ipc/TabChild.h | 6 +- dom/ipc/TabParent.cpp | 6 +- dom/ipc/TabParent.h | 3 +- dom/src/geolocation/nsGeolocation.cpp | 24 +++---- dom/src/geolocation/nsGeolocation.h | 6 +- .../notification/nsDesktopNotification.cpp | 16 ++--- dom/src/notification/nsDesktopNotification.h | 8 +-- .../components/ContentPermissionPrompt.js | 10 +-- mobile/xul/chrome/content/IndexedDB.js | 2 +- mobile/xul/chrome/content/WebappsUI.js | 9 +-- .../xul/components/ContentPermissionPrompt.js | 24 +++---- webapprt/ContentPermission.js | 4 +- 25 files changed, 256 insertions(+), 119 deletions(-) create mode 100644 dom/ipc/PermissionMessageUtils.cpp create mode 100644 dom/ipc/PermissionMessageUtils.h diff --git a/b2g/components/ContentPermissionPrompt.js b/b2g/components/ContentPermissionPrompt.js index 7e24486eebe..c0313f3419a 100644 --- a/b2g/components/ContentPermissionPrompt.js +++ b/b2g/components/ContentPermissionPrompt.js @@ -15,7 +15,7 @@ function ContentPermissionPrompt() {} ContentPermissionPrompt.prototype = { handleExistingPermission: function handleExistingPermission(request) { - let result = Services.perms.testExactPermission(request.uri, request.type); + let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type); if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { request.allow(); return true; @@ -56,7 +56,7 @@ ContentPermissionPrompt.prototype = { "type": "permission-prompt", "permission": request.type, "id": requestId, - "url": request.uri.spec + "url": request.principal.URI.spec }; let event = content.document.createEvent("CustomEvent"); event.initCustomEvent("mozChromeEvent", true, true, details); diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index 3a59b241464..d3af28d1309 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -1560,13 +1560,14 @@ ContentPermissionPrompt.prototype = { return; } - var requestingURI = request.uri; + var requestingPrincipal = request.principal; + var requestingURI = requestingPrincipal.URI; // Ignore requests from non-nsIStandardURLs if (!(requestingURI instanceof Ci.nsIStandardURL)) return; - var result = Services.perms.testExactPermission(requestingURI, "geo"); + var result = Services.perms.testExactPermissionFromPrincipal(requestingPrincipal, "geo"); if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { request.allow(); @@ -1619,7 +1620,7 @@ ContentPermissionPrompt.prototype = { label: browserBundle.GetStringFromName("geolocation.alwaysShareLocation"), accessKey: browserBundle.GetStringFromName("geolocation.alwaysShareLocation.accesskey"), callback: function () { - Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.ALLOW_ACTION); + Services.perms.addFromPrincipal(requestingPrincipal, "geo", Ci.nsIPermissionManager.ALLOW_ACTION); request.allow(); } }); @@ -1627,7 +1628,7 @@ ContentPermissionPrompt.prototype = { label: browserBundle.GetStringFromName("geolocation.neverShareLocation"), accessKey: browserBundle.GetStringFromName("geolocation.neverShareLocation.accesskey"), callback: function () { - Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.DENY_ACTION); + Services.perms.addFromPrincipal(requestingPrincipal, "geo", Ci.nsIPermissionManager.DENY_ACTION); request.cancel(); } }); diff --git a/dom/base/nsContentPermissionHelper.cpp b/dom/base/nsContentPermissionHelper.cpp index 885bd92bbd2..4930b0b55ba 100644 --- a/dom/base/nsContentPermissionHelper.cpp +++ b/dom/base/nsContentPermissionHelper.cpp @@ -7,10 +7,11 @@ #include "nsCOMPtr.h" #include "nsIDOMWindow.h" #include "nsIDOMElement.h" - +#include "nsIPrincipal.h" #include "mozilla/unused.h" using mozilla::unused; // +using namespace mozilla::dom; nsContentPermissionRequestProxy::nsContentPermissionRequestProxy() { @@ -24,7 +25,7 @@ nsContentPermissionRequestProxy::~nsContentPermissionRequestProxy() nsresult nsContentPermissionRequestProxy::Init(const nsACString & type, - mozilla::dom::ContentPermissionRequestParent* parent) + ContentPermissionRequestParent* parent) { NS_ASSERTION(parent, "null parent"); mParent = parent; @@ -63,13 +64,14 @@ nsContentPermissionRequestProxy::GetWindow(nsIDOMWindow * *aRequestingWindow) } NS_IMETHODIMP -nsContentPermissionRequestProxy::GetUri(nsIURI * *aRequestingURI) +nsContentPermissionRequestProxy::GetPrincipal(nsIPrincipal * *aRequestingPrincipal) { - NS_ENSURE_ARG_POINTER(aRequestingURI); - if (mParent == nullptr) + NS_ENSURE_ARG_POINTER(aRequestingPrincipal); + if (mParent == nullptr) { return NS_ERROR_FAILURE; + } - NS_ADDREF(*aRequestingURI = mParent->mURI); + NS_ADDREF(*aRequestingPrincipal = mParent->mPrincipal); return NS_OK; } @@ -77,8 +79,10 @@ NS_IMETHODIMP nsContentPermissionRequestProxy::GetElement(nsIDOMElement * *aRequestingElement) { NS_ENSURE_ARG_POINTER(aRequestingElement); - if (mParent == nullptr) + if (mParent == nullptr) { return NS_ERROR_FAILURE; + } + NS_ADDREF(*aRequestingElement = mParent->mElement); return NS_OK; } @@ -86,9 +90,11 @@ nsContentPermissionRequestProxy::GetElement(nsIDOMElement * *aRequestingElement) NS_IMETHODIMP nsContentPermissionRequestProxy::Cancel() { - if (mParent == nullptr) + if (mParent == nullptr) { return NS_ERROR_FAILURE; - unused << mozilla::dom::ContentPermissionRequestParent::Send__delete__(mParent, false); + } + + unused << ContentPermissionRequestParent::Send__delete__(mParent, false); mParent = nullptr; return NS_OK; } @@ -96,9 +102,10 @@ nsContentPermissionRequestProxy::Cancel() NS_IMETHODIMP nsContentPermissionRequestProxy::Allow() { - if (mParent == nullptr) + if (mParent == nullptr) { return NS_ERROR_FAILURE; - unused << mozilla::dom::ContentPermissionRequestParent::Send__delete__(mParent, true); + } + unused << ContentPermissionRequestParent::Send__delete__(mParent, true); mParent = nullptr; return NS_OK; } @@ -108,11 +115,11 @@ namespace dom { ContentPermissionRequestParent::ContentPermissionRequestParent(const nsACString& aType, nsIDOMElement *aElement, - const IPC::URI& aUri) + const IPC::Principal& aPrincipal) { MOZ_COUNT_CTOR(ContentPermissionRequestParent); - - mURI = aUri; + + mPrincipal = aPrincipal; mElement = aElement; mType = aType; } @@ -127,8 +134,9 @@ ContentPermissionRequestParent::Recvprompt() { mProxy = new nsContentPermissionRequestProxy(); NS_ASSERTION(mProxy, "Alloc of request proxy failed"); - if (NS_FAILED(mProxy->Init(mType, this))) + if (NS_FAILED(mProxy->Init(mType, this))) { mProxy->Cancel(); + } return true; } diff --git a/dom/base/nsContentPermissionHelper.h b/dom/base/nsContentPermissionHelper.h index 67250160172..7411dbb7347 100644 --- a/dom/base/nsContentPermissionHelper.h +++ b/dom/base/nsContentPermissionHelper.h @@ -11,6 +11,7 @@ #include "nsString.h" #include "nsIDOMElement.h" +#include "mozilla/dom/PermissionMessageUtils.h" #include "mozilla/dom/PContentPermissionRequestParent.h" class nsContentPermissionRequestProxy; @@ -21,19 +22,19 @@ namespace dom { class ContentPermissionRequestParent : public PContentPermissionRequestParent { public: - ContentPermissionRequestParent(const nsACString& type, nsIDOMElement *element, const IPC::URI& principal); + ContentPermissionRequestParent(const nsACString& type, nsIDOMElement *element, const IPC::Principal& principal); virtual ~ContentPermissionRequestParent(); - - nsCOMPtr mURI; + + nsCOMPtr mPrincipal; nsCOMPtr mElement; nsCOMPtr mProxy; nsCString mType; - private: + private: virtual bool Recvprompt(); virtual void ActorDestroy(ActorDestroyReason why); }; - + } // namespace dom } // namespace mozilla @@ -42,10 +43,10 @@ class nsContentPermissionRequestProxy : public nsIContentPermissionRequest public: nsContentPermissionRequestProxy(); virtual ~nsContentPermissionRequestProxy(); - + nsresult Init(const nsACString& type, mozilla::dom::ContentPermissionRequestParent* parent); void OnParentDestroyed(); - + NS_DECL_ISUPPORTS NS_DECL_NSICONTENTPERMISSIONREQUEST diff --git a/dom/devicestorage/DeviceStorage.h b/dom/devicestorage/DeviceStorage.h index e29b1e3110c..842ea7b9e82 100644 --- a/dom/devicestorage/DeviceStorage.h +++ b/dom/devicestorage/DeviceStorage.h @@ -7,6 +7,7 @@ #include "nsIDOMDeviceStorage.h" #include "nsIFile.h" +#include "nsIPrincipal.h" #include "nsIObserver.h" #include "nsDOMEventTargetHelper.h" @@ -55,7 +56,7 @@ private: PRInt32 mStorageType; nsCOMPtr mFile; - nsCOMPtr mURI; + nsCOMPtr mPrincipal; friend class WatchFileEvent; friend class DeviceStorageRequest; diff --git a/dom/devicestorage/nsDeviceStorage.cpp b/dom/devicestorage/nsDeviceStorage.cpp index 6f0cc549824..461c222c1fb 100644 --- a/dom/devicestorage/nsDeviceStorage.cpp +++ b/dom/devicestorage/nsDeviceStorage.cpp @@ -34,6 +34,7 @@ #include "mozilla/Services.h" #include "nsIObserverService.h" #include "GeneratedEvents.h" +#include "mozilla/dom/PermissionMessageUtils.h" // Microsoft's API Name hackery sucks #undef CreateEvent @@ -636,14 +637,14 @@ NS_IMPL_ADDREF_INHERITED(nsDOMDeviceStorageCursor, DOMRequest) NS_IMPL_RELEASE_INHERITED(nsDOMDeviceStorageCursor, DOMRequest) nsDOMDeviceStorageCursor::nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow, - nsIURI* aURI, + nsIPrincipal* aPrincipal, DeviceStorageFile* aFile, PRUint64 aSince) : DOMRequest(aWindow) , mOkToCallContinue(false) , mSince(aSince) , mFile(aFile) - , mURI(aURI) + , mPrincipal(aPrincipal) { } @@ -659,9 +660,9 @@ nsDOMDeviceStorageCursor::GetType(nsACString & aType) } NS_IMETHODIMP -nsDOMDeviceStorageCursor::GetUri(nsIURI * *aRequestingURI) +nsDOMDeviceStorageCursor::GetPrincipal(nsIPrincipal * *aRequestingPrincipal) { - NS_IF_ADDREF(*aRequestingURI = mURI); + NS_IF_ADDREF(*aRequestingPrincipal = mPrincipal); return NS_OK; } @@ -937,28 +938,28 @@ public: DeviceStorageRequest(const DeviceStorageRequestType aRequestType, nsPIDOMWindow *aWindow, - nsIURI *aURI, + nsIPrincipal *aPrincipal, DeviceStorageFile *aFile, DOMRequest* aRequest, nsDOMDeviceStorage *aDeviceStorage, nsIDOMEventListener *aListener) : mRequestType(aRequestType) , mWindow(aWindow) - , mURI(aURI) + , mPrincipal(aPrincipal) , mFile(aFile) , mRequest(aRequest) , mDeviceStorage(aDeviceStorage) - , mListener(aListener) {} + , mListener(aListener) {} DeviceStorageRequest(const DeviceStorageRequestType aRequestType, nsPIDOMWindow *aWindow, - nsIURI *aURI, + nsIPrincipal *aPrincipal, DeviceStorageFile *aFile, DOMRequest* aRequest, nsIDOMBlob *aBlob = nullptr) : mRequestType(aRequestType) , mWindow(aWindow) - , mURI(aURI) + , mPrincipal(aPrincipal) , mFile(aFile) , mRequest(aRequest) , mBlob(aBlob) {} @@ -987,7 +988,7 @@ public: AddRef(); nsCString type = NS_LITERAL_CSTRING("device-storage"); - child->SendPContentPermissionRequestConstructor(this, type, IPC::URI(mURI)); + child->SendPContentPermissionRequestConstructor(this, type, IPC::Principal(mPrincipal)); Sendprompt(); return NS_OK; @@ -1006,9 +1007,9 @@ public: return NS_OK; } - NS_IMETHOD GetUri(nsIURI * *aRequestingURI) + NS_IMETHOD GetPrincipal(nsIPrincipal * *aRequestingPrincipal) { - NS_IF_ADDREF(*aRequestingURI = mURI); + NS_IF_ADDREF(*aRequestingPrincipal = mPrincipal); return NS_OK; } @@ -1153,7 +1154,7 @@ public: private: PRInt32 mRequestType; nsCOMPtr mWindow; - nsCOMPtr mURI; + nsCOMPtr mPrincipal; nsRefPtr mFile; nsRefPtr mRequest; @@ -1226,14 +1227,14 @@ nsDOMDeviceStorage::Init(nsPIDOMWindow* aWindow, const nsAString &aType) BindToOwner(aWindow); - // Grab the uri of the document + // Grab the principal of the document nsCOMPtr domdoc; aWindow->GetDocument(getter_AddRefs(domdoc)); nsCOMPtr doc = do_QueryInterface(domdoc); if (!doc) { return NS_ERROR_FAILURE; } - doc->NodePrincipal()->GetURI(getter_AddRefs(mURI)); + mPrincipal = doc->NodePrincipal(); return NS_OK; } @@ -1311,7 +1312,7 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob *aBlob, } else { r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_WRITE, - win, mURI, dsf, request, aBlob); + win, mPrincipal, dsf, request, aBlob); } NS_DispatchToMainThread(r); return NS_OK; @@ -1367,7 +1368,7 @@ nsDOMDeviceStorage::GetInternal(const JS::Value & aPath, r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf); } else { r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_READ, - win, mURI, dsf, request); + win, mPrincipal, dsf, request); } NS_DispatchToMainThread(r); return NS_OK; @@ -1402,7 +1403,7 @@ nsDOMDeviceStorage::Delete(const JS::Value & aPath, JSContext* aCx, nsIDOMDOMReq } else { r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_DELETE, - win, mURI, dsf, request); + win, mPrincipal, dsf, request); } NS_DispatchToMainThread(r); return NS_OK; @@ -1485,7 +1486,8 @@ nsDOMDeviceStorage::EnumerateInternal(const JS::Value & aName, nsRefPtr dsf = new DeviceStorageFile(mFile, path); dsf->SetEditable(aEditable); - nsRefPtr cursor = new nsDOMDeviceStorageCursor(win, mURI, dsf, since); + nsRefPtr cursor = new nsDOMDeviceStorageCursor(win, mPrincipal, + dsf, since); nsRefPtr r = new DeviceStorageCursorRequest(cursor); NS_ADDREF(*aRetval = cursor); @@ -1507,7 +1509,7 @@ nsDOMDeviceStorage::EnumerateInternal(const JS::Value & aName, r->AddRef(); nsCString type = NS_LITERAL_CSTRING("device-storage"); - child->SendPContentPermissionRequestConstructor(r, type, IPC::URI(mURI)); + child->SendPContentPermissionRequestConstructor(r, type, IPC::Principal(mPrincipal)); r->Sendprompt(); @@ -1613,7 +1615,7 @@ nsDOMDeviceStorage::AddEventListener(const nsAString & aType, nsRefPtr request = new DOMRequest(win); nsRefPtr dsf = new DeviceStorageFile(mFile); nsCOMPtr r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_WATCH, - win, mURI, dsf, request, this, aListener); + win, mPrincipal, dsf, request, this, aListener); NS_DispatchToMainThread(r); return nsDOMEventTargetHelper::AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted, aArgc); } diff --git a/dom/devicestorage/nsDeviceStorage.h b/dom/devicestorage/nsDeviceStorage.h index cf23aa45dc9..1f48a0cbdbe 100644 --- a/dom/devicestorage/nsDeviceStorage.h +++ b/dom/devicestorage/nsDeviceStorage.h @@ -18,6 +18,7 @@ class nsPIDOMWindow; #include "nsIDOMWindow.h" #include "nsIURI.h" #include "nsInterfaceHashtable.h" +#include "nsIPrincipal.h" #include "nsString.h" #include "nsWeakPtr.h" #include "nsIDOMEventListener.h" @@ -86,7 +87,7 @@ public: NS_DECL_NSIDOMDEVICESTORAGECURSOR nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow, - nsIURI* aURI, + nsIPrincipal* aPrincipal, DeviceStorageFile* aFile, PRUint64 aSince); @@ -102,7 +103,7 @@ private: ~nsDOMDeviceStorageCursor(); nsRefPtr mFile; - nsCOMPtr mURI; + nsCOMPtr mPrincipal; }; //helpers diff --git a/dom/interfaces/base/nsIContentPermissionPrompt.idl b/dom/interfaces/base/nsIContentPermissionPrompt.idl index b0eaaf59977..a22b979538f 100644 --- a/dom/interfaces/base/nsIContentPermissionPrompt.idl +++ b/dom/interfaces/base/nsIContentPermissionPrompt.idl @@ -4,7 +4,7 @@ #include "nsISupports.idl" -interface nsIURI; +interface nsIPrincipal; interface nsIDOMWindow; interface nsIDOMElement; @@ -13,7 +13,7 @@ interface nsIDOMElement; * permission to perform a privileged operation such as * geolocation. */ -[scriptable, uuid(E79C7063-DBAB-45E3-8A98-D0142E1ABC9A)] +[scriptable, uuid(E1F3796C-ADFA-414B-B2A7-AC62F29395EE)] interface nsIContentPermissionRequest : nsISupports { /** @@ -23,9 +23,9 @@ interface nsIContentPermissionRequest : nsISupports { readonly attribute ACString type; /** - * The uri of the permission request. + * The principal of the permission request. */ - readonly attribute nsIURI uri; + readonly attribute nsIPrincipal principal; /** * The window or element that the permission request was diff --git a/dom/ipc/Makefile.in b/dom/ipc/Makefile.in index 8f14f729356..7710a47a0be 100644 --- a/dom/ipc/Makefile.in +++ b/dom/ipc/Makefile.in @@ -33,6 +33,7 @@ EXPORTS_mozilla/dom = \ ContentProcess.h \ CrashReporterChild.h \ CrashReporterParent.h \ + PermissionMessageUtils.h \ StructuredCloneUtils.h \ TabParent.h \ TabChild.h \ @@ -52,6 +53,7 @@ CPPSRCS = \ ContentChild.cpp \ CrashReporterParent.cpp \ CrashReporterChild.cpp \ + PermissionMessageUtils.cpp \ ProcessPriorityManager.cpp \ StructuredCloneUtils.cpp \ TabParent.cpp \ diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index d45ff2ff39b..e8930cae2b2 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -17,12 +17,14 @@ include protocol PIndexedDB; include "gfxMatrix.h"; include "IPC/nsGUIEventIPC.h"; include "mozilla/dom/TabMessageUtils.h"; +include "mozilla/dom/PermissionMessageUtils.h"; include "mozilla/layout/RenderFrameUtils.h"; include "mozilla/net/NeckoMessageUtils.h"; include DOMTypes; using IPC::URI; +using IPC::Principal; using gfxMatrix; using gfxSize; using mozilla::layers::LayersBackend; @@ -174,7 +176,20 @@ parent: SetCursor(PRUint32 value); SetBackgroundColor(nscolor color); - PContentPermissionRequest(nsCString aType, URI uri); + /** + * Initiates an asynchronous request for permission for the + * provided principal. + * + * @param aType + * The type of permission to request. + * @param aPrincipal + * The principal of the request. + * + * NOTE: The principal is untrusted in the parent process. Only + * principals that can live in the content process should + * provided. + */ + PContentPermissionRequest(nsCString aType, Principal principal); PContentDialog(PRUint32 aType, nsCString aName, nsCString aFeatures, PRInt32[] aIntParams, nsString[] aStringParams); @@ -342,4 +357,4 @@ state DYING: }; } -} \ No newline at end of file +} diff --git a/dom/ipc/PermissionMessageUtils.cpp b/dom/ipc/PermissionMessageUtils.cpp new file mode 100644 index 00000000000..3e9f665b565 --- /dev/null +++ b/dom/ipc/PermissionMessageUtils.cpp @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 2; 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 "mozilla/dom/PermissionMessageUtils.h" +#include "nsISerializable.h" +#include "nsSerializationHelper.h" + +namespace IPC { + +void +ParamTraits::Write(Message* aMsg, const paramType& aParam) { + bool isNull = !aParam.mPrincipal; + WriteParam(aMsg, isNull); + if (isNull) { + return; + } + + bool isSerialized = false; + nsCString principalString; + nsCOMPtr serializable = do_QueryInterface(aParam.mPrincipal); + if (serializable) { + nsresult rv = NS_SerializeToString(serializable, principalString); + if (NS_SUCCEEDED(rv)) { + isSerialized = true; + } + } + + if (!isSerialized) { + NS_RUNTIMEABORT("Unable to serialize principal."); + return; + } + + WriteParam(aMsg, principalString); +} + +bool +ParamTraits::Read(const Message* aMsg, void** aIter, paramType* aResult) +{ + bool isNull; + if (!ReadParam(aMsg, aIter, &isNull)) { + return false; + } + + if (isNull) { + aResult->mPrincipal = nullptr; + return true; + } + + nsCString principalString; + if (!ReadParam(aMsg, aIter, &principalString)) { + return false; + } + + nsCOMPtr iSupports; + nsresult rv = NS_DeserializeObject(principalString, getter_AddRefs(iSupports)); + NS_ENSURE_SUCCESS(rv, false); + + nsCOMPtr principal = do_QueryInterface(iSupports); + NS_ENSURE_TRUE(principal, false); + + principal.swap(aResult->mPrincipal); + return true; +} + +} // namespace IPC + diff --git a/dom/ipc/PermissionMessageUtils.h b/dom/ipc/PermissionMessageUtils.h new file mode 100644 index 00000000000..e3f34778570 --- /dev/null +++ b/dom/ipc/PermissionMessageUtils.h @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 2; 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/. */ + +#ifndef mozilla_dom_permission_message_utils_h__ +#define mozilla_dom_permission_message_utils_h__ + +#include "IPC/IPCMessageUtils.h" +#include "nsCOMPtr.h" +#include "nsIPrincipal.h" + +namespace IPC { + +class Principal { + friend struct ParamTraits; + +public: + Principal() : mPrincipal(nsnull) {} + Principal(nsIPrincipal* aPrincipal) : mPrincipal(aPrincipal) {} + operator nsIPrincipal*() const { return mPrincipal.get(); } + +private: + // Unimplemented + Principal& operator=(Principal&); + nsCOMPtr mPrincipal; +}; + +template <> +struct ParamTraits +{ + typedef Principal paramType; + static void Write(Message* aMsg, const paramType& aParam); + static bool Read(const Message* aMsg, void** aIter, paramType* aResult); +}; + +} // namespace IPC + +#endif // mozilla_dom_permission_message_utils_h__ + diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 8aee4abbf25..f81f1805c69 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -919,7 +919,7 @@ TabChild::DeallocPContentDialog(PContentDialogChild* aDialog) } PContentPermissionRequestChild* -TabChild::AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI&) +TabChild::AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal&) { NS_RUNTIMEABORT("unused"); return nullptr; diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 67b6c2ade8a..e4a6609af08 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -230,16 +230,16 @@ public: #ifdef DEBUG virtual PContentPermissionRequestChild* SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor, const nsCString& aType, - const URI& aUri) + const IPC::Principal& aPrincipal) { PCOMContentPermissionRequestChild* child = static_cast(aActor); - PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aType, aUri); + PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aType, aPrincipal); child->mIPCOpen = true; return request; } #endif /* DEBUG */ - virtual PContentPermissionRequestChild* AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI& uri); + virtual PContentPermissionRequestChild* AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal& aPrincipal); virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestChild* actor); virtual POfflineCacheUpdateChild* AllocPOfflineCacheUpdate(const URI& manifestURI, diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 39c34f12d71..2fd64f2fbef 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -292,11 +292,11 @@ TabParent::DeallocPDocumentRenderer(PDocumentRendererParent* actor) } PContentPermissionRequestParent* -TabParent::AllocPContentPermissionRequest(const nsCString& type, const IPC::URI& uri) +TabParent::AllocPContentPermissionRequest(const nsCString& type, const IPC::Principal& principal) { - return new ContentPermissionRequestParent(type, mFrameElement, uri); + return new ContentPermissionRequestParent(type, mFrameElement, principal); } - + bool TabParent::DeallocPContentPermissionRequest(PContentPermissionRequestParent* actor) { diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index b3b80598b57..e7e1635a16a 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -147,7 +147,8 @@ public: const nsIntSize& renderSize); virtual bool DeallocPDocumentRenderer(PDocumentRendererParent* actor); - virtual PContentPermissionRequestParent* AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI& uri); + virtual PContentPermissionRequestParent* + AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal& aPrincipal); virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestParent* actor); virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdate( diff --git a/dom/src/geolocation/nsGeolocation.cpp b/dom/src/geolocation/nsGeolocation.cpp index 2ab9766ee97..39130b9b583 100644 --- a/dom/src/geolocation/nsGeolocation.cpp +++ b/dom/src/geolocation/nsGeolocation.cpp @@ -280,12 +280,12 @@ nsGeolocationRequest::Notify(nsITimer* aTimer) } NS_IMETHODIMP -nsGeolocationRequest::GetUri(nsIURI * *aRequestingURI) +nsGeolocationRequest::GetPrincipal(nsIPrincipal * *aRequestingPrincipal) { - NS_ENSURE_ARG_POINTER(aRequestingURI); + NS_ENSURE_ARG_POINTER(aRequestingPrincipal); - nsCOMPtr uri = mLocator->GetURI(); - uri.forget(aRequestingURI); + nsCOMPtr principal = mLocator->GetPrincipal(); + principal.forget(aRequestingPrincipal); return NS_OK; } @@ -905,7 +905,7 @@ nsGeolocation::Init(nsIDOMWindow* aContentDom) return NS_ERROR_FAILURE; } - // Grab the uri of the document + // Grab the principal of the document nsCOMPtr domdoc; aContentDom->GetDocument(getter_AddRefs(domdoc)); nsCOMPtr doc = do_QueryInterface(domdoc); @@ -913,15 +913,11 @@ nsGeolocation::Init(nsIDOMWindow* aContentDom) return NS_ERROR_FAILURE; } - doc->NodePrincipal()->GetURI(getter_AddRefs(mURI)); - - if (!mURI) { - return NS_ERROR_FAILURE; - } + mPrincipal = doc->NodePrincipal(); } // If no aContentDom was passed into us, we are being used - // by chrome/c++ and have no mOwner, no mURI, and no need + // by chrome/c++ and have no mOwner, no mPrincipal, and no need // to prompt. mService = nsGeolocationService::GetInstance(); if (mService) { @@ -947,7 +943,7 @@ nsGeolocation::Shutdown() } mService = nullptr; - mURI = nullptr; + mPrincipal = nullptr; } bool @@ -1174,8 +1170,8 @@ nsGeolocation::RegisterRequestWithPrompt(nsGeolocationRequest* request) request->AddRef(); nsCString type = NS_LITERAL_CSTRING("geolocation"); - child->SendPContentPermissionRequestConstructor(request, type, IPC::URI(mURI)); - + child->SendPContentPermissionRequestConstructor(request, type, IPC::Principal(mPrincipal)); + request->Sendprompt(); return true; } diff --git a/dom/src/geolocation/nsGeolocation.h b/dom/src/geolocation/nsGeolocation.h index e26fbefa543..cd2383b4852 100644 --- a/dom/src/geolocation/nsGeolocation.h +++ b/dom/src/geolocation/nsGeolocation.h @@ -181,8 +181,8 @@ public: // Shutting down. void Shutdown(); - // Getter for the URI that this nsGeolocation was loaded from - nsIURI* GetURI() { return mURI; } + // Getter for the principal that this nsGeolocation was loaded from + nsIPrincipal* GetPrincipal() { return mPrincipal; } // Getter for the window that this nsGeolocation is owned by nsIWeakReference* GetOwner() { return mOwner; } @@ -208,7 +208,7 @@ private: nsWeakPtr mOwner; // where the content was loaded from - nsCOMPtr mURI; + nsCOMPtr mPrincipal; // owning back pointer. nsRefPtr mService; diff --git a/dom/src/notification/nsDesktopNotification.cpp b/dom/src/notification/nsDesktopNotification.cpp index bde76c786d2..13587a7bf34 100644 --- a/dom/src/notification/nsDesktopNotification.cpp +++ b/dom/src/notification/nsDesktopNotification.cpp @@ -67,11 +67,11 @@ nsDOMDesktopNotification::nsDOMDesktopNotification(const nsAString & title, const nsAString & description, const nsAString & iconURL, nsPIDOMWindow *aWindow, - nsIURI* uri) + nsIPrincipal* principal) : mTitle(title) , mDescription(description) , mIconURL(iconURL) - , mURI(uri) + , mPrincipal(principal) , mAllow(false) , mShowHasBeenCalled(false) { @@ -102,14 +102,14 @@ nsDOMDesktopNotification::nsDOMDesktopNotification(const nsAString & title, // because owner implements nsITabChild, we can assume that it is // the one and only TabChild for this docshell. TabChild* child = GetTabChildFrom(GetOwner()->GetDocShell()); - + // Retain a reference so the object isn't deleted without IPDL's knowledge. // Corresponding release occurs in DeallocPContentPermissionRequest. nsRefPtr copy = request; nsCString type = NS_LITERAL_CSTRING("desktop-notification"); - child->SendPContentPermissionRequestConstructor(copy.forget().get(), type, IPC::URI(mURI)); - + child->SendPContentPermissionRequestConstructor(copy.forget().get(), type, IPC::Principal(mPrincipal)); + request->Sendprompt(); return; } @@ -232,7 +232,7 @@ nsDesktopNotificationCenter::CreateNotification(const nsAString & title, description, iconURL, mOwner, - mURI); + mPrincipal); notification.forget(aResult); return NS_OK; } @@ -247,12 +247,12 @@ NS_IMPL_ISUPPORTS2(nsDesktopNotificationRequest, nsIRunnable) NS_IMETHODIMP -nsDesktopNotificationRequest::GetUri(nsIURI * *aRequestingURI) +nsDesktopNotificationRequest::GetPrincipal(nsIPrincipal * *aRequestingPrincipal) { if (!mDesktopNotification) return NS_ERROR_NOT_INITIALIZED; - NS_IF_ADDREF(*aRequestingURI = mDesktopNotification->mURI); + NS_IF_ADDREF(*aRequestingPrincipal = mDesktopNotification->mPrincipal); return NS_OK; } diff --git a/dom/src/notification/nsDesktopNotification.h b/dom/src/notification/nsDesktopNotification.h index ef349553115..711c08b8b15 100644 --- a/dom/src/notification/nsDesktopNotification.h +++ b/dom/src/notification/nsDesktopNotification.h @@ -48,7 +48,7 @@ public: nsCOMPtr domdoc; mOwner->GetDocument(getter_AddRefs(domdoc)); nsCOMPtr doc = do_QueryInterface(domdoc); - doc->NodePrincipal()->GetURI(getter_AddRefs(mURI)); + mPrincipal = doc->NodePrincipal(); } virtual ~nsDesktopNotificationCenter() @@ -61,7 +61,7 @@ public: private: nsCOMPtr mOwner; - nsCOMPtr mURI; + nsCOMPtr mPrincipal; }; @@ -79,7 +79,7 @@ public: const nsAString & description, const nsAString & iconURL, nsPIDOMWindow *aWindow, - nsIURI* uri); + nsIPrincipal* principal); virtual ~nsDOMDesktopNotification(); @@ -108,7 +108,7 @@ protected: nsRefPtr mOnCloseCallback; nsRefPtr mObserver; - nsCOMPtr mURI; + nsCOMPtr mPrincipal; bool mAllow; bool mShowHasBeenCalled; }; diff --git a/mobile/android/components/ContentPermissionPrompt.js b/mobile/android/components/ContentPermissionPrompt.js index 22c9c916307..8f1067a38ea 100644 --- a/mobile/android/components/ContentPermissionPrompt.js +++ b/mobile/android/components/ContentPermissionPrompt.js @@ -21,7 +21,7 @@ ContentPermissionPrompt.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]), handleExistingPermission: function handleExistingPermission(request) { - let result = Services.perms.testExactPermission(request.uri, request.type); + let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type); if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { request.allow(); return true; @@ -70,7 +70,7 @@ ContentPermissionPrompt.prototype = { callback: function(aChecked) { // If the user checked "Don't ask again", make a permanent exception if (aChecked) - Services.perms.add(request.uri, request.type, Ci.nsIPermissionManager.ALLOW_ACTION); + Services.perms.addFromPrincipal(request.principal, request.type, Ci.nsIPermissionManager.ALLOW_ACTION); request.allow(); } @@ -80,18 +80,18 @@ ContentPermissionPrompt.prototype = { callback: function(aChecked) { // If the user checked "Don't ask again", make a permanent exception if (aChecked) - Services.perms.add(request.uri, request.type, Ci.nsIPermissionManager.DENY_ACTION); + Services.perms.addFromPrincipal(request.principal, request.type, Ci.nsIPermissionManager.DENY_ACTION); request.cancel(); } }]; let message = browserBundle.formatStringFromName(entityName + ".wantsTo", - [request.uri.host], 1); + [request.principal.URI.host], 1); let options = { checkbox: browserBundle.GetStringFromName(entityName + ".dontAskAgain") }; chromeWin.NativeWindow.doorhanger.show(message, - entityName + request.uri.host, + entityName + request.principal.URI.host, buttons, tab.id, options); } }; diff --git a/mobile/xul/chrome/content/IndexedDB.js b/mobile/xul/chrome/content/IndexedDB.js index 8c347ab5e36..71de83f90a3 100644 --- a/mobile/xul/chrome/content/IndexedDB.js +++ b/mobile/xul/chrome/content/IndexedDB.js @@ -61,7 +61,7 @@ let IndexedDB = { prompt.prompt({ type: type, - uri: Services.io.newURI(payload.location, null, null), + principal: browser.contentPrincipal, window: null, element: aMessage.target, diff --git a/mobile/xul/chrome/content/WebappsUI.js b/mobile/xul/chrome/content/WebappsUI.js index 4d84265bad5..d822414c820 100644 --- a/mobile/xul/chrome/content/WebappsUI.js +++ b/mobile/xul/chrome/content/WebappsUI.js @@ -64,8 +64,9 @@ var WebappsUI = { }, askPermission: function(aMessage, aType, aCallbacks) { - let uri = Services.io.newURI(aMessage.json.from, null, null); - let perm = Services.perms.testExactPermission(uri, aType); + let browser = aMessage.target; + let principal = browser.contentPrincipal; + let perm = Services.perms.testExactPermissionFromPrincipal(principal, aType); switch(perm) { case Ci.nsIPermissionManager.ALLOW_ACTION: aCallbacks.allow(); @@ -79,7 +80,7 @@ var WebappsUI = { prompt.prompt({ type: aType, - uri: uri, + principal: principal, window: null, element: getBrowser(), @@ -88,7 +89,7 @@ var WebappsUI = { }, allow: function() { - Services.perms.add(uri, aType, Ci.nsIPermissionManager.ALLOW_ACTION); + Services.perms.addFromPrincipal(principal, aType, Ci.nsIPermissionManager.ALLOW_ACTION); aCallbacks.allow(); } }); diff --git a/mobile/xul/components/ContentPermissionPrompt.js b/mobile/xul/components/ContentPermissionPrompt.js index 13d18b4e7db..de8d0e941fe 100644 --- a/mobile/xul/components/ContentPermissionPrompt.js +++ b/mobile/xul/components/ContentPermissionPrompt.js @@ -11,26 +11,26 @@ Cu.import("resource://gre/modules/Services.jsm"); const kCountBeforeWeRemember = 5; -function setPagePermission(type, uri, allow) { +function setPagePermission(type, principal, allow) { let pm = Services.perms; let contentPrefs = Services.contentPrefs; let contentPrefName = type + ".request.remember"; - if (!contentPrefs.hasPref(uri, contentPrefName)) - contentPrefs.setPref(uri, contentPrefName, 0); + if (!contentPrefs.hasPref(principal.URI, contentPrefName)) + contentPrefs.setPref(principal.URI, contentPrefName, 0); - let count = contentPrefs.getPref(uri, contentPrefName); + let count = contentPrefs.getPref(principal.URI, contentPrefName); if (allow == false) count--; else count++; - - contentPrefs.setPref(uri, contentPrefName, count); + + contentPrefs.setPref(principal.URI, contentPrefName, count); if (count == kCountBeforeWeRemember) - pm.add(uri, type, Ci.nsIPermissionManager.ALLOW_ACTION); + pm.addFromPrincipal(principal, type, Ci.nsIPermissionManager.ALLOW_ACTION); else if (count == -kCountBeforeWeRemember) - pm.add(uri, type, Ci.nsIPermissionManager.DENY_ACTION); + pm.addFromPrincipal(principal, type, Ci.nsIPermissionManager.DENY_ACTION); } const kEntities = { "geolocation": "geolocation", "desktop-notification": "desktopNotification", @@ -70,7 +70,7 @@ ContentPermissionPrompt.prototype = { }, handleExistingPermission: function handleExistingPermission(request) { - let result = Services.perms.testExactPermission(request.uri, request.type); + let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type); if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { request.allow(); return true; @@ -101,7 +101,7 @@ ContentPermissionPrompt.prototype = { label: browserBundle.GetStringFromName(entityName + ".allow"), accessKey: null, callback: function(notification) { - setPagePermission(request.type, request.uri, true); + setPagePermission(request.type, request.principal, true); request.allow(); } }, @@ -109,13 +109,13 @@ ContentPermissionPrompt.prototype = { label: browserBundle.GetStringFromName(entityName + ".dontAllow"), accessKey: null, callback: function(notification) { - setPagePermission(request.type, request.uri, false); + setPagePermission(request.type, request.principal, false); request.cancel(); } }]; let message = browserBundle.formatStringFromName(entityName + ".wantsTo", - [request.uri.host], 1); + [request.principal.URI.host], 1); let newBar = notificationBox.appendNotification(message, request.type, "", // Notifications in Fennec do not display images. diff --git a/webapprt/ContentPermission.js b/webapprt/ContentPermission.js index 2fd6377dcf2..0f7d2d06399 100644 --- a/webapprt/ContentPermission.js +++ b/webapprt/ContentPermission.js @@ -23,7 +23,7 @@ ContentPermission.prototype = { } // Reuse any remembered permission preferences - let result = Services.perms.testExactPermission(request.uri, "geo"); + let result = Services.perms.testExactPermissionFromPrincipal(request.principal, "geo"); if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { request.allow(); return; @@ -73,7 +73,7 @@ ContentPermission.prototype = { if (choice != 0) { action = Ci.nsIPermissionManager.DENY_ACTION; } - Services.perms.add(request.uri, "geo", action); + Services.perms.addFromPrincipal(request.principal, "geo", action); } // Trigger the selected choice