[RFC] netx: show security dialogs in a separate AppContext
Dr Andrew John Hughes
ahughes at redhat.com
Tue Oct 19 10:37:25 PDT 2010
On 12:09 Tue 19 Oct , Omair Majid wrote:
> Hi,
>
> The attached patch makes security prompts appear in a separate
> AppContext. This ensures that the applet's look and feel is not
> automatically set to the system look and feel.
>
> The patch is a superset of
> http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2010-October/010500.html
>
> This patch also implements a large part of the code necessary to allow
> applets to access their EventQueues. However, I still have to figure out
> how to use http://hg.openjdk.java.net/jdk7/awt/jdk/rev/8022709a306d to
> ensure allowing access to the EventQueue is safe. So for now, that code
> is disabled.
>
> The patch ensures that the JNLPRuntime is always initialized in the main
> AppContext. It starts a thread in this AppContext to listen for security
> dialog messages, and shows security dialogs when it receives an
> appropriate security message. The security dialogs block the client
> applet/application until the user responds.
>
> Any thoughts or comments?
>
This needs to be applied against the new IcedTea-Web repository when approved.
I'm doing a test build then will be deleting NetX and the plugin from IcedTea6.
> Thanks,
> Omair
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/NetxPanel.java
> --- a/netx/net/sourceforge/jnlp/NetxPanel.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/NetxPanel.java Tue Oct 19 12:07:40 2010 -0400
> @@ -83,19 +83,6 @@
> getHeight(),
> atts);
>
> - synchronized(JNLPRuntime.initMutex) {
> - //The custom NetX Policy and SecurityManager are set here.
> - if (!JNLPRuntime.isInitialized()) {
> - if (JNLPRuntime.isDebug())
> - System.out.println("initializing JNLPRuntime...");
> -
> - JNLPRuntime.initialize(false);
> - } else {
> - if (JNLPRuntime.isDebug())
> - System.out.println("JNLPRuntime already initialized");
> - }
> - }
> -
> doInit = true;
> dispatchAppletEvent(APPLET_LOADING, null);
> status = APPLET_LOAD;
> @@ -145,6 +132,19 @@
> */
> // Reminder: Relax visibility in sun.applet.AppletPanel
> protected synchronized void createAppletThread() {
> + synchronized(JNLPRuntime.initMutex) {
> + //The custom NetX Policy and SecurityManager are set here.
> + if (!JNLPRuntime.isInitialized()) {
> + if (JNLPRuntime.isDebug())
> + System.out.println("initializing JNLPRuntime...");
> +
> + JNLPRuntime.initialize(false);
> + } else {
> + if (JNLPRuntime.isDebug())
> + System.out.println("JNLPRuntime already initialized");
> + }
> + }
> +
> // when this was being done (incorrectly) in Launcher, the call was
> // new AppThreadGroup(mainGroup, file.getTitle());
> ThreadGroup tg = new AppThreadGroup(Launcher.mainGroup,
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/runtime/ApplicationInstance.java
> --- a/netx/net/sourceforge/jnlp/runtime/ApplicationInstance.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/runtime/ApplicationInstance.java Tue Oct 19 12:07:40 2010 -0400
> @@ -35,7 +35,7 @@
> import net.sourceforge.jnlp.ShortcutDesc;
> import net.sourceforge.jnlp.event.ApplicationEvent;
> import net.sourceforge.jnlp.event.ApplicationListener;
> -import net.sourceforge.jnlp.security.SecurityWarningDialog.AccessType;
> +import net.sourceforge.jnlp.security.AccessType;
> import net.sourceforge.jnlp.services.ServiceUtil;
> import net.sourceforge.jnlp.util.WeakList;
> import net.sourceforge.jnlp.util.XDesktopEntry;
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
> --- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java Tue Oct 19 12:07:40 2010 -0400
> @@ -57,7 +57,8 @@
> import net.sourceforge.jnlp.cache.CacheUtil;
> import net.sourceforge.jnlp.cache.ResourceTracker;
> import net.sourceforge.jnlp.cache.UpdatePolicy;
> -import net.sourceforge.jnlp.security.SecurityWarningDialog;
> +import net.sourceforge.jnlp.security.SecurityWarning;
> +import net.sourceforge.jnlp.security.AccessType;
> import net.sourceforge.jnlp.tools.JarSigner;
> import sun.misc.JarIndex;
>
> @@ -254,7 +255,7 @@
>
> if (extLoader != null && extLoader != loader) {
> if (loader.signing && !extLoader.signing)
> - if (!SecurityWarningDialog.showNotAllSignedWarningDialog(file))
> + if (!SecurityWarning.showNotAllSignedWarningDialog(file))
> throw new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LSignedAppJarUsingUnsignedJar"), R("LSignedAppJarUsingUnsignedJarInfo"));
>
> loader.merge(extLoader);
> @@ -401,7 +402,7 @@
> signing = true;
>
> if (!js.allJarsSigned() &&
> - !SecurityWarningDialog.showNotAllSignedWarningDialog(file))
> + !SecurityWarning.showNotAllSignedWarningDialog(file))
> throw new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LSignedAppJarUsingUnsignedJar"), R("LSignedAppJarUsingUnsignedJarInfo"));
>
>
> @@ -455,19 +456,19 @@
>
> private void checkTrustWithUser(JarSigner js) throws LaunchException {
> if (!js.getRootInCacerts()) { //root cert is not in cacerts
> - boolean b = SecurityWarningDialog.showCertWarningDialog(
> - SecurityWarningDialog.AccessType.UNVERIFIED, file, js);
> + boolean b = SecurityWarning.showCertWarningDialog(
> + AccessType.UNVERIFIED, file, js);
> if (!b)
> throw new LaunchException(null, null, R("LSFatal"),
> R("LCLaunching"), R("LNotVerified"), "");
> } else if (js.getRootInCacerts()) { //root cert is in cacerts
> boolean b = false;
> if (js.noSigningIssues())
> - b = SecurityWarningDialog.showCertWarningDialog(
> - SecurityWarningDialog.AccessType.VERIFIED, file, js);
> + b = SecurityWarning.showCertWarningDialog(
> + AccessType.VERIFIED, file, js);
> else if (!js.noSigningIssues())
> - b = SecurityWarningDialog.showCertWarningDialog(
> - SecurityWarningDialog.AccessType.SIGNING_ERROR, file, js);
> + b = SecurityWarning.showCertWarningDialog(
> + AccessType.SIGNING_ERROR, file, js);
> if (!b)
> throw new LaunchException(null, null, R("LSFatal"),
> R("LCLaunching"), R("LCancelOnUserRequest"), "");
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java
> --- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java Tue Oct 19 12:07:40 2010 -0400
> @@ -25,9 +25,11 @@
> import java.util.List;
> import java.security.*;
> import javax.jnlp.*;
> +import javax.swing.UIManager;
>
> import net.sourceforge.jnlp.*;
> import net.sourceforge.jnlp.cache.*;
> +import net.sourceforge.jnlp.security.SecurityDialogMessageHandler;
> import net.sourceforge.jnlp.services.*;
> import net.sourceforge.jnlp.util.*;
>
> @@ -63,6 +65,9 @@
> /** the security policy */
> private static JNLPPolicy policy;
>
> + /** handles all security message to show appropriate security dialogs */
> + private static SecurityDialogMessageHandler securityDialogMessageHandler;
> +
> /** the base dir for cache, etc */
> private static File baseDir;
>
> @@ -165,6 +170,8 @@
> * security manager and security policy, initializing the JNLP
> * standard services, etc.<p>
> *
> + * This method should be called from the main AppContext/Thread. <p>
> + *
> * This method cannot be called more than once. Once
> * initialized, methods that alter the runtime can only be
> * called by the exit class.<p>
> @@ -206,15 +213,39 @@
> policy = new JNLPPolicy();
> security = new JNLPSecurityManager(); // side effect: create JWindow
>
> + try {
> + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
> + } catch (Exception e) {
> + // ignore it
> + }
> +
> if (securityEnabled) {
> Policy.setPolicy(policy); // do first b/c our SM blocks setPolicy
> System.setSecurityManager(security);
> }
>
> + securityDialogMessageHandler = startSecurityThreads();
> +
> initialized = true;
> }
>
> /**
> + * This must NOT be called form the application ThreadGroup. An application
> + * can inject events into its {@link EventQueue} and bypass the security
> + * dialogs.
> + *
> + * @return a {@link SecurityDialogMessageHandler} that can be used to post
> + * security messages
> + */
> + private static SecurityDialogMessageHandler startSecurityThreads() {
> + ThreadGroup securityThreadGroup = new ThreadGroup("NetxSecurityThreadGroup");
> + SecurityDialogMessageHandler runner = new SecurityDialogMessageHandler();
> + Thread securityThread = new Thread(securityThreadGroup, runner, "NetxSecurityThread");
> + securityThread.start();
> + return runner;
> + }
> +
> + /**
> * Returns true if a webstart application has been initialized, and false
> * for a plugin applet.
> */
> @@ -321,6 +352,20 @@
> }
>
> /**
> + *
> + * @return the {@link SecurityDialogMessageHandler} that should be used to
> + * post security dialog messages
> + */
> + public static SecurityDialogMessageHandler getSecurityDialogHandler() {
> + SecurityManager sm = System.getSecurityManager();
> + if (sm != null) {
> + // TODO might want to reduce the permission required
> + sm.checkPermission(new AllPermission());
> + }
> + return securityDialogMessageHandler;
> + }
> +
> + /**
> * Returns the system default base dir for or if not set,
> * prompts the user for the location.
> *
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java
> --- a/netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java Tue Oct 19 12:07:40 2010 -0400
> @@ -34,7 +34,7 @@
> import javax.swing.JWindow;
>
> import net.sourceforge.jnlp.JNLPFile;
> -import net.sourceforge.jnlp.security.SecurityWarningDialog;
> +import net.sourceforge.jnlp.security.AccessType;
> import net.sourceforge.jnlp.services.ServiceUtil;
> import net.sourceforge.jnlp.util.WeakList;
> import sun.awt.AWTSecurityManager;
> @@ -392,7 +392,7 @@
> ApplicationInstance app = getApplication();
> if (app != null && !app.isSigned()) {
> if (perm instanceof SocketPermission
> - && ServiceUtil.checkAccess(SecurityWarningDialog.AccessType.NETWORK, perm.getName())) {
> + && ServiceUtil.checkAccess(AccessType.NETWORK, perm.getName())) {
> return true;
> }
> }
> @@ -434,7 +434,7 @@
> Window w = (Window) window;
>
> if (JNLPRuntime.isDebug())
> - System.err.println("SM: app: "+app.getTitle()+" is adding a window: "+window);
> + System.err.println("SM: app: "+app.getTitle()+" is adding a window: "+window+" with appContext"+AppContext.getAppContext());
>
> weakWindows.add(window); // for mapping window -> app
> weakApplications.add(app);
> @@ -538,4 +538,31 @@
>
> }
>
> + /**
> + * Tests if a client can get access to the AWT event queue. This version allows
> + * complete access to the EventQueue for its own AppContext-specific EventQueue.
> + *
> + * FIXME there are probably huge security implications for this. Eg:
> + * http://hg.openjdk.java.net/jdk7/awt/jdk/rev/8022709a306d
> + *
> + * @exception SecurityException if the caller does not have
> + * permission to accesss the AWT event queue.
> + */
> + public void checkAwtEventQueueAccess() {
> + /*
> + * this is the templace of the code that should allow applets access to
> + * eventqueues
> + */
> +
> + // AppContext appContext = AppContext.getAppContext();
> + // ApplicationInstance instance = getApplication();
> +
> + // if ((appContext == mainAppContext) && (instance != null)) {
> + // If we're about to allow access to the main EventQueue,
> + // and anything untrusted is on the class context stack,
> + // disallow access.
> + super.checkAwtEventQueueAccess();
> + // }
> + }
> +
> }
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/security/AccessType.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/netx/net/sourceforge/jnlp/security/AccessType.java Tue Oct 19 12:07:40 2010 -0400
> @@ -0,0 +1,53 @@
> +/* AccessType.java
> + Copyright (C) 2010 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;
> +
> +/** The types of access which may need user permission. */
> +public enum AccessType {
> + READ_FILE,
> + WRITE_FILE,
> + CREATE_DESTKOP_SHORTCUT,
> + CLIPBOARD_READ,
> + CLIPBOARD_WRITE,
> + PRINTER,
> + NETWORK,
> + VERIFIED,
> + UNVERIFIED,
> + NOTALLSIGNED,
> + SIGNING_ERROR
> +}
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/security/AccessWarningPane.java
> --- a/netx/net/sourceforge/jnlp/security/AccessWarningPane.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/security/AccessWarningPane.java Tue Oct 19 12:07:40 2010 -0400
> @@ -56,6 +56,7 @@
> import javax.swing.SwingConstants;
>
> import net.sourceforge.jnlp.JNLPFile;
> +import net.sourceforge.jnlp.security.AccessType;
> import net.sourceforge.jnlp.util.FileUtils;
>
> /**
> @@ -86,7 +87,7 @@
> * Creates the actual GUI components, and adds it to this panel
> */
> private void addComponents() {
> - SecurityWarningDialog.AccessType type = parent.getAccessType();
> + AccessType type = parent.getAccessType();
> JNLPFile file = parent.getFile();
>
> String name = "";
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/security/CertWarningPane.java
> --- a/netx/net/sourceforge/jnlp/security/CertWarningPane.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/security/CertWarningPane.java Tue Oct 19 12:07:40 2010 -0400
> @@ -60,6 +60,7 @@
> import net.sourceforge.jnlp.JNLPFile;
> import net.sourceforge.jnlp.PluginBridge;
> import net.sourceforge.jnlp.runtime.JNLPRuntime;
> +import net.sourceforge.jnlp.security.AccessType;
> import net.sourceforge.jnlp.tools.KeyTool;
>
> /**
> @@ -85,7 +86,7 @@
> * Creates the actual GUI components, and adds it to this panel
> */
> private void addComponents() {
> - SecurityWarningDialog.AccessType type = parent.getAccessType();
> + AccessType type = parent.getAccessType();
> JNLPFile file = parent.getFile();
> Certificate c = parent.getJarSigner().getPublisher();
>
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/security/SecurityDialogMessage.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/netx/net/sourceforge/jnlp/security/SecurityDialogMessage.java Tue Oct 19 12:07:40 2010 -0400
> @@ -0,0 +1,40 @@
> +package net.sourceforge.jnlp.security;
> +
> +import java.security.cert.X509Certificate;
> +import java.util.concurrent.Semaphore;
> +
> +import javax.swing.JDialog;
> +
> +import net.sourceforge.jnlp.JNLPFile;
> +import net.sourceforge.jnlp.security.AccessType;
> +import net.sourceforge.jnlp.security.SecurityWarning.DialogType;
> +
> +/**
> + * Represents a message to the security framework to show a specific security
> + * dialog
> + */
> +final class SecurityDialogMessage {
> +
> + /*
> + * These fields contain information need to display the correct dialog type
> + */
> +
> + public DialogType dialogType;
> + public AccessType accessType;
> + public JNLPFile file;
> + public CertVerifier certVerifier;
> + public X509Certificate certificate;
> + public Object[] extras;
> +
> + public volatile Object userResponse;
> +
> + /*
> + * These two fields are used to block/unblock the application or the applet.
> + * If either of them is not null, call release() or dispose() on it to allow
> + * the application/applet to continue.
> + */
> +
> + public Semaphore lock;
> + public JDialog toDispose;
> +
> +}
> \ No newline at end of file
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/security/SecurityDialogMessageHandler.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/netx/net/sourceforge/jnlp/security/SecurityDialogMessageHandler.java Tue Oct 19 12:07:40 2010 -0400
> @@ -0,0 +1,68 @@
> +package net.sourceforge.jnlp.security;
> +
> +import java.awt.event.ActionEvent;
> +import java.awt.event.ActionListener;
> +import java.util.concurrent.BlockingQueue;
> +import java.util.concurrent.LinkedBlockingQueue;
> +
> +import net.sourceforge.jnlp.runtime.JNLPRuntime;
> +
> +/**
> + * Handles {@link SecurityDialogMessage}s and shows appropriate security dialogs
> + */
> +public final class SecurityDialogMessageHandler implements Runnable {
> +
> + private BlockingQueue<SecurityDialogMessage> queue = new LinkedBlockingQueue<SecurityDialogMessage>();
> +
> + @Override
> + public void run() {
> + try {
> + if (JNLPRuntime.isDebug()) {
> + System.out.println("Starting security dialog thread");
> + }
> + while (true) {
> + SecurityDialogMessage msg = queue.take();
> + handleMessage(msg);
> + }
> + } catch (InterruptedException e) {
> + if (JNLPRuntime.isDebug()) {
> + System.out.println("Shutting down security event thread");
> + }
> + return;
> + }
> +
> + }
> +
> + private void handleMessage(SecurityDialogMessage message) {
> + final SecurityDialogMessage msg = message;
> +
> + final SecurityWarningDialog dialog = new SecurityWarningDialog(message.dialogType,
> + message.accessType, message.file, message.certVerifier, message.certificate, message.extras);
> +
> + dialog.addActionListener(new ActionListener() {
> +
> + @Override
> + public void actionPerformed(ActionEvent e) {
> + msg.userResponse = dialog.getValue();
> + /* Allow the client to continue on the other side */
> + if (msg.toDispose != null) {
> + msg.toDispose.dispose();
> + }
> + if (msg.lock != null) {
> + msg.lock.release();
> + }
> + }
> + });
> + dialog.setVisible(true);
> +
> + }
> +
> + public void postMessage(SecurityDialogMessage message) {
> + try {
> + queue.put(message);
> + } catch (InterruptedException e) {
> + e.printStackTrace();
> + }
> + }
> +
> +}
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/security/SecurityWarning.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/netx/net/sourceforge/jnlp/security/SecurityWarning.java Tue Oct 19 12:07:40 2010 -0400
> @@ -0,0 +1,278 @@
> +/* SecurityWarningDialogFactory.java
> + Copyright (C) 2010 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.Dialog.ModalityType;
> +import java.awt.event.WindowAdapter;
> +import java.awt.event.WindowEvent;
> +import java.security.AccessController;
> +import java.security.PrivilegedAction;
> +import java.util.concurrent.Semaphore;
> +
> +import javax.swing.JDialog;
> +import javax.swing.SwingUtilities;
> +
> +import net.sourceforge.jnlp.JNLPFile;
> +import net.sourceforge.jnlp.runtime.JNLPRuntime;
> +
> +/**
> + * A factory for showing many possible types of security warning to the user.<p>
> + *
> + * This contains all the public methods that classes outside this package should
> + * use instead of using {@link SecurityWarningDialog} directly.
> + *
> + * All of these methods post a message to the
> + * {@link SecurityDialogMessageHandler} and block waiting for a response.
> + */
> +public class SecurityWarning {
> + /** Types of dialogs we can create */
> + public static enum DialogType {
> + CERT_WARNING,
> + MORE_INFO,
> + CERT_INFO,
> + SINGLE_CERT_INFO,
> + ACCESS_WARNING,
> + NOTALLSIGNED_WARNING,
> + APPLET_WARNING
> + }
> +
> + /**
> + * Shows a warning dialog for different types of system access (i.e. file
> + * open/save, clipboard read/write, printing, etc).
> + *
> + * @param accessType the type of system access requested.
> + * @param file the jnlp file associated with the requesting application.
> + * @return true if permission was granted by the user, false otherwise.
> + */
> + public static boolean showAccessWarningDialog(AccessType accessType, JNLPFile file) {
> + return showAccessWarningDialog(accessType, file, null);
> + }
> +
> + /**
> + * Shows a warning dialog for different types of system access (i.e. file
> + * open/save, clipboard read/write, printing, etc).
> + *
> + * @param accessType the type of system access requested.
> + * @param file the jnlp file associated with the requesting application.
> + * @param extras an optional array of Strings (typically) that gets
> + * passed to the dialog labels.
> + * @return true if permission was granted by the user, false otherwise.
> + */
> + public static boolean showAccessWarningDialog(final AccessType accessType,
> + final JNLPFile file, final Object[] extras) {
> + final SecurityDialogMessage message = new SecurityDialogMessage();
> +
> + message.dialogType = DialogType.ACCESS_WARNING;
> + message.accessType = accessType;
> + message.file = file;
> + message.extras = extras;
> +
> + Object selectedValue = getUserResponse(message);
> +
> + 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 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) {
> +
> + final SecurityDialogMessage message = new SecurityDialogMessage();
> + message.dialogType = DialogType.NOTALLSIGNED_WARNING;
> + message.accessType = AccessType.NOTALLSIGNED;
> + message.file = file;
> + message.extras = new Object[0];
> +
> + Object selectedValue = getUserResponse(message);
> +
> + 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
> + * to code signing and signing certificates.
> + *
> + * @param accessType the type of warning dialog to show
> + * @param file the JNLPFile associated with this warning
> + * @param jarSigner the JarSigner used to verify this application
> + */
> + public static boolean showCertWarningDialog(AccessType accessType,
> + JNLPFile file, CertVerifier jarSigner) {
> +
> + final SecurityDialogMessage message = new SecurityDialogMessage();
> + message.dialogType = DialogType.CERT_WARNING;
> + message.accessType = accessType;
> + message.file = file;
> + message.certVerifier = jarSigner;
> +
> + Object selectedValue = getUserResponse(message);
> +
> + if (selectedValue == null) {
> + return false;
> + } else if (selectedValue instanceof Integer) {
> + if (((Integer) selectedValue).intValue() == 0)
> + return true;
> + else
> + return false;
> + } else {
> + return false;
> + }
> + }
> +
> + /**
> + * FIXME This is unused. Remove it?
> + * @return (0, 1, 2) => (Yes, No, Cancel)
> + */
> + public static int showAppletWarning() {
> +
> + SecurityDialogMessage message = new SecurityDialogMessage();
> + message.dialogType = DialogType.APPLET_WARNING;
> +
> + Object selectedValue = getUserResponse(message);
> +
> + // result 0 = Yes, 1 = No, 2 = Cancel
> + if (selectedValue == null) {
> + return 2;
> + } else if (selectedValue instanceof Integer) {
> + return ((Integer) selectedValue).intValue();
> + } else {
> + return 2;
> + }
> + }
> +
> + /**
> + * Posts the message to the SecurityThread and gets the response. Blocks
> + * until a response has been recieved. It's safe to call this from an
> + * EventDispatchThread.
> + *
> + * @param message the SecuritDialogMessage indicating what type of dialog to
> + * display
> + * @return The user's response. Can be null. The exact answer depends on the
> + * type of message, but generally an Integer corresponding to the value 0
> + * indicates success/proceed, and everything else indicates failure
> + */
> + private static Object getUserResponse(final SecurityDialogMessage message) {
> + /*
> + * Want to show a security warning, while blocking the client
> + * application. This would be easy except there is a bug in showing
> + * modal JDialogs in a different AppContext. The source EventQueue -
> + * that sends the message to the (destination) EventQueue which is
> + * supposed to actually show the dialog - must not block. If the source
> + * EventQueue blocks, the destination EventQueue stops responding. So we
> + * have a hack here to work around it.
> + */
> +
> + /*
> + * If this is the event dispatch thread the use the hack
> + */
> + if (SwingUtilities.isEventDispatchThread()) {
> + /*
> + * Create a tiny modal dialog (which creates a new EventQueue for
> + * this AppContext, but blocks the original client EventQueue) and
> + * then post the message - this makes the source EventQueue continue
> + * running - but dot not allow the actual applet/application to
> + * continue processing
> + */
> + final JDialog fakeDialog = new JDialog();
> + fakeDialog.setSize(0, 0);
> + fakeDialog.setResizable(false);
> + fakeDialog.setModalityType(ModalityType.APPLICATION_MODAL);
> + fakeDialog.addWindowListener(new WindowAdapter() {
> +
> + @Override
> + public void windowOpened(WindowEvent e) {
> + message.toDispose = fakeDialog;
> + message.lock = null;
> + AccessController.doPrivileged(new PrivilegedAction<Void>() {
> + @Override
> + public Void run() {
> + JNLPRuntime.getSecurityDialogHandler().postMessage(message);
> + return null;
> + }
> + });
> + }
> + });
> +
> + /* this dialog will be disposed/hidden when the user closes the security prompt */
> + fakeDialog.setVisible(true);
> + } else {
> + /*
> + * Otherwise do it the normal way. Post a message to the security
> + * thread to make it show the security dialog. Wait until it tells us
> + * to proceed.
> + */
> + message.toDispose = null;
> + message.lock = new Semaphore(0);
> + JNLPRuntime.getSecurityDialogHandler().postMessage(message);
> +
> + try {
> + message.lock.acquire();
> + } catch (InterruptedException e) {
> + message.userResponse = null;
> + }
> + }
> +
> + return message.userResponse;
> + }
> +
> +}
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java
> --- a/netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java Tue Oct 19 12:07:40 2010 -0400
> @@ -39,49 +39,29 @@
>
> import net.sourceforge.jnlp.JNLPFile;
> import net.sourceforge.jnlp.runtime.JNLPRuntime;
> +import net.sourceforge.jnlp.security.AccessType;
> +import net.sourceforge.jnlp.security.SecurityWarning.DialogType;
>
> import java.awt.*;
>
> import javax.swing.*;
>
> import java.awt.event.*;
> +import java.security.cert.X509Certificate;
> +import java.util.concurrent.CopyOnWriteArrayList;
>
> -import java.security.cert.X509Certificate;
> +import java.util.List;
>
> /**
> - * Provides methods for showing security warning dialogs
> - * for a wide range of JNLP security issues.
> + * Provides methods for showing security warning dialogs for a wide range of
> + * JNLP security issues. Note that the security dialogs should be running in the
> + * secure AppContext - this class should not be used directly from an applet or
> + * application. See {@link SecurityWarning} for a way to show security dialogs.
> *
> * @author <a href="mailto:jsumali at redhat.com">Joshua Sumali</a>
> */
> public class SecurityWarningDialog extends JDialog {
>
> - /** Types of dialogs we can create */
> - public static enum DialogType {
> - CERT_WARNING,
> - MORE_INFO,
> - CERT_INFO,
> - SINGLE_CERT_INFO,
> - ACCESS_WARNING,
> - NOTALLSIGNED_WARNING,
> - APPLET_WARNING
> - }
> -
> - /** The types of access which may need user permission. */
> - public static enum AccessType {
> - READ_FILE,
> - WRITE_FILE,
> - CREATE_DESTKOP_SHORTCUT,
> - CLIPBOARD_READ,
> - CLIPBOARD_WRITE,
> - PRINTER,
> - NETWORK,
> - VERIFIED,
> - UNVERIFIED,
> - NOTALLSIGNED,
> - SIGNING_ERROR
> - }
> -
> /** The type of dialog we want to show */
> private DialogType dialogType;
>
> @@ -112,61 +92,59 @@
> */
> private Object value;
>
> - public SecurityWarningDialog(DialogType dialogType, AccessType accessType,
> - JNLPFile file) {
> - super();
> - this.dialogType = dialogType;
> - this.accessType = accessType;
> - this.file = file;
> - this.certVerifier = null;
> - initialized = true;
> - initDialog();
> - }
> -
> - public SecurityWarningDialog(DialogType dialogType, AccessType accessType,
> - JNLPFile file, CertVerifier jarSigner) {
> - super();
> - this.dialogType = dialogType;
> - this.accessType = accessType;
> - this.file = file;
> - this.certVerifier = jarSigner;
> - initialized = true;
> - initDialog();
> - }
> -
> - public SecurityWarningDialog(DialogType dialogType, AccessType accessType,
> - CertVerifier certVerifier) {
> + SecurityWarningDialog(DialogType dialogType, AccessType accessType,
> + JNLPFile file, CertVerifier jarSigner, X509Certificate cert, Object[] extras) {
> super();
> this.dialogType = dialogType;
> this.accessType = accessType;
> - this.file = null;
> - this.certVerifier = certVerifier;
> + this.file = file;
> + this.certVerifier = jarSigner;
> + this.cert = cert;
> + this.extras = extras;
> initialized = true;
> +
> initDialog();
> }
>
> - public SecurityWarningDialog(DialogType dialogType, AccessType accessType,
> - JNLPFile file, Object[] extras) {
> - super();
> - this.dialogType = dialogType;
> - this.accessType = accessType;
> - this.file = file;
> - this.certVerifier = null;
> - initialized = true;
> - this.extras = extras;
> - initDialog();
> + /**
> + * Construct a SecurityWarningDialog to display some sort of access warning
> + */
> + SecurityWarningDialog(DialogType dialogType, AccessType accessType,
> + JNLPFile file) {
> + this(dialogType, accessType, file, null, null, null);
> }
>
> - //for displaying a single certificate
> - public SecurityWarningDialog(DialogType dialogType, X509Certificate c) {
> - super();
> - this.dialogType = dialogType;
> - this.accessType = null;
> - this.file = null;
> - this.certVerifier = null;
> - this.cert = c;
> - initialized = true;
> - initDialog();
> + /**
> + * Create a SecurityWarningDialog to display a certificate-related warning
> + */
> + SecurityWarningDialog(DialogType dialogType, AccessType accessType,
> + JNLPFile file, CertVerifier jarSigner) {
> + this(dialogType, accessType, file, jarSigner, null, null);
> + }
> +
> + /**
> + * Create a SecurityWarningDialog to display a certificate-related warning
> + */
> + SecurityWarningDialog(DialogType dialogType, AccessType accessType,
> + CertVerifier certVerifier) {
> + this(dialogType, accessType, null, certVerifier, null, null);
> + }
> +
> + /**
> + * Create a SecurityWarningDialog to display some sort of access warning
> + * with more information
> + */
> + SecurityWarningDialog(DialogType dialogType, AccessType accessType,
> + JNLPFile file, Object[] extras) {
> + this(dialogType, accessType, file, null, null, extras);
> + }
> +
> + /**
> + * Create a SecurityWarningDailog to display information about a single
> + * certificate
> + */
> + SecurityWarningDialog(DialogType dialogType, X509Certificate c) {
> + this(dialogType, null, null, null, c, null);
> }
>
> /**
> @@ -178,105 +156,6 @@
> }
>
> /**
> - * Shows a warning dialog for different types of system access (i.e. file
> - * open/save, clipboard read/write, printing, etc).
> - *
> - * @param accessType the type of system access requested.
> - * @param file the jnlp file associated with the requesting application.
> - * @return true if permission was granted by the user, false otherwise.
> - */
> - public static boolean showAccessWarningDialog(AccessType accessType,
> - JNLPFile file) {
> - return showAccessWarningDialog(accessType, file, null);
> - }
> -
> - /**
> - * Shows a warning dialog for different types of system access (i.e. file
> - * open/save, clipboard read/write, printing, etc).
> - *
> - * @param accessType the type of system access requested.
> - * @param file the jnlp file associated with the requesting application.
> - * @param extras an optional array of Strings (typically) that gets
> - * passed to the dialog labels.
> - * @return true if permission was granted by the user, false otherwise.
> - */
> - public static boolean showAccessWarningDialog(AccessType accessType,
> - JNLPFile file, Object[] extras) {
> - SecurityWarningDialog dialog = new SecurityWarningDialog(
> - DialogType.ACCESS_WARNING, accessType, file, extras);
> - dialog.setVisible(true);
> - dialog.dispose();
> -
> - Object selectedValue = dialog.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 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 dialog = new SecurityWarningDialog(
> - DialogType.NOTALLSIGNED_WARNING, AccessType.NOTALLSIGNED, file, (new Object[0]));
> - dialog.setVisible(true);
> - dialog.dispose();
> -
> - Object selectedValue = dialog.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
> - * to code signing and signing certificates.
> - *
> - * @param accessType the type of warning dialog to show
> - * @param file the JNLPFile associated with this warning
> - * @param jarSigner the JarSigner used to verify this application
> - */
> - public static boolean showCertWarningDialog(AccessType accessType,
> - JNLPFile file, CertVerifier jarSigner) {
> - SecurityWarningDialog dialog =
> - new SecurityWarningDialog(DialogType.CERT_WARNING, accessType, file,
> - jarSigner);
> - dialog.setVisible(true);
> - dialog.dispose();
> -
> - Object selectedValue = dialog.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 more information regarding jar code signing
> *
> * @param jarSigner the JarSigner used to verify this application
> @@ -320,23 +199,7 @@
> dialog.dispose();
> }
>
> - public static int showAppletWarning() {
> - SecurityWarningDialog dialog = new SecurityWarningDialog(DialogType.APPLET_WARNING,
> - null, null, (CertVerifier) null);
> - dialog.setVisible(true);
> - dialog.dispose();
>
> - Object selectedValue = dialog.getValue();
> -
> - //result 0 = Yes, 1 = No, 2 = Cancel
> - if (selectedValue == null) {
> - return 2;
> - } else if (selectedValue instanceof Integer) {
> - return ((Integer)selectedValue).intValue();
> - } else {
> - return 2;
> - }
> - }
>
> private void initDialog() {
> setSystemLookAndFeel();
> @@ -366,10 +229,7 @@
>
> WindowAdapter adapter = new WindowAdapter() {
> private boolean gotFocus = false;
> - @Override
> - public void windowClosing(WindowEvent we) {
> - setValue(null);
> - }
> +
> @Override
> public void windowGainedFocus(WindowEvent we) {
> // Once window gets focus, set initial focus
> @@ -454,7 +314,7 @@
> this.value = value;
> }
>
> - protected Object getValue() {
> + public Object getValue() {
> if (JNLPRuntime.isDebug()) {
> System.out.println("Returning value:" + value);
> }
> @@ -462,6 +322,16 @@
> }
>
> /**
> + * Called when the SecurityWarningDialog is hidden - either because the user
> + * made a choice (Ok, Cancel, etc) or closed the window
> + */
> + @Override
> + public void dispose() {
> + notifySelectionMade();
> + super.dispose();
> + }
> +
> + /**
> * Updates the look and feel of the window to be the system look and feel
> */
> protected void setSystemLookAndFeel() {
> @@ -471,4 +341,26 @@
> //don't worry if we can't.
> }
> }
> +
> + private List<ActionListener> listeners = new CopyOnWriteArrayList<ActionListener>();
> +
> + /**
> + * Notify all the listeners that the user has made a decision using this
> + * security dialog.
> + */
> + public void notifySelectionMade() {
> + for (ActionListener listener : listeners) {
> + listener.actionPerformed(null);
> + }
> + }
> +
> + /**
> + * Adds an {@link ActionListener} which will be notified if the user makes a
> + * choice using this SecurityWarningDialog. The listener should use {@link #getValue()}
> + * to actually get the user's response.
> + */
> + public void addActionListener(ActionListener listener) {
> + listeners.add(listener);
> + }
> +
> }
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java
> --- a/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java Tue Oct 19 12:07:40 2010 -0400
> @@ -52,6 +52,8 @@
>
> import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
>
> +import net.sourceforge.jnlp.security.AccessType;
> +
> /**
> * This class implements an X509 Trust Manager. The certificates it trusts are
> * "variable", in the sense that it can dynamically, and temporarily support
> @@ -293,8 +295,8 @@
> private boolean askUser(X509Certificate[] chain, String authType,
> boolean isTrusted, boolean hostMatched,
> String hostName) {
> - return SecurityWarningDialog.showCertWarningDialog(
> - SecurityWarningDialog.AccessType.UNVERIFIED, null,
> + return SecurityWarning.showCertWarningDialog(
> + AccessType.UNVERIFIED, null,
> new HttpsCertVerifier(this, chain, authType,
> isTrusted, hostMatched,
> hostName));
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/services/ServiceUtil.java
> --- a/netx/net/sourceforge/jnlp/services/ServiceUtil.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/services/ServiceUtil.java Tue Oct 19 12:07:40 2010 -0400
> @@ -40,7 +40,8 @@
> import net.sourceforge.jnlp.JNLPFile;
> import net.sourceforge.jnlp.runtime.ApplicationInstance;
> import net.sourceforge.jnlp.runtime.JNLPRuntime;
> -import net.sourceforge.jnlp.security.SecurityWarningDialog;
> +import net.sourceforge.jnlp.security.SecurityWarning;
> +import net.sourceforge.jnlp.security.AccessType;
>
> /**
> * Provides static methods to interact useful for using the JNLP
> @@ -219,8 +220,7 @@
> * message formatting.
> * @return true if the access was granted, false otherwise.
> */
> - public static boolean checkAccess(SecurityWarningDialog.AccessType type,
> - Object... extras) {
> + public static boolean checkAccess(AccessType type, Object... extras) {
> return checkAccess(null, type, extras);
> }
>
> @@ -235,8 +235,7 @@
> * message formatting.
> * @return true if the access was granted, false otherwise.
> */
> - public static boolean checkAccess(ApplicationInstance app,
> - SecurityWarningDialog.AccessType type,
> + public static boolean checkAccess(ApplicationInstance app, AccessType type,
> Object... extras) {
>
> if (app == null)
> @@ -270,7 +269,7 @@
> }
>
> if (!codeTrusted) {
> - final SecurityWarningDialog.AccessType tmpType = type;
> + final AccessType tmpType = type;
> final Object[] tmpExtras = extras;
> final ApplicationInstance tmpApp = app;
>
> @@ -279,7 +278,7 @@
> //from resources.jar.
> Boolean b = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
> public Boolean run() {
> - boolean b = SecurityWarningDialog.showAccessWarningDialog(tmpType,
> + boolean b = SecurityWarning.showAccessWarningDialog(tmpType,
> tmpApp.getJNLPFile(), tmpExtras);
> return new Boolean(b);
> }
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/services/XClipboardService.java
> --- a/netx/net/sourceforge/jnlp/services/XClipboardService.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/services/XClipboardService.java Tue Oct 19 12:07:40 2010 -0400
> @@ -39,7 +39,7 @@
>
> import javax.jnlp.*;
>
> -import net.sourceforge.jnlp.security.SecurityWarningDialog;
> +import net.sourceforge.jnlp.security.AccessType;
>
> import java.awt.datatransfer.Transferable;
> import java.awt.Toolkit;
> @@ -59,7 +59,7 @@
> */
> public java.awt.datatransfer.Transferable getContents(){
>
> - if (ServiceUtil.checkAccess(SecurityWarningDialog.AccessType.CLIPBOARD_READ)) {
> + if (ServiceUtil.checkAccess(AccessType.CLIPBOARD_READ)) {
> Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
> return (Transferable) ServiceUtil.createPrivilegedProxy(
> Transferable.class, t);
> @@ -72,7 +72,7 @@
> * Sets the contents of the system clipboard.
> */
> public void setContents(java.awt.datatransfer.Transferable contents) {
> - if (ServiceUtil.checkAccess(SecurityWarningDialog.AccessType.CLIPBOARD_WRITE)) {
> + if (ServiceUtil.checkAccess(AccessType.CLIPBOARD_WRITE)) {
> Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
> contents, null);
> }
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/services/XExtendedService.java
> --- a/netx/net/sourceforge/jnlp/services/XExtendedService.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/services/XExtendedService.java Tue Oct 19 12:07:40 2010 -0400
> @@ -22,7 +22,7 @@
> import javax.jnlp.ExtendedService;
> import javax.jnlp.FileContents;
>
> -import net.sourceforge.jnlp.security.SecurityWarningDialog;
> +import net.sourceforge.jnlp.security.AccessType;
>
> /**
> * Implementation of ExtendedService
> @@ -35,8 +35,7 @@
> public FileContents openFile(File file) throws IOException {
>
> /* FIXME: this opens a file with read/write mode, not just read or write */
> - if (ServiceUtil.checkAccess(SecurityWarningDialog.AccessType.READ_FILE,
> - new Object[]{ file.getAbsolutePath() })) {
> + if (ServiceUtil.checkAccess(AccessType.READ_FILE, new Object[]{ file.getAbsolutePath() })) {
> return (FileContents) ServiceUtil.createPrivilegedProxy(FileContents.class,
> new XFileContents(file));
> } else {
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/services/XFileOpenService.java
> --- a/netx/net/sourceforge/jnlp/services/XFileOpenService.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/services/XFileOpenService.java Tue Oct 19 12:07:40 2010 -0400
> @@ -45,7 +45,7 @@
>
> import net.sourceforge.jnlp.*;
> import net.sourceforge.jnlp.runtime.*;
> -import net.sourceforge.jnlp.security.SecurityWarningDialog;
> +import net.sourceforge.jnlp.security.AccessType;
>
> import javax.swing.JFileChooser;
> import javax.swing.JOptionPane;
> @@ -67,7 +67,7 @@
> public FileContents openFileDialog (java.lang.String pathHint,
> java.lang.String[] extensions) throws java.io.IOException {
>
> - if (ServiceUtil.checkAccess(SecurityWarningDialog.AccessType.READ_FILE)) {
> + if (ServiceUtil.checkAccess(AccessType.READ_FILE)) {
>
> //open a file dialog here, let the user choose the file.
> JFileChooser chooser = new JFileChooser();
> @@ -90,7 +90,7 @@
> public FileContents[] openMultiFileDialog (java.lang.String pathHint,
> java.lang.String[] extensions) throws java.io.IOException {
>
> - if (ServiceUtil.checkAccess(SecurityWarningDialog.AccessType.WRITE_FILE)) {
> + if (ServiceUtil.checkAccess(AccessType.WRITE_FILE)) {
> JFileChooser chooser = new JFileChooser();
> chooser.setMultiSelectionEnabled(true);
> int chosen = chooser.showOpenDialog(null);
> diff -r afdd3f284524 netx/net/sourceforge/jnlp/services/XFileSaveService.java
> --- a/netx/net/sourceforge/jnlp/services/XFileSaveService.java Mon Oct 18 21:29:09 2010 +0100
> +++ b/netx/net/sourceforge/jnlp/services/XFileSaveService.java Tue Oct 19 12:07:40 2010 -0400
> @@ -43,8 +43,7 @@
> import java.lang.ref.*;
> import javax.jnlp.*;
>
> -import net.sourceforge.jnlp.*;
> -import net.sourceforge.jnlp.security.*;
> +import net.sourceforge.jnlp.security.AccessType;
>
> import javax.swing.JFileChooser;
> import javax.swing.JOptionPane;
> @@ -67,7 +66,7 @@
> java.lang.String[] extensions, java.io.InputStream stream,
> java.lang.String name) throws java.io.IOException {
>
> - if (ServiceUtil.checkAccess(SecurityWarningDialog.AccessType.WRITE_FILE)) {
> + if (ServiceUtil.checkAccess(AccessType.WRITE_FILE)) {
> JFileChooser chooser = new JFileChooser();
> int chosen = chooser.showSaveDialog(null);
>
> @@ -90,7 +89,7 @@
> public FileContents saveAsFileDialog(java.lang.String pathHint,
> java.lang.String[] extensions, FileContents contents) throws java.io.IOException {
>
> - if (ServiceUtil.checkAccess(SecurityWarningDialog.AccessType.WRITE_FILE)) {
> + if (ServiceUtil.checkAccess(AccessType.WRITE_FILE)) {
> JFileChooser chooser = new JFileChooser();
> chooser.setSelectedFile(new File(contents.getName()));
> int chosen = chooser.showSaveDialog(null);
--
Andrew :)
Free Java Software Engineer
Red Hat, Inc. (http://www.redhat.com)
Support Free Java!
Contribute to GNU Classpath and the OpenJDK
http://www.gnu.org/software/classpath
http://openjdk.java.net
PGP Key: 94EFD9D8 (http://subkeys.pgp.net)
Fingerprint = F8EF F1EA 401E 2E60 15FA 7927 142C 2591 94EF D9D8
More information about the distro-pkg-dev
mailing list