changeset 1077:86fbcf148d1f

- Implemented JS->Java security. - Removed ambiguity from class finding mechanism for cases where JS needs a signature involving an applet specific class. - Rewrote code that parsed messages from C++ side -- now it can handle any number of optional components.
author Deepak Bhole <dbhole@redhat.com>
date Wed, 08 Oct 2008 17:00:19 -0400
parents ab8aa9425fc4
children 6790b974078e
files ChangeLog IcedTeaPlugin.cc plugin/icedtea/sun/applet/AppletSecurityContextManager.java plugin/icedtea/sun/applet/PluginAppletSecurityContext.java plugin/icedtea/sun/applet/PluginAppletViewer.java plugin/icedtea/sun/applet/PluginObjectStore.java plugin/icedtea/sun/applet/PluginStreamHandler.java
diffstat 7 files changed, 723 insertions(+), 316 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Oct 07 11:16:16 2008 -0400
+++ b/ChangeLog	Wed Oct 08 17:00:19 2008 -0400
@@ -1,3 +1,16 @@
+2008-10-08  Deepak Bhole <dbhole@redhat.com>
+	* IcedTeaPlugin.cc: Implemented JS->Java security.
+	* plugin/icedtea/sun/applet/AppletSecurityContextManager.java: Same.
+	* plugin/icedtea/sun/applet/PluginAppletSecurityContext.java: Same. Also,
+	remove ambiguity from class finding mechanism for cases where JS needs a
+	signature involving an applet specific class.
+	* plugin/icedtea/sun/applet/PluginAppletViewer.java: Implemented JS->Java
+	security.
+	* plugin/icedtea/sun/applet/PluginObjectStore.java: Same.
+	* plugin/icedtea/sun/applet/PluginStreamHandler.java: Rewrote code that
+	parsed messages from C++ side -- now it can handle any number of optional
+	components.
+
 2008-10-07  Gary Benson  <gbenson@redhat.com>
 	    Andrew Haley  <aph@redhat.com>
 
--- a/IcedTeaPlugin.cc	Tue Oct 07 11:16:16 2008 -0400
+++ b/IcedTeaPlugin.cc	Wed Oct 08 17:00:19 2008 -0400
@@ -309,29 +309,36 @@
 #include <nsIThread.h>
 
 // FIXME: create index from security context.
-#define MESSAGE_CREATE(reference)                            \
-  const char* addr; \
-  char context[16]; \
-  GetCurrentPageAddress(&addr); \
-  GetCurrentContextAddr(context); \
+#define MESSAGE_CREATE()                                     \
   nsCString message ("context ");                            \
   message.AppendInt (0);                                     \
+
+#define MESSAGE_ADD_STACK_REFERENCE(reference) \
   message += " reference ";                                  \
   message.AppendInt (reference);                             \
-  if (factory->codebase_map.find(nsCString(addr)) != factory->codebase_map.end()) \
-  { \
-	  message += " src "; \
-	  message += factory->codebase_map[nsCString(addr)];\
-  } \
-  message += " ";											 \
-  message += __func__;                                       \
   if (factory->result_map[reference] == NULL) {                \
 	   factory->result_map[reference] = new ResultContainer();  \
 	   printf("ResultMap created -- %p %d\n", factory->result_map[reference], factory->result_map[reference]->returnIdentifier); \
   } \
   else                                                      \
-	   factory->result_map[reference]->Clear(); 
-
+	   factory->result_map[reference]->Clear();
+
+#define MESSAGE_ADD_SRC(src) \
+	message += " src "; \
+	message += src;
+
+#define MESSAGE_ADD_PRIVILEGES()                \
+  nsCString privileges("");                     \
+  GetEnabledPrivileges(&privileges);            \
+  if (privileges.Length() > 0)                  \
+  {                                             \
+    message += " privileges ";                  \
+    message += privileges;                      \
+  }
+
+#define MESSAGE_ADD_FUNC() \
+  message += " ";											 \
+  message += __func__;
 
 #define MESSAGE_ADD_STRING(name)                \
   message += " ";                               \
@@ -396,7 +403,7 @@
 
 #define PROCESS_PENDING_EVENTS_REF(reference) \
     if (factory->shutting_down == PR_TRUE && \
-		factory->result_map[reference]->errorOccured == PR_TRUE) \
+		factory->result_map[reference]->errorOccurred == PR_TRUE) \
 	{                                                           \
 		printf("Error occured. Exiting function\n");            \
 		return NS_ERROR_FAILURE; \
@@ -424,13 +431,13 @@
   nsresult res = NS_OK;                                                 \
   printf ("RECEIVE 1\n");                                               \
   while (factory->result_map[reference]->returnIdentifier == -1 &&\
-	     factory->result_map[reference]->errorOccured == PR_FALSE)     \
+	     factory->result_map[reference]->errorOccurred == PR_FALSE)     \
     {                                                                   \
       PROCESS_PENDING_EVENTS_REF (reference);                                \
     }                                                                   \
   printf ("RECEIVE 3\n"); \
   if (factory->result_map[reference]->returnIdentifier == 0 || \
-	  factory->result_map[reference]->errorOccured == PR_TRUE) \
+	  factory->result_map[reference]->errorOccurred == PR_TRUE) \
   {  \
 	  *name = NULL;                                                     \
   } else {                                                              \
@@ -447,12 +454,12 @@
   nsresult res = NS_OK;                                                 \
   printf("RECEIVE ID 1\n");                                             \
   while (factory->result_map[reference]->returnIdentifier == -1 &&\
-	     factory->result_map[reference]->errorOccured == PR_FALSE)     \
+	     factory->result_map[reference]->errorOccurred == PR_FALSE)     \
     {                                                                   \
       PROCESS_PENDING_EVENTS_REF (reference);                                \
     }                                                                   \
                                                                         \
-  if (factory->result_map[reference]->errorOccured == PR_TRUE)	 	    \
+  if (factory->result_map[reference]->errorOccurred == PR_TRUE)	 	    \
   { \
 	  *id = NULL; \
   } else \
@@ -468,7 +475,7 @@
   nsresult res = NS_OK;                                                    \
   printf("RECEIVE VALUE 1\n");                                             \
   while (factory->result_map[reference]->returnValue == "" && \
-	     factory->result_map[reference]->errorOccured == PR_FALSE)            \
+	     factory->result_map[reference]->errorOccurred == PR_FALSE)            \
     {                                                                      \
       PROCESS_PENDING_EVENTS_REF (reference);                                   \
     }                                                                      \
@@ -485,12 +492,12 @@
   nsresult res = NS_OK;                                         \
   printf("RECEIVE SIZE 1\n");                                 \
   while (factory->result_map[reference]->returnValue == "" && \
-	     factory->result_map[reference]->errorOccured == PR_FALSE) \
+	     factory->result_map[reference]->errorOccurred == PR_FALSE) \
     {                                                           \
       PROCESS_PENDING_EVENTS_REF (reference);                        \
     }                                                           \
   nsresult conversionResult;                                    \
-  if (factory->result_map[reference]->errorOccured == PR_TRUE) \
+  if (factory->result_map[reference]->errorOccurred == PR_TRUE) \
 	*result = NULL; \
   else \
   { \
@@ -507,11 +514,11 @@
   nsresult res = NS_OK;                                         \
   printf("RECEIVE STRING 1\n");                                 \
   while (factory->result_map[reference]->returnValue == "" && \
-	     factory->result_map[reference]->errorOccured == PR_FALSE)  \
+	     factory->result_map[reference]->errorOccurred == PR_FALSE)  \
     {                                                           \
       PROCESS_PENDING_EVENTS_REF (reference);                        \
     }                                                           \
-	if (factory->result_map[reference]->errorOccured == PR_TRUE) \
+	if (factory->result_map[reference]->errorOccurred == PR_TRUE) \
 		*result = NULL; \
 	else \
 	{\
@@ -529,11 +536,11 @@
   nsresult res = NS_OK;                                         \
   printf("RECEIVE STRING UCS 1\n");                                 \
   while (factory->result_map[reference]->returnValueUCS.IsEmpty() && \
-	     factory->result_map[reference]->errorOccured == PR_FALSE) \
+	     factory->result_map[reference]->errorOccurred == PR_FALSE) \
     {                                                           \
       PROCESS_PENDING_EVENTS_REF (reference);                        \
     }                                                           \
-	if (factory->result_map[reference]->errorOccured == PR_TRUE) \
+	if (factory->result_map[reference]->errorOccurred == PR_TRUE) \
 		*result = NULL; \
 	else \
 	{ \
@@ -554,11 +561,11 @@
   nsresult res = NS_OK;                                         \
   printf("RECEIVE BOOLEAN 1\n");                             \
   while (factory->result_map[reference]->returnIdentifier == -1 && \
-	     factory->result_map[reference]->errorOccured == PR_FALSE)               \
+	     factory->result_map[reference]->errorOccurred == PR_FALSE)               \
     {                                                           \
       PROCESS_PENDING_EVENTS_REF (reference);                        \
     }                                                           \
-	if (factory->result_map[reference]->errorOccured == PR_TRUE) \
+	if (factory->result_map[reference]->errorOccurred == PR_TRUE) \
 		*result = NULL; \
 	else \
 	  *result = factory->result_map[reference]->returnIdentifier;
@@ -717,8 +724,8 @@
   		PRUint32 returnIdentifier;
 		nsCString returnValue;
 		nsString returnValueUCS;
-		PRBool errorOccured;
-
+		nsCString errorMessage;
+		PRBool errorOccurred;
 };
 
 ResultContainer::ResultContainer () 
@@ -728,7 +735,8 @@
 	returnIdentifier = -1;
 	returnValue.Truncate();
 	returnValueUCS.Truncate();
-	errorOccured = PR_FALSE;
+	errorMessage.Truncate();
+	errorOccurred = PR_FALSE;
 }
 
 ResultContainer::~ResultContainer ()
@@ -738,6 +746,7 @@
     returnIdentifier = -1;
 	returnValue.Truncate();
 	returnValueUCS.Truncate();
+	errorMessage.Truncate();
 }
 
 void
@@ -748,7 +757,8 @@
 	returnIdentifier = -1;
 	returnValue.Truncate();
 	returnValueUCS.Truncate();
-	errorOccured = PR_FALSE;
+	errorMessage.Truncate();
+	errorOccurred = PR_FALSE;
 }
 
 #include <nsTArray.h>
@@ -1182,6 +1192,7 @@
   void DecrementContextCounter();
   nsresult GetCurrentContextAddr(char *addr);
   nsresult GetCurrentPageAddress(const char **addr);
+  nsresult GetEnabledPrivileges(nsCString *privileges);
   int contextCounter;
 };
 
@@ -2780,7 +2791,16 @@
       else if (command == "Error")
         {
 			printf("Error occured. Setting error flag for container @ %d to true\n", reference);
-			result_map[reference]->errorOccured = PR_TRUE;
+			result_map[reference]->errorOccurred = PR_TRUE;
+			result_map[reference]->errorMessage = (nsCString) rest;
+
+			rest += "ERROR: ";
+			IcedTeaPluginInstance* instance = NULL;
+			instances.Get (identifier, &instance);
+			if (instance != 0)
+			{
+				instance->peer->ShowStatus (nsCString (rest).get ());
+			}
 		}
     }
   else if (prefix == "context")
@@ -3916,93 +3936,74 @@
     PR_ExitMonitor(contextCounterPRMonitor);
 }
 
-#include <nsIJSContextStack.h>
-
 nsresult
-IcedTeaJNIEnv::GetCurrentContextAddr(char *addr)
+IcedTeaJNIEnv::GetEnabledPrivileges(nsCString *privileges)
 {
-	return NS_OK;
-    PLUGIN_TRACE_JNIENV ();
-
-    // Get JSContext from stack.
-    nsCOMPtr<nsIJSContextStack> mJSContextStack(do_GetService("@mozilla.org/js/xpc/ContextStack;1"));
-    if (mJSContextStack) {
-        JSContext *cx;
-        if (NS_FAILED(mJSContextStack->Peek(&cx)))
-            return NS_ERROR_FAILURE;
-
-        printf("Context1: %p\n", cx);
-
-        // address cannot be more than 8 bytes (8 bytes = 64 bits)
-		sprintf(addr, "%p", cx);
-
-        printf("Context2: %s\n", addr);
+	nsresult rv;
+	nsCOMPtr<nsIScriptSecurityManager> sec_man = 
+		do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
+
+	if (NS_FAILED(rv) || !sec_man) {
+		return NS_ERROR_FAILURE;
 	}
 
+	PRBool isEnabled = PR_FALSE;
+
+	// check privileges one by one
+
+	privileges->Truncate();
+	char available_privileges[1024];
+
+	// see: http://docs.sun.com/source/816-6170-10/index.htm
+	
+	// Should these other privileges be supported? According to 
+	// http://java.sun.com/j2se/1.3/docs/guide/plugin/security.html it is
+	// either UniversalBrowserRead/UniversalJavaPermissions or the highway...
+
+/*
+	// broken down to make it clean...
+	sprintf(available_privileges, "%s %s %s %s %s %s %s %s %s %s %s %s", 
+								"LimitedInstall FullInstall SilentInstall",
+								"UniversalAccept UniversalAwtEventQueueAccess UniversalConnect",
+								"UniversalConnectWithRedirect UniversalDialogModality",
+								"UniversalExecAccess UniversalExitAccess UniversalFdRead",
+								"UniversalFileDelete UniversalFileRead UniversalFileWrite",
+								"UniversalLinkAccess UniversalListen UniversalMulticast", 
+								"UniversalJavaPermissions UniversalPackageAccess",
+								"UniversalPackageDefinition UniversalPrintJobAccess", 
+								"UniversalPropertyRead UniversalPropertyWrite",
+								"UniversalSendMail UniversalSetFactory UniversalSystemClipboardAccess",
+								"UniversalThreadAccess UniversalThreadGroupAccess",
+								"UniversalTopLevelWindow");
+*/
+
+	sprintf(available_privileges, "%s", 
+							"UniversalBrowserRead UniversalJavaPermissions");
+
+
+	char *token = strtok(available_privileges, " ");
+	while (token != NULL) 
+	{
+		isEnabled = PR_FALSE;
+		sec_man->IsCapabilityEnabled(token, &isEnabled);
+
+		if (isEnabled == PR_TRUE)
+		{
+			printf("GetEnabledPrivileges : %s is enabled\n", token);
+			*privileges += token;
+			*privileges += ",";
+		} else {
+			printf("GetEnabledPrivileges : %s is _NOT_ enabled\n", token);
+		}
+
+		token = strtok (NULL, " ");
+	}
+
+	privileges->Trim(",");
+
 	return NS_OK;
 }
 
-nsresult
-IcedTeaJNIEnv::GetCurrentPageAddress(const char **addr)
-{
-	return NS_OK;
-    PLUGIN_TRACE_JNIENV ();
-
-    nsIPrincipal *prin;
-	nsCOMPtr<nsIScriptSecurityManager> sec_man(do_GetService("@mozilla.org/scriptsecuritymanager;1"));
-
-    if (sec_man) {
-    
-		PRBool isEnabled = PR_FALSE;
-    	sec_man->IsCapabilityEnabled("UniversalBrowserRead", &isEnabled);
-
-		if (isEnabled == PR_FALSE) {
-			printf("UniversalBrowserRead is NOT enabled\n");
-		} else {
-			printf("UniversalBrowserRead IS enabled\n");
-		}
-
-    	sec_man->IsCapabilityEnabled("UniversalBrowserWrite", &isEnabled);
-
-		if (isEnabled == PR_FALSE) {
-			printf("UniversalBrowserWrite is NOT enabled\n");
-		} else {
-			printf("UniversalBrowserWrite IS enabled\n");
-		}
-	}
-
-    if (sec_man)
-	{
-    	sec_man->GetSubjectPrincipal(&prin);
-	} else {
-		return NS_ERROR_FAILURE;
-	}
-
-   if (prin)
-   {
-       nsIURI *uri;
-       prin->GetURI(&uri);
-
-	   if (uri)
-	   {
-           nsCAutoString str;
-           uri->GetSpec(str);
-           NS_CStringGetData(str, addr);
-	   } else {
-		   return NS_ERROR_FAILURE;
-	   }
-   } else {
-	   return NS_ERROR_FAILURE;
-   }
-
-
-	nsCOMPtr<nsIJSID> js_id(do_GetService("@mozilla.org/js/xpc/ID;1"));
-	printf("JS ID is: %s\n", js_id->GetID()->ToString());
-
-    return NS_OK;
-
-}
-
 NS_IMETHODIMP
 IcedTeaJNIEnv::NewObject (jclass clazz,
                           jmethodID methodID,
@@ -4011,14 +4012,41 @@
                           nsISecurityContext* ctx)
 {
   PLUGIN_TRACE_JNIENV ();
+
+  char origin[1024];
+  sprintf(origin, "");
+
+  if (ctx)
+	  ctx->GetOrigin(origin, 1024);
+
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_SRC(origin);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (clazz);
   MESSAGE_ADD_ID (methodID);
   MESSAGE_ADD_ARGS (methodID, args);
   MESSAGE_SEND ();
-  printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
   MESSAGE_RECEIVE_REFERENCE (reference, jobject, result);
+
+  if (factory->result_map[reference]->errorOccurred == PR_TRUE &&
+	  factory->result_map[reference]->errorMessage.Find("LiveConnectPermissionNeeded") == 0)
+  {
+	// Permission error. Try again. This time, send permissions over the wire
+	MESSAGE_CREATE ();
+    MESSAGE_ADD_STACK_REFERENCE(reference);
+    MESSAGE_ADD_SRC(origin);
+	MESSAGE_ADD_PRIVILEGES();
+    MESSAGE_ADD_FUNC();
+	MESSAGE_ADD_REFERENCE (clazz);
+    MESSAGE_ADD_ID (methodID);
+    MESSAGE_ADD_ARGS (methodID, args);
+	MESSAGE_SEND ();
+	MESSAGE_RECEIVE_REFERENCE (reference, jobject, result);
+  }
+
+  
   DecrementContextCounter ();
 
   return NS_OK;
@@ -4033,15 +4061,43 @@
                            nsISecurityContext* ctx)
 {
   PLUGIN_TRACE_JNIENV ();
+
+  char origin[1024];
+  sprintf(origin, "");
+
+  if (ctx)
+	  ctx->GetOrigin(origin, 1024);
+
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_SRC(origin);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (obj);
   MESSAGE_ADD_ID (methodID);
   MESSAGE_ADD_ARGS (methodID, args);
-  std::cout << "CALLMETHOD -- OBJ: " << obj << " METHOD: " << methodID << " ARGS: " << args << std::endl;
   MESSAGE_SEND ();
-  printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
   MESSAGE_RECEIVE_VALUE (reference, type, result);
+
+  if (factory->result_map[reference]->errorOccurred == PR_TRUE &&
+	  factory->result_map[reference]->errorMessage.Find("LiveConnectPermissionNeeded") == 0)
+  {
+    MESSAGE_CREATE ();
+    MESSAGE_ADD_STACK_REFERENCE(reference);
+    MESSAGE_ADD_SRC(origin);
+	MESSAGE_ADD_PRIVILEGES();
+    MESSAGE_ADD_FUNC();
+    MESSAGE_ADD_REFERENCE (obj);
+    MESSAGE_ADD_ID (methodID);
+    MESSAGE_ADD_ARGS (methodID, args);
+    MESSAGE_SEND ();
+    MESSAGE_RECEIVE_VALUE (reference, type, result);
+
+    // if everything was OK, clear exception from previous access exception
+	if (factory->result_map[reference]->errorOccurred == PR_FALSE)
+		ExceptionClear();
+  }
+
   DecrementContextCounter ();
 
   return NS_OK;
@@ -4307,13 +4363,37 @@
                          nsISecurityContext* ctx)
 {
   PLUGIN_TRACE_JNIENV ();
+
+  char origin[1024];
+  sprintf(origin, "");
+
+  if (ctx)
+	  ctx->GetOrigin(origin, 1024);
+
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_SRC(origin);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (obj);
   MESSAGE_ADD_ID (fieldID);
   MESSAGE_SEND ();
-  printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
   MESSAGE_RECEIVE_VALUE (reference, type, result);
+
+  if (factory->result_map[reference]->errorOccurred == PR_TRUE &&
+	  factory->result_map[reference]->errorMessage.Find("LiveConnectPermissionNeeded") == 0)
+  {
+    MESSAGE_CREATE ();
+    MESSAGE_ADD_STACK_REFERENCE(reference);
+    MESSAGE_ADD_SRC(origin);
+	MESSAGE_ADD_PRIVILEGES();
+    MESSAGE_ADD_FUNC();
+    MESSAGE_ADD_REFERENCE (obj);
+    MESSAGE_ADD_ID (fieldID);
+    MESSAGE_SEND ();
+    MESSAGE_RECEIVE_VALUE (reference, type, result);
+  }
+
   DecrementContextCounter ();
 
   return NS_OK;
@@ -4327,7 +4407,17 @@
                          nsISecurityContext* ctx)
 {
   PLUGIN_TRACE_JNIENV ();
-  MESSAGE_CREATE (-1);
+
+  char origin[1024];
+  sprintf(origin, "");
+
+  if (ctx)
+	  ctx->GetOrigin(origin, 1024);
+
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(-1);
+  MESSAGE_ADD_SRC(origin);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_TYPE (type);
   MESSAGE_ADD_REFERENCE (obj);
   MESSAGE_ADD_ID (fieldID);
@@ -4346,14 +4436,43 @@
                                  nsISecurityContext* ctx)
 {
   PLUGIN_TRACE_JNIENV ();
+
+  char origin[1024];
+  sprintf(origin, "");
+
+  if (ctx)
+	  ctx->GetOrigin(origin, 1024);
+
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_SRC(origin);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (clazz);
   MESSAGE_ADD_ID (methodID);
   MESSAGE_ADD_ARGS (methodID, args);
   MESSAGE_SEND ();
-  printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
   MESSAGE_RECEIVE_VALUE (reference, type, result);
+  
+  if (factory->result_map[reference]->errorOccurred == PR_TRUE &&
+	  factory->result_map[reference]->errorMessage.Find("LiveConnectPermissionNeeded") == 0)
+  {
+    MESSAGE_CREATE ();
+    MESSAGE_ADD_STACK_REFERENCE(reference);
+    MESSAGE_ADD_SRC(origin);
+	MESSAGE_ADD_PRIVILEGES();
+    MESSAGE_ADD_FUNC();
+    MESSAGE_ADD_REFERENCE (clazz);
+    MESSAGE_ADD_ID (methodID);
+    MESSAGE_ADD_ARGS (methodID, args);
+    MESSAGE_SEND ();
+    MESSAGE_RECEIVE_VALUE (reference, type, result);
+
+    // if everything was OK, clear exception from previous access exception
+	if (factory->result_map[reference]->errorOccurred == PR_FALSE)
+		ExceptionClear();
+  }
+
   DecrementContextCounter ();
 
   return NS_OK;
@@ -4367,13 +4486,37 @@
                                nsISecurityContext* ctx)
 {
   PLUGIN_TRACE_JNIENV ();
+
+  char origin[1024];
+  sprintf(origin, "");
+
+  if (ctx)
+	  ctx->GetOrigin(origin, 1024);
+
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_SRC(origin);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (clazz);
   MESSAGE_ADD_ID (fieldID);
   MESSAGE_SEND ();
-  printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
   MESSAGE_RECEIVE_VALUE (reference, type, result);
+
+  if (factory->result_map[reference]->errorOccurred == PR_TRUE &&
+	  factory->result_map[reference]->errorMessage.Find("LiveConnectPermissionNeeded") == 0)
+  {
+    MESSAGE_CREATE ();
+    MESSAGE_ADD_STACK_REFERENCE(reference);
+    MESSAGE_ADD_SRC(origin);
+	MESSAGE_ADD_PRIVILEGES();
+    MESSAGE_ADD_FUNC();
+    MESSAGE_ADD_REFERENCE (clazz);
+    MESSAGE_ADD_ID (fieldID);
+    MESSAGE_SEND ();
+    MESSAGE_RECEIVE_VALUE (reference, type, result);
+  }
+
   DecrementContextCounter ();
 
   return NS_OK;
@@ -4387,7 +4530,17 @@
                                nsISecurityContext* ctx)
 {
   PLUGIN_TRACE_JNIENV ();
-  MESSAGE_CREATE (-1);
+
+  char origin[1024];
+  sprintf(origin, "");
+
+  if (ctx)
+	  ctx->GetOrigin(origin, 1024);
+
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(-1);
+  MESSAGE_ADD_SRC(origin);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_TYPE (type);
   MESSAGE_ADD_REFERENCE (clazz);
   MESSAGE_ADD_ID (fieldID);
@@ -4423,7 +4576,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_STRING (name);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4438,7 +4593,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (sub);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4454,7 +4611,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (sub);
   MESSAGE_ADD_REFERENCE (super);
   MESSAGE_SEND ();
@@ -4488,7 +4647,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
   // FIXME: potential leak here: when is result free'd?
@@ -4510,9 +4671,10 @@
 IcedTeaJNIEnv::ExceptionClear (void)
 {
   PLUGIN_TRACE_JNIENV ();
-  MESSAGE_CREATE (-1);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(-1);
+  MESSAGE_ADD_FUNC();
   MESSAGE_SEND ();
-  printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
   return NS_OK;
 }
 
@@ -4530,7 +4692,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (lobj);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4543,7 +4707,9 @@
 IcedTeaJNIEnv::DeleteGlobalRef (jobject gref)
 {
   PLUGIN_TRACE_JNIENV ();
-  MESSAGE_CREATE (-1);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(-1);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (gref);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4555,7 +4721,9 @@
 IcedTeaJNIEnv::DeleteLocalRef (jobject obj)
 {
   PLUGIN_TRACE_JNIENV ();
-  MESSAGE_CREATE (-1);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(-1);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (obj);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4590,7 +4758,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (obj);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4606,7 +4776,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (obj);
   MESSAGE_ADD_REFERENCE (clazz);
   MESSAGE_SEND ();
@@ -4624,7 +4796,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (clazz);
   MESSAGE_ADD_STRING (name);
   std::cout << "Args: " << clazz << " " << name << " " << sig << " " << *id << "@" << id << std::endl;
@@ -4647,7 +4821,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (clazz);
   MESSAGE_ADD_STRING (name);
   printf ("SIGNATURE: %s %s %s\n", __func__, name, sig);
@@ -4667,7 +4843,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (clazz);
   MESSAGE_ADD_STRING (name);
   printf ("SIGNATURE: %s %s\n", __func__, sig);
@@ -4687,7 +4865,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (clazz);
   MESSAGE_ADD_STRING (name);
   printf ("SIGNATURE: %s %s\n", __func__, sig);
@@ -4706,7 +4886,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_SIZE (len);
   MESSAGE_ADD_STRING_UCS (unicode, len);
   MESSAGE_SEND ();
@@ -4722,7 +4904,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (str);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4741,7 +4925,9 @@
     *isCopy = JNI_TRUE;
 
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (str);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4765,7 +4951,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_STRING_UTF (utf);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4780,7 +4968,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (str);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4799,7 +4989,9 @@
     *isCopy = JNI_TRUE;
 
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (str);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4823,7 +5015,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (array);
   MESSAGE_SEND ();
   printf("MSG SEND COMPLETE. NOW RECEIVING...\n");
@@ -4840,7 +5034,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_SIZE (len);
   MESSAGE_ADD_REFERENCE (clazz);
   MESSAGE_ADD_REFERENCE (init);
@@ -4858,7 +5054,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (array);
   MESSAGE_ADD_SIZE (index);
   MESSAGE_SEND ();
@@ -4874,7 +5072,9 @@
                                       jobject val)
 {
   PLUGIN_TRACE_JNIENV ();
-  MESSAGE_CREATE (-1);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(-1);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_REFERENCE (array);
   MESSAGE_ADD_SIZE (index);
   MESSAGE_ADD_REFERENCE (val);
@@ -4891,7 +5091,9 @@
 {
   PLUGIN_TRACE_JNIENV ();
   int reference = IncrementContextCounter ();
-  MESSAGE_CREATE (reference);
+  MESSAGE_CREATE ();
+  MESSAGE_ADD_STACK_REFERENCE(reference);
+  MESSAGE_ADD_FUNC();
   MESSAGE_ADD_TYPE (element_type);
   MESSAGE_ADD_SIZE (len);
   MESSAGE_SEND ();
--- a/plugin/icedtea/sun/applet/AppletSecurityContextManager.java	Tue Oct 07 11:16:16 2008 -0400
+++ b/plugin/icedtea/sun/applet/AppletSecurityContextManager.java	Wed Oct 08 17:00:19 2008 -0400
@@ -1,5 +1,6 @@
 package sun.applet;
 
+import java.security.AccessControlContext;
 import java.util.HashMap;
 
 public class AppletSecurityContextManager {
@@ -20,8 +21,13 @@
 		contexts.get(identifier).dumpStore();
 	}
 	
-	public static void handleMessage(int identifier, String src, int reference,	String message) {
+	public static void handleMessage(int identifier, int reference,	String src, String[] privileges, String message) {
 		System.err.println(identifier + " -- " + src + " -- " + reference + " -- " + message + " CONTEXT= " + contexts.get(identifier));
-		contexts.get(identifier).handleMessage(src, reference, message);
+		AccessControlContext callContext = null;
+
+		privileges = privileges != null ? privileges : new String[0];
+		callContext = contexts.get(identifier).getAccessControlContext(privileges, src); 
+
+		contexts.get(identifier).handleMessage(reference, src, callContext, message);
 	}
 }
--- a/plugin/icedtea/sun/applet/PluginAppletSecurityContext.java	Tue Oct 07 11:16:16 2008 -0400
+++ b/plugin/icedtea/sun/applet/PluginAppletSecurityContext.java	Wed Oct 08 17:00:19 2008 -0400
@@ -37,21 +37,30 @@
 
 package sun.applet;
 
+import java.awt.AWTPermission;
+import java.io.FilePermission;
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.SocketPermission;
+import java.net.URL;
 import java.security.AccessControlContext;
+import java.security.AccessControlException;
 import java.security.AccessController;
-import java.security.Permission;
+import java.security.AllPermission;
+import java.security.BasicPermission;
+import java.security.CodeSource;
 import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
 import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
 import java.util.ArrayList;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
-import java.util.StringTokenizer;
+import java.util.PropertyPermission;
 
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
 
@@ -123,7 +132,7 @@
 		}
 	}
 
-	public Signature(String signature, String src) {
+	public Signature(String signature, ClassLoader cl) {
 		this.signature = signature;
 		currentIndex = 0;
 		typeList = new ArrayList<Class>(10);
@@ -159,9 +168,9 @@
 						// System.out.println ("HERE4");
 					} else
 						typeList.add(Array.newInstance(
-								getClass(arrayType, src), dims).getClass());
+								getClass(arrayType, cl), dims).getClass());
 				} else {
-					typeList.add(getClass(elem, src));
+					typeList.add(getClass(elem, cl));
 				}
 			}
 		}
@@ -171,36 +180,22 @@
 		}
 	}
 
-	public static Class getClass(String name, String src) {
+	public static Class getClass(String name, ClassLoader cl) {
 
 		Class c = null;
 		
 		try {
 			c = Class.forName(name);
 		} catch (ClassNotFoundException cnfe) {
-
-			StringTokenizer st = new StringTokenizer(src, ",");
-
-			while (st.hasMoreTokens()) {
-
-				String tok = st.nextToken();
-				System.err.println("Searching for " + name  + " at key " + tok);
-
-				try {
-					c = PluginAppletSecurityContext.classLoaders.get(tok).loadClass(name);
-				} catch (ClassNotFoundException e) {
-					// do nothing .. thrown below
-				}
-
-				if (c != null)
-					break;
+			
+			System.err.println("Class " + name + " not found in primordial loader. Looking in " + cl);
+			try {
+				c = cl.loadClass(name);
+			} catch (ClassNotFoundException e) {
+				throw (new RuntimeException(new ClassNotFoundException("Unable to find class " + name)));
 			}
 		}
 
-		if (c == null) {
-			throw (new RuntimeException(new ClassNotFoundException("Unable to find class " + name)));
-		}
-
 		return c;
 	}
 	
@@ -234,7 +229,7 @@
 
 public class PluginAppletSecurityContext {
 	
-	public static HashMap<String, ClassLoader> classLoaders = new HashMap<String, ClassLoader>();
+	public static HashMap<ClassLoader, String> classLoaders = new HashMap<ClassLoader, String>();
 
 	// FIXME: make private
 	public PluginObjectStore store = new PluginObjectStore();
@@ -246,15 +241,24 @@
 
 	public PluginAppletSecurityContext(int identifier) {
 		this.identifier = identifier;
+		
+		// We need a security manager.. and since there is a good chance that 
+		// an applet will be loaded at some point, we should make it the SM 
+		// that JNLPRuntime will try to install
+		if (System.getSecurityManager() == null) {
+			JNLPRuntime.initialize();
+		}
+
+		this.classLoaders.put(liveconnectLoader, "file://");
 	}
 
-	private static <V> V parseCall(String s, String src, Class<V> c) {
+	private static <V> V parseCall(String s, ClassLoader cl, Class<V> c) {
 		if (c == Integer.class)
 			return (V) new Integer(s);
 		else if (c == String.class)
 			return (V) new String(s);
 		else if (c == Signature.class)
-			return (V) new Signature(s, src);
+			return (V) new Signature(s, cl);
 		else
 			throw new RuntimeException("Unexpected call value.");
 	}
@@ -284,25 +288,17 @@
 			return store.getObject(new Integer(s));
 	}
 
-	public void addClassLoader(String id, ClassLoader cl) {
-		this.classLoaders.put(id, cl);
+	public void associateSrc(ClassLoader cl, String src) {
+		System.err.println("Associating " + cl + " with " + src);
+		this.classLoaders.put(cl, src);
 	}
 
 	public static void setStreamhandler(PluginStreamHandler sh) {
 		streamhandler = sh;
 	}
 
-	public void handleMessage(String src, int reference, String message) {
+	public void handleMessage(int reference, String src, AccessControlContext callContext, String message) {
 
-		// We need a security manager.. and since there is a good chance that 
-		// an applet will be loaded at some point, we should make it the SM 
-		// that JNLPRuntime will try to install
-		if (System.getSecurityManager() == null) {
-			JNLPRuntime.initialize();
-		}
-
-		System.out.println("in handleMessage(), SecurityManager=" + System.getSecurityManager());
-		
 		try {
 			if (message.startsWith("FindClass")) {
 				ClassLoader cl = null;
@@ -322,9 +318,9 @@
 			} else if (message.startsWith("GetStaticMethodID")
 					|| message.startsWith("GetMethodID")) {
 				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
-				String methodName = parseCall(args[2], src, String.class);
-				Signature signature = parseCall(args[3], src, Signature.class);
+				Integer classID = parseCall(args[1], null, Integer.class);
+				String methodName = parseCall(args[2], null, String.class);
+				Signature signature = parseCall(args[3], ((Class) store.getObject(classID)).getClassLoader(), Signature.class);
 				Object[] a = signature.getClassArray();
 
 				Class c = (Class) store.getObject(classID);
@@ -344,9 +340,9 @@
 			} else if (message.startsWith("GetStaticFieldID")
 					|| message.startsWith("GetFieldID")) {
 				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
-				String fieldName = parseCall(args[2], src, String.class);
-				Signature signature = parseCall(args[3], src, Signature.class);
+				Integer classID = parseCall(args[1], null, Integer.class);
+				String fieldName = parseCall(args[2], null, String.class);
+				Signature signature = parseCall(args[3], ((Class) store.getObject(classID)).getClassLoader(), Signature.class);
 
 				Class c = (Class) store.getObject(classID);
 				Field f = null;
@@ -357,14 +353,15 @@
 				write(reference, "GetStaticFieldID " + store.getIdentifier(f));
 			} else if (message.startsWith("GetStaticField")) {
 				String[] args = message.split(" ");
-				String type = parseCall(args[1], src, String.class);
-				Integer classID = parseCall(args[1], src, Integer.class);
-				Integer fieldID = parseCall(args[2], src, Integer.class);
+				String type = parseCall(args[1], null, String.class);
+				Integer classID = parseCall(args[1], null, Integer.class);
+				Integer fieldID = parseCall(args[2], null, Integer.class);
 
 				final Class c = (Class) store.getObject(classID);
 				final Field f = (Field) store.getObject(fieldID);
 
-				AccessControlContext acc = getAccessControlContext(identifier);
+				AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+				checkPermission(src, c, acc);
 
 				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
 					public Object run() {
@@ -399,9 +396,9 @@
 				}
 			} else if (message.startsWith("SetStaticField")) {
 				String[] args = message.split(" ");
-				String type = parseCall(args[1], src, String.class);
-				Integer classID = parseCall(args[2], src, Integer.class);
-				Integer fieldID = parseCall(args[3], src, Integer.class);
+				String type = parseCall(args[1], null, String.class);
+				Integer classID = parseCall(args[2], null, Integer.class);
+				Integer fieldID = parseCall(args[3], null, Integer.class);
 
 				Object value = null;
 				if (Signature.primitiveNameToType(type) != null) {
@@ -417,7 +414,8 @@
 				final Field f = (Field) store.getObject(fieldID);
 
 				final Object fValue = value;
-				AccessControlContext acc = getAccessControlContext(identifier);
+				AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+				checkPermission(src, c, acc);
 
 				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
 					public Object run() {
@@ -437,9 +435,9 @@
 				write(reference, "SetStaticField");
 			} else if (message.startsWith("SetField")) {
 				String[] args = message.split(" ");
-				String type = parseCall(args[1], src, String.class);
-				Integer objectID = parseCall(args[2], src, Integer.class);
-				Integer fieldID = parseCall(args[3], src, Integer.class);
+				String type = parseCall(args[1], null, String.class);
+				Integer objectID = parseCall(args[2], null, Integer.class);
+				Integer fieldID = parseCall(args[3], null, Integer.class);
 
 				Object value = null;
 				if (Signature.primitiveNameToType(type) != null) {
@@ -455,7 +453,8 @@
 				final Field f = (Field) store.getObject(fieldID);
 
 				final Object fValue = value;
-				AccessControlContext acc = getAccessControlContext(identifier);
+				AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+				checkPermission(src, o.getClass(), acc);
 
 				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
 					public Object run() {
@@ -475,8 +474,8 @@
 				write(reference, "SetField");
 			} else if (message.startsWith("GetObjectArrayElement")) {
 				String[] args = message.split(" ");
-				Integer arrayID = parseCall(args[1], src, Integer.class);
-				Integer index = parseCall(args[2], src, Integer.class);
+				Integer arrayID = parseCall(args[1], null, Integer.class);
+				Integer index = parseCall(args[2], null, Integer.class);
 
 				Object[] o = (Object[]) store.getObject(arrayID);
 				Object ret = null;
@@ -490,9 +489,9 @@
 						+ store.getIdentifier(ret));
 			} else if (message.startsWith("SetObjectArrayElement")) {
 				String[] args = message.split(" ");
-				Integer arrayID = parseCall(args[1], src, Integer.class);
-				Integer index = parseCall(args[2], src, Integer.class);
-				Integer objectID = parseCall(args[3], src, Integer.class);
+				Integer arrayID = parseCall(args[1], null, Integer.class);
+				Integer index = parseCall(args[2], null, Integer.class);
+				Integer objectID = parseCall(args[3], null, Integer.class);
 
 				Object[] o = (Object[]) store.getObject(arrayID);
 				Object toSet = (Object) store.getObject(objectID);
@@ -502,7 +501,7 @@
 				write(reference, "SetObjectArrayElement");
 			} else if (message.startsWith("GetArrayLength")) {
 				String[] args = message.split(" ");
-				Integer arrayID = parseCall(args[1], src, Integer.class);
+				Integer arrayID = parseCall(args[1], null, Integer.class);
 
 				System.out.println("ARRAYID: " + arrayID);
 				Object o = (Object) store.getObject(arrayID);
@@ -514,14 +513,15 @@
 				write(reference, "GetArrayLength " + Array.getLength(o));
 			} else if (message.startsWith("GetField")) {
 				String[] args = message.split(" ");
-				String type = parseCall(args[1], src, String.class);
-				Integer objectID = parseCall(args[1], src, Integer.class);
-				Integer fieldID = parseCall(args[2], src, Integer.class);
+				String type = parseCall(args[1], null, String.class);
+				Integer objectID = parseCall(args[1], null, Integer.class);
+				Integer fieldID = parseCall(args[2], null, Integer.class);
 
 				final Object o = (Object) store.getObject(objectID);
 				final Field f = (Field) store.getObject(fieldID);
 
-				AccessControlContext acc = getAccessControlContext(identifier);
+				AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+				checkPermission(src, o.getClass(), acc);
 
 				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
 					public Object run() {
@@ -565,8 +565,8 @@
 				write(reference, "GetObjectClass " + store.getIdentifier(c));
 			} else if (message.startsWith("CallStaticMethod")) {
 				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
-				Integer methodID = parseCall(args[2], src, Integer.class);
+				Integer classID = parseCall(args[1], null, Integer.class);
+				Integer methodID = parseCall(args[2], null, Integer.class);
 
 				System.out.println("GETTING: " + methodID);
 				final Method m = (Method) store.getObject(methodID);
@@ -583,7 +583,9 @@
 				// System.out.println ("Calling " + m);
 
 				final Object[] fArguments = arguments;
-				AccessControlContext acc = getAccessControlContext(identifier);
+				AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+				Class c = (Class) store.getObject(classID);
+				checkPermission(src, c, acc);
 
 				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
 					public Object run() {
@@ -626,8 +628,8 @@
 				}
 			} else if (message.startsWith("CallMethod")) {
 				String[] args = message.split(" ");
-				Integer objectID = parseCall(args[1], src, Integer.class);
-				Integer methodID = parseCall(args[2], src, Integer.class);
+				Integer objectID = parseCall(args[1], null, Integer.class);
+				Integer methodID = parseCall(args[2], null, Integer.class);
 
 				final Object o = (Object) store.getObject(objectID);
 				final Method m = (Method) store.getObject(methodID);
@@ -648,7 +650,8 @@
 				PluginDebug.debug("Calling method " + m + " on object " + o
 						+ " with " + arguments);
 
-				AccessControlContext acc = getAccessControlContext(identifier);
+				AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+				checkPermission(src, o.getClass(), acc);
 
 				final Object[] fArguments = arguments;
 				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
@@ -697,7 +700,7 @@
 				}
 			} else if (message.startsWith("GetSuperclass")) {
 				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
+				Integer classID = parseCall(args[1], null, Integer.class);
 				Class c = null;
 				Class ret = null;
 
@@ -708,8 +711,8 @@
 				write(reference, "GetSuperclass " + store.getIdentifier(ret));
 			} else if (message.startsWith("IsAssignableFrom")) {
 				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
-				Integer superclassID = parseCall(args[2], src, Integer.class);
+				Integer classID = parseCall(args[1], null, Integer.class);
+				Integer superclassID = parseCall(args[2], null, Integer.class);
 
 				boolean result = false;
 				Class clz = (Class) store.getObject(classID);
@@ -720,8 +723,8 @@
 				write(reference, "IsAssignableFrom " + (result ? "1" : "0"));
 			} else if (message.startsWith("IsInstanceOf")) {
 				String[] args = message.split(" ");
-				Integer objectID = parseCall(args[1], src, Integer.class);
-				Integer classID = parseCall(args[2], src, Integer.class);
+				Integer objectID = parseCall(args[1], null, Integer.class);
+				Integer classID = parseCall(args[2], null, Integer.class);
 
 				boolean result = false;
 				Object o = (Object) store.getObject(objectID);
@@ -732,7 +735,7 @@
 				write(reference, "IsInstanceOf " + (result ? "1" : "0"));
 			} else if (message.startsWith("GetStringUTFLength")) {
 				String[] args = message.split(" ");
-				Integer stringID = parseCall(args[1], src, Integer.class);
+				Integer stringID = parseCall(args[1], null, Integer.class);
 
 				String o = null;
 				byte[] b = null;
@@ -744,7 +747,7 @@
 				write(reference, "GetStringUTFLength " + o.length());
 			} else if (message.startsWith("GetStringLength")) {
 				String[] args = message.split(" ");
-				Integer stringID = parseCall(args[1], src, Integer.class);
+				Integer stringID = parseCall(args[1], null, Integer.class);
 
 				String o = null;
 				byte[] b = null;
@@ -757,7 +760,7 @@
 				write(reference, "GetStringLength " + o.length());
 			} else if (message.startsWith("GetStringUTFChars")) {
 				String[] args = message.split(" ");
-				Integer stringID = parseCall(args[1], src, Integer.class);
+				Integer stringID = parseCall(args[1], null, Integer.class);
 
 				String o = null;
 				byte[] b = null;
@@ -777,7 +780,7 @@
 				write(reference, "GetStringUTFChars " + buf);
 			} else if (message.startsWith("GetStringChars")) {
 				String[] args = message.split(" ");
-				Integer stringID = parseCall(args[1], src, Integer.class);
+				Integer stringID = parseCall(args[1], null, Integer.class);
 
 				String o = null;
 				byte[] b = null;
@@ -798,8 +801,8 @@
 				write(reference, "GetStringChars " + buf);
 			} else if (message.startsWith("NewArray")) {
 				String[] args = message.split(" ");
-				String type = parseCall(args[1], src, String.class);
-				Integer length = parseCall(args[2], src, Integer.class);
+				String type = parseCall(args[1], null, String.class);
+				Integer length = parseCall(args[2], null, Integer.class);
 
 				// System.out.println ("CALLING: NewArray: " + type + " " +
 				// length + " "
@@ -813,9 +816,9 @@
 				write(reference, "NewArray " + store.getIdentifier(newArray));
 			} else if (message.startsWith("NewObjectArray")) {
 				String[] args = message.split(" ");
-				Integer length = parseCall(args[1], src, Integer.class);
-				Integer classID = parseCall(args[2], src, Integer.class);
-				Integer objectID = parseCall(args[3], src, Integer.class);
+				Integer length = parseCall(args[1], null, Integer.class);
+				Integer classID = parseCall(args[2], null, Integer.class);
+				Integer objectID = parseCall(args[3], null, Integer.class);
 
 				// System.out.println ("CALLING: NewObjectArray: " +
 				// classID + " " + length + " "
@@ -833,8 +836,8 @@
 						+ store.getIdentifier(newArray));
 			} else if (message.startsWith("NewObject")) {
 				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
-				Integer methodID = parseCall(args[2], src, Integer.class);
+				Integer classID = parseCall(args[1], null, Integer.class);
+				Integer methodID = parseCall(args[2], null, Integer.class);
 
 				final Constructor m = (Constructor) store.getObject(methodID);
 				Class[] argTypes = m.getParameterTypes();
@@ -848,7 +851,10 @@
 				}
 
 				final Object[] fArguments = arguments;
-				AccessControlContext acc = getAccessControlContext(identifier);
+				AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+
+				Class c = (Class) store.getObject(classID);
+				checkPermission(src, c, acc);
 
 				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
 					public Object run() {
@@ -870,12 +876,12 @@
 			} else if (message.startsWith("NewString")) {
 				System.out.println("MESSAGE: " + message);
 				String[] args = message.split(" ");
-				Integer strlength = parseCall(args[1], src, Integer.class);
+				Integer strlength = parseCall(args[1], null, Integer.class);
 				int bytelength = 2 * strlength;
 				byte[] byteArray = new byte[bytelength];
 				String ret = null;
 				for (int i = 0; i < strlength; i++) {
-					int c = parseCall(args[2 + i], src, Integer.class);
+					int c = parseCall(args[2 + i], null, Integer.class);
 					System.out.println("char " + i + " " + c);
 					// Low.
 					byteArray[2 * i] = (byte) (c & 0x0ff);
@@ -898,7 +904,7 @@
 				int i = 0;
 				int c = 0;
 				while (((byte) c) != 0) {
-					c = parseCall(args[1 + i], src, Integer.class);
+					c = parseCall(args[1 + i], null, Integer.class);
 					byteArray[i] = (byte) c;
 					i++;
 					if (i == byteArray.length) {
@@ -921,29 +927,36 @@
 				write(reference, "ExceptionOccurred "
 						+ store.getIdentifier(throwable));
 			} else if (message.startsWith("ExceptionClear")) {
-				if (throwable != null)
+				if (throwable != null && store.contains(throwable))
 					store.unreference(store.getIdentifier(throwable));
 				throwable = null;
 				write(reference, "ExceptionClear");
 			} else if (message.startsWith("DeleteGlobalRef")) {
 				String[] args = message.split(" ");
-				Integer id = parseCall(args[1], src, Integer.class);
+				Integer id = parseCall(args[1], null, Integer.class);
 				store.unreference(id);
 				write(reference, "DeleteGlobalRef");
 			} else if (message.startsWith("DeleteLocalRef")) {
 				String[] args = message.split(" ");
-				Integer id = parseCall(args[1], src, Integer.class);
+				Integer id = parseCall(args[1], null, Integer.class);
 				store.unreference(id);
 				write(reference, "DeleteLocalRef");
 			} else if (message.startsWith("NewGlobalRef")) {
 				String[] args = message.split(" ");
-				Integer id = parseCall(args[1], src, Integer.class);
+				Integer id = parseCall(args[1], null, Integer.class);
 				store.reference(store.getObject(id));
 				write(reference, "NewGlobalRef " + id);
 			}
 		} catch (Throwable t) {
 			t.printStackTrace();
 			String msg = t.getCause() != null ? t.getCause().getMessage() : t.getMessage();
+
+			// add an identifier string to let javaside know of the type of error
+			// check for cause as well, since the top level exception will be InvocationTargetException in most cases
+			if (t instanceof AccessControlException || t.getCause() instanceof AccessControlException) {
+				msg = "LiveConnectPermissionNeeded " + msg;
+			}
+
 			this.streamhandler.write("instance " + identifier + " reference " + reference + " Error " + msg);
 
 			// ExceptionOccured is only called after Callmethod() by mozilla. So
@@ -960,6 +973,32 @@
 		}
 	}
 
+	/**
+	 * Checks if the calling script is allowed to access the specified class
+	 *  
+	 * See http://java.sun.com/j2se/1.3/docs/guide/plugin/security.html#liveconnect for details
+	 *  
+	 * @param jsSrc The source of the script
+	 * @param target The target class that the script is trying to access
+	 * @param acc AccessControlContext for this execution
+	 * @throws AccessControlException If the script has insufficient permissions
+	 */
+	public void checkPermission(String jsSrc, Class target, AccessControlContext acc) throws AccessControlException {
+
+		// target classloader == null => primordial loader. Allow this.
+		if (target.getClassLoader() == null)
+			return;
+
+		String classSrc = this.classLoaders.get(target.getClassLoader());
+
+		System.err.println("jsSrc=" + jsSrc + " classSrc=" + classSrc);
+		
+		// if src is not a file and class loader does not map to the same base, UniversalBrowserRead (BrowserReadPermission) must be set
+		if (jsSrc != "file://" && !classSrc.equals(jsSrc)) {
+			acc.checkPermission(new BrowserReadPermission());
+		}
+	}
+
 	private void write(int reference, String message) {
 		PluginDebug.debug("appletviewer writing " + message);
 		streamhandler.write("context " + identifier + " reference " + reference
@@ -983,39 +1022,150 @@
 	}
 
 	/**
-	 * Returns an 
-	 * 
-	 * @param identifier The unique instance identity of the applet for which the context is needed
-	 * @return The context associated with the given applet
+	 * Returns a "closed" AccessControlContext i.e. no permissions to get out of sandbox.
 	 */
-	public AccessControlContext getAccessControlContext(int identifier) {
-		
-		// TODO: 
-		// 1. Find applet URL
-		// 2. If startsWith file://, some permissions are lax
-		// 3. If not, find out associated permissions
-
-		// Deny everything for now
-		PermissionCollection pc = new PermissionCollection(){
-			@Override
-			public boolean implies(Permission permission) {
-				// TODO Auto-generated method stub
-				return false;
-			}
-		
-			@Override
-			public Enumeration<Permission> elements() {
-				// TODO Auto-generated method stub
-				return null;
-			}
-		
-			@Override
-			public void add(Permission permission) {
-				// TODO Auto-generated method stub
-			}
-		};
-
-		ProtectionDomain pd = new ProtectionDomain(PluginAppletSecurityContext.class.getProtectionDomain().getCodeSource(), pc);
+	public AccessControlContext getClosedAccessControlContext() {
+		// Deny everything
+		Permissions p = new Permissions();
+		ProtectionDomain pd = new ProtectionDomain(PluginAppletSecurityContext.class.getProtectionDomain().getCodeSource(), p);
 		return new AccessControlContext(new ProtectionDomain[] {pd});
 	}
+	
+	public AccessControlContext getAccessControlContext(String[] nsPrivilegeList, String src) {
+
+/*
+		for (int i=0; i < nsPrivilegeList.length; i++) {
+			String privilege = nsPrivilegeList[i];
+
+			if (privilege.equals("UniversalAccept")) {
+				SocketPermission sp = new SocketPermission("*", "accept,resolve");
+				grantedPermissions.add(sp);
+			} else if (privilege.equals("UniversalAwtEventQueueAccess")) {
+				AWTPermission awtp = new AWTPermission("accessEventQueue");
+				grantedPermissions.add(awtp);
+			} else if (privilege.equals("UniversalConnect")) {
+				SocketPermission sp = new SocketPermission("*", "connect,resolve");
+				grantedPermissions.add(sp);
+			} else if (privilege.equals("UniversalListen")) {
+				SocketPermission sp = new SocketPermission("*", "listen,resolve");
+				grantedPermissions.add(sp);
+			} else if (privilege.equals("UniversalExecAccess")) {
+				FilePermission fp = new FilePermission("<<ALL FILES>>", "execute");
+				RuntimePermission rtp = new RuntimePermission("setIO");
+				grantedPermissions.add(fp);
+				grantedPermissions.add(rtp);
+			} else if (privilege.equals("UniversalExitAccess")) {
+				// Doesn't matter what the permissions are. Do not allow VM to exit.. we 
+				// use a single VM for the entire browser lifecycle once invoked, we 
+				// cannot let it exit
+
+				//RuntimePermission rtp = new RuntimePermission("exitVM.*");
+				//grantedPermissions.add(rtp);
+			} else if (privilege.equals("UniversalFileDelete")) {
+				FilePermission fp = new FilePermission("<<ALL FILES>>", "delete");
+				grantedPermissions.add(fp);
+			} else if (privilege.equals("UniversalFileRead")) {
+				FilePermission fp = new FilePermission("<<ALL FILES>>", "read");
+				grantedPermissions.add(fp);
+			} else if (privilege.equals("UniversalFileWrite")) {
+				FilePermission fp = new FilePermission("<<ALL FILES>>", "write");
+				grantedPermissions.add(fp);
+			}  else if (privilege.equals("UniversalFdRead")) {
+				RuntimePermission rtp = new RuntimePermission("readFileDescriptor");
+				grantedPermissions.add(rtp);
+			} else if (privilege.equals("UniversalFdWrite")) {
+				RuntimePermission rtp = new RuntimePermission("writeFileDescriptor");
+				grantedPermissions.add(rtp);
+			} else if (privilege.equals("UniversalLinkAccess")) {
+				RuntimePermission rtp = new RuntimePermission("loadLibrary.*");
+				grantedPermissions.add(rtp);
+			} else if (privilege.equals("UniversalListen")) {
+				SocketPermission sp = new SocketPermission("*", "listen");
+				grantedPermissions.add(sp);
+			} else if (privilege.equals("UniversalMulticast")) {
+				SocketPermission sp = new SocketPermission("*", "accept,connect,resolve");
+				grantedPermissions.add(sp);
+			} else if (privilege.equals("UniversalPackageAccess")) {
+				RuntimePermission rtp = new RuntimePermission("defineClassInPackage.*");
+				grantedPermissions.add(rtp);
+			} else if (privilege.equals("UniversalPackageDefinition")) {
+				RuntimePermission rtp = new RuntimePermission("accessClassInPackage.*");
+				grantedPermissions.add(rtp);
+			} else if (privilege.equals("UniversalPrintJobAccess")) {
+				RuntimePermission rtp = new RuntimePermission("queuePrintJob");
+				grantedPermissions.add(rtp);
+			} else if (privilege.equals("UniversalPropertyRead")) {
+				PropertyPermission pp = new PropertyPermission("*", "read");
+				grantedPermissions.add(pp);
+			} else if (privilege.equals("UniversalPropertyWrite")) {
+				PropertyPermission pp = new PropertyPermission("*", "write");
+				grantedPermissions.add(pp);
+			} else if (privilege.equals("UniversalSetFactory")) {
+				RuntimePermission rtp = new RuntimePermission("setFactory");
+				grantedPermissions.add(rtp);
+			} else if (privilege.equals("UniversalSystemClipboardAccess")) {
+				AWTPermission awtp = new AWTPermission("accessClipboard");
+				grantedPermissions.add(awtp);
+			} else if (privilege.equals("UniversalThreadAccess")) {
+				RuntimePermission rtp1 = new RuntimePermission("modifyThread");
+				RuntimePermission rtp2 = new RuntimePermission("stopThread");
+				grantedPermissions.add(rtp1);
+				grantedPermissions.add(rtp2);
+			} else if (privilege.equals("UniversalThreadGroupAccess")) {
+				RuntimePermission rtp1 = new RuntimePermission("modifyThreadGroup");
+				RuntimePermission rtp2 = new RuntimePermission("modifyThread");
+				RuntimePermission rtp3 = new RuntimePermission("stopThread");
+				grantedPermissions.add(rtp1);
+				grantedPermissions.add(rtp2);
+				grantedPermissions.add(rtp3);
+			} else if (privilege.equals("UniversalTopLevelWindow")) {
+				AWTPermission awtp = new AWTPermission("topLevelWindow");
+				grantedPermissions.add(awtp);
+			} else if (privilege.equals("UniversalBrowserRead")) {
+				BrowserReadPermission bp = new BrowserReadPermission();
+				grantedPermissions.add(bp);
+			} else if (privilege.equals("UniversalJavaPermissions")) {
+				AllPermission ap = new AllPermission();
+				grantedPermissions.add(ap);
+			}
+		}
+		
+		// what to do with these is unknown: UniversalConnectWithRedirect, UniversalDialogModality, UniversalSendMail, LimitedInstall, FullInstall, SilentInstall
+*/
+
+		Permissions grantedPermissions = new Permissions();
+
+		for (int i=0; i < nsPrivilegeList.length; i++) {
+			String privilege = nsPrivilegeList[i];
+
+			if (privilege.equals("UniversalBrowserRead")) {
+				BrowserReadPermission bp = new BrowserReadPermission();
+				grantedPermissions.add(bp);
+			} else if (privilege.equals("UniversalJavaPermissions")) {
+				AllPermission ap = new AllPermission();
+				grantedPermissions.add(ap);
+			}
+		}
+
+		CodeSource cs = new CodeSource((URL) null, (java.security.cert.Certificate  [])null);
+		
+		if (src != null) {
+			try {
+				cs = new CodeSource(new URL(src + "/"), (java.security.cert.Certificate[]) null);
+			} catch (MalformedURLException mfue) {
+				// do nothing
+			}
+		}
+
+		ProtectionDomain pd = new ProtectionDomain(cs, grantedPermissions, null, null);
+
+		// Add to hashmap
+		return new AccessControlContext(new ProtectionDomain[] {pd});
+	}
+
+	class BrowserReadPermission extends BasicPermission {
+		public BrowserReadPermission() {
+			super("browserRead");
+		}
+	}
 }
--- a/plugin/icedtea/sun/applet/PluginAppletViewer.java	Tue Oct 07 11:16:16 2008 -0400
+++ b/plugin/icedtea/sun/applet/PluginAppletViewer.java	Wed Oct 08 17:00:19 2008 -0400
@@ -47,9 +47,11 @@
 import java.io.PrintStream;
 import java.io.Reader;
 import java.io.StringReader;
+import java.net.MalformedURLException;
 import java.net.SocketPermission;
 import java.net.URL;
 import java.security.AccessController;
+import java.security.Policy;
 import java.security.PrivilegedAction;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -59,7 +61,6 @@
 import java.util.Vector;
 
 import net.sourceforge.jnlp.NetxPanel;
-
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
 import sun.awt.X11.XEmbeddedFrame;
@@ -266,20 +267,31 @@
     }
 
     PluginDebug.debug("Applet initialized");
-    
+
     // Applet initialized. Find out it's classloader and add it to the list
-    AppletSecurityContextManager.getSecurityContext(0).addClassLoader(Integer.toString(identifier), a.getClass().getClassLoader());
+    String codeBase = doc.getProtocol() + "://" + doc.getHost();
+
+    if (atts.get("codebase") != null) {
+    	try {
+    		URL appletSrcURL = new URL((String) atts.get("codebase"));
+    		codeBase = appletSrcURL.getProtocol() + "://" + appletSrcURL.getHost();
+    	} catch (MalformedURLException mfue) {
+    		// do nothing
+    	}
+    }
+
+    AppletSecurityContextManager.getSecurityContext(0).associateSrc(a.getClass().getClassLoader(), codeBase);
 
      }
- 
+
  	public static void setStreamhandler(PluginStreamHandler sh) {
 		streamhandler = sh;
 	}
-     
+
  	public static void setPluginCallRequestFactory(PluginCallRequestFactory rf) {
 		requestFactory = rf;
 	}
- 	
+
      /**
       * Handle an incoming message from the plugin.
       */
@@ -287,7 +299,7 @@
      {
 
 		 PluginDebug.debug("PAV handling: " + message);
-
+		 
          try {
         	 if (message.startsWith("tag")) {
         		 
@@ -320,6 +332,7 @@
         				 PluginDebug.debug ("REQUEST HANDLE NOT SET: " + request.handle + ". BYPASSING");
         			 }
         		 }
+        		 
              } else if (message.startsWith("handle")) {
             	 synchronized(requests) {
             		 PluginParseRequest request = requests.get(identifier);
@@ -360,11 +373,13 @@
         	 int width =
         		 Integer.parseInt(message.substring("width".length() + 1));
              //panel.setAppletSizeIfNeeded(width, -1);
+        	 panel.setSize(width, getHeight());
              setSize(width, getHeight());
          } else if (message.startsWith("height")) {
              int height = 
             	 Integer.parseInt(message.substring("height".length() + 1));
              //panel.setAppletSizeIfNeeded(-1, height);
+             panel.setSize(getWidth(), height);
              setSize(getWidth(), height);
          } else if (message.startsWith("destroy")) {
              dispose();
--- a/plugin/icedtea/sun/applet/PluginObjectStore.java	Tue Oct 07 11:16:16 2008 -0400
+++ b/plugin/icedtea/sun/applet/PluginObjectStore.java	Wed Oct 08 17:00:19 2008 -0400
@@ -70,6 +70,17 @@
             return 0;
         return identifiers.get(object);
     }
+    
+    public boolean contains(Object object) {
+    	if (object == null)
+    		return identifiers.containsKey(object);
+
+    	return false;
+    }
+    
+    public boolean contains(int identifier) {
+   		return objects.containsKey(identifier);
+    }
 
     public void reference(Object object) {
         Integer identifier = identifiers.get(object);
--- a/plugin/icedtea/sun/applet/PluginStreamHandler.java	Tue Oct 07 11:16:16 2008 -0400
+++ b/plugin/icedtea/sun/applet/PluginStreamHandler.java	Wed Oct 08 17:00:19 2008 -0400
@@ -146,34 +146,44 @@
     
     public void handleMessage(String message) throws PluginException {
 
-    	StringTokenizer st = new StringTokenizer(message, " ");
-
-    	String type = st.nextToken();
-    	final int identifier = Integer.parseInt(st.nextToken());
-
-    	String rest = "";
+    	int nextIndex = 0;
     	int reference = -1;
     	String src = null;
-
-    	String potentialReference = st.hasMoreTokens() ? st.nextToken() : "";
+    	String[] privileges = null;
+    	String rest = "";
 
-    	// if the next token is reference, read it, else reset "rest"
-    	if (potentialReference.equals("reference")) {
-    		reference = Integer.parseInt(st.nextToken());
-    	} else {
-    		rest += potentialReference + " ";
+    	String[] msgComponents = message.split(" ");
+    	
+    	// type and identifier are guaranteed to be there
+    	String type = msgComponents[0];
+    	final int identifier = Integer.parseInt(msgComponents[1]);
+    	nextIndex = 2;
+    	
+    	// reference, src and privileges are optional components, 
+    	// and are guaranteed to be in that order, if they occur
+
+    	// is there a reference ?
+    	if (msgComponents[nextIndex].equals("reference")) {
+    		reference = Integer.parseInt(msgComponents[nextIndex+1]);
+    		nextIndex += 2;
     	}
 
-    	String potentialSrc = st.hasMoreTokens() ? st.nextToken() : "";
-
-    	if (potentialSrc.equals("src")) {
-    		src = st.nextToken();
-    	} else {
-    		rest += potentialSrc + " ";
+    	// is there a src?
+    	if (msgComponents[nextIndex].equals("src")) {
+    		src = msgComponents[nextIndex+1];
+    		nextIndex += 2;
     	}
 
-    	while (st.hasMoreElements()) {
-    		rest += st.nextToken();
+    	// is there a privileges?
+    	if (msgComponents[nextIndex].equals("privileges")) {
+    		String privs = msgComponents[nextIndex+1];
+    		privileges = privs.split(",");
+    		nextIndex += 2;
+    	}
+    	
+    	// rest
+    	for (int i=nextIndex; i < msgComponents.length; i++) {
+    		rest += msgComponents[i];
     		rest += " ";
     	}
 
@@ -181,7 +191,7 @@
 
     	try {
 
-    		System.err.println("Breakdown -- type: " + type + " identifier: " + identifier + " reference: " + reference + " src: " + src + " rest: " + rest);
+    		System.err.println("Breakdown -- type: " + type + " identifier: " + identifier + " reference: " + reference + " src: " + src + " privileges: " + privileges + " rest: \"" + rest + "\"");
 
     		if (rest.contains("JavaScriptGetWindow")
     				|| rest.contains("JavaScriptGetMember")
@@ -205,7 +215,7 @@
     			PluginAppletViewer.handleMessage(identifier, freference,frest);
     		} else if (type.equals("context")) {
     			PluginDebug.debug("Sending to PASC: " + identifier + "/" + reference + " and " + rest);
-    			AppletSecurityContextManager.handleMessage(identifier, src, reference, rest);
+    			AppletSecurityContextManager.handleMessage(identifier, reference, src, privileges, rest);
     		}
     	} catch (Exception e) {
     		throw new PluginException(this, identifier, reference, e);