Bug 434522. Make the "Permission denied to access Class.property" mesage more useful. r+sr=jst
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 28 Jul 2008 23:03:19 -0700
changeset 16268 dee1a1ced0f923b8f868deefe7c4ded839ba5227
parent 16267 c5b7201cf5c05c28c85632535a54eab7915d79bb
child 16269 034c981d323f1994806c05da00b242fa35e15760
push idunknown
push userunknown
push dateunknown
bugs434522
milestone1.9.1a2pre
Bug 434522. Make the "Permission denied to access Class.property" mesage more useful. r+sr=jst
caps/src/nsScriptSecurityManager.cpp
dom/locales/en-US/chrome/security/caps.properties
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -682,16 +682,18 @@ nsScriptSecurityManager::CheckPropertyAc
     nsIPrincipal* subjectPrincipal = GetSubjectPrincipal(cx, &rv);
     if (NS_FAILED(rv))
         return rv;
 
     if (!subjectPrincipal || subjectPrincipal == mSystemPrincipal)
         // We have native code or the system principal: just allow access
         return NS_OK;
 
+    nsCOMPtr<nsIPrincipal> objectPrincipal;
+
     // Hold the class info data here so we don't have to go back to virtual
     // methods all the time
     ClassInfoData classInfoData(aClassInfo, aClassName);
 #ifdef DEBUG_CAPS_CheckPropertyAccessImpl
     nsCAutoString propertyName;
     propertyName.AssignWithConversion((PRUnichar*)JSValIDToString(cx, aProperty));
     printf("### CanAccess(%s.%s, %i) ", classInfoData.GetName(), 
            propertyName.get(), aAction);
@@ -736,30 +738,27 @@ nsScriptSecurityManager::CheckPropertyAc
             break;
 
         case SCRIPT_SECURITY_SAME_ORIGIN_ACCESS:
             {
 #ifdef DEBUG_CAPS_CheckPropertyAccessImpl
                 printf("sameOrigin ");
 #endif
                 nsCOMPtr<nsIPrincipal> principalHolder;
-                nsIPrincipal *objectPrincipal;
                 if(aJSObject)
                 {
                     objectPrincipal = doGetObjectPrincipal(aJSObject);
                     if (!objectPrincipal)
                         rv = NS_ERROR_DOM_SECURITY_ERR;
                 }
                 else if(aTargetURI)
                 {
                     if (NS_FAILED(GetCodebasePrincipal(
-                          aTargetURI, getter_AddRefs(principalHolder))))
+                          aTargetURI, getter_AddRefs(objectPrincipal))))
                         return NS_ERROR_FAILURE;
-
-                    objectPrincipal = principalHolder;
                 }
                 else
                 {
                     NS_ERROR("CheckPropertyAccessImpl called without a target object or URL");
                     return NS_ERROR_FAILURE;
                 }
                 if(NS_SUCCEEDED(rv))
                     rv = CheckSameOriginDOMProp(subjectPrincipal, objectPrincipal,
@@ -850,41 +849,63 @@ nsScriptSecurityManager::CheckPropertyAc
 #endif
 
     if (NS_FAILED(rv)) //-- Security tests failed, access is denied, report error
     {
         nsAutoString stringName;
         switch(aAction)
         {
         case nsIXPCSecurityManager::ACCESS_GET_PROPERTY:
-            stringName.AssignLiteral("GetPropertyDenied");
+            stringName.AssignLiteral("GetPropertyDeniedOrigins");
             break;
         case nsIXPCSecurityManager::ACCESS_SET_PROPERTY:
-            stringName.AssignLiteral("SetPropertyDenied");
+            stringName.AssignLiteral("SetPropertyDeniedOrigins");
             break;
         case nsIXPCSecurityManager::ACCESS_CALL_METHOD:
-            stringName.AssignLiteral("CallMethodDenied");
+            stringName.AssignLiteral("CallMethodDeniedOrigins");
         }
 
         NS_ConvertUTF8toUTF16 className(classInfoData.GetName());
+        nsCAutoString subjectOrigin;
+        GetPrincipalDomainOrigin(subjectPrincipal, subjectOrigin);
+        NS_ConvertUTF8toUTF16 subjectOriginUnicode(subjectOrigin);
+
+        nsCAutoString objectOrigin;
+        if (objectPrincipal) {
+            GetPrincipalDomainOrigin(objectPrincipal, objectOrigin);
+        }
+        NS_ConvertUTF8toUTF16 objectOriginUnicode(objectOrigin);
+            
+        nsXPIDLString errorMsg;
         const PRUnichar *formatStrings[] =
         {
+            subjectOriginUnicode.get(),
             className.get(),
-            JSValIDToString(cx, aProperty)
+            JSValIDToString(cx, aProperty),
+            objectOriginUnicode.get()
         };
 
-        nsXPIDLString errorMsg;
+        PRUint32 length = NS_ARRAY_LENGTH(formatStrings);
+
+        if (!objectPrincipal) {
+            stringName.AppendLiteral("OnlySubject");
+            --length;
+        }
+        
         // We need to keep our existing failure rv and not override it
         // with a likely success code from the following string bundle
         // call in order to throw the correct security exception later.
         nsresult rv2 = sStrBundle->FormatStringFromName(stringName.get(),
                                                         formatStrings,
-                                                        NS_ARRAY_LENGTH(formatStrings),
+                                                        length,
                                                         getter_Copies(errorMsg));
-        NS_ENSURE_SUCCESS(rv2, rv2);
+        if (NS_FAILED(rv2)) {
+            // Might just be missing the string...  Do our best
+            errorMsg = stringName;
+        }
 
         SetPendingException(cx, errorMsg.get());
 
         if (sXPConnect)
         {
             nsAXPCNativeCallContext *xpcCallContext = nsnull;
             sXPConnect->GetCurrentNativeCallContext(&xpcCallContext);
             if (xpcCallContext)
@@ -2956,29 +2977,43 @@ nsScriptSecurityManager::CanCreateWrappe
     nsXPIDLCString objectSecurityLevel;
     if (checkedComponent)
         checkedComponent->CanCreateWrapper((nsIID *)&aIID, getter_Copies(objectSecurityLevel));
 
     nsresult rv = CheckXPCPermissions(aObj, objectSecurityLevel);
     if (NS_FAILED(rv))
     {
         //-- Access denied, report an error
-
-        NS_NAMED_LITERAL_STRING(strName, "CreateWrapperDenied");
+        NS_ConvertUTF8toUTF16 strName("CreateWrapperDenied");
+        nsCAutoString origin;
+        nsresult rv2;
+        nsIPrincipal* subjectPrincipal = doGetSubjectPrincipal(&rv2);
+        if (NS_SUCCEEDED(rv2) && subjectPrincipal) {
+            GetPrincipalDomainOrigin(subjectPrincipal, origin);
+        }
+        NS_ConvertUTF8toUTF16 originUnicode(origin);
         NS_ConvertUTF8toUTF16 className(objClassInfo.GetName());
-        const PRUnichar* formatStrings[] = { className.get() };
+        const PRUnichar* formatStrings[] = {
+            className.get(),
+            originUnicode.get()
+        };
+        PRUint32 length = NS_ARRAY_LENGTH(formatStrings);
+        if (originUnicode.IsEmpty()) {
+            --length;
+        } else {
+            strName.AppendLiteral("ForOrigin");
+        }
         nsXPIDLString errorMsg;
         // We need to keep our existing failure rv and not override it
         // with a likely success code from the following string bundle
         // call in order to throw the correct security exception later.
-        nsresult rv2 =
-            sStrBundle->FormatStringFromName(strName.get(),
-                                             formatStrings,
-                                             NS_ARRAY_LENGTH(formatStrings),
-                                             getter_Copies(errorMsg));
+        rv2 = sStrBundle->FormatStringFromName(strName.get(),
+                                               formatStrings,
+                                               length,
+                                               getter_Copies(errorMsg));
         NS_ENSURE_SUCCESS(rv2, rv2);
 
         SetPendingException(cx, errorMsg.get());
 
 #ifdef DEBUG_CAPS_CanCreateWrapper
         printf("DENIED.\n");
     }
     else
--- a/dom/locales/en-US/chrome/security/caps.properties
+++ b/dom/locales/en-US/chrome/security/caps.properties
@@ -38,20 +38,24 @@
 Yes = Allow
 No = Deny
 Titleline = Internet Security
 CheckMessage = Remember this decision
 EnableCapabilityQuery = A script from "%S" is requesting enhanced abilities that are UNSAFE and could be used to compromise your machine or data:\n\n%S\n\nAllow these abilities only if you trust this source to be free of viruses or malicious programs.
 EnableCapabilityDenied = A script from "%S" was denied %S privileges.
 CheckLoadURIError = Security Error: Content at %S may not load or link to %S.
 CheckSameOriginError = Security Error: Content at %S may not load data from %S.
-GetPropertyDenied = Permission denied to get property %S.%S
-SetPropertyDenied = Permission denied to set property %S.%S
-CallMethodDenied = Permission denied to call method %S.%S
+GetPropertyDeniedOrigins = Permission denied for <%S> to get property %S.%S from <%S>.
+SetPropertyDeniedOrigins = Permission denied for <%S> to set property %S.%S on <%S>.
+CallMethodDeniedOrigins = Permission denied for <%S> to call method %S.%S on <%S>.
+GetPropertyDeniedOriginsOnlySubject = Permission denied for <%S> to get property %S.%S
+SetPropertyDeniedOriginsOnlySubject = Permission denied for <%S> to set property %S.%S
+CallMethodDeniedOriginsOnlySubject = Permission denied for <%S> to call method %S.%S
 CreateWrapperDenied = Permission denied to create wrapper for object of class %S
+CreateWrapperDeniedForOrigin = Permission denied for <%2$S> to create wrapper for object of class %1$S
 ExtensionCapability = Unknown: %S
 ProtocolFlagError = Warning: Protocol handler for '%S' doesn't advertise a security policy.  While loading of such protocols is allowed for now, this is deprecated.  Please see the documentation in nsIProtocolHandler.idl.
 #
 # The following descriptions are shown in the EnableCapabilityQuery dialog
 #
 capdesc.UniversalBrowserRead = Read private data from any site or window
 capdesc.UniversalBrowserWrite = Modify any open window
 capdesc.UniversalXPConnect = Run or install software on your machine