diff --git a/netx/net/sourceforge/jnlp/resources/Messages.properties b/netx/net/sourceforge/jnlp/resources/Messages.properties --- a/netx/net/sourceforge/jnlp/resources/Messages.properties +++ b/netx/net/sourceforge/jnlp/resources/Messages.properties @@ -19,10 +19,13 @@ ButShowDetails=Show Details ButHideDetails=Hide Details ButYes=Yes ButNo=No +ButPolicyEditorDropdown=v CertWarnRunTip=Trust this applet and run with full permissions CertWarnSandboxTip=Do not trust this applet and run with restricted permissions CertWarnCancelTip=Do not run this applet +CertWarnPolicyTip=Advanced sandbox settings +CertWarnPolicyEditorItem=Launch PolicyEditor AFileOnTheMachine=a file on the machine AlwaysAllowAction=Always allow this action diff --git a/netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java b/netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java --- a/netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java +++ b/netx/net/sourceforge/jnlp/security/dialogs/CertWarningPane.java @@ -50,6 +50,8 @@ import java.awt.event.ActionListener; 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; @@ -60,11 +62,15 @@ import javax.swing.ImageIcon; 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.JNLPRuntime; import net.sourceforge.jnlp.security.CertVerifier; import net.sourceforge.jnlp.security.CertificateUtils; import net.sourceforge.jnlp.security.HttpsCertVerifier; @@ -74,6 +80,7 @@ import net.sourceforge.jnlp.security.Key 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.util.FileUtils; import net.sourceforge.jnlp.util.logging.OutputController; @@ -87,12 +94,27 @@ import net.sourceforge.jnlp.util.logging */ public class CertWarningPane extends SecurityDialogPanel { + JNLPFile file; + AccessType accessType; + Certificate cert; JCheckBox alwaysTrust; CertVerifier certVerifier; + JPopupMenu policyMenu; + JPanel topPanel, infoPanel, buttonPanel, bottomPanel; + JLabel topLabel, nameLabel, publisherLabel, fromLabel, bottomLabel; + JButton run, sandbox, advancedOptions, cancel, moreInfo; + boolean alwaysTrustSelected; + String bottomLabelWarningText; + PolicyEditor policyEditor = null; public CertWarningPane(SecurityDialog x, CertVerifier certVerifier) { super(x, certVerifier); this.certVerifier = certVerifier; + + accessType = parent.getAccessType(); + file = parent.getFile(); + cert = parent.getCertVerifier().getPublisher(null); + addComponents(); } @@ -100,10 +122,11 @@ public class CertWarningPane extends Sec * Creates the actual GUI components, and adds it to this panel */ private void addComponents() { - AccessType type = parent.getAccessType(); - JNLPFile file = parent.getFile(); - Certificate c = parent.getCertVerifier().getPublisher(null); + setTextAndLabels(); + addButtons(); + } + private void setTextAndLabels() { String name = ""; String publisher = ""; String from = ""; @@ -112,8 +135,8 @@ public class CertWarningPane extends Sec //these strings -- we just want to fill in as many as possible. try { if ((certVerifier instanceof HttpsCertVerifier) && - (c instanceof X509Certificate)) { - name = SecurityUtil.getCN(((X509Certificate) c) + (cert instanceof X509Certificate)) { + name = SecurityUtil.getCN(((X509Certificate) cert) .getSubjectX500Principal().getName()); } else if (file instanceof PluginBridge) { name = file.getTitle(); @@ -124,8 +147,8 @@ public class CertWarningPane extends Sec } try { - if (c instanceof X509Certificate) { - publisher = SecurityUtil.getCN(((X509Certificate) c) + if (cert instanceof X509Certificate) { + publisher = SecurityUtil.getCN(((X509Certificate) cert) .getSubjectX500Principal().getName()); } } catch (Exception e) { @@ -142,63 +165,60 @@ public class CertWarningPane extends Sec // Labels String topLabelText = ""; - String bottomLabelText = parent.getCertVerifier().getRootInCacerts() ? - R("STrustedSource") : R("SUntrustedSource"); - String propertyName = ""; + bottomLabelWarningText = parent.getCertVerifier().getRootInCacerts() ? + R("STrustedSource") : R("SUntrustedSource"); String iconLocation = "net/sourceforge/jnlp/resources/"; - boolean alwaysTrustSelected = false; + alwaysTrustSelected = false; if (certVerifier instanceof HttpsCertVerifier) { // HTTPS certs that are verified do not prompt for a dialog. // @see VariableX509TrustManager#checkServerTrusted topLabelText = R("SHttpsUnverified") + " " + R("Continue"); - propertyName = "OptionPane.warningIcon"; iconLocation += "warning.png"; } else { - switch (type) { + switch (accessType) { case VERIFIED: topLabelText = R("SSigVerified"); - propertyName = "OptionPane.informationIcon"; iconLocation += "question.png"; alwaysTrustSelected = true; break; case UNVERIFIED: topLabelText = R("SSigUnverified"); - propertyName = "OptionPane.warningIcon"; iconLocation += "warning.png"; - bottomLabelText += " " + R("SWarnFullPermissionsIgnorePolicy"); + bottomLabelWarningText += " " + R("SWarnFullPermissionsIgnorePolicy"); break; case SIGNING_ERROR: topLabelText = R("SSignatureError"); - propertyName = "OptionPane.warningIcon"; iconLocation += "warning.png"; - bottomLabelText += " " + R("SWarnFullPermissionsIgnorePolicy"); + bottomLabelWarningText += " " + R("SWarnFullPermissionsIgnorePolicy"); break; } } ImageIcon icon = new ImageIcon((new sun.misc.Launcher()) .getClassLoader().getResource(iconLocation)); - JLabel topLabel = new JLabel(htmlWrap(topLabelText), icon, SwingConstants.LEFT); + topLabel = new JLabel(htmlWrap(topLabelText), icon, SwingConstants.LEFT); topLabel.setFont(new Font(topLabel.getFont().toString(), Font.BOLD, 12)); - JPanel topPanel = new JPanel(new BorderLayout()); + topPanel = new JPanel(new BorderLayout()); topPanel.setBackground(Color.WHITE); topPanel.add(topLabel, BorderLayout.CENTER); topPanel.setPreferredSize(new Dimension(400, 75)); topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); //application info - JLabel nameLabel = new JLabel(R("Name") + ": " + name); + nameLabel = new JLabel(R("Name") + ": " + name); nameLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - JLabel publisherLabel = new JLabel(R("Publisher") + ": " + publisher); + publisherLabel = new JLabel(R("Publisher") + ": " + publisher); publisherLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - JLabel fromLabel = new JLabel(R("From") + ": " + from); + fromLabel = new JLabel(R("From") + ": " + from); fromLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + } + private void addButtons() { alwaysTrust = new JCheckBox(R("SAlwaysTrustPublisher")); alwaysTrust.setEnabled(true); alwaysTrust.setSelected(alwaysTrustSelected); - JPanel infoPanel = new JPanel(new GridLayout(4, 1)); + infoPanel = new JPanel(new GridLayout(4, 1)); infoPanel.add(nameLabel); infoPanel.add(publisherLabel); @@ -210,12 +230,15 @@ public class CertWarningPane extends Sec infoPanel.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25)); //run and cancel buttons - JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); - JButton run = new JButton(R("ButRun")); - JButton sandbox = new JButton(R("ButSandbox")); - JButton cancel = new JButton(R("ButCancel")); + buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + run = new JButton(R("ButRun")); + sandbox = new JButton(R("ButSandbox")); + advancedOptions = new JButton(R("ButPolicyEditorDropdown")); + cancel = new JButton(R("ButCancel")); + run.setToolTipText(R("CertWarnRunTip")); sandbox.setToolTipText(R("CertWarnSandboxTip")); + advancedOptions.setToolTipText(R("CertWarnPolicyTip")); cancel.setToolTipText(R("CertWarnCancelTip")); alwaysTrust.addActionListener(new ButtonDisableListener(sandbox)); @@ -224,16 +247,24 @@ public class CertWarningPane extends Sec buttonWidth = Math.max(buttonWidth, cancel.getMinimumSize().width); int buttonHeight = run.getMinimumSize().height; Dimension d = new Dimension(buttonWidth, buttonHeight); + run.setPreferredSize(d); sandbox.setPreferredSize(d); + advancedOptions.setPreferredSize(new Dimension(advancedOptions.getMinimumSize().width, buttonHeight)); cancel.setPreferredSize(d); sandbox.setEnabled(!alwaysTrust.isSelected()); run.addActionListener(createSetValueListener(parent, 0)); run.addActionListener(new CheckBoxListener()); + sandbox.addActionListener(createSetValueListener(parent, 1)); + + advancedOptions.addActionListener(new PolicyEditorPopupListener(buttonHeight)); + advancedOptions.add(createPolicyPermissionsMenu()); + cancel.addActionListener(createSetValueListener(parent, 2)); + initialFocusComponent = cancel; buttonPanel.add(run); // file will be null iff this dialog is being called from VariableX509TrustManager. @@ -242,8 +273,10 @@ public class CertWarningPane extends Sec // Since there is no app, there is nothing to run sandboxed. if (file != null) { buttonPanel.add(sandbox); + buttonPanel.add(advancedOptions); } buttonPanel.add(cancel); + buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); //all of the above @@ -252,18 +285,66 @@ public class CertWarningPane extends Sec add(infoPanel); add(buttonPanel); - JLabel bottomLabel = new JLabel(htmlWrap(bottomLabelText)); - JButton moreInfo = new JButton(R("ButMoreInformation")); + bottomLabel = new JLabel(htmlWrap(bottomLabelWarningText)); + moreInfo = new JButton(R("ButMoreInformation")); moreInfo.addActionListener(new MoreInfoButtonListener()); - JPanel bottomPanel = new JPanel(); + bottomPanel = new JPanel(); bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS)); bottomPanel.add(bottomLabel); bottomPanel.add(moreInfo); bottomPanel.setPreferredSize(new Dimension(600, 100)); bottomPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); add(bottomPanel); + } + private JPopupMenu createPolicyPermissionsMenu() { + policyMenu = new JPopupMenu(); + + JMenuItem launchPolicyEditor = new JMenuItem(R("CertWarnPolicyEditorItem")); + launchPolicyEditor.addActionListener(new PolicyEditorLaunchListener()); + + policyMenu.add(launchPolicyEditor); + policyMenu.setSize(policyMenu.getMinimumSize()); + 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.isClosed()) { + policyEditor = PolicyEditor.createInstance(filepath); + } else { + policyEditor.toFront(); + policyEditor.repaint(); + } + policyEditor.addNewCodebase(file.getCodeBase().toString()); + policyEditor.setVisible(true); + policyMenu.setVisible(false); + } + } + + private class PolicyEditorPopupListener implements ActionListener { + + private final int buttonHeight; + + public PolicyEditorPopupListener(final int buttonHeight) { + this.buttonHeight = buttonHeight; + } + + @Override + public void actionPerformed(final ActionEvent e) { + policyMenu.setLocation(advancedOptions.getLocationOnScreen().x, advancedOptions.getLocationOnScreen().y + buttonHeight); + policyMenu.setVisible(!policyMenu.isVisible()); + } } private class MoreInfoButtonListener implements ActionListener {