Need help finding cause of java.security.AccessControlException when rmi client attempts to connect to rmi server
Lenny Wintfeld <[email protected]> Wed, 30 May 2007 13:06:05 -0400
| Newsgroups | gmane.comp.java.sun.rmi |
|---|---|
| Message-ID | <[email protected]> |
Hi,
Please forgive the length of this post, I'm just trying to put in the
information that may be needed to help me solve my problem.
I'm trying to get the sample rmi program in the sun Core Java 2 (Volume
II) book to run. The client side rmi code runs great when it's on the
same host as the server (accessing thes server not using localhost but
using the actual ip address of the machine they're both running on).
But when attempting to run the client on a different host than the
server, I get "java.security.AccessControlException: access denied
(java.net.SocketPermission 192.168.45.105:1099 connect, resolve)" . To
eliminate as many causes as possible I confirmed the server's own
address at the server with ipconfig and it is 192.168.45.105. I also
probed the server (which is running Windows XP) from the linux client
machine with a netcat -v -w 1 -z 192.168.45.105 1099 and netcat
responds with "(UNKNOWN) [192.168.45.105] 1099 (rmiregistry) open"
which to me looks like the server is accessible from the client. I also
have the Windows firewall on the server opened for port 1099 for both
tcp and for udp.
My client side security policy file looks like:
grant
{
permission java.net.SocketPermission
"*:1024-65535","connect, resolve";
};
// "*:1024-65535","connect,accept,resolve,listen";
//permission java.security.AllPermission;
//permission java.net.SocketPermission "*", "accept, connect, listen,
resolve";
As you can see I've been fooling with various security entries, trying
to get the client to work remotely.
On the server side at various times the code has used and has not
created an instance of a security manager in attempt to get the client
and server to work together remotely (the books sample code doesn't use
a security manager at the server). The server code which runs under
eclipse has the following commandline entry for the VM:
-Djava.rmi.server.codebase="file://c:/eclipse/workspace2/TestRMIProductServer/bin/"
which is the base directory for where the server code is located (below
that is the package name and the .class files in the package directory).
I start the client from a remote putty bash session by simply entering
"java rmicl.ProductClient" from the parent directory of the the code's
package directory (which is rmicl). I've tried this from both my home
directory with the default ".java.policy" file in the /home/lenny
directory and from /root with ".java.policy" in /root.
I've looked at the sun rmi tutorial for some more guidance but don't
know what to apply from that to my specific situation. At this point I'm
plumb out of ideas and hope you can point me to what may be wrong or
missing from my set up or from my code that's preventing the client from
using the server when the client is remote.
Here for reference are the gory details. The client code is chock full
of lines used for debugging and some of them may have made diagnostic
output look a bit different than you'd normally see with just a stack dump.
Here is the client code
package rmicl;
import java.rmi.*;
import java.rmi.server.*;
import javax.naming.*;
import rmips.*;
public class ProductClient {
public static void main(String[] args)
{
System.setProperty("java.security.policy", "client.policy");
String ssp = System.getProperty("java.security.policy");
System.out.println("java security policy is " + ssp);
System.setSecurityManager(new RMISecurityManager());
SecurityManager sm = System.getSecurityManager();
try {
if(sm != null)
{
System.out.println("about to check connect permission\n");
sm.checkConnect("192.168.45.105", 1099);
}
} catch (RuntimeException e1) {
System.out.println("Uh Oh connect to 192.168.45.105 not permitted");
e1.printStackTrace();
}
//String url = "rmi://localhost/";
String url = "rmi://192.168.45.105/"; //url of a Product server
try {
Context namingContext = new InitialContext();
System.out.println("Got naming context");
Product c1 = (Product) namingContext.lookup(url+"drill");
System.out.println("Got c1");
Product c2 = (Product) namingContext.lookup(url+"mixer");
System.out.println("Got c2 context");
System.out.println(c1.getDesc());
System.out.println(c2.getDesc());
} catch (RemoteException e) {
// TODO Auto-generated catch block
System.out.println("Uh Oh - remote");
System.out.println(e.getMessage());
e.printStackTrace();
} catch (NamingException e) {
// TODO Auto-generated catch block
System.out.println("Uh Oh - naming ");
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Here is the diagnostic output from the console when the code above is
run on the linux machine remote from the server code:
java security policy is client.policy
about to check connect permission
Uh Oh connect to 192.168.45.105 not permitted
java.security.AccessControlException: access denied
(java.net.SocketPermission 192.168.45.105:1099 connect,resolve)
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.checkConnect(SecurityManager.java:1034)
at rmicl.ProductClient.main(ProductClient.java:26)
Got naming context
Exception in thread "main" java.security.AccessControlException: access
denied (java.net.SocketPermission 192.168.45.105:1099 connect,resolve)
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.checkConnect(SecurityManager.java:1034)
at java.net.Socket.connect(Socket.java:513)
at java.net.Socket.connect(Socket.java:469)
at java.net.Socket.<init>(Socket.java:366)
at java.net.Socket.<init>(Socket.java:179)
at
sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
at
sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569)
at
sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at
com.sun.jndi.rmi.registry.RegistryContext.lookup(RegistryContext.java:93)
at
com.sun.jndi.toolkit.url.GenericURLContext.lookup(GenericURLContext.java:185)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at rmicl.ProductClient.main(ProductClient.java:40)
Here is the server main with lots of lines commented out from when I was
doing various experiments trying to get it going (note the code that
I've sometimes had in place that declares a security manager at the
server end, even though that's not shown in the book) :
package rmips;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import javax.naming.*;
import java.util.*;
public class ProductServer {
/**
* @param args
*/
public static void main(String[] args)
{
try {
System.out.println("main() constructing server
implementations....");
ProductImpl p1 = new ProductImpl("Porter Drill");
ProductImpl p2 = new ProductImpl("Mixmaster");
//System.out.println("Setting up server security policy using
server.policy file in classfile directory");
//System.setProperty("java.security.policy", "server.policy");
//System.setSecurityManager(new RMISecurityManager());
System.out.println("main() Binding server implementations to
rmi registry...");
//This didn't work
//This works with
-Djava.rmi.server.codebase="file://c:/eclipse/workspace2/TestRMIProductServer/bin/"
in
//the vm commandline
Context namingContext = new InitialContext();
namingContext.bind("rmi:drill", p1);
namingContext.bind("rmi:mixer",p2);
System.out.println("Set for client calls to methods of the
product objects");
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NamingException e) {
// TODO Auto-generated catch block
System.out.println(e.getExplanation());
System.out.println(e.getLocalizedMessage());
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Finally here is the server.policy file which is used along with a server
security manager (if present) (it's in the same directory as the .class
files).
grant
{
//permission java.security.AllPermission;
permission java.net.SocketPermission
"*:1024-65535","accept,connect,listen,resolve";
};
I'd be happy to answer any questions about info I many have neglected to
include here. What else do I have to do to achieve this modest objective???
Thanks in advance for your help.
Lenny Wintfeld
CecilRep LLC
NYC
===========================================================================
To unsubscribe, send email to [email protected] and include in the body
of the message "signoff RMI-USERS". For general help, send email to
[email protected] and include in the body of the message "help".
For a list of frequently asked RMI questions please refer to:
http://java.sun.com/j2se/1.3/docs/guide/rmi/faq.html
To view past RMI-USERS postings, please see:
http://archives.java.sun.com/archives/rmi-users.html