previous chapter table of contents next chapter


An activatable service runs within a JVM started by rmid . It does so with the same user identity as rmid , so if rmid is run by, say, the superuser root on a Unix system, then all activatable services will run with that same user ID, root . This is a security flaw, as any user on that system can write and start an activatable service, and then write and run a client that makes calls on the service. This is a way to run programs with superuser privileges from an arbitrary user.

My own machine has only a few users, and all of them I trust not to write deliberately malicious programs (and right now, I am the only one who can write Jini services). However, most people may not be in such a fortunate position. Consequently, rmid should be run in such a way that even if it is attacked , it will not be able to do any damage.

On Unix, there are two ways of reducing the risk:

  • Run rmid as a harmless user, such as user nobody . This can be done by changing rmid to be setuid to this user. Note that the program rmid in the Java bin directory is actually a shell script that eventually calls a program such as bin/i386/green_threads/rmid , and it is this program that needs to have the setuid bit set.
  • Use the chroot mechanism to run rmid in a subdirectory that appears to be the top-level directory '/' . This will make all other files invisible to rmid .

setuid is the description of the Unix mechanism for changing the apparent user of a program. Unix performs this change when the setuid bit is set in the file permissions of the program. This can be added by the Unix command chmod +s program .

Since the attack can only come from someone who already has an account on the machine, the setuid method is probably good enough, and it is certainly simpler to set up than chroot .

On an NT system, rmid should be set up so that it only runs under general user access rights.

rmid and JDK 1.3

The security problems of the last section have been partly addressed by a tighter security mechanism introduced in JDK 1.3. These restrict what activatable services can do by using a security mechanism that is under the control of whoever starts rmid . This means that there has to be cooperation between the person who starts rmid and the person who starts an activatable service that will use rmid .

The simplest mechanism is to just turn the new security system off. This was discussed briefly in Chapter 3, and it means running rmid with an additional argument:

 rmid -J-Dsun.rmi.activation.execPolicy=none 

All that rmid then checks is that any activatable service that registers with it is started on the same machine as rmid . This is the weak security mechanism in the JDK 1.2 version of rmid , which assumes that users on the same machine pose no security risks.

The default new mechanism can also be set explicitly:

 rmid -J-Dsun.rmi.activation.execPolicy=default 

This requires an additional security policy file that will be used by rmid , and the location of this policy file is also given on the command line for rmid . For example, the following command will start rmid using the new default mechanism with the policy file set to /usr/local/jini1_1/rmid.policy:

 rmid -J-Djava.security.policy=/usr/local/jini1_1/rmid.policy 

The policy file used by rmid is a standard JDK 1.2 policy file, and it grants permissions to do various things. For rmid , the main permission that has to be granted is to use the various options of the activation commands. Granting option permissions is done using the com.sun.rmi.rmid.ExecOptionPermission permission.

For example, reggie is an activatable service. To run this on my system, I use this command:

 java -jar /usr/local/jini1_1/lib/reggie.jar \           http://jannote.dstc.edu.au:8080/reggie-dl.jar\           /usr/local/jini1_1/example/lookup/policy \           /tmp/reggie_log public 

To run this with the JDK 1.3 rmid , I need to place the following in the security policy file:

 grant {     permission com.sun.rmi.rmid.ExecOptionPermission         "/usr/local/jini1_1/lib/reggie.jar";     permission com.sun.rmi.rmid.ExecOptionPermission         "-Djava.rmi.server.codebase=http://jannote.dstc.edu.au:8080/reggie-dl.jar\     permission com.sun.rmi.rmid.ExecOptionPermission         "-Djava.security.policy=/usr/local/jini1_1/example/lookup/policy";     permission com.sun.rmi.rmid.ExecOptionPermission "-cp"; }; 

The permissions granted are, in turn:

  1. The jar file that contains the main application class. This distinguishes reggie from other activation services.
  2. The HTTP address of the class files used in the implementation.
  3. The security policy file used by reggie .

Unless all three match, rmid will not run reggie . Wildcards can be used, but this will reduce the amount of security that rmid has over the activatable services it looks after.

You may have noticed that there is a mismatch between the command I type to get reggie running and the contents of the policy file. Not all of the command line arguments I type are in the policy file. For example, what has happened to the /tmp/reggie_log argument?

Well, arguments like /usr/local/jini1_1/example/lookup/policy are property overrides that are defined to the JVM in the form -D= , as shown here:


On the other hand, the argument /tmp/reggie_log is just a simple command line argument and not a property override at all. The property overrides need to go in the policy file, but the ordinary command line arguments do not.

So do you have to go through each argument in turn, to decide if it is a property? No, that would be too tedious . Instead, you start with an empty policy file, start rmid , and then start an activa

table service such as reggie . Generally, this will fail with an exception message such as this:

 Unable to invoke by reflection, the method: com.sun.jini.reggie.CreateLookup.create. An exception was thrown by the invoked method. java.lang.reflect.InvocationTargetException: java.rmi.activation.ActivateFailedEx- ception: failed to activate object; nested exception is:         java.security.AccessControlException: access denied (com.sun.rmi.rmid.Exec- OptionPermission -Djava.security.policy=/usr/local/jini1_1/example/lookup/policy) java.security.AccessControlException: access denied (com.sun.rmi.rmid.ExecOption- Permission -Djava.security.policy=/usr/local/jini1_1/example/lookup/policy) 

In this exception message is the phrase "com.sun.rmi.rmid.ExecOptionPermission -Djava.security.policy=/usr/local/jini1_1/example/lookup/policy." The person who wants to run reggie must communicate this information to the person who controls rmid so that they can place this information in the rmid policy file.

You'll need to go through this process a few times to build up the complete set of permissions for reggie . That's tedious too but there isn't any other way. The document http://developer.java.sun.com/developer/products/jini/execpolicy.html gives policy files for the Jini services reggie , mahalo , and FrontEndSpace .

There is a third choice in mechanisms, and that is to specify an object that will be used to establish the security access, but that is beyond the scope of this chapter. It is discussed in the JDK 1.3 documentation for rmid .


A Programmer[ap]s Guide to Jini Technology
A Programmer[ap]s Guide to Jini Technology
ISBN: 1893115801
Year: 2000
Pages: 189

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net