changeset 957:ede0279b5c53

Applets can be granted temporary permissions from security dialogs Applets can be temporarily granted permission levels above fully sandboxed but below all-permission * netx/net/sourceforge/jnlp/resources/Messages.properties: (STempPermNoFile, STempPermNoNetwork, STempPermNoExec, STempPermNoFileOrNetwork, STempPermNoExecOrNetwork, STempPermNoFileOrExec, STempPermNoFileOrNetworkOrExec, STempAllMedia, STempSoundOnly, STempClipboardOnly, STempPrintOnly, STempAllFileAndPropertyAccess, STempReadLocalFilesAndProperties, STempReflectionOnly): new messages * netx/net/sourceforge/jnlp/security/SecurityDialog.java: (installPanel) pass SecurityDelegate to partially signed dialog * netx/net/sourceforge/jnlp/security/SecurityDialogs.java: (showPartiallySignedWarningDialog) added SecutityDelegate param for message extras * netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java: (checkPartiallySignedWithUserIfRequired) added SecurityDelegate param * netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java: (createPolicyPermissionsMenu, PolicyEditorLaunchListener, PolicyEditorPopupListener) removed in favour of TemporaryPermissionsButton * netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java: same * netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningDialog.java: (partiallySigned) SecurityDelegate param * netx/net/sourceforge/jnlp/security/policyeditor/PermissionActions.java: (DELETE, READLINK, FILE_ALL) new actions. (rawActions, rawString) can retrieve raw String representation of the action * netx/net/sourceforge/jnlp/security/policyeditor/PermissionTarget.java: (USER_HOME, TMPDIR) grant permissions to entire directory, not only children * netx/net/sourceforge/jnlp/security/policyeditor/PolicyEditorPermissions.java: (DELETE_LOCAL_FILES, DELETE_TMP_FILES) new permissions. (Group.WriteFileSystem) added DELETE* permissions * nests/netx/unit/net/sourceforge/jnlp/security/policyeditor/PolicyEditorParsingTest.java: update for change in PermissionTarget * netx/net/sourceforge/jnlp/security/dialogs/TemporaryPermissions.java: new class * netx/net/sourceforge/jnlp/security/dialogs/TemporaryPermissionsButton.java: new class
author Andrew Azores <aazores@redhat.com>
date Thu, 27 Mar 2014 11:08:09 -0400
parents b4631fce293a
children e9f222be36b5
files ChangeLog netx/net/sourceforge/jnlp/resources/Messages.properties netx/net/sourceforge/jnlp/security/SecurityDialog.java netx/net/sourceforge/jnlp/security/SecurityDialogs.java netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java netx/net/sourceforge/jnlp/security/dialogs/TemporaryPermissions.java netx/net/sourceforge/jnlp/security/dialogs/TemporaryPermissionsButton.java netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningDialog.java netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java netx/net/sourceforge/jnlp/security/policyeditor/PermissionActions.java netx/net/sourceforge/jnlp/security/policyeditor/PermissionTarget.java netx/net/sourceforge/jnlp/security/policyeditor/PolicyEditorPermissions.java tests/netx/unit/net/sourceforge/jnlp/security/policyeditor/PolicyEditorParsingTest.java
diffstat 14 files changed, 530 insertions(+), 176 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Mar 27 14:08:54 2014 +0100
+++ b/ChangeLog	Thu Mar 27 11:08:09 2014 -0400
@@ -1,3 +1,43 @@
+2014-03-27  Andrew Azores  <aazores@redhat.com>
+
+	Applets can be temporarily granted permission levels above fully sandboxed
+	but below all-permission
+	* netx/net/sourceforge/jnlp/resources/Messages.properties:
+	(STempPermNoFile, STempPermNoNetwork, STempPermNoExec,
+	STempPermNoFileOrNetwork, STempPermNoExecOrNetwork, STempPermNoFileOrExec,
+	STempPermNoFileOrNetworkOrExec, STempAllMedia, STempSoundOnly,
+	STempClipboardOnly, STempPrintOnly, STempAllFileAndPropertyAccess,
+	STempReadLocalFilesAndProperties, STempReflectionOnly): new messages
+	* netx/net/sourceforge/jnlp/security/SecurityDialog.java: (installPanel)
+	pass SecurityDelegate to partially signed dialog
+	* netx/net/sourceforge/jnlp/security/SecurityDialogs.java:
+	(showPartiallySignedWarningDialog) added SecutityDelegate param for
+	message extras
+	* netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java:
+	(checkPartiallySignedWithUserIfRequired) added SecurityDelegate param
+	* netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java:
+	(createPolicyPermissionsMenu, PolicyEditorLaunchListener,
+	PolicyEditorPopupListener) removed in favour of TemporaryPermissionsButton
+	* netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java:
+	same
+	* netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningDialog.java:
+	(partiallySigned) SecurityDelegate param
+	* netx/net/sourceforge/jnlp/security/policyeditor/PermissionActions.java:
+	(DELETE, READLINK, FILE_ALL) new actions. (rawActions, rawString) can
+	retrieve raw String representation of the action
+	* netx/net/sourceforge/jnlp/security/policyeditor/PermissionTarget.java:
+	(USER_HOME, TMPDIR) grant permissions to entire directory, not only
+	children
+	* netx/net/sourceforge/jnlp/security/policyeditor/PolicyEditorPermissions.java: 
+	(DELETE_LOCAL_FILES, DELETE_TMP_FILES) new permissions.
+	(Group.WriteFileSystem) added DELETE* permissions
+	* nests/netx/unit/net/sourceforge/jnlp/security/policyeditor/PolicyEditorParsingTest.java: 
+	update for change in PermissionTarget
+	* netx/net/sourceforge/jnlp/security/dialogs/TemporaryPermissions.java:
+	new class
+	* netx/net/sourceforge/jnlp/security/dialogs/TemporaryPermissionsButton.java:
+	new class
+
 2014-03-27  Jiri Vanek  <jvanek@redhat.com>
 
 	Clenaup in PolicyEditor tests and MVC
--- a/netx/net/sourceforge/jnlp/resources/Messages.properties	Thu Mar 27 14:08:54 2014 +0100
+++ b/netx/net/sourceforge/jnlp/resources/Messages.properties	Thu Mar 27 11:08:09 2014 -0400
@@ -305,6 +305,20 @@
 STOAsignedMsgFully = The applet is fully signed
 STOAsignedMsgAndSandbox = The applet is fully signed and sandboxed
 STOAsignedMsgPartiall = The applet is not fully signed
+STempPermNoFile=No file access
+STempPermNoNetwork=No network access
+STempPermNoExec=No command execution
+STempNoFileOrNetwork=No file or network access
+STempNoExecOrNetwork=No command execution or network access
+STempNoFileOrExec=No file access or command execution
+STempNoFileOrNetworkOrExec=No file access, network access, or command execution
+STempAllMedia=All media
+STempSoundOnly=Play audio
+STempClipboardOnly=Access clipboard
+STempPrintOnly=Print documents
+STempAllFileAndPropertyAccess=All file and properties access
+STempReadLocalFilesAndProperties=Read-only local files and properties
+STempReflectionOnly=Java Reflection only
 
 # Security - used for the More Information dialog
 SBadKeyUsage=Resources contain entries whose signer certificate's KeyUsage extension doesn't allow code signing.
@@ -501,6 +515,8 @@
 PEReadFilesDetail=Allow applets to read from files in your home directory
 PEWriteFiles=Write to local files
 PEWriteFilesDetail=Allow applets to write to files in your home directory
+PEDeleteFiles=Delete local files
+PEDeleteFilesDetail=Allow applets to delete files in your home directory
 PEReadSystemFiles=Read all system files
 PEReadSystemFilesDetail=Allow applets read-only access to all locations on your computer
 PEWriteSystemFiles=Write all system files
@@ -509,6 +525,8 @@
 PEReadTempFilesDetail=Allow applets to read from your temporary files directory
 PEWriteTempFiles=Write to temp files
 PEWriteTempFilesDetail=Allow applets to write to your temporary files directory
+PEDeleteTempFiles=Delete temp files
+PEDeleteTempFilesDetail=Allow applets to delete files in your temporary files directory
 PEAWTPermission=Window System Access
 PEAWTPermissionDetail=Allow applets all AWT windowing system access
 PEClipboard=Access clipboard
--- a/netx/net/sourceforge/jnlp/security/SecurityDialog.java	Thu Mar 27 14:08:54 2014 +0100
+++ b/netx/net/sourceforge/jnlp/security/SecurityDialog.java	Thu Mar 27 11:08:09 2014 -0400
@@ -315,7 +315,7 @@
         else if (dialogType == DialogType.APPLET_WARNING)
             panel = new AppletWarningPane(this, this.certVerifier);
         else if (dialogType == DialogType.PARTIALLYSIGNED_WARNING)
-            panel = AppTrustWarningDialog.partiallySigned(this, file);
+            panel = AppTrustWarningDialog.partiallySigned(this, file, (SecurityDelegate) extras[0]);
         else if (dialogType == DialogType.UNSIGNED_WARNING) // Only necessary for applets on 'high security' or above
             panel = AppTrustWarningDialog.unsigned(this, file);
         else if (dialogType == DialogType.AUTHENTICATION)
--- a/netx/net/sourceforge/jnlp/security/SecurityDialogs.java	Thu Mar 27 14:08:54 2014 +0100
+++ b/netx/net/sourceforge/jnlp/security/SecurityDialogs.java	Thu Mar 27 11:08:09 2014 -0400
@@ -221,13 +221,15 @@
      *
      * @return true if permission was granted by the user, false otherwise.
      */
-    public static AppSigningWarningAction showPartiallySignedWarningDialog(JNLPFile file, CertVerifier certVerifier) {
+    public static AppSigningWarningAction showPartiallySignedWarningDialog(JNLPFile file, CertVerifier certVerifier,
+            SecurityDelegate securityDelegate) {
 
         final SecurityDialogMessage message = new SecurityDialogMessage();
         message.dialogType = DialogType.PARTIALLYSIGNED_WARNING;
         message.accessType = AccessType.PARTIALLYSIGNED;
         message.file = file;
         message.certVerifier = certVerifier;
+        message.extras = new Object[] { securityDelegate };
 
         return (AppSigningWarningAction) getUserResponse(message);
     }
--- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java	Thu Mar 27 14:08:54 2014 +0100
+++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java	Thu Mar 27 11:08:09 2014 -0400
@@ -239,7 +239,7 @@
             appletOK = false;
         } else {
             // No remembered decision, prompt the user
-            AppSigningWarningAction warningResponse = SecurityDialogs.showPartiallySignedWarningDialog(file, certVerifier);
+            AppSigningWarningAction warningResponse = SecurityDialogs.showPartiallySignedWarningDialog(file, certVerifier, securityDelegate);
             ExecuteAppletAction executeAction = warningResponse.getAction();
 
             if (executeAction == ExecuteAppletAction.SANDBOX) {
--- a/netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java	Thu Mar 27 14:08:54 2014 +0100
+++ b/netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java	Thu Mar 27 11:08:09 2014 -0400
@@ -41,20 +41,15 @@
 
 import java.awt.BorderLayout;
 import java.awt.Color;
-import java.awt.Dialog.ModalityType;
 import java.awt.Dimension;
 import java.awt.FlowLayout;
 import java.awt.Font;
 import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
 import java.security.KeyStore;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
@@ -65,16 +60,13 @@
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
 import javax.swing.JLabel;
-import javax.swing.JMenuItem;
 import javax.swing.JPanel;
 import javax.swing.JPopupMenu;
 import javax.swing.SwingConstants;
 
 import net.sourceforge.jnlp.JNLPFile;
 import net.sourceforge.jnlp.PluginBridge;
-import net.sourceforge.jnlp.config.DeploymentConfiguration;
 import net.sourceforge.jnlp.runtime.JNLPClassLoader.SecurityDelegate;
-import net.sourceforge.jnlp.runtime.JNLPRuntime;
 import net.sourceforge.jnlp.security.CertVerifier;
 import net.sourceforge.jnlp.security.CertificateUtils;
 import net.sourceforge.jnlp.security.HttpsCertVerifier;
@@ -84,7 +76,6 @@
 import net.sourceforge.jnlp.security.SecurityDialog;
 import net.sourceforge.jnlp.security.SecurityDialogs.AccessType;
 import net.sourceforge.jnlp.security.SecurityUtil;
-import net.sourceforge.jnlp.security.policyeditor.PolicyEditor;
 import net.sourceforge.jnlp.security.policyeditor.PolicyEditor.PolicyEditorWindow;
 import net.sourceforge.jnlp.util.FileUtils;
 import net.sourceforge.jnlp.util.logging.OutputController;
@@ -225,8 +216,6 @@
     }
 
     private void addButtons() {
-        createPolicyPermissionsMenu();
-
         alwaysTrust = new JCheckBox(R("SAlwaysTrustPublisher"));
         alwaysTrust.setEnabled(true);
         alwaysTrust.setSelected(alwaysTrustSelected);
@@ -246,7 +235,7 @@
         buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
         run = new JButton(R("ButRun"));
         sandbox = new JButton(R("ButSandbox"));
-        advancedOptions = new JButton("\u2630"); // "hamburger" navicon
+        advancedOptions = new TemporaryPermissionsButton(file, securityDelegate, sandbox);
         cancel = new JButton(R("ButCancel"));
 
         run.setToolTipText(R("CertWarnRunTip"));
@@ -273,8 +262,6 @@
 
         sandbox.addActionListener(createSetValueListener(parent, 1));
 
-        advancedOptions.addMouseListener(new PolicyEditorPopupListener());
-
         cancel.addActionListener(createSetValueListener(parent, 2));
 
         initialFocusComponent = cancel;
@@ -310,65 +297,6 @@
         add(bottomPanel);
     }
 
-    private void createPolicyPermissionsMenu() {
-        policyMenu = new JPopupMenu();
-
-        JMenuItem launchPolicyEditor = new JMenuItem(R("CertWarnPolicyEditorItem"));
-        launchPolicyEditor.addActionListener(new PolicyEditorLaunchListener());
-
-        policyMenu.add(launchPolicyEditor);
-        policyMenu.setSize(policyMenu.getMinimumSize());
-        policyMenu.setVisible(false);
-    }
-
-    private class PolicyEditorLaunchListener implements ActionListener {
-        @Override
-        public void actionPerformed(final ActionEvent e) {
-            final String rawFilepath = JNLPRuntime.getConfiguration().getProperty(DeploymentConfiguration.KEY_USER_SECURITY_POLICY);
-            String filepath;
-            try {
-                filepath = new URL(rawFilepath).getPath();
-            } catch (final MalformedURLException mfue) {
-                filepath = null;
-            }
-
-            if (policyEditor == null || policyEditor.getPolicyEditor().isClosed()) {
-                policyEditor = PolicyEditor.getPolicyEditorDialog(filepath);
-            } else {
-                policyEditor.asWindow().toFront();
-                policyEditor.asWindow().repaint();
-            }
-            policyEditor.setModalityType(ModalityType.DOCUMENT_MODAL);
-            policyEditor.getPolicyEditor().addNewCodebase(file.getCodeBase().toString());
-            policyEditor.asWindow().setVisible(true);
-            policyMenu.setVisible(false);
-        }
-    }
-
-    private class PolicyEditorPopupListener implements MouseListener {
-        @Override
-        public void mouseClicked(final MouseEvent e) {
-            policyMenu.setLocation(e.getLocationOnScreen());
-            policyMenu.setVisible(!policyMenu.isVisible());
-        }
-
-        @Override
-        public void mousePressed(final MouseEvent e) {
-        }
-
-        @Override
-        public void mouseReleased(final MouseEvent e) {
-        }
-
-        @Override
-        public void mouseEntered(final MouseEvent e) {
-        }
-
-        @Override
-        public void mouseExited(final MouseEvent e) {
-        }
-    }
-
     private class MoreInfoButtonListener implements ActionListener {
         @Override
         public void actionPerformed(ActionEvent e) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/security/dialogs/TemporaryPermissions.java	Thu Mar 27 11:08:09 2014 -0400
@@ -0,0 +1,204 @@
+/* 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 net.sourceforge.jnlp.security.dialogs;
+
+import java.awt.AWTPermission;
+import java.io.FilePermission;
+import java.lang.reflect.ReflectPermission;
+import java.net.SocketPermission;
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.PropertyPermission;
+
+import javax.sound.sampled.AudioPermission;
+
+import static net.sourceforge.jnlp.security.policyeditor.PolicyEditorPermissions.*;
+
+public class TemporaryPermissions {
+
+    // We can't use the PolicyEditorPermissions versions of these, because they rely on System Property expansion, which is perfomed
+    // by the policy parser, but not by the Permissions constructors.
+    private static final String USER_HOME = System.getProperty("user.home");
+    private static final String TMPDIR = System.getProperty("java.io.tmpdir");
+
+    public static final FilePermission READ_LOCAL_FILES_PERMISSION = new FilePermission(USER_HOME, READ_LOCAL_FILES.getActions().rawString());
+    public static final FilePermission WRITE_LOCAL_FILES_PERMISSION = new FilePermission(USER_HOME, WRITE_LOCAL_FILES.getActions().rawString());
+    public static final FilePermission DELETE_LOCAL_FILES_PERMISSION = new FilePermission(USER_HOME, DELETE_LOCAL_FILES.getActions().rawString());
+    public static final FilePermission READ_TMP_FILES_PERMISSION = new FilePermission(TMPDIR, READ_TMP_FILES.getActions().rawString());
+    public static final FilePermission WRITE_TMP_FILES_PERMISSION = new FilePermission(TMPDIR, WRITE_TMP_FILES.getActions().rawString());
+    public static final FilePermission DELETE_TMP_FILES_PERMISSION = new FilePermission(TMPDIR, DELETE_TMP_FILES.getActions().rawString());
+    public static final FilePermission READ_SYSTEM_FILES_PERMISSION = new FilePermission(READ_SYSTEM_FILES.getTarget().target, READ_SYSTEM_FILES.getActions()
+            .rawString());
+    public static final FilePermission WRITE_SYSTEM_FILES_PERMISSION = new FilePermission(WRITE_SYSTEM_FILES.getTarget().target, WRITE_SYSTEM_FILES
+            .getActions().rawString());
+
+    public static final PropertyPermission READ_PROPERTIES_PERMISSION = new PropertyPermission(READ_PROPERTIES.getTarget().target, READ_PROPERTIES.getActions()
+            .rawString());
+    public static final PropertyPermission WRITE_PROPERTIES_PERMISSION = new PropertyPermission(WRITE_PROPERTIES.getTarget().target, WRITE_PROPERTIES
+            .getActions().rawString());
+
+    public static final FilePermission EXEC_PERMISSION = new FilePermission(EXEC_COMMANDS.getTarget().target, EXEC_COMMANDS.getActions().rawString());
+    public static final RuntimePermission GETENV_PERMISSION = new RuntimePermission(GET_ENV.getTarget().target);
+
+    public static final SocketPermission NETWORK_PERMISSION = new SocketPermission(NETWORK.getTarget().target, NETWORK.getActions().rawString());
+
+    public static final ReflectPermission REFLECTION_PERMISSION = new ReflectPermission(JAVA_REFLECTION.getTarget().target);
+    public static final RuntimePermission CLASSLOADER_PERMISSION = new RuntimePermission(GET_CLASSLOADER.getTarget().target);
+    public static final RuntimePermission ACCESS_CLASS_IN_PACKAGE_PERMISSION = new RuntimePermission(ACCESS_CLASS_IN_PACKAGE.getTarget().target);
+    public static final RuntimePermission ACCESS_DECLARED_MEMBERS_PERMISSION = new RuntimePermission(ACCESS_DECLARED_MEMBERS.getTarget().target);
+
+    public static final AWTPermission AWT_PERMISSION = new AWTPermission(ALL_AWT.getTarget().target);
+    public static final AudioPermission PLAY_AUDIO_PERMISSION = new AudioPermission(PLAY_AUDIO.getTarget().target);
+    public static final AudioPermission RECORD_AUDIO_PERMISSION = new AudioPermission(RECORD_AUDIO.getTarget().target);
+    public static final AWTPermission CLIPBOARD_PERMISSION = new AWTPermission(CLIPBOARD.getTarget().target);
+    public static final RuntimePermission PRINT_PERMISSION = new RuntimePermission(PRINT.getTarget().target);
+
+    public static final Collection<Permission> ALL_PERMISSIONS, FILE_PERMISSIONS, PROPERTY_PERMISSIONS, NETWORK_PERMISSIONS, EXEC_PERMISSIONS,
+            REFLECTION_PERMISSIONS, MEDIA_PERMISSIONS;
+    static {
+        final Collection<Permission> all = new HashSet<Permission>(), file = new HashSet<Permission>(), property = new HashSet<Permission>(),
+                network = new HashSet<Permission>(), exec = new HashSet<Permission>(), reflection = new HashSet<Permission>(), media = new HashSet<Permission>();
+
+        file.add(READ_LOCAL_FILES_PERMISSION);
+        file.add(WRITE_LOCAL_FILES_PERMISSION);
+        file.add(DELETE_LOCAL_FILES_PERMISSION);
+        file.add(READ_TMP_FILES_PERMISSION);
+        file.add(WRITE_TMP_FILES_PERMISSION);
+        file.add(DELETE_TMP_FILES_PERMISSION);
+        file.add(READ_SYSTEM_FILES_PERMISSION);
+        file.add(WRITE_SYSTEM_FILES_PERMISSION);
+        FILE_PERMISSIONS = Collections.unmodifiableCollection(file);
+
+        property.add(READ_PROPERTIES_PERMISSION);
+        property.add(WRITE_PROPERTIES_PERMISSION);
+        PROPERTY_PERMISSIONS = Collections.unmodifiableCollection(property);
+
+        exec.add(EXEC_PERMISSION);
+        exec.add(GETENV_PERMISSION);
+        EXEC_PERMISSIONS = Collections.unmodifiableCollection(exec);
+
+        network.add(NETWORK_PERMISSION);
+        NETWORK_PERMISSIONS = Collections.unmodifiableCollection(network);
+
+        reflection.add(REFLECTION_PERMISSION);
+        reflection.add(CLASSLOADER_PERMISSION);
+        reflection.add(ACCESS_CLASS_IN_PACKAGE_PERMISSION);
+        reflection.add(ACCESS_DECLARED_MEMBERS_PERMISSION);
+        REFLECTION_PERMISSIONS = Collections.unmodifiableCollection(reflection);
+
+        media.add(AWT_PERMISSION);
+        media.add(PLAY_AUDIO_PERMISSION);
+        media.add(RECORD_AUDIO_PERMISSION);
+        media.add(CLIPBOARD_PERMISSION);
+        media.add(PRINT_PERMISSION);
+        MEDIA_PERMISSIONS = Collections.unmodifiableCollection(media);
+
+        all.addAll(file);
+        all.addAll(property);
+        all.addAll(exec);
+        all.addAll(network);
+        all.addAll(reflection);
+        all.addAll(media);
+        ALL_PERMISSIONS = Collections.unmodifiableCollection(all);
+    }
+
+    private static final Collection<Permission> allMinus(final Collection<Permission> permissions) {
+        return subtract(ALL_PERMISSIONS, permissions);
+    }
+
+    private static Collection<Permission> sum(final Permission... permissions) {
+        final Collection<Permission> result = new HashSet<Permission>(Arrays.asList(permissions));
+        return Collections.unmodifiableCollection(result);
+    }
+
+    private static Collection<Permission> sum(final Collection<Permission> a, final Collection<Permission> b) {
+        final Collection<Permission> result = new HashSet<Permission>();
+        result.addAll(a);
+        result.addAll(b);
+        return Collections.unmodifiableCollection(result);
+    }
+
+    private static final Collection<Permission> subtract(final Collection<Permission> from, final Collection<Permission> remove) {
+        final Collection<Permission> result = new HashSet<Permission>(from);
+        result.removeAll(remove);
+        return Collections.unmodifiableCollection(result);
+    }
+
+    public static Collection<Permission> noFileAccess() {
+        return allMinus(FILE_PERMISSIONS);
+    }
+
+    public static Collection<Permission> noNetworkAccess() {
+        return allMinus(Arrays.asList(new Permission[] { NETWORK_PERMISSION }));
+    }
+
+    public static Collection<Permission> noFileOrNetworkAccess() {
+        return subtract(allMinus(FILE_PERMISSIONS), NETWORK_PERMISSIONS);
+    }
+
+    public static Collection<Permission> allFileAccessAndProperties() {
+        return sum(FILE_PERMISSIONS, PROPERTY_PERMISSIONS);
+    }
+
+    public static Collection<Permission> readLocalFilesAndProperties() {
+        return sum(READ_LOCAL_FILES_PERMISSION, READ_PROPERTIES_PERMISSION);
+    }
+
+    public static Collection<Permission> reflectionOnly() {
+        return REFLECTION_PERMISSIONS;
+    }
+
+    public static Collection<Permission> allMedia() {
+        return MEDIA_PERMISSIONS;
+    }
+
+    public static Collection<Permission> audioOnly() {
+        return sum(PLAY_AUDIO_PERMISSION, RECORD_AUDIO_PERMISSION);
+    }
+
+    public static Collection<Permission> clipboardOnly() {
+        return sum(CLIPBOARD_PERMISSION);
+    }
+
+    public static Collection<Permission> printOnly() {
+        return sum(PRINT_PERMISSION);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/security/dialogs/TemporaryPermissionsButton.java	Thu Mar 27 11:08:09 2014 -0400
@@ -0,0 +1,191 @@
+/* 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 net.sourceforge.jnlp.security.dialogs;
+
+import static net.sourceforge.jnlp.runtime.Translator.R;
+
+import java.awt.Component;
+import java.awt.Dialog.ModalityType;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.Permission;
+import java.util.Collection;
+
+import javax.swing.JButton;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+
+import net.sourceforge.jnlp.JNLPFile;
+import net.sourceforge.jnlp.config.DeploymentConfiguration;
+import net.sourceforge.jnlp.runtime.JNLPClassLoader.SecurityDelegate;
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.security.policyeditor.PolicyEditor;
+import net.sourceforge.jnlp.security.policyeditor.PolicyEditor.PolicyEditorWindow;
+
+public class TemporaryPermissionsButton extends JButton {
+
+    private final JPopupMenu menu;
+    private final JButton linkedButton;
+    private PolicyEditorWindow policyEditorWindow = null;
+    private final JNLPFile file;
+    private final SecurityDelegate securityDelegate;
+
+    public TemporaryPermissionsButton(final JNLPFile file, final SecurityDelegate securityDelegate, final JButton linkedButton) {
+        super("\u2630");
+        this.menu = createPolicyPermissionsMenu();
+        this.linkedButton = linkedButton;
+        this.file = file;
+        this.securityDelegate = securityDelegate;
+
+        addMouseListener(new PolicyEditorPopupListener(this));
+    }
+
+    private JPopupMenu createPolicyPermissionsMenu() {
+        final JPopupMenu policyMenu = new JPopupMenu();
+
+        final JMenuItem launchPolicyEditor = new JMenuItem(R("CertWarnPolicyEditorItem"));
+        launchPolicyEditor.addActionListener(new PolicyEditorLaunchListener());
+        policyMenu.add(launchPolicyEditor);
+
+        policyMenu.addSeparator();
+
+
+        final JMenuItem noFileAccess = new JMenuItem(R("STempPermNoFile"));
+        noFileAccess.addActionListener(new TemporaryPermissionsListener(TemporaryPermissions.noFileAccess()));
+        policyMenu.add(noFileAccess);
+
+        final JMenuItem noNetworkAccess = new JMenuItem(R("STempPermNoNetwork"));
+        noNetworkAccess.addActionListener(new TemporaryPermissionsListener(TemporaryPermissions.noNetworkAccess()));
+        policyMenu.add(noNetworkAccess);
+
+        final JMenuItem noFileOrNetwork = new JMenuItem(R("STempNoFileOrNetwork"));
+        noFileOrNetwork.addActionListener(new TemporaryPermissionsListener(TemporaryPermissions.noFileOrNetworkAccess()));
+        policyMenu.add(noFileOrNetwork);
+
+        policyMenu.addSeparator();
+
+        final JMenuItem allFileAccessOnly = new JMenuItem(R("STempAllFileAndPropertyAccess"));
+        allFileAccessOnly.addActionListener(new TemporaryPermissionsListener(TemporaryPermissions.allFileAccessAndProperties()));
+        policyMenu.add(allFileAccessOnly);
+
+        final JMenuItem readLocalFilesAndProperties = new JMenuItem(R("STempReadLocalFilesAndProperties"));
+        readLocalFilesAndProperties.addActionListener(new TemporaryPermissionsListener(TemporaryPermissions.readLocalFilesAndProperties()));
+        policyMenu.add(readLocalFilesAndProperties);
+
+        final JMenuItem reflectionOnly = new JMenuItem(R("STempReflectionOnly"));
+        reflectionOnly.addActionListener(new TemporaryPermissionsListener(TemporaryPermissions.reflectionOnly()));
+        policyMenu.add(reflectionOnly);
+
+        policyMenu.addSeparator();
+
+        final JMenuItem allMedia = new JMenuItem(R("STempAllMedia"));
+        allMedia.addActionListener(new TemporaryPermissionsListener(TemporaryPermissions.allMedia()));
+        policyMenu.add(allMedia);
+
+        final JMenuItem soundOnly = new JMenuItem(R("STempSoundOnly"));
+        soundOnly.addActionListener(new TemporaryPermissionsListener(TemporaryPermissions.audioOnly()));
+        policyMenu.add(soundOnly);
+
+        final JMenuItem clipboardOnly = new JMenuItem(R("STempClipboardOnly"));
+        clipboardOnly.addActionListener(new TemporaryPermissionsListener(TemporaryPermissions.clipboardOnly()));
+        policyMenu.add(clipboardOnly);
+
+        final JMenuItem printOnly = new JMenuItem(R("STempPrintOnly"));
+        printOnly.addActionListener(new TemporaryPermissionsListener(TemporaryPermissions.printOnly()));
+        policyMenu.add(printOnly);
+
+        return policyMenu;
+    }
+
+    private class TemporaryPermissionsListener implements ActionListener {
+        private Collection<Permission> permissions;
+
+        public TemporaryPermissionsListener(final Collection<Permission> permissions) {
+            this.permissions = permissions;
+        }
+
+        @Override
+        public void actionPerformed(final ActionEvent e) {
+            securityDelegate.addPermissions(permissions);
+            menu.setVisible(false);
+            if (linkedButton != null) {
+                linkedButton.doClick();
+            }
+        }
+    }
+
+    private class PolicyEditorLaunchListener implements ActionListener {
+        @Override
+        public void actionPerformed(final ActionEvent e) {
+            final String rawFilepath = JNLPRuntime.getConfiguration().getProperty(DeploymentConfiguration.KEY_USER_SECURITY_POLICY);
+            String filepath;
+            try {
+                filepath = new URL(rawFilepath).getPath();
+            } catch (final MalformedURLException mfue) {
+                filepath = null;
+            }
+
+            if (policyEditorWindow == null || policyEditorWindow.getPolicyEditor().isClosed()) {
+                policyEditorWindow = PolicyEditor.getPolicyEditorDialog(filepath);
+            } else {
+                policyEditorWindow.asWindow().toFront();
+                policyEditorWindow.asWindow().repaint();
+            }
+            policyEditorWindow.setModalityType(ModalityType.DOCUMENT_MODAL);
+            policyEditorWindow.getPolicyEditor().addNewCodebase(file.getCodeBase().toString());
+            policyEditorWindow.asWindow().setVisible(true);
+            menu.setVisible(false);
+        }
+    }
+
+    private class PolicyEditorPopupListener extends MouseAdapter {
+        private final Component parent;
+
+        public PolicyEditorPopupListener(final Component parent) {
+            this.parent = parent;
+        }
+
+        @Override
+        public void mouseClicked(final MouseEvent e) {
+            menu.show(parent, e.getX(), e.getY());
+        }
+    }
+}
--- a/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningDialog.java	Thu Mar 27 14:08:54 2014 +0100
+++ b/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/AppTrustWarningDialog.java	Thu Mar 27 11:08:09 2014 -0400
@@ -37,10 +37,11 @@
 package net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel;
 
 import net.sourceforge.jnlp.JNLPFile;
+import net.sourceforge.jnlp.runtime.JNLPClassLoader.SecurityDelegate;
 import net.sourceforge.jnlp.security.SecurityDialog;
+import net.sourceforge.jnlp.security.dialogs.SecurityDialogPanel;
 import net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel.AppTrustWarningPanel.ActionChoiceListener;
 import net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel.AppTrustWarningPanel.AppSigningWarningAction;
-import net.sourceforge.jnlp.security.dialogs.SecurityDialogPanel;
 
 /**
  * A panel that confirms that the user is OK with unsigned code running.
@@ -57,9 +58,9 @@
         return warningDialog;
     }
 
-    public static AppTrustWarningDialog partiallySigned(final SecurityDialog dialog, final JNLPFile file) {
+    public static AppTrustWarningDialog partiallySigned(final SecurityDialog dialog, final JNLPFile file, final SecurityDelegate securityDelegate) {
         final AppTrustWarningDialog warningDialog = new AppTrustWarningDialog(dialog);
-        warningDialog.add(new PartiallySignedAppTrustWarningPanel(file, warningDialog.getActionChoiceListener(), dialog));
+        warningDialog.add(new PartiallySignedAppTrustWarningPanel(file, warningDialog.getActionChoiceListener(), dialog, securityDelegate));
         return warningDialog;
     }
 
--- a/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java	Thu Mar 27 14:08:54 2014 +0100
+++ b/netx/net/sourceforge/jnlp/security/dialogs/apptrustwarningpanel/PartiallySignedAppTrustWarningPanel.java	Thu Mar 27 11:08:09 2014 -0400
@@ -1,32 +1,57 @@
+/* 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 net.sourceforge.jnlp.security.dialogs.apptrustwarningpanel;
 
 import static net.sourceforge.jnlp.runtime.Translator.R;
 
-import java.awt.Dialog.ModalityType;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.net.MalformedURLException;
-import java.net.URL;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 
 import javax.swing.ImageIcon;
 import javax.swing.JButton;
-import javax.swing.JMenuItem;
-import javax.swing.JPopupMenu;
 
 import net.sourceforge.jnlp.JNLPFile;
 import net.sourceforge.jnlp.PluginBridge;
-import net.sourceforge.jnlp.config.DeploymentConfiguration;
-import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.runtime.JNLPClassLoader.SecurityDelegate;
 import net.sourceforge.jnlp.security.SecurityDialog;
 import net.sourceforge.jnlp.security.SecurityUtil;
 import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteAppletAction;
 import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletTrustConfirmation;
-import net.sourceforge.jnlp.security.policyeditor.PolicyEditor;
-import net.sourceforge.jnlp.security.policyeditor.PolicyEditor.PolicyEditorWindow;
+import net.sourceforge.jnlp.security.dialogs.TemporaryPermissionsButton;
 import net.sourceforge.jnlp.tools.CertInformation;
 import net.sourceforge.jnlp.tools.JarCertVerifier;
 
@@ -35,10 +60,9 @@
     private final JarCertVerifier jcv;
     private final JButton sandboxButton;
     private final JButton advancedOptionsButton;
-    private final JPopupMenu policyMenu;
-    private PolicyEditorWindow policyEditor = null;
 
-    public PartiallySignedAppTrustWarningPanel(JNLPFile file, ActionChoiceListener actionChoiceListener, SecurityDialog securityDialog) {
+    public PartiallySignedAppTrustWarningPanel(JNLPFile file, ActionChoiceListener actionChoiceListener,
+            SecurityDialog securityDialog, SecurityDelegate securityDelegate) {
         super(file, actionChoiceListener);
         this.jcv = (JarCertVerifier) securityDialog.getCertVerifier();
         this.INFO_PANEL_HEIGHT = 200;
@@ -47,11 +71,7 @@
         sandboxButton.setText(R("ButSandbox"));
         sandboxButton.addActionListener(chosenActionSetter(ExecuteAppletAction.SANDBOX));
 
-        policyMenu = createPolicyPermissionsMenu();
-        advancedOptionsButton = new JButton();
-        advancedOptionsButton.setText("\u2630");
-        advancedOptionsButton.addMouseListener(new PolicyEditorPopupListener());
-        advancedOptionsButton.setToolTipText(R("CertWarnPolicyTip"));
+        advancedOptionsButton = new TemporaryPermissionsButton(file, securityDelegate, sandboxButton);
 
         buttons.add(1, sandboxButton);
         buttons.add(2, advancedOptionsButton);
@@ -153,65 +173,4 @@
         return htmlWrap(R(getQuestionPanelTextKey()));
     }
 
-    private JPopupMenu createPolicyPermissionsMenu() {
-        final JPopupMenu policyMenu = new JPopupMenu();
-
-        JMenuItem launchPolicyEditor = new JMenuItem(R("CertWarnPolicyEditorItem"));
-        launchPolicyEditor.addActionListener(new PolicyEditorLaunchListener());
-
-        policyMenu.add(launchPolicyEditor);
-        policyMenu.setSize(policyMenu.getMinimumSize());
-        policyMenu.setVisible(false);
-
-        return policyMenu;
-    }
-
-    private class PolicyEditorLaunchListener implements ActionListener {
-        @Override
-        public void actionPerformed(final ActionEvent e) {
-            final String rawFilepath = JNLPRuntime.getConfiguration().getProperty(DeploymentConfiguration.KEY_USER_SECURITY_POLICY);
-            String filepath;
-            try {
-                filepath = new URL(rawFilepath).getPath();
-            } catch (final MalformedURLException mfue) {
-                filepath = null;
-            }
-
-            if (policyEditor == null || policyEditor.getPolicyEditor().isClosed()) {
-                policyEditor = PolicyEditor.getPolicyEditorDialog(filepath);
-            } else {
-                policyEditor.asWindow().toFront();
-                policyEditor.asWindow().repaint();
-            }
-            policyEditor.setModalityType(ModalityType.DOCUMENT_MODAL);
-            policyEditor.getPolicyEditor().addNewCodebase(file.getCodeBase().toString());
-            policyEditor.asWindow().setVisible(true);
-            policyMenu.setVisible(false);
-        }
-    }
-
-    private class PolicyEditorPopupListener implements MouseListener {
-        @Override
-        public void mouseClicked(final MouseEvent e) {
-            policyMenu.setLocation(e.getLocationOnScreen());
-            policyMenu.setVisible(!policyMenu.isVisible());
-        }
-
-        @Override
-        public void mousePressed(final MouseEvent e) {
-        }
-
-        @Override
-        public void mouseReleased(final MouseEvent e) {
-        }
-
-        @Override
-        public void mouseEntered(final MouseEvent e) {
-        }
-
-        @Override
-        public void mouseExited(final MouseEvent e) {
-        }
-    }
-
 }
--- a/netx/net/sourceforge/jnlp/security/policyeditor/PermissionActions.java	Thu Mar 27 14:08:54 2014 +0100
+++ b/netx/net/sourceforge/jnlp/security/policyeditor/PermissionActions.java	Thu Mar 27 11:08:09 2014 -0400
@@ -50,15 +50,20 @@
     READ("read"),
     WRITE("write"),
     EXECUTE("execute"),
+    DELETE("delete"),
+    READLINK("readlink"),
+    FILE_ALL("read,write,execute,delete,readlink"),
     ACCEPT("accept"),
     LISTEN("listen"),
     CONNECT("connect"),
     RESOLVE("resolve"),
     NETALL("accept,listen,connect,resolve");
 
+    private final String rawActions;
     private final Set<String> actions;
 
     private PermissionActions(final String actions) {
+        this.rawActions = actions;
         this.actions = setFromString(actions);
     }
 
@@ -87,4 +92,8 @@
         Collections.addAll(set, string.split(","));
         return set;
     }
+
+    public String rawString() {
+        return rawActions;
+    }
 }
--- a/netx/net/sourceforge/jnlp/security/policyeditor/PermissionTarget.java	Thu Mar 27 14:08:54 2014 +0100
+++ b/netx/net/sourceforge/jnlp/security/policyeditor/PermissionTarget.java	Thu Mar 27 11:08:09 2014 -0400
@@ -44,8 +44,8 @@
     NONE(""),
     ALL("*"),
     ALL_FILES("<<ALL FILES>>"),
-    USER_HOME("${user.home}${/}*"),
-    TMPDIR("${java.io.tmpdir}${/}*"),
+    USER_HOME("${user.home}"),
+    TMPDIR("${java.io.tmpdir}"),
     CLIPBOARD("accessClipboard"),
     PRINT("queuePrintJob"),
     PLAY("play"),
--- a/netx/net/sourceforge/jnlp/security/policyeditor/PolicyEditorPermissions.java	Thu Mar 27 14:08:54 2014 +0100
+++ b/netx/net/sourceforge/jnlp/security/policyeditor/PolicyEditorPermissions.java	Thu Mar 27 11:08:09 2014 -0400
@@ -53,6 +53,9 @@
     WRITE_LOCAL_FILES(R("PEWriteFiles"), R("PEWriteFilesDetail"),
             PermissionType.FILE_PERMISSION, PermissionTarget.USER_HOME, PermissionActions.WRITE),
 
+    DELETE_LOCAL_FILES(R("PEDeleteFiles"), R("PEDeleteFilesDetail"),
+            PermissionType.FILE_PERMISSION, PermissionTarget.USER_HOME, PermissionActions.DELETE),
+
     READ_PROPERTIES(R("PEReadProps"), R("PEReadPropsDetail"),
             PermissionType.PROPERTY_PERMISSION, PermissionTarget.ALL, PermissionActions.READ),
 
@@ -71,6 +74,9 @@
     WRITE_TMP_FILES(R("PEWriteTempFiles"), R("PEWriteTempFilesDetail"),
             PermissionType.FILE_PERMISSION, PermissionTarget.TMPDIR, PermissionActions.WRITE),
 
+    DELETE_TMP_FILES(R("PEDeleteTempFiles"), R("PEDeleteTempFilesDetail"),
+            PermissionType.FILE_PERMISSION, PermissionTarget.TMPDIR, PermissionActions.DELETE),
+
     JAVA_REFLECTION(R("PEReflection"), R("PEReflectionDetail"),
             PermissionType.REFLECT_PERMISSION, PermissionTarget.REFLECT, PermissionActions.NONE),
 
@@ -107,15 +113,13 @@
     PRINT(R("PEPrint"), R("PEPrintDetail"),
             PermissionType.RUNTIME_PERMISSION, PermissionTarget.PRINT, PermissionActions.NONE);
 
-    
     public static enum Group {
 
-       
         ReadFileSystem(R("PEGReadFileSystem"),  READ_LOCAL_FILES, READ_PROPERTIES, READ_SYSTEM_FILES, READ_TMP_FILES, GET_ENV),
-        WriteFileSystem(R("PEGWriteFileSystem"), WRITE_LOCAL_FILES, WRITE_PROPERTIES, WRITE_SYSTEM_FILES, WRITE_TMP_FILES, EXEC_COMMANDS),
+        WriteFileSystem(R("PEGWriteFileSystem"), WRITE_LOCAL_FILES, DELETE_LOCAL_FILES, WRITE_PROPERTIES, WRITE_SYSTEM_FILES, WRITE_TMP_FILES,
+                DELETE_TMP_FILES, EXEC_COMMANDS),
         AccesUnowenedCode(R("PEGAccesUnowenedCode"), JAVA_REFLECTION, GET_CLASSLOADER, ACCESS_CLASS_IN_PACKAGE, ACCESS_DECLARED_MEMBERS),
         MediaAccess(R("PEGMediaAccess"), PLAY_AUDIO, RECORD_AUDIO, PRINT, CLIPBOARD);
-        
 
         private final PolicyEditorPermissions[] permissions;
         private final String title; 
@@ -124,7 +128,7 @@
             this.permissions = permissions;
         
         }
-        
+
         public static boolean anyContains(PolicyEditorPermissions permission) {
             for (Group g : Group.values()) {
                 if (g.contains(permission)) {
@@ -133,7 +137,7 @@
             }
             return false;
         }
-        
+
         public static boolean anyContains(JCheckBox view, Map<PolicyEditorPermissions, JCheckBox> checkboxMap) {
             for (Map.Entry<PolicyEditorPermissions, JCheckBox> pairs : checkboxMap.entrySet()){
                 if (pairs.getValue() == view) {
@@ -146,7 +150,7 @@
             }
             return false;
         }
-        
+
         /*
          * + all is selected
          * 0 invalid
@@ -174,7 +178,7 @@
             }
             return 0;
         }
-        
+
         public boolean contains(PolicyEditorPermissions permission) {
             for (PolicyEditorPermissions policyEditorPermissions : permissions) {
                 if (policyEditorPermissions == permission) {
@@ -192,9 +196,7 @@
         public PolicyEditorPermissions[] getPermissions() {
             return permissions;
         }
-        
-        
-        
+
     }
 
     
--- a/tests/netx/unit/net/sourceforge/jnlp/security/policyeditor/PolicyEditorParsingTest.java	Thu Mar 27 14:08:54 2014 +0100
+++ b/tests/netx/unit/net/sourceforge/jnlp/security/policyeditor/PolicyEditorParsingTest.java	Thu Mar 27 11:08:09 2014 -0400
@@ -52,8 +52,8 @@
 
     private static final String LINEBREAK = System.getProperty("line.separator");
 
-    private static final String READ_PERMISSION = "permission java.io.FilePermission \"${user.home}${/}*\", \"read\";";
-    private static final String WRITE_PERMISSION = "permission java.io.FilePermission \"${user.home}${/}*\", \"write\";";
+    private static final String READ_PERMISSION = "permission java.io.FilePermission \"${user.home}\", \"read\";";
+    private static final String WRITE_PERMISSION = "permission java.io.FilePermission \"${user.home}\", \"write\";";
     private static final String COMMENT_HEADER = "/* TEST COMMENT */" + LINEBREAK;
 
     private static final String NORMAL_POLICY = "grant {" + LINEBREAK