This fix makes Liveconnect smarter about getting a security principal
when verifying that call from an applet to JS should be allowed.
This commit is contained in:
jeff.dyer%compilercompany.com 2000-10-19 11:51:22 +00:00
Родитель 2c05333359
Коммит feccfe330f
6 изменённых файлов: 134 добавлений и 24 удалений

Просмотреть файл

@ -702,7 +702,7 @@ jsj_enter_js(JNIEnv *jEnv, void* applet_obj, jobject java_wrapper_obj,
/* Invoke callback, presumably used to implement concurrency constraints */ /* Invoke callback, presumably used to implement concurrency constraints */
if (JSJ_callbacks && JSJ_callbacks->enter_js_from_java) { if (JSJ_callbacks && JSJ_callbacks->enter_js_from_java) {
#ifdef OJI #ifdef OJI
if (!JSJ_callbacks->enter_js_from_java(jEnv, &err_msg, pNSIPrincipaArray, numPrincipals, pNSISecurityContext)) if (!JSJ_callbacks->enter_js_from_java(jEnv, &err_msg, pNSIPrincipaArray, numPrincipals, pNSISecurityContext,applet_obj))
#else #else
if (!JSJ_callbacks->enter_js_from_java(jEnv, &err_msg)) if (!JSJ_callbacks->enter_js_from_java(jEnv, &err_msg))
#endif #endif

Просмотреть файл

@ -125,7 +125,7 @@ typedef struct JSJCallbacks {
semantics of JavaScript. It is acceptable for either function pointer semantics of JavaScript. It is acceptable for either function pointer
to be NULL. */ to be NULL. */
#ifdef OJI #ifdef OJI
JSBool (*enter_js_from_java)(JNIEnv *jEnv, char **errp, void **pNSIPrincipaArray, int numPrincipals, void *pNSISecurityContext); JSBool (*enter_js_from_java)(JNIEnv *jEnv, char **errp, void **pNSIPrincipaArray, int numPrincipals, void *pNSISecurityContext,void* applet_obj);
#else #else
JSBool (*enter_js_from_java)(JNIEnv *jEnv, char **errp); JSBool (*enter_js_from_java)(JNIEnv *jEnv, char **errp);
#endif #endif

Просмотреть файл

@ -28,7 +28,10 @@
#include "lcglue.h" #include "lcglue.h"
#include "nscore.h" #include "nscore.h"
#include "nsISecurityContext.h" #include "nsISecurityContext.h"
#include "nsCSecurityContext.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptObjectOwner.h"
extern "C" int XP_PROGRESS_STARTING_JAVA; extern "C" int XP_PROGRESS_STARTING_JAVA;
extern "C" int XP_PROGRESS_STARTING_JAVA_DONE; extern "C" int XP_PROGRESS_STARTING_JAVA_DONE;
@ -89,6 +92,7 @@ JVMContext* GetJVMContext()
context->jsj_env = NULL; context->jsj_env = NULL;
context->js_context = NULL; context->js_context = NULL;
context->js_startframe = NULL; context->js_startframe = NULL;
context->java_applet_obj = NULL;
localContext.set(context); localContext.set(context);
} }
return context; return context;
@ -370,27 +374,64 @@ unwrap_java_wrapper_impl(JNIEnv *pJNIEnv, jobject java_wrapper)
static JSBool PR_CALLBACK static JSBool PR_CALLBACK
enter_js_from_java_impl(JNIEnv *jEnv, char **errp, enter_js_from_java_impl(JNIEnv *jEnv, char **errp,
void **pNSIPrincipaArray, int numPrincipals, void *pNSISecurityContext) void **pNSIPrincipaArray, int numPrincipals,
void *pNSISecurityContext,
void *java_applet_obj)
{ {
JVMContext* context = GetJVMContext(); JVMContext* context = GetJVMContext();
JSContext *pJSCX = context->js_context;
if (pNSISecurityContext != NULL) { // Get and Save the current applet object in the vm context.
// There is not a 1:1 coorespondence between jvmcontexts and
// jscontexts, but there is a 1:1 correspondence between
// jvmcontexts and applet objects. So syncronize the two
// here and use the applet object to get the jscontext when
// needed.
nsCOMPtr<nsISecurityContext> jscontext = dont_AddRef(JVM_GetJSSecurityContext()); if (java_applet_obj) {
context->java_applet_obj = java_applet_obj;
}
else if (context->java_applet_obj) {
java_applet_obj=context->java_applet_obj;
}
JSContext *pJSCX = map_jsj_thread_to_js_context_impl(nsnull,java_applet_obj,jEnv,errp);
nsCOMPtr<nsIPrincipal> principal;
if (pNSISecurityContext != nsnull) {
if (pJSCX) {
JSPrincipals *jsprin = nsnull;
nsCOMPtr<nsIScriptContext> scriptContext = (nsIScriptContext*)JS_GetContextPrivate(pJSCX);
if (scriptContext) {
nsCOMPtr<nsIScriptGlobalObject> global = scriptContext->GetGlobalObject();
NS_ASSERTION(global, "script context has no global object");
if (global) {
nsCOMPtr<nsIScriptObjectPrincipal> globalData = do_QueryInterface(global);
if (globalData) {
if (NS_FAILED(globalData->GetPrincipal(getter_AddRefs(principal))))
return NS_ERROR_FAILURE;
}
}
}
}
// What if !pJSCX?
nsCOMPtr<nsISecurityContext> jscontext = dont_AddRef(new nsCSecurityContext(principal));
nsISecurityContext* jvcontext = NS_STATIC_CAST(nsISecurityContext*,pNSISecurityContext); nsISecurityContext* jvcontext = NS_STATIC_CAST(nsISecurityContext*,pNSISecurityContext);
// Should be NS_DYNAMIC_CAST, but no such define exists. // Should be NS_DYNAMIC_CAST, but no such define exists.
// So for the sake of portability, we'll live // So for the sake of portability, we'll live
// dangerously and use brute force. // dangerously and use brute force.
if( !jscontext || !jvcontext ) { if (!jscontext || !jvcontext) {
return PR_FALSE; return PR_FALSE;
} }
// Check that the origin + certificate are the same. // Check that the origin + certificate are the same.
// If not, then return false. // If not, then return false.
const int buflen = 128; const int buflen = 512;
char jsorigin[buflen]; char jsorigin[buflen];
char jvorigin[buflen]; char jvorigin[buflen];
*jsorigin = nsnull; *jsorigin = nsnull;
@ -399,10 +440,14 @@ enter_js_from_java_impl(JNIEnv *jEnv, char **errp,
jscontext->GetOrigin(jsorigin,buflen); jscontext->GetOrigin(jsorigin,buflen);
jvcontext->GetOrigin(jvorigin,buflen); jvcontext->GetOrigin(jvorigin,buflen);
if( nsCRT::strcasecmp(jsorigin,jvorigin) ) { if (nsCRT::strcasecmp(jsorigin,jvorigin)) {
return PR_FALSE; return PR_FALSE;
} }
#if 0 // ISSUE: Needs security review. We don't compare certificates.
// because currently there is no basis for making a postive comparision.
// If one or the other context is signed, the comparision will fail.
char jscertid[buflen]; char jscertid[buflen];
char jvcertid[buflen]; char jvcertid[buflen];
*jscertid = nsnull; *jscertid = nsnull;
@ -411,12 +456,12 @@ enter_js_from_java_impl(JNIEnv *jEnv, char **errp,
jscontext->GetCertificateID(jscertid,buflen); jscontext->GetCertificateID(jscertid,buflen);
jvcontext->GetCertificateID(jvcertid,buflen); jvcontext->GetCertificateID(jvcertid,buflen);
if( nsCRT::strcasecmp(jscertid,jvcertid) ) { if (nsCRT::strcasecmp(jscertid,jvcertid)) {
return PR_FALSE; return PR_FALSE;
} }
} else { #endif
return PR_FALSE;
} }
return PR_TRUE; return PR_TRUE;

Просмотреть файл

@ -52,6 +52,7 @@ struct JVMContext {
JSJavaThreadState *jsj_env; /* thread local JavaScript execution env. */ JSJavaThreadState *jsj_env; /* thread local JavaScript execution env. */
JSContext *js_context; /* thread local JavaScript context. */ JSContext *js_context; /* thread local JavaScript context. */
JSStackFrame *js_startframe; /* thread local JavaScript stack frame. */ JSStackFrame *js_startframe; /* thread local JavaScript stack frame. */
void *java_applet_obj;
}; };
JVMContext* GetJVMContext(); JVMContext* GetJVMContext();

Просмотреть файл

@ -43,6 +43,8 @@
#include "nsCodebasePrincipal.h" #include "nsCodebasePrincipal.h"
#include "nsCertificatePrincipal.h" #include "nsCertificatePrincipal.h"
#include "nsScriptSecurityManager.h" #include "nsScriptSecurityManager.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptObjectOwner.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
@ -102,8 +104,6 @@ nsCSecurityContext::Implies(const char* target, const char* action, PRBool *bAll
NS_METHOD NS_METHOD
nsCSecurityContext::GetOrigin(char* buf, int buflen) nsCSecurityContext::GetOrigin(char* buf, int buflen)
{ {
nsCOMPtr<nsIPrincipal> principal = NULL;
// Get the Script Security Manager. // Get the Script Security Manager.
nsresult rv = NS_OK; nsresult rv = NS_OK;
@ -112,20 +112,49 @@ nsCSecurityContext::GetOrigin(char* buf, int buflen)
if (NS_FAILED(rv) || !secMan) return NS_ERROR_FAILURE; if (NS_FAILED(rv) || !secMan) return NS_ERROR_FAILURE;
if (NS_FAILED(secMan->GetSubjectPrincipal(getter_AddRefs(principal)))) // First, try to get the principal from the security manager.
return NS_ERROR_FAILURE; // Next, try to get it from the dom.
// If neither of those work, the qi for codebase will fail.
nsCOMPtr<nsICodebasePrincipal> codebase = do_QueryInterface(principal); if (!m_pPrincipal) {
if (NS_FAILED(secMan->GetSubjectPrincipal(&m_pPrincipal)))
// return NS_ERROR_FAILURE;
; // Don't return here because the security manager returns
// NS_ERROR_FAILURE when there is no subject principal. In
// that case we are not done.
if (!m_pPrincipal && m_pJSCX ) {
JSPrincipals *jsprin = nsnull;
nsCOMPtr<nsIScriptContext> scriptContext = (nsIScriptContext*)JS_GetContextPrivate(m_pJSCX);
if (scriptContext) {
nsCOMPtr<nsIScriptGlobalObject> global = scriptContext->GetGlobalObject();
NS_ASSERTION(global, "script context has no global object");
if (global) {
nsCOMPtr<nsIScriptObjectPrincipal> globalData = do_QueryInterface(global);
if (globalData) {
// ISSUE: proper ref counting.
if (NS_FAILED(globalData->GetPrincipal(&m_pPrincipal)))
return NS_ERROR_FAILURE;
}
}
}
}
}
nsCOMPtr<nsICodebasePrincipal> codebase = do_QueryInterface(m_pPrincipal);
if (!codebase) if (!codebase)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
char* origin=nsnull; char* origin=nsnull;
codebase->GetOrigin(&origin); codebase->GetOrigin(&origin);
if( origin ) { if (origin) {
PRInt32 originlen = (PRInt32) nsCRT::strlen(origin); PRInt32 originlen = (PRInt32) nsCRT::strlen(origin);
if(!buf || buflen<=originlen) { if (!buf || buflen<=originlen) {
if( origin ) { if (origin) {
nsCRT::free(origin); nsCRT::free(origin);
} }
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -165,7 +194,7 @@ nsCSecurityContext::GetCertificateID(char* buf, int buflen)
char* certificate = nsnull; char* certificate = nsnull;
cprincipal->GetCertificateID(&certificate); cprincipal->GetCertificateID(&certificate);
if( certificate ) { if (certificate) {
PRInt32 certlen = (PRInt32) nsCRT::strlen(certificate); PRInt32 certlen = (PRInt32) nsCRT::strlen(certificate);
if( buflen<=certlen ) { if( buflen<=certlen ) {
nsCRT::free(certificate); nsCRT::free(certificate);
@ -219,8 +248,43 @@ nsCSecurityContext::nsCSecurityContext(JSContext* cx)
PRBool equals; PRBool equals;
if (!principal || if (!principal ||
NS_SUCCEEDED(principal->Equals(sysprincipal, &equals)) && equals) NS_SUCCEEDED(principal->Equals(sysprincipal, &equals)) && equals) {
{ // We have native code or the system principal: just allow general access
m_HasUniversalBrowserReadCapability = PR_TRUE;
m_HasUniversalJavaCapability = PR_TRUE;
}
else {
// Otherwise, check with the js security manager.
secMan->IsCapabilityEnabled("UniversalBrowserRead",&m_HasUniversalBrowserReadCapability);
secMan->IsCapabilityEnabled("UniversalJavaPermission",&m_HasUniversalJavaCapability);
}
}
nsCSecurityContext::nsCSecurityContext(nsIPrincipal *principal)
: m_pJStoJavaFrame(NULL), m_pJSCX(NULL),
m_pPrincipal(principal),
m_HasUniversalBrowserReadCapability(PR_FALSE),
m_HasUniversalJavaCapability(PR_FALSE)
{
MOZ_COUNT_CTOR(nsCSecurityContext);
NS_INIT_REFCNT();
// Get the Script Security Manager.
nsresult rv = NS_OK;
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)
if (NS_FAILED(rv) || !secMan) return;
nsCOMPtr<nsIPrincipal> sysprincipal;
if (NS_FAILED(secMan->GetSystemPrincipal(getter_AddRefs(sysprincipal))))
return;
// Do early evaluation of "UniversalJavaPermission" capability.
PRBool equals;
if (!m_pPrincipal ||
NS_SUCCEEDED(m_pPrincipal->Equals(sysprincipal, &equals)) && equals) {
// We have native code or the system principal: just allow general access // We have native code or the system principal: just allow general access
m_HasUniversalBrowserReadCapability = PR_TRUE; m_HasUniversalBrowserReadCapability = PR_TRUE;
m_HasUniversalJavaCapability = PR_TRUE; m_HasUniversalJavaCapability = PR_TRUE;

Просмотреть файл

@ -86,6 +86,7 @@ public:
// from nsCSecurityContext: // from nsCSecurityContext:
nsCSecurityContext(JSContext* cx); nsCSecurityContext(JSContext* cx);
nsCSecurityContext(nsIPrincipal* principal);
virtual ~nsCSecurityContext(void); virtual ~nsCSecurityContext(void);
protected: protected:
@ -95,7 +96,6 @@ private:
nsIPrincipal *m_pPrincipal; nsIPrincipal *m_pPrincipal;
PRBool m_HasUniversalJavaCapability; PRBool m_HasUniversalJavaCapability;
PRBool m_HasUniversalBrowserReadCapability; PRBool m_HasUniversalBrowserReadCapability;
}; };
#endif // nsCSecurityContext_h___ #endif // nsCSecurityContext_h___