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 */
if (JSJ_callbacks && JSJ_callbacks->enter_js_from_java) {
#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
if (!JSJ_callbacks->enter_js_from_java(jEnv, &err_msg))
#endif

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

@ -125,7 +125,7 @@ typedef struct JSJCallbacks {
semantics of JavaScript. It is acceptable for either function pointer
to be NULL. */
#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
JSBool (*enter_js_from_java)(JNIEnv *jEnv, char **errp);
#endif

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

@ -28,7 +28,10 @@
#include "lcglue.h"
#include "nscore.h"
#include "nsISecurityContext.h"
#include "nsCSecurityContext.h"
#include "nsCRT.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptObjectOwner.h"
extern "C" int XP_PROGRESS_STARTING_JAVA;
extern "C" int XP_PROGRESS_STARTING_JAVA_DONE;
@ -89,6 +92,7 @@ JVMContext* GetJVMContext()
context->jsj_env = NULL;
context->js_context = NULL;
context->js_startframe = NULL;
context->java_applet_obj = NULL;
localContext.set(context);
}
return context;
@ -370,27 +374,64 @@ unwrap_java_wrapper_impl(JNIEnv *pJNIEnv, jobject java_wrapper)
static JSBool PR_CALLBACK
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();
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);
// Should be NS_DYNAMIC_CAST, but no such define exists.
// So for the sake of portability, we'll live
// dangerously and use brute force.
if( !jscontext || !jvcontext ) {
if (!jscontext || !jvcontext) {
return PR_FALSE;
}
// Check that the origin + certificate are the same.
// If not, then return false.
const int buflen = 128;
const int buflen = 512;
char jsorigin[buflen];
char jvorigin[buflen];
*jsorigin = nsnull;
@ -399,10 +440,14 @@ enter_js_from_java_impl(JNIEnv *jEnv, char **errp,
jscontext->GetOrigin(jsorigin,buflen);
jvcontext->GetOrigin(jvorigin,buflen);
if( nsCRT::strcasecmp(jsorigin,jvorigin) ) {
if (nsCRT::strcasecmp(jsorigin,jvorigin)) {
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 jvcertid[buflen];
*jscertid = nsnull;
@ -411,12 +456,12 @@ enter_js_from_java_impl(JNIEnv *jEnv, char **errp,
jscontext->GetCertificateID(jscertid,buflen);
jvcontext->GetCertificateID(jvcertid,buflen);
if( nsCRT::strcasecmp(jscertid,jvcertid) ) {
if (nsCRT::strcasecmp(jscertid,jvcertid)) {
return PR_FALSE;
}
} else {
return PR_FALSE;
#endif
}
return PR_TRUE;

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

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

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

@ -43,6 +43,8 @@
#include "nsCodebasePrincipal.h"
#include "nsCertificatePrincipal.h"
#include "nsScriptSecurityManager.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptObjectOwner.h"
#include "nsTraceRefcnt.h"
@ -102,8 +104,6 @@ nsCSecurityContext::Implies(const char* target, const char* action, PRBool *bAll
NS_METHOD
nsCSecurityContext::GetOrigin(char* buf, int buflen)
{
nsCOMPtr<nsIPrincipal> principal = NULL;
// Get the Script Security Manager.
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(secMan->GetSubjectPrincipal(getter_AddRefs(principal))))
return NS_ERROR_FAILURE;
// First, try to get the principal from the security manager.
// 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)
return NS_ERROR_FAILURE;
char* origin=nsnull;
codebase->GetOrigin(&origin);
if( origin ) {
if (origin) {
PRInt32 originlen = (PRInt32) nsCRT::strlen(origin);
if(!buf || buflen<=originlen) {
if( origin ) {
if (!buf || buflen<=originlen) {
if (origin) {
nsCRT::free(origin);
}
return NS_ERROR_FAILURE;
@ -165,7 +194,7 @@ nsCSecurityContext::GetCertificateID(char* buf, int buflen)
char* certificate = nsnull;
cprincipal->GetCertificateID(&certificate);
if( certificate ) {
if (certificate) {
PRInt32 certlen = (PRInt32) nsCRT::strlen(certificate);
if( buflen<=certlen ) {
nsCRT::free(certificate);
@ -219,8 +248,43 @@ nsCSecurityContext::nsCSecurityContext(JSContext* cx)
PRBool equals;
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
m_HasUniversalBrowserReadCapability = PR_TRUE;
m_HasUniversalJavaCapability = PR_TRUE;

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

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