Bug 968335 - Implement Cu.getWebIDLCallerPrincipal. r=bz
authorBobby Holley <bobbyholley@gmail.com>
Fri, 14 Feb 2014 22:36:44 -0800
changeset 169275 c7c4abfa527d0b92afa5229f76b30db5760b1c0c
parent 169274 95570aef1a27feec974a8b9ae321187257523bee
child 169276 032861ed6fcc09544180eda69106f6bbb325ff65
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersbz
bugs968335
milestone30.0a1
Bug 968335 - Implement Cu.getWebIDLCallerPrincipal. r=bz
js/xpconnect/idl/xpccomponents.idl
js/xpconnect/src/XPCComponents.cpp
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -9,16 +9,17 @@
 #include "jspubtd.h"
 %}
 
 interface xpcIJSWeakReference;
 interface nsIClassInfo;
 interface nsIComponentManager;
 interface nsIJSCID;
 interface nsIJSIID;
+interface nsIPrincipal;
 interface nsIStackFrame;
 
 /**
 * interface of Components.interfacesByID
 * (interesting stuff only reflected into JavaScript)
 */
 [scriptable, uuid(c99cffac-5aed-4267-ad2f-f4a4c9d4a081)]
 interface nsIXPCComponents_InterfacesByID : nsISupports
@@ -115,17 +116,17 @@ interface nsIXPCComponents_utils_Sandbox
 interface ScheduledGCCallback : nsISupports
 {
     void callback();
 };
 
 /**
 * interface of Components.utils
 */
-[scriptable, uuid(cd4bccf4-3433-492e-8dfd-dfdb3fe9efa1)]
+[scriptable, uuid(f4b12240-02aa-47e5-99d5-43cd50fbd4b7)]
 interface nsIXPCComponents_Utils : nsISupports
 {
 
     /* reportError is designed to be called from JavaScript only.
      *
      * It will report a JS Error object to the JS console, and return. It
      * is meant for use in exception handler blocks which want to "eat"
      * an exception, but still want to report it to the console.
@@ -556,16 +557,32 @@ interface nsIXPCComponents_Utils : nsISu
      * Clone an object into a scope.
      * The 3rd argument is an optional options object:
      * - cloneFunction: boolean. If true, any function in the value is are
      *   wrapped in a function forwarder that appears to be a native function in
      *   the content scope.
      */
     [implicit_jscontext]
     jsval cloneInto(in jsval value, in jsval scope, [optional] in jsval options);
+
+    /*
+     * When C++-Implemented code does security checks, it can generally query
+     * the subject principal (i.e. the principal of the most-recently-executed
+     * script) in order to determine the responsible party. However, when an API
+     * is implemented in JS, this doesn't work - the most-recently-executed
+     * script is always the System-Principaled API implementation. So we need
+     * another mechanism.
+     *
+     * Hence the notion of the "WebIDL Caller". If the current Entry Script on
+     * the Script Settings Stack represents the invocation of JS-implemented
+     * WebIDL, this API returns the principal of the caller at the time
+     * of invocation. Otherwise (i.e. outside of JS-implemented WebIDL), this
+     * function throws. If it throws, you probably shouldn't be using it.
+     */
+    nsIPrincipal getWebIDLCallerPrincipal();
 };
 
 /**
 * Interface for the 'Components' object.
 *
 * The first interface contains things that are available to non-chrome XBL code
 * that runs in a scope with an nsExpandedPrincipal. The second interface
 * includes members that are only exposed to chrome.
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3621,16 +3621,29 @@ nsXPCComponents_Utils::CloneInto(HandleV
     }
 
     if (!JS_WrapValue(aCx, aCloned))
         return NS_ERROR_FAILURE;
 
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsXPCComponents_Utils::GetWebIDLCallerPrincipal(nsIPrincipal **aResult)
+{
+    // This API may only be when the Entry Settings Object corresponds to a
+    // JS-implemented WebIDL call. In all other cases, the value will be null,
+    // and we throw.
+    nsCOMPtr<nsIPrincipal> callerPrin = mozilla::dom::GetWebIDLCallerPrincipal();
+    if (!callerPrin)
+        return NS_ERROR_NOT_AVAILABLE;
+    callerPrin.forget(aResult);
+    return NS_OK;
+}
+
 /***************************************************************************/
 /***************************************************************************/
 /***************************************************************************/
 
 
 nsXPCComponentsBase::nsXPCComponentsBase(XPCWrappedNativeScope* aScope)
     :   mScope(aScope)
 {