users@glassfish.java.net

Re: AppClient/JWS/Derby/Security problems

From: Tim Quinn <Timothy.Quinn_at_Sun.COM>
Date: Thu, 14 Sep 2006 09:56:41 -0500

Hi, again, Ray.

OK, I sort of expected that you'd say that part of the code is
dynamically loaded. That is leading to the permissions problem under
Java Web Start.

Because KART is loading the add on JAR itself dynamically, and because
Java Web Start did not download it there is no opportunity for Java Web
Start's security manager to grant that code elevated permissions. The
Java Web Start model is that it - meaning Java Web Start - downloads all
JARs that are needed to run the application. It grants code in an
unsigned downloaded JAR a minimal set of permissions. It grants code in
a signed downloaded JAR full permissions if the user indicates he or she
trusts the cert used to sign the JAR.

The key point of interest here is that Java Web Start does not grant any
permissions to code it did not download, not even the minimum it would
grant an unsigned JAR that it did download. Because this
separately-loaded code is in the call stack when the TopLink logic tries
to read the property, the security manager rejects TopLink's attempt
because it does not trust the intervening code. This is even though the
TopLink code itself was signed and is itself trusted.

So this aspect, at least, is a more general Java Web Start application
design issue as opposed to something related directly to app clients or
their support via Java Web Start.

I don't know if your design and the way the persistence layer works
would permit this but here's one idea you might consider. The
java.security.AccessController.doPrivileged method allows your app to
run a block of code with elevated permissions but temporarily suspending
the requirement that all intervening code has been granted elevated
permissions. This is very useful in situations like what you've
described in which privileged code calls out to non-priv'd code which
then calls back into the priv'd code again. doPrivileged lets the
trusted code do what it needs to despite the fact that it has been
called by untrusted code.

So, if you could structure your app so that code in the app client (I
guess I can call it KART) - and therefore downloaded by Java Web Start -
calls the add-on code - and then the add-on code calls back into the
KART code, then the KART code could use doPrivileged to invoke the
TopLink methods so that the TopLink code can run with the required
permissions.

Obviously, one needs to be very cautious in what one codes in the
doPrivileged block because untrusted code is allowed to invoke code that
runs with elevated permissions.

This page http://java.sun.com/j2se/1.5.0/docs/guide/security/ has lots
of links to useful security information. This one
http://java.sun.com/j2se/1.5.0/docs/guide/security/doprivileged.html has
lots of information about doPrivileged in particular, and the
"Background" section does a much better job than I have here of
describing this feature.

- Tim


Martin, Ray wrote:
> KART.jar is deployed to Glassfish as an AppClient Module. There is no
> enterprise archive file relative to KART. When an AppClient Module is
> deployed, there are two pages in the Web Admin Console. The first
> page has a check box for Java Web Start enabled. I check that box.
> Thereafter, the following URL in Firefox causes KART to stand up:
> http//:gateway:8080/KART?prop=DBHome=/usr/local/dbHome
>
> I also have a JSP available from an enterprise app deployed to
> Glassfish. But, this is probably a 'don't care' relative to our
> discussion - just wanted to make sure.
>
> So what is the next step? Should I send something? test something?
> your wish is my command...
>
> I reviewed the stack trace below before hitting the send button and I
> thought of something else that may be relevant.
>
> There is a web app, Addons.war, that is deployed to Glassfish. In
> that war file are simply three jar files - ChatAddon2.jar,
> DrawingAddon.jar, and SecurityAuditor.jar
>
> After JWS has launched KART, the substrate, a GUI is available - the
> user can select a button, "VisitAddon Store". This button points to
> the URL of Addons.war in Glassfish. The resulting HTTP response is
> parsed and the three jar files are shown in a Swing Listbox. The user
> can select an addon one at a time.
>
> If I select ChatAddon2 from several different computers (each from a
> KART launched via JWS) then the chat GUI stands up and a chat session
> can occur between the collaboration nodes of the structured overlay
> network. This is working.
>
> If I select the addon, SecurityAuditor, the GUI stands up - but, this
> addon is immature and does not do much just yet (but, eventually, it
> will need data persistence). This addon is working to its current
> level and does not crash.
>
> If I select the addon, DrawingAddon, then the bold lines below occur
> - and crash.
>
> What is happening is that when the user selects an addon from the
> list, KART asks that addon if it has a DataAccess layer. Both
> ChatEditor2 and SecurityAuditor respond with a null signifying that
> they do not have a DataAccess layer. DrawingAddon responds with the
> name of the class that is its DataAccess layer. KART then uses its
> AddonClassLoader to retrieve the DataAccess class, in this case,
> DataAccessImpl, from DrawingAddon.jar not from KART.jar. After
> DataAccessImpl has been instantiated, KART passes emf
> (EntityManagerFactory). In the method that DataAccessImpl receives
> emf, it then has the line: em = emf.createEntityManager();
>
> We discussed that EntityManagerFactory needed to be in the main class
> of KART. But, we did not discuss that EntityManager needed to be in
> the main class of KART. But, I will go ahead and test passing
> EntityManager from KART to the DataAccessImpl - just as easy to do -
> just did not happen to do it that way.
>
> Before sending the email, I moved: em = emf.createEntityManager(); -
> the main class of KART and re-tested. The error moved for both
> 'appclient only' and appclient/JWS as can be seen in the attached traces.
>
>
>
> I would like to have EntityManager and EntityManagerFactory in my
> addon.DataAccessImpl class and not in kart.Main class. Also, I would
> like to utilize persistence.xml from the addon jar not the KART jar.
> PLEASE.
>
> -----Original Message-----
> *From:* Timothy.Quinn_at_Sun.COM [mailto:Timothy.Quinn_at_Sun.COM]
> *Sent:* Wednesday, September 13, 2006 4:19 PM
> *To:* users_at_glassfish.dev.java.net
> *Subject:* Re: AppClient/JWS/Derby/Security problems
>
> Hi, again, Ray.
>
> In the stack trace related to the permission problem launching via
> Java Web Start (in Thread-25 as excerpted below) I suspect the
> error occurs because, although the TopLink code itself has been
> granted elevated permissions and would be allowed to read the
> property, the SecurityManager will not permit it to do so unless
> all intervening methods in the call stack also have that
> permission. I suspect that the kart... classes are not being
> granted permissions (bolded in the stack trace).
>
>
> With that in mind - and if you have already described this earlier
> in the mail thread I apologize for asking again - can I ask how,
> physically, are the kart.* classes made available to the client?
> Are they packaged in the app client itself, or in a JAR within the
> containing EAR? The Java Web Start-aware app client container
> (ACC) should be making sure, within the Java Web Start security
> model, that adequate permissions are granted to the code
> downloaded in the app client JAR. If this is not happening then
> we need to find out why.
>
> - Tim
>
>
> Exception in thread "Thread-25" java.lang.ExceptionInInitializerError
> at
> sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
> at
> sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
> at
> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
> at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
> at java.lang.Class.newInstance0(Class.java:350)
> at java.lang.Class.newInstance(Class.java:303)
> * at kart.Model.setDataAccessLayer(Model.java:326)
> at
> kart.addon.loader.AddonClassLoader.loadAddon(AddonClassLoader.java:223)
> at
> kart.addon.loader.AddonClassLoader.beginLoad(AddonClassLoader.java:264)
> at
> kart.addon.loader.AddonClassLoader.start(AddonClassLoader.java:256)
> at kart.Model.execAddon(Model.java:230)
> at kart.KARTgui$11$1.run(KARTgui.java:592)*
> at java.lang.Thread.run(Thread.java:595)
> Caused by: java.security.AccessControlException: access denied
> (java.util.PropertyPermission toplink.validation-only read)
> at
> java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
> at
> java.security.AccessController.checkPermission(AccessController.java:427)
> at
> java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
> at
> java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1285)
> at java.lang.System.getProperty(System.java:627)
> at
> oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(EntityManagerFactoryProvider.java:295)
> at
> oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.isValidationOnly(EntityManagerSetupImpl.java:567)
> at
> oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.shouldGetSessionOnCreateFactory(EntityManagerSetupImpl.java:577)
> at
> oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.createEntityManagerFactory(EntityManagerFactoryProvider.java:130)
> at
> javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83)
> at
> javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:60)
> at
> draw.resources.dal.DataAccessImpl.<clinit>(DataAccessImpl.java:62)
> ... 13 more
>
> ------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: users-help_at_glassfish.dev.java.net