diff options
author | Adam Domurad <[email protected]> | 2013-04-11 10:02:11 -0400 |
---|---|---|
committer | Adam Domurad <[email protected]> | 2013-04-11 10:02:11 -0400 |
commit | 038866be9293d5194b04af3c98c71e5e66712cf2 (patch) | |
tree | ccc11c87c0bc7dbc0b9a31e39d8377d446e33bb5 /netx | |
parent | 10d6ef89fcd4c6f31856df24a3b9e2cd1d637023 (diff) |
Allow for remembered unsigned trust based on codebase
Diffstat (limited to 'netx')
5 files changed, 94 insertions, 22 deletions
diff --git a/netx/net/sourceforge/jnlp/resources/Messages.properties b/netx/net/sourceforge/jnlp/resources/Messages.properties index 7d66087..f20277a 100644 --- a/netx/net/sourceforge/jnlp/resources/Messages.properties +++ b/netx/net/sourceforge/jnlp/resources/Messages.properties @@ -224,6 +224,8 @@ SUnverified=(unverified) SAlwaysTrustPublisher=Always trust content from this publisher SHttpsUnverified=The website's HTTPS certificate cannot be verified. SRememberOption=<b>Remember this option?</b> +SRememberAppletOnly=For applet +SRememberCodebase=For site SUnsignedSummary=An unsigned Java application wants to run SUnsignedDetail=An unsigned application from the following location wants to run:<br><u>{0}</u><br><br><b>It is recommended you only run applications from sites you trust.</b> SUnsignedAllowedBefore=<font color="green">You have accepted this applet previously.</font> diff --git a/netx/net/sourceforge/jnlp/security/SecurityDialogs.java b/netx/net/sourceforge/jnlp/security/SecurityDialogs.java index a1af82e..a2dc6eb 100644 --- a/netx/net/sourceforge/jnlp/security/SecurityDialogs.java +++ b/netx/net/sourceforge/jnlp/security/SecurityDialogs.java @@ -37,6 +37,7 @@ exception statement from your version. package net.sourceforge.jnlp.security; +import net.sourceforge.jnlp.security.UnsignedAppletTrustWarningPanel.UnsignedWarningAction; import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteUnsignedApplet; import java.awt.Dialog.ModalityType; @@ -182,10 +183,10 @@ public class SecurityDialogs { * * @return true if permission was granted by the user, false otherwise. */ - public static ExecuteUnsignedApplet showUnsignedWarningDialog(JNLPFile file) { + public static UnsignedWarningAction showUnsignedWarningDialog(JNLPFile file) { if (!shouldPromptUser()) { - return ExecuteUnsignedApplet.NO; + return new UnsignedWarningAction(ExecuteUnsignedApplet.NO, false); } final SecurityDialogMessage message = new SecurityDialogMessage(); @@ -193,7 +194,7 @@ public class SecurityDialogs { message.accessType = AccessType.UNSIGNED; message.file = file; - return (ExecuteUnsignedApplet)getUserResponse(message); + return (UnsignedWarningAction)getUserResponse(message); } /** diff --git a/netx/net/sourceforge/jnlp/security/UnsignedAppletTrustWarningDialog.java b/netx/net/sourceforge/jnlp/security/UnsignedAppletTrustWarningDialog.java index 4860e52..7db6a19 100644 --- a/netx/net/sourceforge/jnlp/security/UnsignedAppletTrustWarningDialog.java +++ b/netx/net/sourceforge/jnlp/security/UnsignedAppletTrustWarningDialog.java @@ -37,8 +37,8 @@ exception statement from your version. package net.sourceforge.jnlp.security; import net.sourceforge.jnlp.PluginBridge; +import net.sourceforge.jnlp.security.UnsignedAppletTrustWarningPanel.UnsignedWarningAction; import net.sourceforge.jnlp.security.UnsignedAppletTrustWarningPanel.ActionChoiceListener; -import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteUnsignedApplet; /** * A panel that confirms that the user is OK with unsigned code running. @@ -52,7 +52,7 @@ public class UnsignedAppletTrustWarningDialog extends SecurityDialogPanel { add(new UnsignedAppletTrustWarningPanel(file, new ActionChoiceListener() { @Override - public void actionChosen(ExecuteUnsignedApplet action) { + public void actionChosen(UnsignedWarningAction action) { parent.setValue(action); parent.dispose(); } diff --git a/netx/net/sourceforge/jnlp/security/UnsignedAppletTrustWarningPanel.java b/netx/net/sourceforge/jnlp/security/UnsignedAppletTrustWarningPanel.java index e20967c..fefa2df 100644 --- a/netx/net/sourceforge/jnlp/security/UnsignedAppletTrustWarningPanel.java +++ b/netx/net/sourceforge/jnlp/security/UnsignedAppletTrustWarningPanel.java @@ -43,19 +43,21 @@ import java.awt.Color; 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 javax.swing.BorderFactory; import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JRadioButton; import javax.swing.SwingConstants; -import net.sourceforge.jnlp.JNLPFile; import net.sourceforge.jnlp.PluginBridge; import net.sourceforge.jnlp.security.appletextendedsecurity.ExecuteUnsignedApplet; import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletTrustConfirmation; @@ -63,10 +65,31 @@ import net.sourceforge.jnlp.security.appletextendedsecurity.UnsignedAppletTrustC public class UnsignedAppletTrustWarningPanel extends JPanel { /* + * Details of decided action. + */ + public static class UnsignedWarningAction { + private ExecuteUnsignedApplet action; + private boolean applyToCodeBase; + + public UnsignedWarningAction(ExecuteUnsignedApplet action, + boolean applyToCodeBase) { + this.action = action; + this.applyToCodeBase = applyToCodeBase; + } + + public ExecuteUnsignedApplet getAction() { + return action; + } + public boolean rememberForCodeBase() { + return applyToCodeBase; + } + } + + /* * Callback for when action is decided. */ public static interface ActionChoiceListener { - void actionChosen(ExecuteUnsignedApplet action); + void actionChosen(UnsignedWarningAction action); } private final int PANE_WIDTH = 500; @@ -79,6 +102,8 @@ public class UnsignedAppletTrustWarningPanel extends JPanel { private JButton allowButton; private JButton rejectButton; private JCheckBox permanencyCheckBox; + private JRadioButton applyToAppletButton; + private JRadioButton applyToCodeBaseButton; private PluginBridge file; @@ -128,7 +153,7 @@ public class UnsignedAppletTrustWarningPanel extends JPanel { private void setupInfoPanel() { String infoLabelText = R("SUnsignedDetail", file.getCodeBase()); - ExecuteUnsignedApplet rememberedAction = UnsignedAppletTrustConfirmation.getStoredAction((PluginBridge)file); + ExecuteUnsignedApplet rememberedAction = UnsignedAppletTrustConfirmation.getStoredAction(file); int panelHeight = INFO_PANEL_HEIGHT; if (rememberedAction == ExecuteUnsignedApplet.YES) { infoLabelText += "<br>" + R("SUnsignedAllowedBefore"); @@ -158,14 +183,33 @@ public class UnsignedAppletTrustWarningPanel extends JPanel { add(questionPanel); } + private JPanel createMatchOptionsPanel() { + JPanel matchOptionsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + + ButtonGroup group = new ButtonGroup(); + applyToAppletButton = new JRadioButton(R("SRememberAppletOnly")); + applyToAppletButton.setSelected(true); + applyToAppletButton.setEnabled(false); // Start disabled until 'Remember this option' is selected + + applyToCodeBaseButton = new JRadioButton(R("SRememberCodebase")); + applyToCodeBaseButton.setEnabled(false); + + group.add(applyToAppletButton); + group.add(applyToCodeBaseButton); + + matchOptionsPanel.add(applyToAppletButton); + matchOptionsPanel.add(applyToCodeBaseButton); + + return matchOptionsPanel; + } + private JPanel createCheckBoxPanel() { JPanel checkBoxPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); permanencyCheckBox = new JCheckBox(htmlWrap(R("SRememberOption"))); + permanencyCheckBox.addActionListener(permanencyListener()); checkBoxPanel.add(permanencyCheckBox); - checkBoxPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - return checkBoxPanel; } @@ -189,8 +233,12 @@ public class UnsignedAppletTrustWarningPanel extends JPanel { // Set up 'Remember Option' checkbox & Proceed/Cancel buttons private void setupButtonAndCheckBoxPanel() { JPanel outerPanel = new JPanel(new BorderLayout()); + JPanel rememberPanel = new JPanel(new GridLayout(2 /*rows*/, 1 /*column*/)); + rememberPanel.add(createCheckBoxPanel()); + rememberPanel.add(createMatchOptionsPanel()); + rememberPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - outerPanel.add(createCheckBoxPanel(), BorderLayout.WEST); + outerPanel.add(rememberPanel, BorderLayout.WEST); outerPanel.add(createButtonPanel(), BorderLayout.EAST); add(outerPanel); @@ -208,6 +256,16 @@ public class UnsignedAppletTrustWarningPanel extends JPanel { setupButtonAndCheckBoxPanel(); } + // Toggles whether 'match applet' or 'match codebase' options are greyed out + private ActionListener permanencyListener() { + return new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + applyToAppletButton.setEnabled(permanencyCheckBox.isSelected()); + applyToCodeBaseButton.setEnabled(permanencyCheckBox.isSelected()); + } + }; + } // Sets action depending on allowApplet + checkbox state private ActionListener chosenActionSetter(final boolean allowApplet) { return new ActionListener() { @@ -221,7 +279,8 @@ public class UnsignedAppletTrustWarningPanel extends JPanel { action = permanencyCheckBox.isSelected() ? ExecuteUnsignedApplet.NEVER : ExecuteUnsignedApplet.NO; } - actionChoiceListener.actionChosen(action); + boolean applyToCodeBase = applyToCodeBaseButton.isSelected(); + actionChoiceListener.actionChosen(new UnsignedWarningAction(action, applyToCodeBase)); } }; } diff --git a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java index 6139321..afe693f 100644 --- a/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java +++ b/netx/net/sourceforge/jnlp/security/appletextendedsecurity/UnsignedAppletTrustConfirmation.java @@ -51,6 +51,7 @@ import net.sourceforge.jnlp.LaunchException; import net.sourceforge.jnlp.PluginBridge; import net.sourceforge.jnlp.cache.ResourceTracker; import net.sourceforge.jnlp.security.SecurityDialogs; +import net.sourceforge.jnlp.security.UnsignedAppletTrustWarningPanel.UnsignedWarningAction; public class UnsignedAppletTrustConfirmation { static private final boolean DEBUG = System.getenv().containsKey("ICEDTEAPLUGIN_DEBUG"); @@ -116,9 +117,9 @@ public class UnsignedAppletTrustConfirmation { return fileNames; } - private static void updateAppletAction(PluginBridge file, ExecuteUnsignedApplet behaviour) { - + private static void updateAppletAction(PluginBridge file, ExecuteUnsignedApplet behaviour, boolean rememberForCodeBase) { UnsignedAppletActionStorage userActionStorage = securitySettings.getUnsignedAppletActionCustomStorage(); + userActionStorage.lock(); // We should ensure this operation is atomic try { UnsignedAppletActionEntry oldEntry = getMatchingItem(userActionStorage, file); @@ -136,14 +137,22 @@ public class UnsignedAppletTrustConfirmation { /* Else, create a new entry */ UrlRegEx codebaseRegex = new UrlRegEx("\\Q" + codebase + "\\E"); - UrlRegEx documentbaseRegex = new UrlRegEx("\\Q" + documentbase + "\\E"); + UrlRegEx documentbaseRegex = new UrlRegEx(".*"); // Match any from codebase + List<String> archiveMatches = null; // Match any from codebase + + if (!rememberForCodeBase) { + documentbaseRegex = new UrlRegEx("\\Q" + documentbase + "\\E"); // Match only this applet + archiveMatches = toRelativePaths(file.getArchiveJars(), file.getCodeBase().toString()); // Match only this applet + } UnsignedAppletActionEntry entry = new UnsignedAppletActionEntry( behaviour, new Date(), documentbaseRegex, - codebaseRegex, - toRelativePaths(file.getArchiveJars(), file.getCodeBase().toString())); + codebaseRegex, + archiveMatches + ); + userActionStorage.add(entry); } finally { userActionStorage.unlock(); @@ -179,15 +188,16 @@ public class UnsignedAppletTrustConfirmation { appletOK = false; } else { // No remembered decision, prompt the user - ExecuteUnsignedApplet decidedAction = SecurityDialogs.showUnsignedWarningDialog(file); + UnsignedWarningAction warningResponse = SecurityDialogs.showUnsignedWarningDialog(file); + ExecuteUnsignedApplet executeAction = warningResponse.getAction(); - appletOK = (decidedAction == ExecuteUnsignedApplet.YES || decidedAction == ExecuteUnsignedApplet.ALWAYS); + appletOK = (executeAction == ExecuteUnsignedApplet.YES || executeAction == ExecuteUnsignedApplet.ALWAYS); - if (decidedAction != null) { - updateAppletAction(file, decidedAction); + if (executeAction != null) { + updateAppletAction(file, executeAction, warningResponse.rememberForCodeBase()); } - debug("Decided action for unsigned applet at " + file.getCodeBase() +" was " + decidedAction); + debug("Decided action for unsigned applet at " + file.getCodeBase() +" was " + executeAction); } if (!appletOK) { |