changeset 264:a0b951436a6d

PR794: IcedTea-Web does not work if a Web Start app jar has a Class-Path element in the manifest.
author Deepak Bhole <dbhole@redhat.com>
date Wed, 28 Sep 2011 15:28:14 -0400
parents 0a1733685325
children 3352c0b0d9bb
files ChangeLog NEWS netx/net/sourceforge/jnlp/runtime/CachedJarFileCallback.java netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
diffstat 4 files changed, 104 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Sep 23 12:14:39 2011 -0400
+++ b/ChangeLog	Wed Sep 28 15:28:14 2011 -0400
@@ -1,3 +1,14 @@
+2011-09-28  Deepak Bhole <dbhole@redhat.com>
+
+	PR794: IcedTea-Web does not work if a Web Start app jar has a Class-Path
+	element in the manifest.
+	* netx/net/sourceforge/jnlp/runtime/CachedJarFileCallback.java
+	(retrieve): Blank out the Class-Path elements in manifest.
+	* netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
+	(activateJars): Only load Class-Path elements if this is an applet.
+	(addNewJar): Add the right permissions for the cached jar file and verify
+	signatures. 
+
 2011-09-23  Omair Majid  <omajid@redhat.com>
 
 	RH738814: Access denied at ssl handshake
--- a/NEWS	Fri Sep 23 12:14:39 2011 -0400
+++ b/NEWS	Wed Sep 28 15:28:14 2011 -0400
@@ -11,6 +11,8 @@
 New in release 1.1.3 (2011-XX-XX):
 * Plugin
   - PR782: Support building against npapi-sdk as well
+* Common
+  - PR794: IcedTea-Web does not work if a Web Start app jar has a Class-Path element in the manifest
 
 New in release 1.1.2 (2011-08-31):
 * Plugin
--- a/netx/net/sourceforge/jnlp/runtime/CachedJarFileCallback.java	Fri Sep 23 12:14:39 2011 -0400
+++ b/netx/net/sourceforge/jnlp/runtime/CachedJarFileCallback.java	Wed Sep 28 15:28:14 2011 -0400
@@ -94,7 +94,24 @@
 
         if (UrlUtils.isLocalFile(localUrl)) {
             // if it is known to us, just return the cached file
-            return new JarFile(localUrl.getPath());
+            JarFile returnFile = new JarFile(localUrl.getPath());
+            
+            try {
+                
+                // Blank out the class-path because:
+                // 1) Web Start does not support it
+                // 2) For the plug-in, we want to cache files from class-path so we do it manually
+                returnFile.getManifest().getMainAttributes().putValue("Class-Path", "");
+
+                if (JNLPRuntime.isDebug()) {
+                    System.err.println("Class-Path attribute cleared for " + returnFile.getName());
+                }
+
+            } catch (NullPointerException npe) {
+                // Discard NPE here. Maybe there was no manifest, maybe there were no attributes, etc.
+            }
+
+            return returnFile;
         } else {
             // throw new IllegalStateException("a non-local file in cache");
             return null;
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Fri Sep 23 12:14:39 2011 -0400
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Wed Sep 28 15:28:14 2011 -0400
@@ -32,6 +32,7 @@
 import java.security.PermissionCollection;
 import java.security.Permissions;
 import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
@@ -779,7 +780,11 @@
 
                             JarFile jarFile = new JarFile(localFile.getAbsolutePath());
                             Manifest mf = jarFile.getManifest();
-                            classpaths.addAll(getClassPathsFromManifest(mf, jar.getLocation().getPath()));
+
+                            if (file instanceof PluginBridge) {
+                                classpaths.addAll(getClassPathsFromManifest(mf, jar.getLocation().getPath()));
+                            }
+
                             JarIndex index = JarIndex.getJarIndex(jarFile, null);
                             if (index != null)
                                 jarIndexes.add(index);
@@ -1094,7 +1099,7 @@
      * is downloaded.
      * @param desc the JARDesc for the new jar
      */
-    private void addNewJar(JARDesc desc) {
+    private void addNewJar(final JARDesc desc) {
 
         available.add(desc);
 
@@ -1104,10 +1109,72 @@
                 JNLPRuntime.getDefaultUpdatePolicy()
                 );
 
-        URL remoteURL = desc.getLocation();
-        URL cachedUrl = tracker.getCacheURL(remoteURL);
-        addURL(remoteURL);
-        CachedJarFileCallback.getInstance().addMapping(remoteURL, cachedUrl);
+        // Give read permissions to the cached jar file
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                Permission p = CacheUtil.getReadPermission(desc.getLocation(),
+                        desc.getVersion());
+
+                resourcePermissions.add(p);
+
+                return null;
+            }
+        });
+
+        final URL remoteURL = desc.getLocation();
+        final URL cachedUrl = tracker.getCacheURL(remoteURL); // blocks till download
+
+        available.remove(desc); // Resource downloaded. Remove from available list.
+        
+        try {
+
+            // Verify if needed
+
+            final JarSigner signer = new JarSigner();
+            final List<JARDesc> jars = new ArrayList<JARDesc>();
+            jars.add(desc);
+
+            // Decide what level of security this jar should have
+            // The verification and security setting functions rely on 
+            // having AllPermissions as those actions normally happen
+            // during initialization. We therefore need to do those 
+            // actions as privileged.
+
+            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+                public Void run() throws Exception {
+                    signer.verifyJars(jars, tracker);
+
+                    if (signer.anyJarsSigned() && !signer.getAlreadyTrustPublisher()) {
+                        checkTrustWithUser(signer);
+                    }
+
+                    final SecurityDesc security;
+                    if (signer.anyJarsSigned()) {
+                        security = new SecurityDesc(file,
+                                SecurityDesc.ALL_PERMISSIONS,
+                                file.getCodeBase().getHost());
+                    } else {
+                        security = new SecurityDesc(file,
+                                SecurityDesc.SANDBOX_PERMISSIONS,
+                                file.getCodeBase().getHost());
+                    }
+
+                    jarLocationSecurityMap.put(remoteURL, security);
+
+                    return null;
+                }
+            });
+
+            addURL(remoteURL);
+            CachedJarFileCallback.getInstance().addMapping(remoteURL, cachedUrl);
+
+        } catch (Exception e) {
+            // Do nothing. This code is called by loadClass which cannot 
+            // throw additional exceptions. So instead, just ignore it. 
+            // Exception => jar will not get added to classpath, which will 
+            // result in CNFE from loadClass.
+            e.printStackTrace();
+        }
     }
 
     /**