I am having problems granting permissions to a URLClassLoader
that is executed
from as a signed application.
I have 3 java programs and 2 batch files as follows:
1. ReadFile.java that reads a file called
"c:\\testdata\\data".
2. WriteFile.java that writes to a file called
"c:\\testdata\\WriteFile.data".
3. Load.java located at d:\testsecurity\local subdirectory.
This program loads
ReadFile.class and WriteFile.class from a signed jar file
located at
"d:\testsecurity subdirectory.
4. build.bat which creates and digitally signs all three java
files mentioned above
5. run.bat
In addition I have my.policy which contains the different
permissions granted to all
three java files.
Every thing works fine when I use the following policy file:
//my.policy:
/* AUTOMATICALLY GENERATED ON Wed May 02 09:29:08 EDT 2001*/
/* DO NOT EDIT */
keystore "file:/d:/testsecurity/local/my.keyStore";
grant signedBy "Frank",codeBase "file://d:/TestSecurity/local/*"{
permission java.security.AllPermission;
};
grant signedBy "Laci",codeBase "file://d:/TestSecurity/*" {
permission java.io.FilePermission "C:\\TestData\\*", "read";
};
grant signedBy "Ted",codeBase "file://d:/TestSecurity/*" {
permission java.io.FilePermission "C:\\TestData\\*", "write";
};
BUT when I change line 7 from
permission java.security.AllPermission;
to
permission java.lang.RuntimePermission "createClassLoader";
I get two AccessControlException exception as follos:
Load.run(): Exception:java.security.AccessControlException:
access denied (java.io.FilePerm
ission \\d\testsecurity\sReadFile.jar read)
java.security.AccessControlException: access denied
(java.io.FilePermission \\d\testsecurit
y\sReadFile.jar read)
at
java.security.AccessControlContext.checkPermission(Unknown
Source)
at java.security.AccessController.checkPermission(Unknown
Source)
at java.lang.SecurityManager.checkPermission(Unknown
Source)
at java.lang.SecurityManager.checkRead(Unknown Source)
at java.io.File.isDirectory(Unknown Source)
at
sun.net.www.protocol.file.FileURLConnection.connect(Unknown
Source)
at
sun.net.www.protocol.file.Handler.openConnection(Unknown Source)
at java.net.URL.openConnection(Unknown Source)
at java.net.URLClassLoader.getPermissions(Unknown Source)
at
java.security.SecureClassLoader.getProtectionDomain(Unknown
Source)
at java.security.SecureClassLoader.defineClass(Unknown
Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native
Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at Load$LoadAndInstantiate.run(Load.java:54)
Load.run(): Exception:java.security.AccessControlException:
access denied (java.io.FilePerm
ission \\d\testsecurity\sWriteFile.jar read)
java.security.AccessControlException: access denied
(java.io.FilePermission \\d\testsecurit
y\sWriteFile.jar read)
at
java.security.AccessControlContext.checkPermission(Unknown
Source)
at java.security.AccessController.checkPermission(Unknown
Source)
at java.lang.SecurityManager.checkPermission(Unknown
Source)
at java.lang.SecurityManager.checkRead(Unknown Source)
at java.io.File.isDirectory(Unknown Source)
at
sun.net.www.protocol.file.FileURLConnection.connect(Unknown
Source)
at
sun.net.www.protocol.file.Handler.openConnection(Unknown Source)
at java.net.URL.openConnection(Unknown Source)
at java.net.URLClassLoader.getPermissions(Unknown Source)
at
java.security.SecureClassLoader.getProtectionDomain(Unknown
Source)
at java.security.SecureClassLoader.defineClass(Unknown
Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native
Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at Load$LoadAndInstantiate.run(Load.java:54)
MY QUESTION IS: What are the proper permissions that should be
granted to
a classloader,like that one I have in Load.java, in order for it
to work
properly.
The following are the complete codes for the java files and batch
files I used.
The first line indicated the name of the file
NOTE: I ran this under NT4.0 and used JDK1.2.2 and JDK1.3.0_02
and ended
with the same results.
============================================
// Load.java
import java.awt.event.KeyEvent;
import java.net.URL;
import java.net.URLClassLoader;
import java.lang.reflect.Constructor;
public class Load
{
public Load()
{
System.out.println("Load Constructor: about to Load
ReadFile class");
loadRemoteClass("ReadFile");
loadRemoteClass("WriteFile");
}
public static void main (String args[])
{
Load load = new Load();
}
private void loadRemoteClass(String className)
{
LoadAndInstantiate t1 =new
LoadAndInstantiate(className);
t1.start();
System.out.println("loadRemoteClass: Should have
instantiated dynamic class");
}
class LoadAndInstantiate extends Thread
{
String myUrlString, className;
public LoadAndInstantiate( String classNam)
{
super(classNam);
className = classNam;
}
public void run()
{
System.out.println("loadRemoteClass: " + className +
".class");
Class dynClass=null;
try
{
try
{
int urlSize = 2;
URL[] myUrl =new URL[urlSize];
myUrl[0] = new
URL("file://d:/testsecurity/sReadFile.jar");
myUrl[1] = new
URL("file://d:/testsecurity/sWriteFile.jar");
for (int i=0; i<urlSize; i++)
System.out.println("Looking in: "+myUrl[i]);
URLClassLoader urlLoader = new
URLClassLoader(myUrl);
dynClass = urlLoader.loadClass(className);
Constructor[] allTheConstructors =
dynClass.getConstructors();
Object dynObj = null;
dynObj = dynClass.newInstance();
System.out.println("created new instance
of " + dynObj.getClass());
}catch (Error ee)
{
System.out.println(">>Error with dynamic
class loading"+ee);
ee.printStackTrace();
if (ee instanceof
java.lang.NoClassDefFoundError)
{
this.sleep(1000);
System.out.println("Error
NoClassDefFoundError dynamic class loading"+ee);
}
}
}
catch (Exception e)
{
System.out.println("\n\nLoad.run(): Exception:" +
e);
e.printStackTrace();
}
}
}
}
============================================
//ReadFile.java
import java.io.*;
public class ReadFile
{
public ReadFile()
{
System.out.println("\nReadFile() Constructor........");
try{
countChars(new FileInputStream("c:\\testdata\\data")
);
}
catch(IOException e)
{
System.out.println("ReadFile(): IOException e= " +
e);
}
}
public void countChars(InputStream in) throws IOException
{
System.out.println("ReadFile Constructor");
int count = 0;
while (in.read() != -1)
count++;
System.out.println("Read: Counted " + count + " chars.
RRRRRRRRRRRRRRRRR");
}
}
============================================
//WriteFile.java
import java.io.*;
public class WriteFile
{
public WriteFile()
{
System.out.println("\nWriteFile() Constructor........");
String str = "this line was written by WriteFile.java";
writeToFile( "c:\\testdata\\WriteFile.data", str);
}
public void writeToFile(String fileName, String string)
{
try
{
PrintWriter out = new PrintWriter( new
FileWriter(fileName));
out.println(string);
out.close();
}
catch (IOException ioe)
{
System.out.println("IO error: " + ioe) ;
System.exit(-1) ;
}
System.out.println("WriteFile.writeToFile(): data is
written to \n" + fileName + " WWWWWWWWWWWWW");
}
}
============================================
REM build.bat
del *.jar
del *.class
del Frank.keystore
del Laci.keystore
del Ted.keystore
del my.keystore
del Frank.cer
del Laci.cer
del Ted.cer
javac Load.java
jar cvf Load.jar Load.class Load$LoadAndInstantiate.class
keytool -genkey -dname "cn=Frank, ou=orgUnit0, o=org0, l=Shelby0,
st=mi, c=us" -alias loadRec -keypass kpi135 -keystore
Frank.keyStore -storepass ab987c
jarsigner -keypass kpi135 -keystore Frank.keystore -storepass
ab987c -signedjar sLoad.jar Load.jar loadRec
keytool -export -keystore Frank.keyStore -storepass ab987c -alias
loadRec -file Frank.cer
keytool -import -alias Frank -file Frank.cer -keystore
my.keyStore -storepass myPassword
javac ReadFile.java
jar cvf ReadFile.jar ReadFile.class
keytool -genkey -dname "cn=Laci, ou=orgUnit1, o=org1, l=Shelby1,
st=mi, c=us" -alias ReadFileRec -keypass kpi135 -keystore
Laci.keyStore -storepass ab987c
jarsigner -keypass kpi135 -keystore Laci.keystore -storepass
ab987c -signedjar sReadFile.jar ReadFile.jar ReadFileRec
keytool -export -keystore Laci.keyStore -storepass ab987c -alias
ReadFileRec -file Laci.cer
keytool -import -alias Laci -file Laci.cer -keystore my.keyStore
-storepass myPassword
javac WriteFile.java
jar cvf WriteFile.jar WriteFile.class
keytool -genkey -dname "cn=Ted, ou=orgUnit2, o=org2, l=Shelby2,
st=mi, c=us" -alias WriteFileRec -keypass kpi135 -keystore
Ted.keyStore -storepass ab987c
jarsigner -keypass kpi135 -keystore Ted.keystore -storepass
ab987c -signedjar sWriteFile.jar WriteFile.jar WriteFileRec
keytool -export -keystore Ted.keyStore -storepass ab987c -alias
WriteFileRec -file Ted.cer
keytool -import -alias Ted -file Ted.cer -keystore my.keyStore
-storepass myPassword
copy sReadFile.jar d:\testsecurity
copy sWriteFile.jar d:\testsecurity
del sReadFile.jar
del sWriteFile.jar
del ReadFile.jar
del WriteFile.jar
del *.class
============================================
//my.policy:
/* AUTOMATICALLY GENERATED ON Wed May 02 09:29:08 EDT 2001*/
/* DO NOT EDIT */
keystore "file:/d:/testsecurity/local/my.keyStore";
grant signedBy "Frank",codeBase "file://d:/TestSecurity/local/*"{
permission java.lang.RuntimePermission "createClassLoader";
// permission java.security.AllPermission;
};
grant signedBy "Laci",codeBase "file://d:/TestSecurity/*" {
permission java.io.FilePermission "C:\\TestData\\*", "read";
};
grant signedBy "Ted",codeBase "file://d:/TestSecurity/*" {
permission java.io.FilePermission "C:\\TestData\\*", "write";
};
============================================
REM run.bat
java -Djava.security.manager -Djava.security.policy=my.policy -cp
sLoad.jar Load