/hg/icedtea-web: Codebase-loading signed applet fixes

aazores at icedtea.classpath.org aazores at icedtea.classpath.org
Thu Feb 27 11:35:52 PST 2014


changeset 1fb5b82415ce in /hg/icedtea-web
details: http://icedtea.classpath.org/hg/icedtea-web?cmd=changeset;node=1fb5b82415ce
author: Andrew Azores <aazores at redhat.com>
date: Thu Feb 27 14:35:41 2014 -0500

	Codebase-loading signed applet fixes

	* netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: treat signed
	applets which load from the codebase as partially signed, and fix
	regression with signed applets loading main-classes from codebase
	* tests/reproducers/custom/SignedAppletCodebaseLoading/resources/SignedAppletCodebaseLoading.html:
	new test to ensure that signed applets with codebase loading can run
	* tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/Makefile
	* tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/SignedAppletCodebaseLoading.java
	* tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/SignedAppletCodebaseLoadingHelper.java
	* tests/reproducers/custom/SignedAppletCodebaseLoading/testcases/SignedAppletCodebaseLoadingTests.java
	* tests/reproducers/custom/SignedAppletExternalMainClass/resources/SignedAppletExternalMainClass.html:
	new test to ensure that signed applets with codebase-loaded main-classes
	can run
	* tests/reproducers/custom/SignedAppletExternalMainClass/srcs/Makefile
	* tests/reproducers/custom/SignedAppletExternalMainClass/srcs/SignedAppletExternalMainClass.java
	* tests/reproducers/custom/SignedAppletExternalMainClass/srcs/SignedAppletExternalMainClassHelper.java
	* tests/reproducers/custom/SignedAppletExternalMainClass/testcases/SignedAppletExternalMainClassTest.java


diffstat:

 ChangeLog                                                                                               |  19 +
 netx/net/sourceforge/jnlp/Launcher.java                                                                 |   6 +-
 netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java                                                  |  96 +++++++--
 tests/reproducers/custom/SignedAppletCodebaseLoading/resources/SignedAppletCodebaseLoading.html         |  52 +++++
 tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/Makefile                                      |  33 +++
 tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/SignedAppletCodebaseLoading.java              |  50 +++++
 tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/SignedAppletCodebaseLoadingHelper.java        |  47 ++++
 tests/reproducers/custom/SignedAppletCodebaseLoading/testcases/SignedAppletCodebaseLoadingTests.java    |  83 ++++++++
 tests/reproducers/custom/SignedAppletExternalMainClass/resources/SignedAppletExternalMainClass.html     |  49 +++++
 tests/reproducers/custom/SignedAppletExternalMainClass/srcs/Makefile                                    |  27 ++
 tests/reproducers/custom/SignedAppletExternalMainClass/srcs/SignedAppletExternalMainClass.java          |  49 +++++
 tests/reproducers/custom/SignedAppletExternalMainClass/srcs/SignedAppletExternalMainClassHelper.java    |  42 ++++
 tests/reproducers/custom/SignedAppletExternalMainClass/testcases/SignedAppletExternalMainClassTest.java |  78 ++++++++
 13 files changed, 602 insertions(+), 29 deletions(-)

diffs (truncated from 858 to 500 lines):

diff -r ab3055c30fc7 -r 1fb5b82415ce ChangeLog
--- a/ChangeLog	Wed Feb 26 11:29:13 2014 +0100
+++ b/ChangeLog	Thu Feb 27 14:35:41 2014 -0500
@@ -1,3 +1,22 @@
+2014-02-27  Andrew Azores  <aazores at redhat.com>
+
+	* netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: treat signed
+	applets which load from the codebase as partially signed, and fix
+	regression with signed applets loading main-classes from codebase
+	* tests/reproducers/custom/SignedAppletCodebaseLoading/resources/SignedAppletCodebaseLoading.html:
+	new test to ensure that signed applets with codebase loading can run
+	* tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/Makefile
+	* tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/SignedAppletCodebaseLoading.java
+	* tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/SignedAppletCodebaseLoadingHelper.java
+	* tests/reproducers/custom/SignedAppletCodebaseLoading/testcases/SignedAppletCodebaseLoadingTests.java
+	* tests/reproducers/custom/SignedAppletExternalMainClass/resources/SignedAppletExternalMainClass.html:
+	new test to ensure that signed applets with codebase-loaded main-classes
+	can run
+	* tests/reproducers/custom/SignedAppletExternalMainClass/srcs/Makefile
+	* tests/reproducers/custom/SignedAppletExternalMainClass/srcs/SignedAppletExternalMainClass.java
+	* tests/reproducers/custom/SignedAppletExternalMainClass/srcs/SignedAppletExternalMainClassHelper.java
+	* tests/reproducers/custom/SignedAppletExternalMainClass/testcases/SignedAppletExternalMainClassTest.java
+
 2014-02-21  Jiri Vanek  <jvanek at redhat.com>
 
 	* acinclude.m4: added (IT_CHECK_XULRUNNER_API_VERSION_CONSTCHAR) macro,
diff -r ab3055c30fc7 -r 1fb5b82415ce netx/net/sourceforge/jnlp/Launcher.java
--- a/netx/net/sourceforge/jnlp/Launcher.java	Wed Feb 26 11:29:13 2014 +0100
+++ b/netx/net/sourceforge/jnlp/Launcher.java	Thu Feb 27 14:35:41 2014 -0500
@@ -707,7 +707,7 @@
     protected  AppletInstance createApplet(JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
          AppletInstance appletInstance = null;
          try {
-            JNLPClassLoader loader = JNLPClassLoader.getInstance(file, updatePolicy);
+            JNLPClassLoader loader = JNLPClassLoader.getInstance(file, updatePolicy, enableCodeBase);
 
             if (enableCodeBase) {
                 loader.enableCodeBase();
@@ -754,7 +754,7 @@
      */
     protected Applet createAppletObject(JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
         try {
-            JNLPClassLoader loader = JNLPClassLoader.getInstance(file, updatePolicy);
+            JNLPClassLoader loader = JNLPClassLoader.getInstance(file, updatePolicy, enableCodeBase);
 
             if (enableCodeBase) {
                 loader.enableCodeBase();
@@ -777,7 +777,7 @@
      */
     protected ApplicationInstance createApplication(JNLPFile file) throws LaunchException {
         try {
-            JNLPClassLoader loader = JNLPClassLoader.getInstance(file, updatePolicy);
+            JNLPClassLoader loader = JNLPClassLoader.getInstance(file, updatePolicy, false);
             ThreadGroup group = Thread.currentThread().getThreadGroup();
 
             ApplicationInstance app = new ApplicationInstance(file, group, loader);
diff -r ab3055c30fc7 -r 1fb5b82415ce netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Wed Feb 26 11:29:13 2014 +0100
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Thu Feb 27 14:35:41 2014 -0500
@@ -222,13 +222,15 @@
      */
     private int useCount = 0;
 
+    private boolean enableCodeBase = false;
+
     /**
      * Create a new JNLPClassLoader from the specified file.
      *
      * @param file the JNLP file
      */
     protected JNLPClassLoader(JNLPFile file, UpdatePolicy policy) throws LaunchException {
-        this(file, policy, null);
+        this(file, policy, null, false);
     }
 
     /**
@@ -238,7 +240,7 @@
      * @param policy the UpdatePolicy for this class loader
      * @param mainName name of the application's main class
      */
-    protected JNLPClassLoader(JNLPFile file, UpdatePolicy policy, String mainName) throws LaunchException {
+    protected JNLPClassLoader(JNLPFile file, UpdatePolicy policy, String mainName, boolean enableCodeBase) throws LaunchException {
         super(new URL[0], JNLPClassLoader.class.getClassLoader());
 
         OutputController.getLogger().log("New classloader: " + file.getFileLocation());
@@ -251,6 +253,8 @@
 
         this.mainClass = mainName;
 
+        this.enableCodeBase = enableCodeBase;
+
         //as it is harmless, we can set is as soon as possible.
         file.getManifestsAttributes().setLoader(this);
         
@@ -264,6 +268,10 @@
 
         jcv = new JarCertVerifier(verifier);
 
+        if (this.enableCodeBase) {
+            addToCodeBaseLoader(this.file.getCodeBase());
+        }
+
         // initialize extensions
         initializeExtensions();
 
@@ -379,10 +387,10 @@
      * @param policy the update policy to use when downloading resources
      * @param mainName Overrides the main class name of the application
      */
-    private static JNLPClassLoader createInstance(JNLPFile file, UpdatePolicy policy, String mainName) throws LaunchException {
+    private static JNLPClassLoader createInstance(JNLPFile file, UpdatePolicy policy, String mainName, boolean enableCodeBase) throws LaunchException {
         String uniqueKey = file.getUniqueKey();
         JNLPClassLoader baseLoader = uniqueKeyToLoader.get(uniqueKey);
-        JNLPClassLoader loader = new JNLPClassLoader(file, policy, mainName);
+        JNLPClassLoader loader = new JNLPClassLoader(file, policy, mainName, enableCodeBase);
 
         // If security level is 'high' or greater, we must check if the user allows unsigned applets 
         // when the JNLPClassLoader is created. We do so here, because doing so in the constructor 
@@ -419,8 +427,8 @@
      * @param file the file to load classes for
      * @param policy the update policy to use when downloading resources
      */
-    public static JNLPClassLoader getInstance(JNLPFile file, UpdatePolicy policy) throws LaunchException {
-        return getInstance(file, policy, null);
+    public static JNLPClassLoader getInstance(JNLPFile file, UpdatePolicy policy, boolean enableCodeBase) throws LaunchException {
+        return getInstance(file, policy, null, enableCodeBase);
     }
 
     /**
@@ -430,7 +438,7 @@
      * @param policy the update policy to use when downloading resources
      * @param mainName Overrides the main class name of the application
      */
-    public static JNLPClassLoader getInstance(JNLPFile file, UpdatePolicy policy, String mainName) throws LaunchException {
+    public static JNLPClassLoader getInstance(JNLPFile file, UpdatePolicy policy, String mainName, boolean enableCodeBase) throws LaunchException {
         JNLPClassLoader baseLoader = null;
         JNLPClassLoader loader = null;
         String uniqueKey = file.getUniqueKey();
@@ -444,12 +452,12 @@
                     (file.isApplication() && 
                      !baseLoader.getJNLPFile().getFileLocation().equals(file.getFileLocation()))) {
 
-                loader = createInstance(file, policy, mainName);
+                loader = createInstance(file, policy, mainName, enableCodeBase);
             } else {
                 // if key is same and locations match, this is the loader we want
                 if (!file.isApplication()) {
                     // If this is an applet, we do need to consider its loader
-                    loader = new JNLPClassLoader(file, policy, mainName);
+                    loader = new JNLPClassLoader(file, policy, mainName, enableCodeBase);
 
                     if (baseLoader != null)
                         baseLoader.merge(loader);
@@ -477,7 +485,7 @@
      * @param policy the update policy to use when downloading resources
      * @param mainName Overrides the main class name of the application
      */
-    public static JNLPClassLoader getInstance(URL location, String uniqueKey, Version version,ParserSettings settings, UpdatePolicy policy, String mainName)
+    public static JNLPClassLoader getInstance(URL location, String uniqueKey, Version version, ParserSettings settings, UpdatePolicy policy, String mainName, boolean enableCodeBase)
             throws IOException, ParseException, LaunchException {
 
         JNLPClassLoader loader;
@@ -488,7 +496,7 @@
             if (loader == null || !location.equals(loader.getJNLPFile().getFileLocation())) {
                 JNLPFile jnlpFile = new JNLPFile(location, uniqueKey, version, settings, policy);
 
-                loader = getInstance(jnlpFile, policy, mainName);
+                loader = getInstance(jnlpFile, policy, mainName, enableCodeBase);
             }
         }
 
@@ -521,7 +529,7 @@
         for (ExtensionDesc ext : extDescs) {
             try {
                 String uniqueKey = this.getJNLPFile().getUniqueKey();
-                JNLPClassLoader loader = getInstance(ext.getLocation(), uniqueKey, ext.getVersion(), file.getParserSettings(), updatePolicy, mainClass);
+                JNLPClassLoader loader = getInstance(ext.getLocation(), uniqueKey, ext.getVersion(), file.getParserSettings(), updatePolicy, mainClass, this.enableCodeBase);
                 loaderList.add(loader);
             } catch (Exception ex) {
                 OutputController.getLogger().log(OutputController.Level.ERROR_ALL, ex);
@@ -716,8 +724,8 @@
 
                 // If externalAppletMainClass is true and a LaunchException was not thrown above,
                 // then the main-class can be loaded from the applet codebase, but is obviously not signed
-                if (!jcv.allJarsSigned() || externalAppletMainClass) {
-                    signing = SigningState.PARTIAL;
+                if (!jcv.allJarsSigned()) {
+                    checkPartialSigningWithUser();
                 }
 
                 // If main jar was found, but a signed JNLP file was not located
@@ -796,11 +804,7 @@
         }
 
         if (containsSignedJar && containsUnsignedJar) {
-            signing = SigningState.PARTIAL;
-        }
-
-        if (signing == SigningState.PARTIAL && JNLPRuntime.isVerifying()) {
-            checkNotAllSignedWithUser(file);
+            checkPartialSigningWithUser();
         }
 
         activateJars(initialJars);
@@ -1099,11 +1103,11 @@
     }
 
     /**
-     * Prompt the user to proceed on applets with mixed signing.
+     * Display a dialog prompting the user to proceed on applets with mixed signing.
      * @param file the JNLPFile or PluginBridge describing the applet/application to be launched
      * @throws LaunchException if the user does not approve the prompt
      */
-    private void checkNotAllSignedWithUser(JNLPFile file) throws LaunchException {
+    private void showNotAllSignedDialog(JNLPFile file) throws LaunchException {
         if (JNLPRuntime.isTrustAll()) {
             return;
         }
@@ -1947,6 +1951,29 @@
         return signing == SigningState.FULL;
     }
 
+    /**
+     * Call this when it's suspected that an applet's permission level may have
+     * just changed from Full Signing to Partial Signing.
+     * This will display a one-time prompt asking the user to confirm running
+     * the partially signed applet.
+     * Partially Signed applets always start off as appearing to be Fully
+     * Signed, and then during the initialization or loading process, we find
+     * that we actually need to demote the applet to Partial, either due to
+     * finding that not all of its JARs are actually signed, or because it
+     * needs to load something unsigned out of the codebase.
+     */
+    private void checkPartialSigningWithUser() {
+        if (signing == SigningState.FULL && JNLPRuntime.isVerifying()) {
+            signing = SigningState.PARTIAL;
+            try {
+                showNotAllSignedDialog(this.file);
+            } catch (LaunchException e) {
+                throw new RuntimeException("The signed applet required loading of unsigned code from the codebase, "
+                        + "which the user refused", e);
+            }
+        }
+    }
+
     protected SecurityDesc getSecurity() {
         return security;
     }
@@ -2321,8 +2348,16 @@
 
     /*
      * Helper class to expose protected URLClassLoader methods.
+     * Classes loaded from the codebase are absolutely NOT signed, by definition!
+     * If the CodeBaseClassLoader is used to load any classes in JNLPClassLoader,
+     * then you *MUST* check if the JNLPClassLoader is set to FULL signing. If so,
+     * then it must be set instead to PARTIAL, and the user prompted if it is okay
+     * to proceed. If the JNLPClassLoader is already PARTIAL or NONE signing, then
+     * nothing must be done. This is required so that we can support partial signing
+     * of applets but also ensure that using codebase loading in conjunction with
+     * signed JARs still results in the user having to confirm that this is
+     * acceptable.
      */
-
     public static class CodeBaseClassLoader extends URLClassLoader {
 
         JNLPClassLoader parentJNLPClassLoader;
@@ -2342,17 +2377,21 @@
             super.addURL(url); 
         }
 
-        Class<?> findClassNonRecursive(String name) throws ClassNotFoundException {
+        /*
+         * Use with care! Check the class-level Javadoc before calling this.
+         */
+        Class<?> findClassNonRecursive(final String name) throws ClassNotFoundException {
             // If we have searched this path before, don't try again
             if (Arrays.equals(super.getURLs(), notFoundResources.get(name)))
                 throw new ClassNotFoundException(name);
 
             try {
-                final String fName = name;
                 return AccessController.doPrivileged(
                         new PrivilegedExceptionAction<Class<?>>() {
                             public Class<?> run() throws ClassNotFoundException {
-                                return CodeBaseClassLoader.super.findClass(fName);
+                                Class<?> c = CodeBaseClassLoader.super.findClass(name);
+                                parentJNLPClassLoader.checkPartialSigningWithUser();
+                                return c;
                             }
                         }, parentJNLPClassLoader.getAccessControlContextForClassLoading());
             } catch (PrivilegedActionException pae) {
@@ -2364,10 +2403,15 @@
             }
         }
 
+        /*
+         * Use with care! Check the class-level Javadoc before calling this.
+         */
         @Override
         public Class<?> findClass(String name) throws ClassNotFoundException {
             // Calls JNLPClassLoader#findClass which may call into this.findClassNonRecursive
-            return getParentJNLPClassLoader().findClass(name);
+            Class<?> c = getParentJNLPClassLoader().findClass(name);
+            parentJNLPClassLoader.checkPartialSigningWithUser();
+            return c;
         }
 
         /**
diff -r ab3055c30fc7 -r 1fb5b82415ce tests/reproducers/custom/SignedAppletCodebaseLoading/resources/SignedAppletCodebaseLoading.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/custom/SignedAppletCodebaseLoading/resources/SignedAppletCodebaseLoading.html	Thu Feb 27 14:35:41 2014 -0500
@@ -0,0 +1,52 @@
+<!--
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+IcedTea is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+
+ -->
+<html>
+  <head></head>
+  <body>
+    <applet code="signed.SignedAppletCodebaseLoading.class"
+            archive="SignedAppletCodebaseLoading.jar"
+            codebase="."
+            width="640"
+            height="480">
+      <script language="javascript" type="text/javascript">
+          var testName = window.location.search.substring(1);
+          document.write("<param name='testName' value='" + testName + "'>");
+      </script>
+    </applet>
+  </body>
+</html>
diff -r ab3055c30fc7 -r 1fb5b82415ce tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/Makefile	Thu Feb 27 14:35:41 2014 -0500
@@ -0,0 +1,33 @@
+TESTNAME=SignedAppletCodebaseLoading
+
+SRC_FILES=SignedAppletCodebaseLoading.java SignedAppletCodebaseLoadingHelper.java
+
+JAVAC_CLASSPATH=$(TEST_EXTENSIONS_DIR):$(NETX_DIR)/lib/classes.jar
+JAVAC=$(BOOT_DIR)/bin/javac
+JAR=$(BOOT_DIR)/bin/jar
+JARSIGNER=$(BOOT_DIR)/bin/jarsigner
+JARSIGNER_CMD=$(JARSIGNER) -keystore $(TOP_BUILD_DIR)/$(PRIVATE_KEYSTORE_NAME) -storepass $(PRIVATE_KEYSTORE_PASS) -keypass $(PRIVATE_KEYSTORE_PASS)
+
+TMPDIR:=$(shell mktemp -d)
+
+prepare-reproducer:
+	echo PREPARING REPRODUCER $(TESTNAME)
+
+	$(JAVAC) -d $(TMPDIR) -classpath $(JAVAC_CLASSPATH) $(SRC_FILES); \
+
+	cp ../resources/* $(REPRODUCERS_TESTS_SERVER_DEPLOYDIR); \
+
+	cd $(TMPDIR); \
+	$(JAR) cfe SignedAppletCodebaseLoading.jar signed.SignedAppletCodebaseLoading signed; \
+	cd -; \
+
+	$(JARSIGNER_CMD) -sigfile Alpha $(TMPDIR)/SignedAppletCodebaseLoading.jar $(TEST_CERT_ALIAS)_signed; \
+
+	cp $(TMPDIR)/SignedAppletCodebaseLoading.jar $(REPRODUCERS_TESTS_SERVER_DEPLOYDIR); \
+	cp -r $(TMPDIR)/helper $(REPRODUCERS_TESTS_SERVER_DEPLOYDIR); \
+
+	echo PREPARED REPRODUCER $(TESTNAME), removing $(TMPDIR); \
+	rm -rf $(TMPDIR); \
+
+clean-reproducer:
+	echo NOTHING TO CLEAN FOR $(TESTNAME)
diff -r ab3055c30fc7 -r 1fb5b82415ce tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/SignedAppletCodebaseLoading.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/SignedAppletCodebaseLoading.java	Thu Feb 27 14:35:41 2014 -0500
@@ -0,0 +1,50 @@
+/* SignedAppletCodebaseLoading.java
+Copyright (C) 2014 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+ */
+
+package signed;
+import helper.SignedAppletCodebaseLoadingHelper;
+import java.applet.Applet;
+
+public class SignedAppletCodebaseLoading extends Applet {
+
+    @Override
+    public void start() {
+        System.out.println(SignedAppletCodebaseLoadingHelper.getMessage());
+        System.out.println("*** APPLET FINISHED ***");
+    }
+
+}
diff -r ab3055c30fc7 -r 1fb5b82415ce tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/SignedAppletCodebaseLoadingHelper.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/reproducers/custom/SignedAppletCodebaseLoading/srcs/SignedAppletCodebaseLoadingHelper.java	Thu Feb 27 14:35:41 2014 -0500
@@ -0,0 +1,47 @@
+/* SignedAppletCodebaseLoadingHelper.java
+Copyright (C) 2014 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+ */
+
+package helper;
+import signed.SignedAppletCodebaseLoading;
+
+public class SignedAppletCodebaseLoadingHelper {


More information about the distro-pkg-dev mailing list