changeset 1474:46128f71ec57

- Handle nested archive jars. - Use site address when checking for policy against CodeSource.
author Deepak Bhole <dbhole@redhat.com>
date Thu, 23 Apr 2009 14:35:50 -0400
parents 7c7835fceadc
children 03f65b9f0411
files ChangeLog rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java rt/net/sourceforge/jnlp/runtime/JNLPPolicy.java rt/net/sourceforge/jnlp/tools/JarSigner.java
diffstat 4 files changed, 84 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Apr 23 16:59:47 2009 +0200
+++ b/ChangeLog	Thu Apr 23 14:35:50 2009 -0400
@@ -1,3 +1,12 @@
+2009-04-23 Deepak Bhole <dbhole@redhat.com>
+
+	* rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: Handle nested
+	jars.
+	* rt/net/sourceforge/jnlp/runtime/JNLPPolicy.java: Use site address when
+	checking for policy against CodeSource.
+	* rt/net/sourceforge/jnlp/tools/JarSigner.java: Handle nested
+	jars.
+
 2009-04-23 Xerxes RĂ„nby <xerxes@zafena.se>
 
 	* ports/hotspot/src/share/vm/shark/sharkBuilder.cpp
--- a/rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Thu Apr 23 16:59:47 2009 +0200
+++ b/rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Thu Apr 23 14:35:50 2009 -0400
@@ -20,6 +20,7 @@
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -344,24 +345,7 @@
 
 				//user does not trust this publisher
 				if (!js.getAlreadyTrustPublisher()) {
-					if (!js.getRootInCacerts()) { //root cert is not in cacerts
-						boolean b = SecurityWarningDialog.showCertWarningDialog(
-							SecurityWarningDialog.AccessType.UNVERIFIED, file, js);
-						if (!b)
-							throw new LaunchException(null, null, R("LSFatal"), 
-								R("LCLaunching"), R("LNotVerified"), "");
-					} else if (js.getRootInCacerts()) { //root cert is in cacerts
-						boolean b = false;
-						if (js.noSigningIssues())
-							b = SecurityWarningDialog.showCertWarningDialog(
-									SecurityWarningDialog.AccessType.VERIFIED, file, js);
-						else if (!js.noSigningIssues())
-							b = SecurityWarningDialog.showCertWarningDialog(
-									SecurityWarningDialog.AccessType.SIGNING_ERROR, file, js);
-						if (!b)
-							throw new LaunchException(null, null, R("LSFatal"),
-								R("LCLaunching"), R("LCancelOnUserRequest"), "");
-					}
+				    checkTrustWithUser(js);
 				} else {
 					/**
 					 * If the user trusts this publisher (i.e. the publisher's certificate
@@ -379,6 +363,27 @@
         activateJars(initialJars);
     }
 
+    private void checkTrustWithUser(JarSigner js) throws LaunchException {
+        if (!js.getRootInCacerts()) { //root cert is not in cacerts
+            boolean b = SecurityWarningDialog.showCertWarningDialog(
+                SecurityWarningDialog.AccessType.UNVERIFIED, file, js);
+            if (!b)
+                throw new LaunchException(null, null, R("LSFatal"), 
+                    R("LCLaunching"), R("LNotVerified"), "");
+        } else if (js.getRootInCacerts()) { //root cert is in cacerts
+            boolean b = false;
+            if (js.noSigningIssues())
+                b = SecurityWarningDialog.showCertWarningDialog(
+                        SecurityWarningDialog.AccessType.VERIFIED, file, js);
+            else if (!js.noSigningIssues())
+                b = SecurityWarningDialog.showCertWarningDialog(
+                        SecurityWarningDialog.AccessType.SIGNING_ERROR, file, js);
+            if (!b)
+                throw new LaunchException(null, null, R("LSFatal"),
+                    R("LCLaunching"), R("LCancelOnUserRequest"), "");
+        }
+    }
+
     /**
      * Add applet's codebase URL.  This allows compatibility with
      * applets that load resources from their codebase instead of
@@ -505,8 +510,49 @@
                             
                             JarFile jarFile = new JarFile(localFile);
                             Enumeration e = jarFile.entries();
-                            while (e.hasMoreElements())
-                                jarEntries.add(((JarEntry) e.nextElement()).getName());
+                            while (e.hasMoreElements()) {
+                                
+                                JarEntry je = (JarEntry) e.nextElement();
+                                
+                                // another jar in my jar? it is more likely than you think  
+                                if (je.getName().endsWith(".jar")) {
+                                    // We need to extract that jar so that it can be loaded 
+                                    // (inline loading with "jar:..!/..." path will not work 
+                                    // with standard classloader methods)
+
+                                    String extractedJarLocation = localFile.getParent() + "/" + je.getName();
+                                    FileOutputStream extractedJar = new FileOutputStream(extractedJarLocation);
+                                    InputStream is = jarFile.getInputStream(je);
+
+                                    byte[] bytes = new byte[1024];
+                                    int read = is.read(bytes);
+                                    while (read > 0) {
+                                        extractedJar.write(bytes, 0, read);
+                                        read = is.read(bytes);
+                                    }
+
+                                    is.close();
+                                    extractedJar.close();
+
+                                    JarSigner signer = new JarSigner();
+                                    signer.verifyJar(extractedJarLocation);
+
+                                    if (signer.anyJarsSigned() && !signer.getAlreadyTrustPublisher()) {
+                                        checkTrustWithUser(signer);
+                                    }
+
+                                    try {
+                                        addURL(new URL("file://" + extractedJarLocation));
+                                    } catch (MalformedURLException mfue) {
+                                        if (JNLPRuntime.isDebug())
+                                            System.err.println("Unable to add extracted nested jar to classpath");
+
+                                        mfue.printStackTrace();
+                                    }
+                                }
+
+                                jarEntries.add(je.getName());
+                            }
 
                         }
 
--- a/rt/net/sourceforge/jnlp/runtime/JNLPPolicy.java	Thu Apr 23 16:59:47 2009 +0200
+++ b/rt/net/sourceforge/jnlp/runtime/JNLPPolicy.java	Thu Apr 23 14:35:50 2009 -0400
@@ -65,7 +65,8 @@
         		PermissionCollection clPermissions = cl.getPermissions(source);
         		
         		// systempolicy permissions need to be accounted for as well
-        		Enumeration e = systemPolicy.getPermissions(source).elements();
+        		CodeSource appletCS = new CodeSource(JNLPRuntime.getApplication().getJNLPFile().getSourceLocation(), (java.security.cert.Certificate[]) null);
+        		Enumeration e = systemPolicy.getPermissions(appletCS).elements();
                 while (e.hasMoreElements())
                     clPermissions.add((Permission) e.nextElement());
 
--- a/rt/net/sourceforge/jnlp/tools/JarSigner.java	Thu Apr 23 16:59:47 2009 +0200
+++ b/rt/net/sourceforge/jnlp/tools/JarSigner.java	Thu Apr 23 14:35:50 2009 -0400
@@ -218,7 +218,6 @@
 
                 String localFile = jarFile.getAbsolutePath();
                 boolean result = verifyJar(localFile);
-                checkTrustedCerts();
 
                 if (!result) {
                     //allVerified is true until we encounter a problem
@@ -241,6 +240,10 @@
         boolean hasUnsignedEntry = false;
         JarInputStream jis = null;
 
+        // certs could be uninitialized if one calls this method directly
+        if (certs == null)
+            certs = new ArrayList<CertPath>();
+        
         try {
             jis = new JarInputStream(new FileInputStream(jarName), true);
             Vector<JarEntry> entriesVec = new Vector<JarEntry>();
@@ -352,6 +355,9 @@
             }
         }
 
+        // check if the certs added above are in the trusted path
+        checkTrustedCerts();
+        
         //anySigned does not guarantee that all files were signed.
         return anySigned && !(hasUnsignedEntry || hasExpiredCert
                               || badKeyUsage || badExtendedKeyUsage || badNetscapeCertType