ant-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bode...@apache.org
Subject svn commit: r796702 - in /ant/core/trunk: WHATSNEW src/etc/testcases/core/antclassloader.xml src/main/org/apache/tools/ant/AntClassLoader.java src/tests/junit/org/apache/tools/ant/AntClassLoaderTest.java
Date Wed, 22 Jul 2009 13:17:17 GMT
Author: bodewig
Date: Wed Jul 22 13:17:16 2009
New Revision: 796702

URL: http://svn.apache.org/viewvc?rev=796702&view=rev
Log:
properly set CodeSource when loading classes.  PR 20174

Modified:
    ant/core/trunk/WHATSNEW
    ant/core/trunk/src/etc/testcases/core/antclassloader.xml
    ant/core/trunk/src/main/org/apache/tools/ant/AntClassLoader.java
    ant/core/trunk/src/tests/junit/org/apache/tools/ant/AntClassLoaderTest.java

Modified: ant/core/trunk/WHATSNEW
URL: http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=796702&r1=796701&r2=796702&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Wed Jul 22 13:17:16 2009
@@ -410,7 +410,10 @@
 
  * The default stylesheets for <junitreport> failed to properly escape
    XML content in exception stack traces.
-   Bugzilla Report 39492
+   Bugzilla Report 39492.
+
+ * AntClassLoader didn't set the proper CodeSource for loaded classes.
+   Bugzilla Report 20174.
 
 Other changes:
 --------------

Modified: ant/core/trunk/src/etc/testcases/core/antclassloader.xml
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/etc/testcases/core/antclassloader.xml?rev=796702&r1=796701&r2=796702&view=diff
==============================================================================
--- ant/core/trunk/src/etc/testcases/core/antclassloader.xml (original)
+++ ant/core/trunk/src/etc/testcases/core/antclassloader.xml Wed Jul 22 13:17:16 2009
@@ -67,4 +67,9 @@
       </jar>
     </target>
 
+    <target name="signTestJar" depends="prepareGetPackageTest">
+      <signjar alias="testonly" keystore="../testkeystore"
+               storepass="apacheant" jar="${tmp.dir}/test.jar"/>
+    </target>
+
 </project>

Modified: ant/core/trunk/src/main/org/apache/tools/ant/AntClassLoader.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/AntClassLoader.java?rev=796702&r1=796701&r2=796702&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/AntClassLoader.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/AntClassLoader.java Wed Jul 22 13:17:16 2009
@@ -27,6 +27,9 @@
 import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.security.CodeSource;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -37,6 +40,7 @@
 import java.util.Locale;
 import java.util.jar.Attributes;
 import java.util.jar.Attributes.Name;
+import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
 import java.util.zip.ZipEntry;
@@ -1116,11 +1120,17 @@
     protected Class defineClassFromData(File container, byte[] classData, String classname)
             throws IOException {
         definePackage(container, classname);
-        // XXX should instead make a new ProtectionDomain with a CodeSource
-        // corresponding to container.toURI().toURL() and the same
-        // PermissionCollection as Project.class.protectionDomain had
-        return defineClass(classname, classData, 0, classData.length, Project.class
-                .getProtectionDomain());
+        ProtectionDomain currentPd = Project.class.getProtectionDomain();
+        String classResource = getClassFilename(classname);
+        CodeSource src = new CodeSource(FILE_UTILS.getFileURL(container),
+                                        getCertificates(container,
+                                                        classResource));
+        ProtectionDomain classesPd =
+            new ProtectionDomain(src, currentPd.getPermissions(),
+                                 this,
+                                 currentPd.getPrincipals());
+        return defineClass(classname, classData, 0, classData.length,
+                           classesPd);
     }
 
     /**
@@ -1180,6 +1190,41 @@
     }
 
     /**
+     * Get the certificates for a given jar entry, if it is indeed a jar.
+     *
+     * @param container the File from which to read the entry
+     * @param entry the entry of which the certificates are requested
+     *
+     * @return the entry's certificates or null is the container is
+     *         not a jar or it has no certificates.
+     *
+     * @exception IOException if the manifest cannot be read.
+     */
+    private Certificate[] getCertificates(File container, String entry)
+        throws IOException {
+        if (container.isDirectory()) {
+            return null;
+        }
+        JarFile jarFile = null;
+        InputStream is = null;
+        try {
+            jarFile = new JarFile(container);
+            JarEntry ent = jarFile.getJarEntry(entry);
+            if (ent != null) {
+                // must read the input in order to obtain certificates
+                is = jarFile.getInputStream(ent);
+                while (is.read() >= 0);
+            }
+            return ent == null ? null : ent.getCertificates();
+        } finally {
+            FileUtils.close(is);
+            if (jarFile != null) {
+                jarFile.close();
+            }
+        }
+    }
+
+    /**
      * Define the package information when the class comes from a
      * jar with a manifest
      *

Modified: ant/core/trunk/src/tests/junit/org/apache/tools/ant/AntClassLoaderTest.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/apache/tools/ant/AntClassLoaderTest.java?rev=796702&r1=796701&r2=796702&view=diff
==============================================================================
--- ant/core/trunk/src/tests/junit/org/apache/tools/ant/AntClassLoaderTest.java (original)
+++ ant/core/trunk/src/tests/junit/org/apache/tools/ant/AntClassLoaderTest.java Wed Jul 22
13:17:16 2009
@@ -28,6 +28,7 @@
 public class AntClassLoaderTest extends BuildFileTest {
 
     private Project p;
+    private AntClassLoader loader;
 
     public AntClassLoaderTest(String name) {
         super(name);
@@ -41,6 +42,9 @@
     }
 
     public void tearDown() {
+        if (loader != null) {
+            loader.cleanup();
+        }
         getProject().executeTarget("cleanup");
     }
     //test inspired by bug report 37085
@@ -50,8 +54,8 @@
         Path myPath = new Path(getProject());
         myPath.setLocation(new File(mainjarstring));
         getProject().setUserProperty("build.sysclasspath","ignore");
-        AntClassLoader myLoader = getProject().createClassLoader(myPath);
-        String path = myLoader.getClasspath();
+        loader = getProject().createClassLoader(myPath);
+        String path = loader.getClasspath();
         assertEquals(mainjarstring + File.pathSeparator + extjarstring, path);
     }
     public void testJarWithManifestInNonAsciiDir() {
@@ -60,13 +64,13 @@
         Path myPath = new Path(getProject());
         myPath.setLocation(new File(mainjarstring));
         getProject().setUserProperty("build.sysclasspath","ignore");
-        AntClassLoader myLoader = getProject().createClassLoader(myPath);
-        String path = myLoader.getClasspath();
+        loader = getProject().createClassLoader(myPath);
+        String path = loader.getClasspath();
         assertEquals(mainjarstring + File.pathSeparator + extjarstring, path);
     }
     public void testCleanup() throws BuildException {
         Path path = new Path(p, ".");
-        AntClassLoader loader = p.createClassLoader(path);
+        loader = p.createClassLoader(path);
         try {
             // we don't expect to find this
             loader.findClass("fubar");
@@ -105,12 +109,44 @@
         myPath.setLocation(new File(getProject().getProperty("tmp.dir")
                                     + "/test.jar"));
         getProject().setUserProperty("build.sysclasspath","ignore");
-        AntClassLoader loader = getProject().createClassLoader(myPath);
+        loader = getProject().createClassLoader(myPath);
         assertNotNull("should find class", loader.findClass("org.example.Foo"));
         assertNotNull("should find package",
                       new GetPackageWrapper(loader).getPackage("org.example"));
     }
 
+    public void testCodeSource() throws Exception {
+        executeTarget("prepareGetPackageTest");
+        Path myPath = new Path(getProject());
+        myPath.setLocation(new File(getProject().getProperty("tmp.dir")
+                                    + "/test.jar"));
+        getProject().setUserProperty("build.sysclasspath","ignore");
+        loader = getProject().createClassLoader(myPath);
+        Class foo = loader.findClass("org.example.Foo");
+        String codeSourceLocation =
+            foo.getProtectionDomain().getCodeSource().getLocation().toString();
+        assertTrue(codeSourceLocation + " should point to test.jar",
+                   codeSourceLocation.endsWith("test.jar"));
+    }
+
+    public void testSignedJar() throws Exception {
+        executeTarget("signTestJar");
+        File jar = new File(getProject().getProperty("tmp.dir")
+                            + "/test.jar");
+
+        Path myPath = new Path(getProject());
+        myPath.setLocation(jar);
+        getProject().setUserProperty("build.sysclasspath","ignore");
+        loader = getProject().createClassLoader(myPath);
+        Class foo = loader.findClass("org.example.Foo");
+
+        assertNotNull("should find class", foo);
+        assertNotNull("should have certificates",
+                      foo.getProtectionDomain().getCodeSource()
+                      .getCertificates());
+        assertNotNull("should be signed", foo.getSigners());
+    }
+
     private static class GetPackageWrapper extends ClassLoader {
         GetPackageWrapper(ClassLoader parent) {
             super(parent);



Mime
View raw message