Having Trouble Getting RMI Security Policy Working - java

I'm having trouble getting RMI security policies working. I have a .policy file on both the server and client, each of which is running a SecurityManager.
When I try and run the client its failing. My policy file grants everything atm. Heres the content:
grant { permission java.security.AllPermission };
I have the file client.policy in the root directory of my JAR file (I tried running it with the policy file outside the jar too). Then I run the client with this:
java -jar PagePlanner.jar -Djava.security.policy=client.policy -Djava.rmi.codebase=http://192.168.0.88:2077/home/me/NetbeansProjects/PageServer/dist/PageServer.jar -Djava.security.debug=access
Specifying my policy file and the path to my code base. I'm not sure if either of these are correct. I also tried setting the debug switch as I read somewhere it should give me extra info about whats going wrong, but it does not seem to make a difference.Heres the output when I run the client:
Exception in thread "main" java.security.AccessControlException: access denied (java.awt.AWTPermission setWindowAlwaysOnTop)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
at java.security.AccessController.checkPermission(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.awt.Window.setAlwaysOnTop(Window.java:2038)
at gui.LoginForm.<init>(LoginForm.java:59)
at main.Main.main(Main.java:21)
From which point the client just hangs. Any ideas what I'm doing wrong here? The policy setup on the server-side is pretty much the same. I can post the details if that helps.
Cheers.

Run the client with -Djava.security.debug=access,failure. Most probably your .policy file isn't being found.
BTW you don't need to set the codebase at the client unless the client has its own implementations of abstract classes/interfaces and the server doesn't know about them. The codebase is normally only set at the server, so as to annotate classes that are downloaded to the client and the Registry.

Related

Read/write a file with credentials [duplicate]

I have a server where I work with a database and files using a java app.
When I start my app I give a report regarding file access to the server using:
public static boolean folderExists(String folderPath) {
File folderToCheck = new File(folderPath);
return folderToCheck.exists();
}
Every time I start my app (after a fresh restart of my computer)
I get a false response, even though the server is on.
The reason is because I must give an authentication as another user.
What I do is access the server through Windows
where I am being asked for username/password,
and after that I get a true response regarding file access to the server.
Is there a way to give the authentication username/password through Java,
and not through Windows?
Thank you
On Windows 'native' Java IO (e.g. java.io.File) always inherits the security context of the user running the JVM process. For example, you could run the Java app as a Windows service with the correct credentials.
The JCIFS project implements CIFS (the Windows SMB file server protocol) and allows you to directly specify the username/password.
See the API for examples.
I am pretty sure, that there is no way to grant fileaccess by java, without a Windows-Call.
You can call cacls file.log /e /t /p Everyone:f but this will be language-dependent.
I had a similar problem: How to change the file ACL in windows, if I only know the SID?
With Java7 there may be a way to do this.

Running a sample RMI application

I am trying to run the example of the RMI application given in the Oracle website http://docs.oracle.com/javase/tutorial/rmi/running.html.
However, trying both Eclipse and in the command line, I can't run the server nor the client.
In fact, when running in Eclipse I get this error:
ComputeEngine exception:
java.security.AccessControlException: access denied ("java.net.SocketPermission" "127.0.0.1:1099" "connect,resolve")
I also have changed the VM Argument like this:
For the ComputeEngine (server):
-Djava.security.manager -Djava.rmi.server.codebase=file:/Users/name/Documents/workspace/PiComputationRM/src/compute/compute.jar -Djava.security.policy=/Users/name/Documents/workspace/PiComputationRM/server.policy
For the ComputePi (client):
-Djava.security.policy=/Users/name/Documents/workspace/PiComputationRM/client.policy
The content of my client and server policy is:
grant {
permission java.security.AllPermission;
};
Also when I try to run the server in terminal with:
java -Djava.security.policy="server.policy" src/engine/ComputeEngine.java
I got this error:
Error: Could not find or load main class src.engine.ComputeEngine.java
Please any help, I have spent many hours on the Internet in vain ??
ComputeEngine exception:
java.security.AccessControlException: access denied ("java.net.SocketPermission" "127.0.0.1:1099" "connect,resolve")
You are using a security manager and you haven't granted that permission in your .policy file.
I also have changed the VM Argument like this:
For the ComputeEngine (server):
-Djava.security.manager -Djava.rmi.server.codebase=file:/Users/name/Documents/workspace/PiComputationRM/src/compute/compute.jar -Djava.security.policy=/Users/name/Documents/workspace/PiComputationRM/server.policy
Several problems there:
a file: codebase isn't going to work unless it specifies a shared location that is visible by that name to the client and the Registry. This doesn't look like one of those.
you need to check whether that is the correct name for the policy file
you don't even need a security manager or policy in the server, unless the client is setting its own codebase and is going to provide classes to you. That doesn't happen in this example.
For the ComputePi (client):
-Djava.security.policy=/Users/name/Documents/workspace/PiComputationRM/client.policy
Double-check this name.
Also when I try to run the server in terminal with:
java -Djava.security.policy="server.policy" src/engine/ComputeEngine.java
I got this error:
Error: Could not find or load main class src.engine.ComputeEngine.java
Of course you did. You gave a compiler command to the JVM. Use the command provided in the tutorial. You don't name .java files to the JVM.
I have spent many hours on the Internet in vain
You should have been double-checking your work against the tutorial instead. You've misread the tutorial in at least two places.
I would also question whether you really need the codebase feature at all. I would start by removing it, and the security managers, altogether, and just get it working without them. It's too much of a complication for a first RMI project.

jnlp.BasicService.showDocument url permission denied with all-permissions and signed jar

I have an applet running in jnlp. My single jar file is signed. I accept the permissions prompt each time the JNLP client is launched. I can obtain the BasicService but it still throws a url permission denied exception when I try to follow a URI:
file:///D:\temp\test.txt
The file is present on all the Windows client machines I've tried and there are no security issues with opening it.
The issue happens when using a 32 or 64-bit JRE on the client. The server is 32-bit but I would think this irrelevant. The only clue (or red-herring perhaps) is that I get no security exception when the client and server are on the same host. If I use a remote client then I get the exception.
Whilst I needed to include the jnlp.jar file to compile the code, I assume it is not needed on the client if run using Java WebStart.
What else might you need to know? What else should I try?
Later that day...
Now this may or may not be a bug, it may be something wrong with the parameters in my jnlp file but I suspect that I'm using the wrong approach. Just to reitterate I'm trying to open a file:// url.
Here is what I am now doing:
I assumed that the Desktop facilities were only available in a Desktop Application - not an applet. I was wrong (and the documentation is scant - even on this hallowed site the only reference tells me to use JNLP Services for an Applet and Desktop for an Application) - Wrong (thankfully)
So you can use Desktop (having first checked that Desktop.isDesktopSupported() of course) in an applet - as long as you are running through WebStart not embedded as an applet.
I would propose the following approach to anyone.
See if Desktop is supported and use that.
Desktop.getDesktop().open(file);
If not then see if you can get the Basic JNLP Service.
BasicService bs = (BasicService)ServiceManager.lookup("javax.jnlp.BasicService");
and if that is available the use it with boolean openedOK = bs.showDocument(url);
Finally resort to the applet API.
AppletContext context = applet.getAppletContext();
context.showDocument(url, targetFrame);

Java - Access file with user authentication

I have a server where I work with a database and files using a java app.
When I start my app I give a report regarding file access to the server using:
public static boolean folderExists(String folderPath) {
File folderToCheck = new File(folderPath);
return folderToCheck.exists();
}
Every time I start my app (after a fresh restart of my computer)
I get a false response, even though the server is on.
The reason is because I must give an authentication as another user.
What I do is access the server through Windows
where I am being asked for username/password,
and after that I get a true response regarding file access to the server.
Is there a way to give the authentication username/password through Java,
and not through Windows?
Thank you
On Windows 'native' Java IO (e.g. java.io.File) always inherits the security context of the user running the JVM process. For example, you could run the Java app as a Windows service with the correct credentials.
The JCIFS project implements CIFS (the Windows SMB file server protocol) and allows you to directly specify the username/password.
See the API for examples.
I am pretty sure, that there is no way to grant fileaccess by java, without a Windows-Call.
You can call cacls file.log /e /t /p Everyone:f but this will be language-dependent.
I had a similar problem: How to change the file ACL in windows, if I only know the SID?
With Java7 there may be a way to do this.

Specifying remote codeBase for Java security policy

I have a client-side security policy, with a statement that grants permissions. I want to be able to specify it to grant the set of permissions for an RMI server only. For example this works:
grant{
//my permissions
};
But I cant figure out how to link the set of permissions so that they apply to my codebase on the server. Actually anything, as long as its tied to the server would be fine. I have tried:
grant codeBase "file://hostname/-"{
//my permissions
};
With the hostname being the name or IP of the machine, both with and w/o the port number. But this does not work, neither does using http instead of file. If I understand what I read so far correctly the hyphen at the end should apply the permissions to anything located on the server. Anyone know what I need to do to get this to work?
Thanks.
Heres the codebase specified when running the server:
-Djava.rmi.server.codebase=file://home/me/PageServer/build/classes/ pageserver.LoginService pageserver.PlannerService
Where is the local JVM getting the code that should be granted permissions?
If it's downloading the code from an HTTP codebase on the server, you can use a URL starting with "http:".
If it's local code, you can use a URL starting with "file:" and ending with a local path.
Disclaimer: I've written security files for Jini, which is built atop RMI, and it's been a few years. Apologies for anything I've missed.
Use a JAR for the codebase, and specify exactly the HTTP URL in the .policy file that you specified in -Djava.rmi.server.codebase.

Categories

Resources