mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-22 02:09:28 +00:00
Improve enablePrivilege confirmation dialog text and presentation, sanity-check
privilege names (bug 253942, bug 253944) r=caillon,sr=brendan,a=chofmann,mkaply
This commit is contained in:
parent
4c15468e7d
commit
e67c6e5dcf
@ -408,6 +408,9 @@ private:
|
||||
CheckConfirmDialog(JSContext* cx, nsIPrincipal* aPrincipal,
|
||||
const char* aCapability, PRBool *checkValue);
|
||||
|
||||
static void
|
||||
FormatCapabilityString(nsAString& aCapability);
|
||||
|
||||
nsresult
|
||||
SavePrincipal(nsIPrincipal* aToSave);
|
||||
|
||||
|
@ -35,11 +35,11 @@
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
Yes = Yes
|
||||
No = No
|
||||
Yes = Allow
|
||||
No = Deny
|
||||
Titleline = Internet Security
|
||||
CheckMessage = Remember this decision
|
||||
EnableCapabilityQuery = A script from "%S" has requested %S privileges. You should grant these privileges only if you are comfortable downloading and executing a program from this source. Do you wish to allow these privileges?
|
||||
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.
|
||||
@ -47,3 +47,14 @@ GetPropertyDenied = Permission denied to get property %S.%S
|
||||
SetPropertyDenied = Permission denied to set property %S.%S
|
||||
CallMethodDenied = Permission denied to call method %S.%S
|
||||
CreateWrapperDenied = Permission denied to create wrapper for object of class %S
|
||||
ExtensionCapability = Unknown: %S
|
||||
#
|
||||
# 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
|
||||
capdesc.UniversalFileRead = Read and upload local files
|
||||
capdesc.CapabilityPreferencesAccess = By-pass core security settings
|
||||
capdesc.UniversalPreferencesRead = Read program settings
|
||||
capdesc.UniversalPreferencesWrite = Modify program settings
|
||||
|
@ -105,6 +105,21 @@ GetScriptContext(JSContext *cx)
|
||||
return GetScriptContextFromJSContext(cx);
|
||||
}
|
||||
|
||||
inline void SetPendingException(JSContext *cx, const char *aMsg)
|
||||
{
|
||||
JSString *str = JS_NewStringCopyZ(cx, aMsg);
|
||||
if (str)
|
||||
JS_SetPendingException(cx, STRING_TO_JSVAL(str));
|
||||
}
|
||||
|
||||
inline void SetPendingException(JSContext *cx, const PRUnichar *aMsg)
|
||||
{
|
||||
JSString *str = JS_NewUCStringCopyZ(cx,
|
||||
NS_REINTERPRET_CAST(const jschar*, aMsg));
|
||||
if (str)
|
||||
JS_SetPendingException(cx, STRING_TO_JSVAL(str));
|
||||
}
|
||||
|
||||
// Helper class to get stuff from the ClassInfo and not waste extra time with
|
||||
// virtual method calls for things it has already gotten
|
||||
class ClassInfoData
|
||||
@ -781,9 +796,7 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
|
||||
getter_Copies(errorMsg));
|
||||
NS_ENSURE_SUCCESS(rv2, rv2);
|
||||
|
||||
JS_SetPendingException(cx,
|
||||
STRING_TO_JSVAL(JS_NewUCStringCopyZ(cx,
|
||||
NS_REINTERPRET_CAST(const jschar*, errorMsg.get()))));
|
||||
SetPendingException(cx, errorMsg.get());
|
||||
|
||||
if (sXPConnect)
|
||||
{
|
||||
@ -1347,9 +1360,7 @@ nsScriptSecurityManager::ReportError(JSContext* cx, const nsAString& messageTag,
|
||||
// and to standard output
|
||||
if (cx)
|
||||
{
|
||||
JS_SetPendingException(cx,
|
||||
STRING_TO_JSVAL(JS_NewUCStringCopyZ(cx,
|
||||
NS_REINTERPRET_CAST(const jschar*, message.get()))));
|
||||
SetPendingException(cx, message.get());
|
||||
// Tell XPConnect that an exception was thrown, if appropriate
|
||||
if (sXPConnect)
|
||||
{
|
||||
@ -2072,6 +2083,51 @@ nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsScriptSecurityManager::FormatCapabilityString(nsAString& aCapability)
|
||||
{
|
||||
nsAutoString newcaps;
|
||||
nsAutoString rawcap;
|
||||
NS_NAMED_LITERAL_STRING(capdesc, "capdesc.");
|
||||
PRInt32 pos;
|
||||
PRInt32 index = kNotFound;
|
||||
nsresult rv;
|
||||
|
||||
NS_ASSERTION(kNotFound == -1, "Basic constant changed, algorithm broken!");
|
||||
|
||||
do {
|
||||
pos = index+1;
|
||||
index = aCapability.FindChar(' ', pos);
|
||||
rawcap = Substring(aCapability, pos,
|
||||
(index == kNotFound) ? index : index - pos);
|
||||
|
||||
nsXPIDLString capstr;
|
||||
rv = sStrBundle->GetStringFromName(
|
||||
nsPromiseFlatString(capdesc+rawcap).get(),
|
||||
getter_Copies(capstr));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
newcaps += capstr;
|
||||
else
|
||||
{
|
||||
nsXPIDLString extensionCap;
|
||||
const PRUnichar* formatArgs[] = { rawcap.get() };
|
||||
rv = sStrBundle->FormatStringFromName(
|
||||
NS_LITERAL_STRING("ExtensionCapability").get(),
|
||||
formatArgs,
|
||||
NS_ARRAY_LENGTH(formatArgs),
|
||||
getter_Copies(extensionCap));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
newcaps += extensionCap;
|
||||
else
|
||||
newcaps += rawcap;
|
||||
}
|
||||
|
||||
newcaps += NS_LITERAL_STRING("\n");
|
||||
} while (index != kNotFound);
|
||||
|
||||
aCapability = newcaps;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsScriptSecurityManager::CheckConfirmDialog(JSContext* cx, nsIPrincipal* aPrincipal,
|
||||
const char* aCapability, PRBool *checkValue)
|
||||
@ -2116,6 +2172,18 @@ nsScriptSecurityManager::CheckConfirmDialog(JSContext* cx, nsIPrincipal* aPrinci
|
||||
if (NS_FAILED(rv))
|
||||
return PR_FALSE;
|
||||
|
||||
nsXPIDLString yesStr;
|
||||
rv = sStrBundle->GetStringFromName(NS_LITERAL_STRING("Yes").get(),
|
||||
getter_Copies(yesStr));
|
||||
if (NS_FAILED(rv))
|
||||
return PR_FALSE;
|
||||
|
||||
nsXPIDLString noStr;
|
||||
rv = sStrBundle->GetStringFromName(NS_LITERAL_STRING("No").get(),
|
||||
getter_Copies(noStr));
|
||||
if (NS_FAILED(rv))
|
||||
return PR_FALSE;
|
||||
|
||||
nsXPIDLCString val;
|
||||
PRBool hasCert;
|
||||
aPrincipal->GetHasCertificate(&hasCert);
|
||||
@ -2128,7 +2196,8 @@ nsScriptSecurityManager::CheckConfirmDialog(JSContext* cx, nsIPrincipal* aPrinci
|
||||
return PR_FALSE;
|
||||
|
||||
NS_ConvertUTF8toUTF16 location(val.get());
|
||||
NS_ConvertUTF8toUTF16 capability(aCapability);
|
||||
NS_ConvertASCIItoUTF16 capability(aCapability);
|
||||
FormatCapabilityString(capability);
|
||||
const PRUnichar *formatStrings[] = { location.get(), capability.get() };
|
||||
|
||||
nsXPIDLString message;
|
||||
@ -2143,9 +2212,9 @@ nsScriptSecurityManager::CheckConfirmDialog(JSContext* cx, nsIPrincipal* aPrinci
|
||||
rv = prompter->ConfirmEx(title.get(), message.get(),
|
||||
(nsIPrompt::BUTTON_DELAY_ENABLE) +
|
||||
(nsIPrompt::BUTTON_POS_1_DEFAULT) +
|
||||
(nsIPrompt::BUTTON_TITLE_YES * nsIPrompt::BUTTON_POS_0) +
|
||||
(nsIPrompt::BUTTON_TITLE_NO * nsIPrompt::BUTTON_POS_1),
|
||||
nsnull, nsnull, nsnull, check.get(), checkValue, &buttonPressed);
|
||||
(nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_0) +
|
||||
(nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_1),
|
||||
yesStr.get(), noStr.get(), nsnull, check.get(), checkValue, &buttonPressed);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
*checkValue = PR_FALSE;
|
||||
@ -2189,10 +2258,32 @@ nsScriptSecurityManager::EnableCapability(const char *capability)
|
||||
if(PL_strlen(capability)>200)
|
||||
{
|
||||
static const char msg[] = "Capability name too long";
|
||||
JS_SetPendingException(cx, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, msg)));
|
||||
SetPendingException(cx, msg);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//-- Check capability string for valid characters
|
||||
//
|
||||
// Logically we might have wanted this in nsPrincipal, but performance
|
||||
// worries dictate it can't go in IsCapabilityEnabled() and we may have
|
||||
// to show the capability on a dialog before we call the principal's
|
||||
// EnableCapability().
|
||||
//
|
||||
// We don't need to validate the capability string on the other APIs
|
||||
// available to web content. Without the ability to enable junk then
|
||||
// isPrivilegeEnabled, disablePrivilege, and revertPrivilege all do
|
||||
// the right thing (effectively nothing) when passed unallowed chars.
|
||||
for (const char *ch = capability; *ch; ++ch)
|
||||
{
|
||||
if (!NS_IS_ALPHA(*ch) && *ch != ' ' && !NS_IS_DIGIT(*ch)
|
||||
&& *ch != '_' && *ch != '-' && *ch != '.')
|
||||
{
|
||||
static const char msg[] = "Invalid character in capability name";
|
||||
SetPendingException(cx, msg);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (NS_FAILED(GetPrincipalAndFrame(cx, getter_AddRefs(principal), &fp)))
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -2234,9 +2325,7 @@ nsScriptSecurityManager::EnableCapability(const char *capability)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
JS_SetPendingException(cx,
|
||||
STRING_TO_JSVAL(JS_NewUCStringCopyZ(cx,
|
||||
NS_REINTERPRET_CAST(const jschar*, message.get()))));
|
||||
SetPendingException(cx, message.get());
|
||||
|
||||
return NS_ERROR_FAILURE; // XXX better error code?
|
||||
}
|
||||
@ -2329,8 +2418,7 @@ nsScriptSecurityManager::SetCanEnableCapability(const char* certificateID,
|
||||
if (!cx) return NS_ERROR_FAILURE;
|
||||
static const char msg1[] = "Only code signed by the system certificate may call SetCanEnableCapability or Invalidate";
|
||||
static const char msg2[] = "Attempt to call SetCanEnableCapability or Invalidate when no system certificate has been established";
|
||||
JS_SetPendingException(cx, STRING_TO_JSVAL(JS_NewStringCopyZ(cx,
|
||||
mSystemCertificate ? msg1 : msg2)));
|
||||
SetPendingException(cx, mSystemCertificate ? msg1 : msg2);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -2397,9 +2485,7 @@ nsScriptSecurityManager::CanCreateWrapper(JSContext *cx,
|
||||
getter_Copies(errorMsg));
|
||||
NS_ENSURE_SUCCESS(rv2, rv2);
|
||||
|
||||
JS_SetPendingException(cx,
|
||||
STRING_TO_JSVAL(JS_NewUCStringCopyZ(cx,
|
||||
NS_REINTERPRET_CAST(const jschar*, errorMsg.get()))));
|
||||
SetPendingException(cx, errorMsg.get());
|
||||
|
||||
#ifdef DEBUG_CAPS_CanCreateWrapper
|
||||
printf("DENIED.\n");
|
||||
@ -2489,8 +2575,7 @@ nsScriptSecurityManager::CanCreateInstance(JSContext *cx,
|
||||
nsXPIDLCString cidStr;
|
||||
cidStr += aCID.ToString();
|
||||
errorMsg.Append(cidStr);
|
||||
JS_SetPendingException(cx,
|
||||
STRING_TO_JSVAL(JS_NewStringCopyZ(cx, errorMsg.get())));
|
||||
SetPendingException(cx, errorMsg.get());
|
||||
|
||||
#ifdef DEBUG_CAPS_CanCreateInstance
|
||||
printf("DENIED\n");
|
||||
@ -2521,8 +2606,7 @@ nsScriptSecurityManager::CanGetService(JSContext *cx,
|
||||
nsXPIDLCString cidStr;
|
||||
cidStr += aCID.ToString();
|
||||
errorMsg.Append(cidStr);
|
||||
JS_SetPendingException(cx,
|
||||
STRING_TO_JSVAL(JS_NewStringCopyZ(cx, errorMsg.get())));
|
||||
SetPendingException(cx, errorMsg.get());
|
||||
|
||||
#ifdef DEBUG_CAPS_CanGetService
|
||||
printf("DENIED\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user