views:

195

answers:

2

Hello everyone,

After doing a lot of reading and testing I've been unable to give all permissions to an intranet applet through the codeBase grant option. This applet need full permissions because it will have to acess driver libs for OCR readers (which also write image files to HDD) and other such external devices.

I've configured my java.policy file and added the following:

grant codebase "http://myIntranetServer/-" { permission java.security.AllPermission; };

After reloading the policy file in the console, and even restarting the browser, I get an java.security.AccessControlException:access denied for many of my operations, including reading the "user.name" system property which is not granted by default.

For debugging I've also tried the giving the all permission by default and it works, so my problem is basically related to de codeBase option. I am runnig Windows 7 and linux clients, with JRE1.6-u17, and both have the same behavior.

Can anyone help?

Thanks in advance,

MadeiraA

A: 

Tried it myself now.

  • class files + html file located on a server http://[domain].xxx/~someusername/somefolder/
  • class files + html file located on local file system C:/Documents and Settings/[USERNAME]/Desktop/somefolder

Policy: .java.policy (located in C:/Documents and Settings/[USERNAME]/. Note the leading .)

When using these applet works and displays [USERNAME]

grant codeBase "file:///-" {
  permission java.util.PropertyPermission "user.name", "read";
};
grant codeBase "http://[domain].xxx/-" {
  permission java.util.PropertyPermission "user.name", "read";
};

Then used these (reloaded policy file in java console) applet fails to display [USERNAME]

grant codeBase "file:///c/*" {
  permission java.util.PropertyPermission "user.name", "read";
};
grant codeBase "http://[domain].xxx/*" {
  permission java.util.PropertyPermission "user.name", "read";
};

Appelt: TestApp.java

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.security.*;

public class TestApp extends Applet {
  Label output = new Label("What is the value of user.name?");
  public void init() {
    Button button = new Button("Click me!");
    setLayout(new BorderLayout());
    add(BorderLayout.NORTH, button);
    add(BorderLayout.CENTER, output);
    button.addActionListener(
      new ActionListener() {
        @Override
        public void actionPerformed( ActionEvent ev ) {
          try {
            output.setText(System.getProperty("user.name"));
          } catch (AccessControlException e) {
            output.setText("Oops, failed. No read permissions");
          }
        }
      }
    );
  }
}

HTML: index.html

<html><body>
  <applet code="TestApp.class" width=350 height=80></applet>
</body></html>


I'm a little confused right now. You state that the above grant statement doesn't work and at the same moment state that "giving the all permission by default ... works"?

A few questions

  • What browser are you using?
  • Which java.policy file did you edit / Where did you place it
  • What does the URL really look like? Is myIntranetServer something that can be resolved via DNS? If not maybe java has some problem applying the rule
jitter
Yes.If I have the permission as grant{permission java.security.AllPermission;};it works fine.If I apply the codebase it does not.I have tried a brute force attack of the problem using either the simple machine name and the full machine name (the one with the domain), and various combinations of case because I have read in another forum that the codeBase is handled case-sentive.Fact is nothing seems to work.
MadeiraA
I'm using both IE8 and Firefox. The policy file is the right one for I can get different behaviors as I change it. like I said above I'm trying several possibilities for myIntranetServer : {servername, servername.domainname.pt} and some combinations of the same values changing the case of the letters.Thanks for your interest.
MadeiraA
The only thing related to case sensitivity known to me is that codeBase should be written all lower case execpt the B. codeBase
jitter
Made a quick test now by myself. Check answer for details
jitter
Yes, that's how I write the codeBase attribute. The case issue I refered applies to the content of the attribute, the path itself. I've been checking your quick test and everything appears to checkout with what I have, although I do not find the .java.policy file you refer. I am using directly te $JAVA_HOME\lib\security\java.policy and I do see changes in behavior when I change it and reload it in the console.
MadeiraA
You refer the codeBase path you used in your quick test to be like "http://[domain].xxx/-", and it seems to be the same structure as the ones I use "http://[MachineName].[Domain]/-" and "http://[MachineName]/-". The domain name I am using is a NTDomain not an internet domain, for the machine is just internal to the organization. Could this problem of mine be related somehow with the proxy?
MadeiraA
I included your code in my applet and it <b>works!</b> when I call it through the buttons. My problem seems to be related to calling my functions externally, in this case, from the Javascript in my page. I am using Live Connect (plugin.jar) and when I call the same functions from the Javascript I get the AccessControlException. How can I solve this situation?
MadeiraA
Added second answer. Partial success with calling restricted functionality from javascript
jitter
A: 

I'm not sure if I understood your last comment correctly. As you state two (for me) different things:

  • You use plugin.jar (which means to me your java calls javascript functions)
  • "I call the same functions from the Javascript" (which means to me your javascript calls java functions)

I assume the later one is the right interpretation.

If you just call java methods (via liveconnect) which don't do anything security related all is ok. And you can just do (assuming applet with id="myapplet") myapplet.safeMethod(); directly in your javascript code.

The main problem with calling java methods, which do something normally restricted for applets, from javascript is that the calls seem to run in a different context in the JVM then the applet itself. Thus are treated as unprivileged code and you get the AccessControlException. While e.g. like in my other answer, methods which are executed by the applet itself, get the right permissions and are executed.

Now if you read this LiveConnect Support in the New Java™ Plug-In Technology in section 2.8 Security Model of JavaScript-to-Java Calls SUN states

When a JavaScript-to-Java call is made, the JavaScript code is modeled as though it were coming from an untrusted applet whose code origin is the document base (i.e., the URL of the directory containing the document).

I read this as: If applet and javascript come from the same site than the javascript-to-java calls should run with the same permissions as the applet itself. Which in our case means with whatever rights we set in our grant.

But this only works in Opera for me. FF and IE6 both throw AccessControlException. But it might still work out for you in all browsers.

The following code has two methods userName2() and userName(). userName2() WFM in all browsers. userName() only works in Opera. Check by pushing the buttons on the html page.

As you can see userName2() is not usable like this for a real usecase (can only be called once). But you can look into a solution someone else came up with when having a similar problem, and accordingly extend userName2()

Java Applet using LiveConnect

Additionally you might consider something I didn't try out. All calls from javascript-to-java do nothing security related just (if needed) pass in data and return immediately. Then the applet does the actual work (like in the link shown above). Then when finished the applet could fire a callback into the html page via the JSObject (plugin.jar)

TestApp.java

import java.applet.Applet;
import java.awt.*;
import java.security.AccessControlException;

public class TestApp extends Applet {
  Label output = new Label("What is the value of user.name?");
  String userName;
  Thread access = new Thread() {
    @Override
    public void run() {
      try {
        userName = System.getProperty("user.name");
      } catch (AccessControlException e) {
        userName = "Oops, failed in thread. No read permissions!";
      }
    }
  };
  public void init() {
    setLayout(new BorderLayout());
    add(BorderLayout.CENTER, output);
  }
  public String userName2() throws InterruptedException {
    access.start();
    access.join();
    output.setText(userName);
    return userName;
  }
  public String userName() {
    String userName = "Oops, failed in liveconnect-context. No read permissions!";
    try {
      userName = System.getProperty("user.name");
    } catch (AccessControlException e) {
      e.printStackTrace();
    }
    output.setText(userName);
    return userName;
  }
}

test.html

<html><head><title>test</title></head><body>
  <applet id="myapplet" code="TestApp" width="350px" height="80px"></applet><br>
  <input type="button" value="liveconnect version" onclick="javascript:alert(myapplet.userName());"><br>
  <input type="button" value="hacky thread version" onclick="javascript:alert(myapplet.userName2());">
</body></html>

Policy: .java.policy (created manually in C:/Documents and Settings/[USERNAME]/ Note the leading .)

grant codeBase "http://[domain].xxx/-" {
  permission java.util.PropertyPermission "user.name", "read";
};
jitter
Jitter, After some reading of the links you provided, I came up with using AccessController.doPrivileged to loose the permission restriction imposed by the stack, and It is finally working!Once again, thanks for thrownig all the right pointers and taking the tinme to help.
MadeiraA
That's interesting, as that didn't work out for me at all. Did play around a bit with AccessController and PrivilegedAction too but that didn't change any of the behavior for me. Well good for you. As this is an intranet thing you might have the luck that it will work on all of your clients too.
jitter
Now consider upvoting my answers and maybe even accepting one for all the effort and time I put in
jitter
I've accepted your last answer. I can't upvote yet since I haven't 15 reputation points on my profile.
MadeiraA