changeset 2064:1c6ebab0ea7f

2010-07-21 Deepak Bhole <dbhole@redhat.com> * netx/net/sourceforge/jnlp/resources/Messages.properties: Add new strings. * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java (getInstance): Prompt user if the main app code is signed, but the extentions aren't. (initializeResources): Prompt user if there are any unsigned jars mixed with signed jars. * netx/net/sourceforge/jnlp/security/NotAllSignedWarningPane.java: New file. Dialog shown to user if the main app code is signed but the extentions aren't. * netx/net/sourceforge/jnlp/security/SecurityDialogUI.java (SecurityDialogUI): Add a constructor that doesn't take a CertVerifier object. * netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java: Added dialog and accesstype enum elements for a 'Not all jars signed' case. (showNotAllSignedWarningDialog): New function. Prompts the user if the main app code is signed but the extentions aren't. (createDialog): Wire in the 'Not all jars signed' case. (updateUI): Same. * netx/net/sourceforge/jnlp/tools/JarSigner.java (allJarsSigned): New function. Returns if there are any unsigned jars.
author doko@ubuntu.com
date Sat, 24 Jul 2010 00:49:21 +0200
parents 50249f734932
children 9257ba041f18
files ChangeLog netx/net/sourceforge/jnlp/resources/Messages.properties netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java netx/net/sourceforge/jnlp/security/NotAllSignedWarningPane.java netx/net/sourceforge/jnlp/security/SecurityDialogUI.java netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java netx/net/sourceforge/jnlp/tools/JarSigner.java
diffstat 7 files changed, 207 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Jul 24 00:46:24 2010 +0200
+++ b/ChangeLog	Sat Jul 24 00:49:21 2010 +0200
@@ -1,3 +1,24 @@
+2010-07-21  Deepak Bhole <dbhole@redhat.com>
+
+	* netx/net/sourceforge/jnlp/resources/Messages.properties: Add new strings.
+	* netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java (getInstance):
+	Prompt user if the main app code is signed, but the extentions aren't.
+	(initializeResources): Prompt user if there are any unsigned jars mixed
+	with signed jars.
+	* netx/net/sourceforge/jnlp/security/NotAllSignedWarningPane.java: New file.
+	Dialog shown to user if the main app code is signed but the extentions aren't.
+	* netx/net/sourceforge/jnlp/security/SecurityDialogUI.java
+	(SecurityDialogUI): Add a constructor that doesn't take a CertVerifier
+	object.
+	* netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java: Added
+	dialog and accesstype enum elements for a 'Not all jars signed' case.
+	(showNotAllSignedWarningDialog): New function. Prompts the user if the
+	main app code is signed but the extentions aren't.
+	(createDialog): Wire in the 'Not all jars signed' case.
+	(updateUI): Same.
+	* netx/net/sourceforge/jnlp/tools/JarSigner.java (allJarsSigned): New
+	function. Returns if there are any unsigned jars.
+
 2010-07-21  Deepak Bhole <dbhole@redhat.com>
 
 	* netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java (getInstance):
--- a/netx/net/sourceforge/jnlp/resources/Messages.properties	Sat Jul 24 00:46:24 2010 +0200
+++ b/netx/net/sourceforge/jnlp/resources/Messages.properties	Sat Jul 24 00:49:21 2010 +0200
@@ -52,6 +52,8 @@
 LCantDetermineMainClassInfo=Could not determine the main class for this application.
 LUnsignedJarWithSecurity=Cannot grant permissions to unsigned jars.
 LUnsignedJarWithSecurityInfo=Application requested security permissions, but jars are not signed.
+LSignedAppJarUsingUnsignedJar=Signed application using unsigned jars.
+LSignedAppJarUsingUnsignedJarInfo=The main application jar is signed, but some of the jars it is using aren't.
 
 JNotApplet=File is not an applet.
 JNotApplication=File is not an application.
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Sat Jul 24 00:46:24 2010 +0200
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Sat Jul 24 00:49:21 2010 +0200
@@ -249,6 +249,11 @@
 		        JNLPClassLoader extLoader = (JNLPClassLoader) urlToLoader.get(uniqueKey);
 
 		        if (extLoader != null && extLoader != loader) {
+
+		        	if (loader.signing && !extLoader.signing)
+		        		if (!SecurityWarningDialog.showNotAllSignedWarningDialog(file))
+		        			throw new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LSignedAppJarUsingUnsignedJar"), R("LSignedAppJarUsingUnsignedJarInfo"));
+
 		            for (URL u : extLoader.getURLs())
 		            	loader.addURL(u);
 		            for (File nativeDirectory: extLoader.getNativeDirectories())
@@ -400,6 +405,10 @@
 			if (js.anyJarsSigned()){
 				signing = true;
 
+				if (!js.allJarsSigned() && 
+					!SecurityWarningDialog.showNotAllSignedWarningDialog(file))
+        			throw new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LSignedAppJarUsingUnsignedJar"), R("LSignedAppJarUsingUnsignedJarInfo"));
+				
 				//user does not trust this publisher
 				if (!js.getAlreadyTrustPublisher()) {
 				    checkTrustWithUser(js);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/security/NotAllSignedWarningPane.java	Sat Jul 24 00:49:21 2010 +0200
@@ -0,0 +1,126 @@
+/* AppletWarningPane.java
+   Copyright (C) 2008 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;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+import net.sourceforge.jnlp.JNLPFile;
+
+
+public class NotAllSignedWarningPane extends SecurityDialogUI {
+
+	public NotAllSignedWarningPane(SecurityWarningDialog x) {
+		super(x);
+		installComponents();
+	}
+
+	/**
+	 * Creates the actual GUI components, and adds it to this panel
+	 */
+	protected void installComponents() {
+
+		String topLabelText = "Only parts of this application code are signed.";
+		String infoLabelText = "This application contains both signed and" +
+		" unsigned code. While signed code is safe if you trust the " +
+		"provider, unsigned code may imply code outside of the trusted " +
+		"provider's control.";
+		String questionLabelText = "Do you wish to proceed and run this " +
+		"application anyway?";
+		
+		ImageIcon icon = new ImageIcon((new sun.misc.Launcher()).getClassLoader().getResource("net/sourceforge/jnlp/resources/warning.png"));
+		JLabel 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.setBackground(Color.WHITE);
+		topPanel.add(topLabel, BorderLayout.CENTER);
+		topPanel.setPreferredSize(new Dimension(500,80));
+		topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+		JLabel infoLabel = new JLabel(htmlWrap(infoLabelText));		
+		JPanel infoPanel = new JPanel(new BorderLayout());
+		infoPanel.add(infoLabel, BorderLayout.CENTER);
+		infoPanel.setPreferredSize(new Dimension(500,100));
+		infoPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+		
+		JLabel questionLabel = new JLabel(htmlWrap(questionLabelText));		
+		JPanel questionPanel = new JPanel(new BorderLayout());
+		questionPanel.add(questionLabel, BorderLayout.CENTER);
+		questionPanel.setPreferredSize(new Dimension(500,100));
+		questionPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+		//run and cancel buttons
+		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+
+		JButton run = new JButton("Proceed");
+		JButton cancel = new JButton("Cancel");
+		run.addActionListener(createButtonActionListener(0));
+		cancel.addActionListener(createButtonActionListener(1));
+		initialFocusComponent = cancel;
+		buttonPanel.add(run);
+		buttonPanel.add(cancel);
+		buttonPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+		//all of the above
+		JPanel main = new JPanel();
+		main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS));
+		main.add(topPanel);
+		main.add(infoPanel);
+		main.add(questionPanel);
+		main.add(buttonPanel);
+		
+		optionPane.add(main, BorderLayout.CENTER);
+	}
+	
+	protected String htmlWrap (String s) {
+        return "<html>"+s+"</html>";
+	}
+}
+
--- a/netx/net/sourceforge/jnlp/security/SecurityDialogUI.java	Sat Jul 24 00:46:24 2010 +0200
+++ b/netx/net/sourceforge/jnlp/security/SecurityDialogUI.java	Sat Jul 24 00:49:21 2010 +0200
@@ -68,7 +68,7 @@
 	/** Component to receive focus when messaged with selectInitialValue. */
 	Component initialFocusComponent;
 	
-	CertVerifier certVerifier;
+	CertVerifier certVerifier = null;
 
 	/** PropertyChangeListener for <code>optionPane</code> */
 	private PropertyChangeListener propertyChangeListener;
@@ -79,6 +79,10 @@
 		this.certVerifier = certVerifier;
 	}
 
+	public SecurityDialogUI(JComponent x){
+		optionPane = (JOptionPane)x;
+	}
+
 	/**
 	 * Installs the user interface for the SecurityWarningDialog.
 	 */
--- a/netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java	Sat Jul 24 00:46:24 2010 +0200
+++ b/netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java	Sat Jul 24 00:49:21 2010 +0200
@@ -63,6 +63,7 @@
 		CERT_INFO,
 		SINGLE_CERT_INFO,
 		ACCESS_WARNING,
+		NOTALLSIGNED_WARNING,
 		APPLET_WARNING
 	}
 	
@@ -77,6 +78,7 @@
         NETWORK,
         VERIFIED,
         UNVERIFIED,
+        NOTALLSIGNED,
         SIGNING_ERROR
     }
 
@@ -210,6 +212,35 @@
 		}
 	
 	/**
+	 * Shows a warning dialog for when the main application jars are signed, 
+	 * but extensions aren't
+	 * 
+	 * @return true if permission was granted by the user, false otherwise.
+	 */
+	public static boolean showNotAllSignedWarningDialog(JNLPFile file) {
+			SecurityWarningDialog swd = new SecurityWarningDialog(
+					DialogType.NOTALLSIGNED_WARNING, AccessType.NOTALLSIGNED, file, (new Object[0]));
+			JDialog dialog = swd.createDialog();
+			swd.selectInitialValue();
+			dialog.setResizable(true);
+			centerDialog(dialog);
+			dialog.setVisible(true);
+			dialog.dispose();
+
+			Object selectedValue = swd.getValue();
+			if (selectedValue == null) {
+				return false;
+			} else if (selectedValue instanceof Integer) {
+				if (((Integer)selectedValue).intValue() == 0)
+					return true;
+				else
+					return false;
+			} else {
+				return false;
+			}
+		}	
+	
+	/**
 	 * Shows a security warning dialog according to the specified type of
 	 * access. If <code>type</code> is one of AccessType.VERIFIED or
 	 * AccessType.UNVERIFIED, extra details will be available with regards
@@ -334,6 +365,8 @@
 			dialogTitle = "Security Warning";
 		else if (dialogType == DialogType.APPLET_WARNING)
 			dialogTitle = "Applet Warning";
+		else if (dialogType == DialogType.NOTALLSIGNED_WARNING)
+			dialogTitle = "Security Warning";
 
 		final JDialog dialog = new JDialog((Frame)null, dialogTitle, true);
 		
@@ -418,6 +451,8 @@
 			setUI((OptionPaneUI) new AccessWarningPane(this, extras, this.certVerifier));
 		else if (dialogType == DialogType.APPLET_WARNING)
 			setUI((OptionPaneUI) new AppletWarningPane(this, this.certVerifier));
+		else if (dialogType == DialogType.NOTALLSIGNED_WARNING)
+			setUI((OptionPaneUI) new NotAllSignedWarningPane(this));
 	}
 
 	private static void centerDialog(JDialog dialog) {
--- a/netx/net/sourceforge/jnlp/tools/JarSigner.java	Sat Jul 24 00:46:24 2010 +0200
+++ b/netx/net/sourceforge/jnlp/tools/JarSigner.java	Sat Jul 24 00:49:21 2010 +0200
@@ -537,7 +537,15 @@
             //
         }
     }
-
+    
+    /**
+     * Returns if all jars are signed. 
+     * 
+     * @return True if all jars are signed, false if there are one or more unsigned jars
+     */
+    public boolean allJarsSigned() {
+    	return this.unverifiedJars.size() == 0;
+    }
 }