[rfc][icedtea-web] Fix support for signed applets with sandbox permissions in manifest

Jiri Vanek jvanek at redhat.com
Wed Jun 18 16:01:02 UTC 2014


On 05/27/2014 06:23 PM, Andrew Azores wrote:
> Hi,
>
> This patch allows signed applets with sandbox permissions specified in their manifests to actually


How it is dealing with mixed (signed + unsigned code) apps?
> be run sandboxed. This is in contrast to the current behaviour where such applets will fail to
> launch, and the failure message presented asks the user to try launching via the Sandbox button next
> time. This was because the dialog which presented the Sandbox button appeared very early in the
> JNLPClassLoader's life cycle - early enough that no security settings had yet been set for the
> classloader or any of the applet's JAR locations - whereas the manifest checks were done later,
> after these settings would have already been initialized. Fixing the issue was not as simple as
> doing the manifest checks before presenting the security dialog because the dialog was presented
> part way through the initialization process, where JARs are being downloaded and checked for
> signing, so that the appropriate security dialog could be shown to the user. Putting the manifest
> checks first would therefore not work properly because the JARs were not yet available. This patch
> resolves the issue by moving the manifest checks inside the method which initializes the relevant
> security settings, such that the required resources are available, it is known what type of applet
> is about to be run, but the security settings for the JAR locations have not yet been initialized
> and the applet can thus still be set to run sandboxed safely.
>
> Additionally, the ManifestAttributesChecker check for the Permissions attribute is no longer skipped
> when Extended Applet Security is set to the Low level, since this allows for signed applets with
> Sandbox permissions specified in their manifests to run with full permissions when Low security is set.
>

Well this concept I do not like.

Imho the correct approach is to check the attributes, but do not take any actions (except print 
warnings eg "normally I would fail because of..,but low security is on".

With exception on sandbox attribute - here probably warning (strong one) requesting users attention.

  What do you think? - Well this dialogue would be good place for run in sandbox button too :)

Otherwise the only way how to disable manifest check willbe the deployment property which I added.

is your patch honoring this variable? - 
http://icedtea.classpath.org/hg/release/icedtea-web-1.5/rev/80e5f17e3bbc


> All existing reproducers have been run with this patch applied and there appears to be no effect.
> Manual tests from the wiki have also been run and no failures noted. Two new applets, reported in
> PR1767 [0], have been added as test cases to the wiki. These fail without the patch and pass with
> it. A reproducer is also included, however, the ALACA dialog will appear, which means manual
> intervention is required to run this test as well. The test is marked KnownToFail and this issue
> documented with the test case. This cannot be worked around by disabling manifest attributes
> checking since this would render the test meaningless as the Permissions manifest attribute would
> then not be run to force sandboxing.
>
> ChangeLog:
>
> 2014-05-27  Andrew Azores <aazores at redhat.com>
>
>      Fixed support for signed applets which specify the Permissions attribute
>      as "sandbox" in their manifests. These applets are now properly run
>      sandboxed automatically, rather than requiring the user to click the
>      "Sandbox" run button.
>      * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
>      (JNLPClassLoader): manifest attributes checking and security settings
>      moved inside initializeResources
>      (initializeResources): do not set entries in jarLocationSecurityMap until
>      after prompting the user on whether to run the applet as well as
>      performing manifest attribute checks
>      (initializeManifestAttributesChecker): new method
>      (getJnlpFileCodebase): new method, extracted from initializeResources
>      (SecurityDelegateImpl.setRunInSandbox): throw exception if already forced
>      to run in sandbox, rather than if already prompted
>      * netx/net/sourceforge/jnlp/runtime/ManifestAttributesChecker.java
>      (checkPermissionsAttribute): do not skip checking if Extended Applet
>      Security is Low. Remove try/catch on setRunInSandbox call as this is now
>      supported.
>      *
> tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/testcases/SignedAppletManifestSpecifiesSandboxTests.java:
>
>      new test case
>      *
> tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/resources/SignedAppletManifestSpecifiesSandbox.html:
>
>      same
>      * tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/MANIFEST.MF:
>      same
>      * tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/Makefile:
>      same
>      *
> tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/SignedAppletManifestSpecifiesSandbox.java:
>
>      same
>
>
> [0] http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1767
>
> Thanks,
>
> --
> Andrew A
>
>
> pr1769-4.patch
>
>
> diff --git a/ChangeLog b/ChangeLog
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,34 @@
> +2014-05-27  Andrew Azores<aazores at redhat.com>
> +
> +	Fixed support for signed applets which specify the Permissions attribute
> +	as "sandbox" in their manifests. These applets are now properly run
> +	sandboxed automatically, rather than requiring the user to click the
> +	"Sandbox" run button.
> +	* netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
> +	(JNLPClassLoader): manifest attributes checking and security settings
> +	moved inside initializeResources
> +	(initializeResources): do not set entries in jarLocationSecurityMap until
> +	after prompting the user on whether to run the applet as well as
> +	performing manifest attribute checks
> +	(initializeManifestAttributesChecker): new method
> +	(getJnlpFileCodebase): new method, extracted from initializeResources
> +	(SecurityDelegateImpl.setRunInSandbox): throw exception if already forced
> +	to run in sandbox, rather than if already prompted
> +	* netx/net/sourceforge/jnlp/runtime/ManifestAttributesChecker.java
> +	(checkPermissionsAttribute): do not skip checking if Extended Applet
> +	Security is Low. Remove try/catch on setRunInSandbox call as this is now
> +	supported.
> +	* tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/testcases/SignedAppletManifestSpecifiesSandboxTests.java:
> +	new test case
> +	* tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/resources/SignedAppletManifestSpecifiesSandbox.html:
> +	same
> +	* tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/MANIFEST.MF:
> +	same
> +	* tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/Makefile:
> +	same
> +	* tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/SignedAppletManifestSpecifiesSandbox.java:
> +	same
> +
>   2014-05-23  Jiri Vanek<jvanek at redhat.com>
>
>   	Fixed cache tests
> diff --git a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
> --- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
> +++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
> @@ -223,6 +223,8 @@ public class JNLPClassLoader extends URL
>
>       private final SecurityDelegate securityDelegate;
>
> +    private ManifestAttributesChecker mac;
> +
>       /**
>        * Create a new JNLPClassLoader from the specified file.
>        *
> @@ -275,18 +277,10 @@ public class JNLPClassLoader extends URL
>           initializeExtensions();
>
>           initializeResources();
> -
> -        //loading mainfests before resources are initialised may cause waiting for resources
> -        file.getManifestsAttributes().setLoader(this);
>
>           // initialize permissions
>           initializePermissions();
>
> -        setSecurity();

I'm wondering, setSecurity moved, but setPermissions remained?
> -
> -        ManifestAttributesChecker mac = new ManifestAttributesChecker(security, file, signing, securityDelegate);
> -        mac.checkAll();
> -
>           installShutdownHooks();
>
>
> @@ -592,14 +586,12 @@ public class JNLPClassLoader extends URL
>               //Check if main jar is found within extensions
>               foundMainJar = foundMainJar || hasMainInExtensions();
>
> +            setSecurity();
> +            initializeManifestAttributesChecker();
> +            mac.checkAll();
>               return;
>           }
> -        /*
> -        if (jars == null || jars.length == 0) {
> -                throw new LaunchException(null, null, R("LSFatal"),
> -                                    R("LCInit"), R("LFatalVerification"), "No jars!");
> -        }
> -        */

This should probably cam in as separate changset. Hmm.. When it was commented Out actually? :)
> +
>           List<JARDesc> initialJars = new ArrayList<JARDesc>();
>
>           for (JARDesc jar : jars) {
> @@ -711,7 +703,9 @@ public class JNLPClassLoader extends URL
>                   signing = SigningState.NONE;
>               }
>           }
> -
> +        setSecurity();
> +
> +        final Set<JARDesc> validJars = new HashSet<>();
>           boolean containsSignedJar = false, containsUnsignedJar = false;
>           for (JARDesc jarDesc : file.getResources().getJARs()) {
>               File cachedFile;
> @@ -729,14 +723,8 @@ public class JNLPClassLoader extends URL
>                   continue; // JAR not found. Keep going.
>               }
>
> -            final URL codebase;
> -            if (file.getCodeBase() != null) {
> -                codebase = file.getCodeBase();
> -            } else {
> -                // FIXME: codebase should be the codebase of the Main Jar not
> -                // the location. Although, it still works in the current state.
> -                codebase = file.getResources().getMainJAR().getLocation();
> -            }
> +            validJars.add(jarDesc);
> +            final URL codebase = getJnlpFileCodebase();
>
>               final SecurityDesc jarSecurity = securityDelegate.getCodebaseSecurityDesc(jarDesc, codebase.getHost());
>               if (jarSecurity.getSecurityType().equals(SecurityDesc.SANDBOX_PERMISSIONS)) {
> @@ -745,15 +733,45 @@ public class JNLPClassLoader extends URL
>                   containsSignedJar = true;
>               }
>
> -            jarLocationSecurityMap.put(jarDesc.getLocation(), jarSecurity);
> +            if (containsUnsignedJar && containsSignedJar) {
> +                break;
> +            }
>           }
>
>           if (containsSignedJar && containsUnsignedJar) {
>               checkPartialSigningWithUser();
>           }
>
> +        initializeManifestAttributesChecker();
> +        mac.checkAll();
> +
> +        for (JARDesc jarDesc : validJars) {

There I'm missing something. Why is this secoond field even needed?
In any case, please mention  it in changelog.
> +            final URL codebase = getJnlpFileCodebase();
> +            final SecurityDesc jarSecurity = securityDelegate.getCodebaseSecurityDesc(jarDesc, codebase.getHost());
> +            jarLocationSecurityMap.put(jarDesc.getLocation(), jarSecurity);
> +        }
> +
>           activateJars(initialJars);
>       }
> +
> +    private void initializeManifestAttributesChecker() throws LaunchException {
> +        if (mac == null) {
> +            file.getManifestsAttributes().setLoader(this);
> +            mac = new ManifestAttributesChecker(security, file, signing, securityDelegate);
> +        }
> +    }
> +
> +    private URL getJnlpFileCodebase() {
> +        final URL codebase;
> +        if (file.getCodeBase() != null) {
> +            codebase = file.getCodeBase();
> +        } else {
> +            // FIXME: codebase should be the codebase of the Main Jar not
> +            // the location. Although, it still works in the current state.
> +            codebase = file.getResources().getMainJAR().getLocation();
> +        }
> +        return codebase;
> +    }
>
>        /***
>        * Checks for the jar that contains the attribute.
> @@ -762,13 +780,12 @@ public class JNLPClassLoader extends URL
>        * @param  name attribute to be found
>        */
>       public String checkForAttributeInJars(List<JARDesc> jars, Attributes.Name name) {
> -
>           if (jars.isEmpty()) {
>               return null;
>           }
>
>           String result = null;
> -
> +
>           // Check main jar
>           JARDesc mainJarDesc = ResourcesDesc.getMainJAR(jars);
>           result = getManifestAttribute(mainJarDesc.getLocation(), name);
> @@ -776,7 +793,7 @@ public class JNLPClassLoader extends URL
>           if (result != null) {
>               return result;
>           }
> -
> +
>           // Check first jar
>           JARDesc firstJarDesc = jars.get(0);
>           result = getManifestAttribute(firstJarDesc.getLocation(),name);
> @@ -2380,12 +2397,15 @@ public class JNLPClassLoader extends URL
>           }
>
>           public void setRunInSandbox() throws LaunchException {
> -            if (promptedForSandbox || classLoader.security != null
> -                    || classLoader.jarLocationSecurityMap.size() != 0) {
> +            if (runInSandbox && classLoader.security != null
> +                    && classLoader.jarLocationSecurityMap.size() != 0) {

Why have this condition changed in thisway? I would expect
promptedForSandbox || runInSandbox || classLoader.security != null  && ...

>                   throw new LaunchException(classLoader.file, null, R("LSFatal"), R("LCInit"), R("LRunInSandboxError"), R("LRunInSandboxErrorInfo"));
>               }
>
> -            JNLPRuntime.reloadPolicy(); // ensure that we have the most up-to-date custom policy loaded
> +            // ensure that we have the most up-to-date custom policy loaded since the user may have just launched PolicyEditor
> +            // to create a custom policy for the applet they are about to run
> +            JNLPRuntime.reloadPolicy();
> +

can go in with the removal of the coment above

>               this.promptedForSandbox = true;
>               this.runInSandbox = true;
>           }
> diff --git a/netx/net/sourceforge/jnlp/runtime/ManifestAttributesChecker.java b/netx/net/sourceforge/jnlp/runtime/ManifestAttributesChecker.java
> --- a/netx/net/sourceforge/jnlp/runtime/ManifestAttributesChecker.java
> +++ b/netx/net/sourceforge/jnlp/runtime/ManifestAttributesChecker.java
> @@ -178,15 +178,19 @@ public class ManifestAttributesChecker {
>        *http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/security/manifest.html#permissions
>        */
>       private void checkPermissionsAttribute() throws LaunchException {
> -        final ManifestBoolean sandboxForced = file.getManifestsAttributes().isSandboxForced();
> -        final AppletSecurityLevel itwSecurityLevel = AppletStartupSecuritySettings.getInstance().getSecurityLevel();
> -        if (itwSecurityLevel == AppletSecurityLevel.ALLOW_UNSIGNED || securityDelegate.getRunInSandbox()) {
> -            OutputController.getLogger().log(OutputController.Level.WARNING_ALL, "Although 'permissions' attribute of this application is '" + file.getManifestsAttributes().permissionsToString()
> -                    + "' Your Extended applets security is at 'low', or you have specifically chosen to run the applet Sandboxed. Continuing");
> +        if (securityDelegate.getRunInSandbox()) {
> +            OutputController.getLogger().log(OutputController.Level.WARNING_ALL, "The 'Permissions' attribute of this application is '" + file.getManifestsAttributes().permissionsToString()
> +                    + "'. You have chosen the Sandbox run option, which overrides the Permissions manifest attribute.");
>               return;
>           }
>
> +        final ManifestBoolean sandboxForced = file.getManifestsAttributes().isSandboxForced();
> +        // If the attribute is not specified in the manifest, prompt the user. Oracle's spec says that the
> +        // attribute is required, but this breaks a lot of existing applets. Therefore, when on the highest
> +        // security level, we refuse to run these applets. On the standard security level, we ask. And on the
> +        // lowest security level, we simply proceed without asking.

I like this ;)

>           if (sandboxForced == ManifestBoolean.UNDEFINED) {
> +            final AppletSecurityLevel itwSecurityLevel = AppletStartupSecuritySettings.getInstance().getSecurityLevel();
>               if (itwSecurityLevel == AppletSecurityLevel.DENY_UNSIGNED) {
>                   throw new LaunchException("Your Extended applets security is at 'Very high', and this application is missing the 'permissions' attribute in manifest. This is fatal");
>               }
> @@ -196,9 +200,9 @@ public class ManifestAttributesChecker {
>                       throw new LaunchException("Your Extended applets security is at 'high' and this application is missing the 'permissions' attribute in manifest. And you have refused to run it.");
>                   } else {
>                       OutputController.getLogger().log("Your Extended applets security is at 'high' and this application is missing the 'permissions' attribute in manifest. And you have allowed to run it.");
> -                    return;
>                   }
>               }
> +            return;
>           }
>
>           final RequestedPermissionLevel requestedPermissions = file.getRequestedPermissionLevel();
> @@ -206,15 +210,7 @@ public class ManifestAttributesChecker {
>           if (file instanceof PluginBridge) { // HTML applet
>               if (isNoneOrDefault(requestedPermissions)) {
>                   if (sandboxForced == ManifestBoolean.TRUE && signing != SigningState.NONE) {
> -                    //http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/security/manifest.html#permissions
> -                    // FIXME: attempting to follow the spec, but it is too late now to actually set the applet
> -                    // to run in sandbox. If we do this the applet will not be run at all, rather than run sandboxed!
> -                    try {
> -                        securityDelegate.setRunInSandbox();
> -                    } catch (final LaunchException e) {
> -                        OutputController.getLogger().log(e);
> -                        throw new LaunchException("The applet is signed but its manifest specifies Sandbox permissions. This is not yet supported. Try running the applet again, but choose the Sandbox run option.", e);
> -                    }
> +                    securityDelegate.setRunInSandbox();
>                   }
>               }
>           } else { // JNLP
>
>




diff --git a/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/MANIFEST.MF 
b/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/MANIFEST.MF
new file mode 100644
--- /dev/null
+++ b/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/MANIFEST.MF
@@ -0,0 +1,2 @@
+Main-Class: SignedAppletManifestSpecifiesSandbox
+Permissions: sandbox


Do we  have/need also one with  Permissions: all-permissions ? I recall there is something...


diff --git a/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/Makefile 
b/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/Makefile
new file mode 100644
--- /dev/null
+++ b/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/Makefile
@@ -0,0 +1,34 @@
+TESTNAME=SignedAppletManifestSpecifiesSandbox
+
+SRC_FILES=SignedAppletManifestSpecifiesSandbox.java
+ENTRYPOINT_CLASSES=SignedAppletManifestSpecifiesSandbox
+
+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 MANIFEST.MF $(TMPDIR) ; \
+
+	cp ../resources/* $(REPRODUCERS_TESTS_SERVER_DEPLOYDIR); \
+
+	cd $(TMPDIR); \
+	$(JAR) cfm SignedAppletManifestSpecifiesSandbox.jar MANIFEST.MF 
SignedAppletManifestSpecifiesSandbox.class ; \
+	cd -; \
+
+	$(JARSIGNER_CMD) -sigfile Alpha $(TMPDIR)/SignedAppletManifestSpecifiesSandbox.jar 
$(TEST_CERT_ALIAS)_signed; \
+
+	cp $(TMPDIR)/SignedAppletManifestSpecifiesSandbox.jar $(REPRODUCERS_TESTS_SERVER_DEPLOYDIR); \
+
+	echo PREPARED REPRODUCER $(TESTNAME), removing $(TMPDIR); \
+	rm -rf $(TMPDIR); \
+
+clean-reproducer:
+	echo NOTHING TO CLEAN FOR $(TESTNAME)


Why do you need custom reproducers? The manifest is handled by engine



diff --git 
a/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/SignedAppletManifestSpecifiesSandbox.java 
b/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/SignedAppletManifestSpecifiesSandbox.java
new file mode 100644
--- /dev/null
+++ 
b/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/srcs/SignedAppletManifestSpecifiesSandbox.java
@@ -0,0 +1,58 @@
+/* SignedAppletManifestSpecifiesSandbox.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.
+ */
+
+import java.applet.Applet;
+
+public class SignedAppletManifestSpecifiesSandbox extends Applet {
+
+    @Override
+    public void init() {
+        System.out.println("SignedAppletManifestSpecifiesSandbox applet starting");
+        System.out.println("Reading user.home: " + getProp("user.home"));
+        System.out.println("*** APPLET FINISHED ***");
+    }
+
+    private static String getProp(final String key) {
+        try {
+            return System.getProperty(key);
+        } catch (final SecurityException se) {
+            se.printStackTrace();
+            return "SECURITY EXCEPTION";
+        }
+    }
+
+}
diff --git 
a/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/testcases/SignedAppletManifestSpecifiesSandboxTests.java 
b/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/testcases/SignedAppletManifestSpecifiesSandboxTests.java
new file mode 100644
--- /dev/null
+++ 
b/tests/reproducers/custom/SignedAppletManifestSpecifiesSandbox/testcases/SignedAppletManifestSpecifiesSandboxTests.java
@@ -0,0 +1,77 @@
+/* SignedAppletManifestSpecifiesSandboxTests.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.
+ */
+
+import net.sourceforge.jnlp.ProcessResult;
+import net.sourceforge.jnlp.ServerAccess;
+import net.sourceforge.jnlp.ServerAccess.AutoClose;
+import net.sourceforge.jnlp.annotations.Bug;
+import net.sourceforge.jnlp.annotations.KnownToFail;
+import net.sourceforge.jnlp.annotations.NeedsDisplay;
+import net.sourceforge.jnlp.annotations.TestInBrowsers;
+import net.sourceforge.jnlp.browsertesting.BrowserTest;
+import net.sourceforge.jnlp.browsertesting.Browsers;
+import net.sourceforge.jnlp.closinglisteners.AutoOkClosingListener;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class SignedAppletManifestSpecifiesSandboxTests extends BrowserTest {
+
+    private static final String STARTING_STRING = "SignedAppletManifestSpecifiesSandbox applet 
starting";
+    private static final String CLOSE_STRING = AutoOkClosingListener.MAGICAL_OK_CLOSING_STRING;
+    private static final String EXPECTED_STDOUT_PRINT = "SECURITY EXCEPTION";
+    private static final String STACKTRACE_EX_TYPE = "AccessControlException";
+
+    /*
+     * As of the writing of this test, it fails due to the ALACA dialog appearing during its run, which
+     * means manual intervention is required for this test's applet to run.
+     */
+    @KnownToFail
+    @Test
+    @NeedsDisplay
+    @TestInBrowsers(testIn={Browsers.one})
+    @Bug(id="PR1769")
+    public void testSignedAppletWithSandboxPermissionsInManifestLaunch() throws Exception {
+        final ProcessResult pr = server.executeBrowser("SignedAppletManifestSpecifiesSandbox.html", 
new AutoOkClosingListener(), null);
+        assertTrue("Applet should have initialized", pr.stdout.contains(STARTING_STRING));
+        assertTrue("Applet should have printed SECURITY EXCEPTION", 
pr.stdout.contains(EXPECTED_STDOUT_PRINT));
+        assertTrue("Applet should have produced an AccessControlException stacktrace", 
pr.stderr.contains(STACKTRACE_EX_TYPE));
+        assertTrue("Applet should have printed its exit string", pr.stdout.contains(CLOSE_STRING));
+    }
+}

As this test is already known to fail, it can go (after manifest is resolved)  in as independent 
changeset.


Thankyou very much for this!

J.



More information about the distro-pkg-dev mailing list