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

Andrew Azores aazores at redhat.com
Wed Jun 18 17:44:50 UTC 2014


On 06/18/2014 12:01 PM, Jiri Vanek wrote:
> 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?

I don't have any examples of mixed signing apps with a Permissions 
manifest attribute, but a reproducer could be prepared for this case.

>> 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.

Sure. I just *really* am not comfortable with leaving it as-is, which 
means Low Security allows applets to be silently granted elevated 
permissions. I can imagine this too easily being abused by a malicious 
applet developer. I'm fine with adding an extra prompt here when on Low 
Security though, warning the user that due to the Low Security the 
applet may be granted elevated permissions if it is run.

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

Yes. That part of ManifestAttributesChecker has not been touched. If 
that deployment attribute is false then the MAC still skips the checks 
entirely.

>
>
>> 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?

You mean initializePermissions? Yea, it didn't have to be moved.

>> -
>> -        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? :)

December 2010...

>> +
>>           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.

Which second field? "mac"?

>> +            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  && ...

The ClassLoader can end up attempting to automatically set the applet to 
run in sandbox multiple times, so that condition would cause it to fail 
in this situation. The condition was very strong before on purpose 
because it was easily possible for the security settings to have already 
been applied before the sandboxing option appeared to the user. Now, the 
sandboxing dialog appears well beforehand, and automatic sandboxing also 
happens early enough, so this condition has to be slightly weakened so 
that it does allow the call to be performed multiple times, but only if 
the security settings have not yet been applied to the 
classloader/applet. I haven't tested this but this condition should also 
work fine:

runInSandbox && (classLoader.security != null || 
jarLocationSecurityMap.size() != 0)

The classLoader.security and jarLocationSecurityMap conditions should 
really always be "in sync" with each other in this regard though.

>
>>                   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...

I don't think so, but maybe there is. I couldn't find anything with a 
quick grep.

>
>
> 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

Ah, I forgot about this. Although a custom reproducer would still be 
needed for the mixed signing case, so I can convert this one to mixed 
and make normal "simple" and "signed" ones as well I suppose.

>
>
>
> 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.
>

Thanks,
-- 
Andrew Azores


More information about the distro-pkg-dev mailing list