view netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java @ 1842:31b0ba36a6b7

Completely restructure the building and inclusion of netx and plugin code. We were relying on the binary plugs process (and thus importing unneeded SNMP classes). We now use the same method as jaxws, jaxp, langtools and corba, and the binary plugs process is turned off (the default, we were turning it on by setting ALT_BINARY_PLUGS_PATH). 2009-05-27 Andrew John Hughes <ahughes@redhat.com> * overlays/openjdk/jdk/src/share/classes/javax/jnlp/BasicService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/ClipboardService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/DownloadService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/DownloadServiceListener.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/ExtensionInstallerService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/FileContents.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/FileOpenService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/FileSaveService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/JNLPRandomAccessFile.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/PersistenceService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/PrintService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/ServiceManager.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/ServiceManagerStub.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/UnavailableServiceException.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/AppletDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/ApplicationDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/ComponentDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/DefaultLaunchHandler.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/ExtensionDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/IconDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/InformationDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/InstallerDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/JARDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/JNLPFile.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/JNLPSplashScreen.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/JREDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/LaunchException.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/LaunchHandler.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/Launcher.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/NetxPanel.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/Node.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/PackageDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/ParseException.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/Parser.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/PluginBridge.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/PropertyDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/ResourcesDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/SecurityDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/Version.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/CacheEntry.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/CacheUtil.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/DefaultDownloadIndicator.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/DownloadIndicator.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/Resource.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/ResourceTracker.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/UpdatePolicy.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/package.html, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/event/ApplicationEvent.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/event/ApplicationListener.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/event/DownloadEvent.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/event/DownloadListener.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/event/package.html, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/package.html, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/resources/Manifest.mf, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/resources/Messages.properties, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/resources/about.jnlp, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/resources/default.jnlp, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/AppThreadGroup.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/AppletAudioClip.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/AppletEnvironment.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/AppletInstance.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/ApplicationInstance.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/Boot.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/Boot13.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPPolicy.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPRuntime.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/package.html, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/AccessWarningPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/AppletWarningPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/CertVerifier.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/CertWarningPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/CertsInfoPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/HttpsCertVerifier.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/MoreInfoPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/SecurityDialogUI.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/SecurityUtil.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/SecurityWarningDialog.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/SingleCertInfoPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/VariableX509TrustManager.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/viewer/CertificatePane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/viewer/CertificateViewer.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/ServiceUtil.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XBasicService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XClipboardService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XDownloadService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XExtensionInstallerService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XFileContents.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XFileOpenService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XFileSaveService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XJNLPRandomAccessFile.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XPersistenceService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XPrintService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XServiceManagerStub.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/package.html, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/CharacterEncoder.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/HexDumpEncoder.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/JarRunner.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/JarSigner.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/JarSignerResources.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/KeyStoreUtil.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/KeyTool.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/util/PropertiesFile.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/util/Reflect.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/util/WeakList.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/nanoxml/XMLElement.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/nanoxml/XMLParseException.java: Moved to... * Makefile.am: Remove use of ALT_BINARY_PLUGS_PATH (and thus turn off the binary plugs build), add a INITIAL_BOOTSTRAP_LINK_STAMP target which allows us to depend on $(ICEDTEA_BOOT_DIR) for both types of build, output to lib/tools.jar not jre/lib/tools.jar, add targets for building netx and liveconnect classes and make icedtea targets dependent on this. * netx/javax/jnlp/BasicService.java, * netx/javax/jnlp/ClipboardService.java, * netx/javax/jnlp/DownloadService.java, * netx/javax/jnlp/DownloadServiceListener.java, * netx/javax/jnlp/ExtensionInstallerService.java, * netx/javax/jnlp/FileContents.java, * netx/javax/jnlp/FileOpenService.java, * netx/javax/jnlp/FileSaveService.java, * netx/javax/jnlp/JNLPRandomAccessFile.java, * netx/javax/jnlp/PersistenceService.java, * netx/javax/jnlp/PrintService.java, * netx/javax/jnlp/ServiceManager.java, * netx/javax/jnlp/ServiceManagerStub.java, * netx/javax/jnlp/UnavailableServiceException.java, * netx/net/sourceforge/jnlp/AppletDesc.java, * netx/net/sourceforge/jnlp/ApplicationDesc.java, * netx/net/sourceforge/jnlp/ComponentDesc.java, * netx/net/sourceforge/jnlp/DefaultLaunchHandler.java, * netx/net/sourceforge/jnlp/ExtensionDesc.java, * netx/net/sourceforge/jnlp/IconDesc.java, * netx/net/sourceforge/jnlp/InformationDesc.java, * netx/net/sourceforge/jnlp/InstallerDesc.java, * netx/net/sourceforge/jnlp/JARDesc.java, * netx/net/sourceforge/jnlp/JNLPFile.java, * netx/net/sourceforge/jnlp/JNLPSplashScreen.java, * netx/net/sourceforge/jnlp/JREDesc.java, * netx/net/sourceforge/jnlp/LaunchException.java, * netx/net/sourceforge/jnlp/LaunchHandler.java, * netx/net/sourceforge/jnlp/Launcher.java, * netx/net/sourceforge/jnlp/NetxPanel.java, * netx/net/sourceforge/jnlp/Node.java, * netx/net/sourceforge/jnlp/PackageDesc.java, * netx/net/sourceforge/jnlp/ParseException.java, * netx/net/sourceforge/jnlp/Parser.java, * netx/net/sourceforge/jnlp/PluginBridge.java, * netx/net/sourceforge/jnlp/PropertyDesc.java, * netx/net/sourceforge/jnlp/ResourcesDesc.java, * netx/net/sourceforge/jnlp/SecurityDesc.java, * netx/net/sourceforge/jnlp/Version.java, * netx/net/sourceforge/jnlp/cache/CacheEntry.java, * netx/net/sourceforge/jnlp/cache/CacheUtil.java, * netx/net/sourceforge/jnlp/cache/DefaultDownloadIndicator.java, * netx/net/sourceforge/jnlp/cache/DownloadIndicator.java, * netx/net/sourceforge/jnlp/cache/Resource.java, * netx/net/sourceforge/jnlp/cache/ResourceTracker.java, * netx/net/sourceforge/jnlp/cache/UpdatePolicy.java, * netx/net/sourceforge/jnlp/cache/package.html, * netx/net/sourceforge/jnlp/event/ApplicationEvent.java, * netx/net/sourceforge/jnlp/event/ApplicationListener.java, * netx/net/sourceforge/jnlp/event/DownloadEvent.java, * netx/net/sourceforge/jnlp/event/DownloadListener.java, * netx/net/sourceforge/jnlp/event/package.html, * netx/net/sourceforge/jnlp/package.html, * netx/net/sourceforge/jnlp/resources/Manifest.mf, * netx/net/sourceforge/jnlp/resources/Messages.properties, * netx/net/sourceforge/jnlp/resources/about.jnlp, * netx/net/sourceforge/jnlp/resources/default.jnlp, * netx/net/sourceforge/jnlp/runtime/AppThreadGroup.java, * netx/net/sourceforge/jnlp/runtime/AppletAudioClip.java, * netx/net/sourceforge/jnlp/runtime/AppletEnvironment.java, * netx/net/sourceforge/jnlp/runtime/AppletInstance.java, * netx/net/sourceforge/jnlp/runtime/ApplicationInstance.java, * netx/net/sourceforge/jnlp/runtime/Boot.java, * netx/net/sourceforge/jnlp/runtime/Boot13.java, * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java, * netx/net/sourceforge/jnlp/runtime/JNLPPolicy.java, * netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java, * netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java, * netx/net/sourceforge/jnlp/runtime/package.html, * netx/net/sourceforge/jnlp/security/AccessWarningPane.java, * netx/net/sourceforge/jnlp/security/AppletWarningPane.java, * netx/net/sourceforge/jnlp/security/CertVerifier.java, * netx/net/sourceforge/jnlp/security/CertWarningPane.java, * netx/net/sourceforge/jnlp/security/CertsInfoPane.java, * netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java, * netx/net/sourceforge/jnlp/security/MoreInfoPane.java, * netx/net/sourceforge/jnlp/security/SecurityDialogUI.java, * netx/net/sourceforge/jnlp/security/SecurityUtil.java, * netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java, * netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java, * netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java, * netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java, * netx/net/sourceforge/jnlp/security/viewer/CertificateViewer.java, * netx/net/sourceforge/jnlp/services/ServiceUtil.java, * netx/net/sourceforge/jnlp/services/XBasicService.java, * netx/net/sourceforge/jnlp/services/XClipboardService.java, * netx/net/sourceforge/jnlp/services/XDownloadService.java, * netx/net/sourceforge/jnlp/services/XExtensionInstallerService.java, * netx/net/sourceforge/jnlp/services/XFileContents.java, * netx/net/sourceforge/jnlp/services/XFileOpenService.java, * netx/net/sourceforge/jnlp/services/XFileSaveService.java, * netx/net/sourceforge/jnlp/services/XJNLPRandomAccessFile.java, * netx/net/sourceforge/jnlp/services/XPersistenceService.java, * netx/net/sourceforge/jnlp/services/XPrintService.java, * netx/net/sourceforge/jnlp/services/XServiceManagerStub.java, * netx/net/sourceforge/jnlp/services/package.html, * netx/net/sourceforge/jnlp/tools/CharacterEncoder.java, * netx/net/sourceforge/jnlp/tools/HexDumpEncoder.java, * netx/net/sourceforge/jnlp/tools/JarRunner.java, * netx/net/sourceforge/jnlp/tools/JarSigner.java, * netx/net/sourceforge/jnlp/tools/JarSignerResources.java, * netx/net/sourceforge/jnlp/tools/KeyStoreUtil.java, * netx/net/sourceforge/jnlp/tools/KeyTool.java, * netx/net/sourceforge/jnlp/util/PropertiesFile.java, * netx/net/sourceforge/jnlp/util/Reflect.java, * netx/net/sourceforge/jnlp/util/WeakList.java, * netx/net/sourceforge/nanoxml/XMLElement.java, * netx/net/sourceforge/nanoxml/XMLParseException.java: to here. * patches/ecj/icedtea.patch: Recreated. * patches/icedtea-ant.patch: Remove hack to jaxws which uses plugs directory (now undefined). * patches/icedtea-javac-debuginfo.patch: Recreated. * patches/icedtea-netx.patch: Include netx and netscape classes via the same import mechanism as jaxws, jaxp, corba and langtools (extracting a classes.zip).
author Andrew John Hughes <ahughes@redhat.com>
date Thu, 28 May 2009 10:18:19 +0100
parents overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java@8dc304404e01
children
line wrap: on
line source

// Copyright (C) 2001-2003 Jon A. Maxwell (JAM)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


package net.sourceforge.jnlp.runtime;

import java.awt.Frame;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.ref.WeakReference;
import java.net.SocketPermission;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;

import javax.swing.JWindow;

import net.sourceforge.jnlp.JNLPFile;
import net.sourceforge.jnlp.security.SecurityWarningDialog;
import net.sourceforge.jnlp.services.ServiceUtil;
import net.sourceforge.jnlp.util.WeakList;
import sun.security.util.SecurityConstants;

/**
 * Security manager for JNLP environment.  This security manager
 * cannot be replaced as it always denies attempts to replace the
 * security manager or policy.<p>
 *
 * The JNLP security manager tracks windows created by an
 * application, allowing those windows to be disposed when the
 * application exits but the JVM does not.  If security is not
 * enabled then the first application to call System.exit will
 * halt the JVM.<p>
 *
 * @author <a href="mailto:jmaxwell@users.sourceforge.net">Jon A. Maxwell (JAM)</a> - initial author
 * @version $Revision: 1.17 $
 */
class JNLPSecurityManager extends SecurityManager {

    // todo: some apps like JDiskReport can close the VM even when
    // an exit class is set - fix!

    // todo: create an event dispatch thread for each application,
    // so that the context classloader doesn't have to be switched
    // to the foreground application (the currently the approach
    // since some apps need their classloader as event dispatch
    // thread's context classloader).

    // todo: use a custom Permission object to identify the current
    // application in an AccessControlContext by setting a side
    // effect in its implies method.  Use a custom
    // AllPermissions-like permission to do this for apps granted
    // all permissions (but investigate whether this will nuke
    // the all-permission optimizations in the JRE).

    // todo: does not exit app if close button pressed on JFrame
    // with CLOSE_ON_EXIT (or whatever) set; if doesn't exit, use an
    // WindowListener to catch WindowClosing event, then if exit is
    // called immediately afterwards from AWT thread.

    // todo: deny all permissions to applications that should have
    // already been 'shut down' by closing their resources and
    // interrupt the threads if operating in a shared-VM (exit class
    // set).  Deny will probably will slow checks down a lot though.

    // todo: weak remember last getProperty application and
    // re-install properties if another application calls, or find
    // another way for different apps to have different properties
    // in java.lang.Sytem with the same names.

    private static String R(String key) { return JNLPRuntime.getMessage(key); }

    /** only class that can exit the JVM, if set */
    private Object exitClass = null;

    /** this exception prevents exiting the JVM */
    private SecurityException closeAppEx = // making here prevents huge stack traces
        new SecurityException(JNLPRuntime.getMessage("RShutdown"));

    /** weak list of windows created */
    private WeakList weakWindows = new WeakList();

    /** weak list of applications corresponding to window list */
    private WeakList weakApplications = new WeakList();

    /** weak reference to most app who's windows was most recently activated */
    private WeakReference activeApplication = null;

    /** listener installs the app's classloader on the event dispatch thread */
    private ContextUpdater contextListener = new ContextUpdater();
    
    /** Sets whether or not exit is allowed (in the context of the plugin, this is always false) */
    private boolean exitAllowed = true;

    private class ContextUpdater extends WindowAdapter implements PrivilegedAction {
        private ApplicationInstance app = null;

        public void windowActivated(WindowEvent e) {
            app = getApplication(e.getWindow());
            AccessController.doPrivileged(this);
            app = null;
        }

        public Object run() {
            if (app != null) {
                Thread.currentThread().setContextClassLoader(app.getClassLoader());
                activeApplication = new WeakReference(app);
            }
            else
                Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());

            return null;
        }

        public void windowDeactivated(WindowEvent e) {
            activeApplication = null;
        }
        
        public void windowClosing(WindowEvent e) {
        	System.err.println("Disposing window");
        	e.getWindow().dispose();
        }
    };


    /**
     * Creates a JNLP SecurityManager.
     */
    JNLPSecurityManager() {
        // this has the side-effect of creating the Swing shared Frame
        // owner.  Since no application is running at this time, it is
        // not added to any window list when checkTopLevelWindow is
        // called for it (and not disposed).

        if (!JNLPRuntime.isHeadless())
            new JWindow().getOwner();
    }

    /**
     * Returns whether the exit class is present on the stack, or
     * true if no exit class is set.
     */
    public boolean isExitClass() {
        return isExitClass(getClassContext());
    }

    /**
     * Returns whether the exit class is present on the stack, or
     * true if no exit class is set.
     */
    private boolean isExitClass(Class stack[]) {
        if (exitClass == null)
            return true;

        for (int i=0; i < stack.length; i++)
            if (stack[i] == exitClass)
                return true;

        return false;
    }

    /**
     * Set the exit class, which is the only class that can exit the
     * JVM; if not set then any class can exit the JVM.
     *
     * @param exitClass the exit class
     * @throws IllegalStateException if the exit class is already set
     */
    public void setExitClass(Class exitClass) throws IllegalStateException {
        if (this.exitClass != null)
            throw new IllegalStateException(R("RExitTaken"));

        this.exitClass = exitClass;
    }

    /**
     * Return the current Application, or null if none can be
     * determined.
     */
    protected ApplicationInstance getApplication() {
        return getApplication(getClassContext(), 0);
    }

    /**
     * Return the application the opened the specified window (only
     * call from event dispatch thread).
     */
    protected ApplicationInstance getApplication(Window window) {
        for (int i = weakWindows.size(); i-->0;) {
            Window w = (Window) weakWindows.get(i);
            if (w == null) {
                weakWindows.remove(i);
                weakApplications.remove(i);
            }

            if (w == window)
                return (ApplicationInstance) weakApplications.get(i);
        }

        return null;
    }

    /**
     * Return the current Application, or null.
     */
    protected ApplicationInstance getApplication(Class stack[], int maxDepth) {
    	if (maxDepth <= 0)
    		maxDepth = stack.length;

    	// this needs to be tightened up
    	for (int i=0; i < stack.length && i < maxDepth; i++) {
    		if (stack[i].getClassLoader() instanceof JNLPClassLoader) {
    			JNLPClassLoader loader = (JNLPClassLoader) stack[i].getClassLoader();

    			if (loader != null && loader.getApplication() != null) {
    				return loader.getApplication();
    			}
    		} 
    	}

    	return null;
    }

    /**
     * Returns the application's thread group if the application can
     * be determined; otherwise returns super.getThreadGroup()
     */
    public ThreadGroup getThreadGroup() {
        ApplicationInstance app = getApplication();
        if (app == null)
            return super.getThreadGroup();

        return app.getThreadGroup();
    }

    /**
     * Throws a SecurityException if the permission is denied,
     * otherwise return normally.  This method always denies
     * permission to change the security manager or policy.
     */
    public void checkPermission(Permission perm) {
        String name = perm.getName();

        // Enable this manually -- it'll produce too much output for -verbose
        // otherwise.
	//	if (true)
	//  	  System.out.println("Checking permission: " + perm.toString());

        if (!JNLPRuntime.isWebstartApplication() && 
	      ("setPolicy".equals(name) || "setSecurityManager".equals(name)))
            throw new SecurityException(R("RCantReplaceSM"));

        try {
            // deny all permissions to stopped applications
        	// The call to getApplication() below might not work if an 
        	// application hasn't been fully initialized yet.
//            if (JNLPRuntime.isDebug()) {
//                if (!"getClassLoader".equals(name)) {
//                    ApplicationInstance app = getApplication();
//                    if (app != null && !app.isRunning())
//                        throw new SecurityException(R("RDenyStopped"));
//                }
//            }
        	
			try {
				super.checkPermission(perm);
			} catch (SecurityException se) {

				//This section is a special case for dealing with SocketPermissions.
				if (JNLPRuntime.isDebug())
					System.err.println("Requesting permission: " + perm.toString());

				//Change this SocketPermission's action to connect and accept
				//(and resolve). This is to avoid asking for connect permission 
				//on every address resolve.
				Permission tmpPerm;
				if (perm instanceof SocketPermission) {
					tmpPerm = new SocketPermission(perm.getName(), 
							SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION);
					
					// before proceeding, check if we are trying to connect to same origin
					ApplicationInstance app = getApplication();
					JNLPFile file = app.getJNLPFile();

					String srcHost =  file.getSourceLocation().getAuthority();
					String destHost = name;
					
					// host = abc.xyz.com or abc.xyz.com:<port> 
					if (destHost.indexOf(':') >= 0)
						destHost = destHost.substring(0, destHost.indexOf(':'));
					
					// host = abc.xyz.com
					String[] hostComponents = destHost.split("\\.");
					
					int length = hostComponents.length;
					if (length >= 2) {
						
						// address is in xxx.xxx.xxx format
						destHost = hostComponents[length -2] + "." + hostComponents[length -1];
					
						// host = xyz.com i.e. origin
						boolean isDestHostName = false;

						// make sure that it is not an ip address
						try {
							Integer.parseInt(hostComponents[length -1]);
						} catch (NumberFormatException e) {
							isDestHostName = true;
						}

						if (isDestHostName) {
							// okay, destination is hostname. Now figure out if it is a subset of origin
							if (srcHost.endsWith(destHost)) {
								addPermission(tmpPerm);
								return;
							}
						}
					}

				} else
					tmpPerm = perm;
				
				//askPermission will only prompt the user on SocketPermission 
				//meaning we're denying all other SecurityExceptions that may arise.
				if (askPermission(tmpPerm)) {
					addPermission(tmpPerm);
					//return quietly.
				} else {
					throw se;
				}
			}
        }
        catch (SecurityException ex) {
            if (JNLPRuntime.isDebug()) {
                System.out.println("Denying permission: "+perm);
            }
            throw ex;
        }
    }
    
    /**
     * Asks the user whether or not to grant permission.
     * @param perm the permission to be granted
     * @return true if the permission was granted, false otherwise.
     */
    private boolean askPermission(Permission perm)	{
    	
    	ApplicationInstance app = getApplication();
    	if (app != null && !app.isSigned()) {
        	if (perm instanceof SocketPermission 
        			&& ServiceUtil.checkAccess(SecurityWarningDialog.AccessType.NETWORK, perm.getName())) {
        		return true;
        	}
    	}

    	return false;
    }

    /**
     * Adds a permission to the JNLPClassLoader.
     * @param perm the permission to add to the JNLPClassLoader
     */
    private void addPermission(Permission perm)	{
    	if (JNLPRuntime.getApplication().getClassLoader() instanceof JNLPClassLoader) {

    		JNLPClassLoader cl = (JNLPClassLoader) JNLPRuntime.getApplication().getClassLoader();
    		cl.addPermission(perm);
        	if (JNLPRuntime.isDebug()) {
        		if (cl.getPermissions(null).implies(perm))
        			System.err.println("Added permission: " + perm.toString());
        		else
        			System.err.println("Unable to add permission: " + perm.toString());
        	}
    	} else {
        	if (JNLPRuntime.isDebug())
        		System.err.println("Unable to add permission: " + perm + ", classloader not JNLP.");
    	}
    }
    
    /**
     * Checks whether the window can be displayed without an applet
     * warning banner, and adds the window to the list of windows to
     * be disposed when the calling application exits.
     */
    public boolean checkTopLevelWindow(Object window) {
        ApplicationInstance app = getApplication();

        // remember window -> application mapping for focus, close on exit 
        if (app != null && window instanceof Window) {
            Window w = (Window) window;

            if (JNLPRuntime.isDebug())
                System.err.println("SM: app: "+app.getTitle()+" is adding a window: "+window);

            weakWindows.add(window); // for mapping window -> app
            weakApplications.add(app);

            w.addWindowListener(contextListener); // for dynamic context classloader

            app.addWindow(w);
        }

        // change coffee cup to netx for default icon
        if (window instanceof Window)
            for (Window w = (Window)window; w != null; w = w.getOwner())
                if (window instanceof Frame)
                    ((Frame)window).setIconImage(JNLPRuntime.getWindowIcon());

        // todo: set awt.appletWarning to custom message
        // todo: logo on with glass pane on JFrame/JWindow?
        
        return super.checkTopLevelWindow(window);
    }

    /**
     * Checks whether the caller can exit the system.  This method
     * identifies whether the caller is a real call to Runtime.exec
     * and has special behavior when returning from this method
     * would exit the JVM and an exit class is set: if the caller is
     * not the exit class then the calling application will be
     * stopped and its resources destroyed (when possible), and an
     * exception will be thrown to prevent the JVM from shutting
     * down.<p>
     *
     * Calls not from Runtime.exit or with no exit class set will
     * behave normally, and the exit class can always exit the JVM.
     */
    public void checkExit(int status) {

    	// applets are not allowed to exit, but the plugin main class (primordial loader) is
        Class stack[] = getClassContext();
        if (!exitAllowed) {
        	for (int i=0; i < stack.length; i++)
        		if (stack[i].getClassLoader() != null)
        			throw new AccessControlException("Applets may not call System.exit()");
        }

    	super.checkExit(status);
        
        boolean realCall = (stack[1] == Runtime.class);

        if (isExitClass(stack)) // either exitClass called or no exitClass set
            return; // to Runtime.exit or fake call to see if app has permission

        // not called from Runtime.exit()
        if (!realCall) {
            // apps that can't exit should think they can exit normally
            super.checkExit(status);
            return;
        }

        // but when they really call, stop only the app instead of the JVM
        ApplicationInstance app = getApplication(stack, 0);
        if (app == null) {
            // should check caller to make sure it is JFrame.close or
            // other known System.exit call
            if (activeApplication != null)
                app = (ApplicationInstance) activeApplication.get();

            if (app == null)
                throw new SecurityException(R("RExitNoApp"));
        }

        app.destroy();

        throw closeAppEx;
    }

    protected void disableExit() {
    	exitAllowed = false;
    }
    
}