001: /*
002: * @(#)AppletSecurity.java 1.89 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.applet;
029:
030: import java.io.File;
031: import java.io.FilePermission;
032: import java.io.IOException;
033: import java.io.FileDescriptor;
034: import java.net.URL;
035: import java.net.InetAddress;
036: import java.net.UnknownHostException;
037: import java.net.SocketPermission;
038: import java.util.StringTokenizer;
039: import java.util.Vector;
040: import java.util.Hashtable;
041: import java.security.*;
042: import sun.awt.AWTSecurityManager;
043: import sun.awt.AppContext;
044: import sun.security.provider.*;
045:
046: /**
047: * This class defines an applet security policy
048: *
049: * @version 1.85, 08/19/02
050: */
051: public class AppletSecurity extends AWTSecurityManager {
052: private AppContext mainAppContext;
053:
054: /**
055: * Construct and initialize.
056: */
057: public AppletSecurity() {
058: reset();
059: mainAppContext = AppContext.getAppContext();
060: }
061:
062: /**
063: * Reset from Properties
064: */
065: public void reset() {
066: }
067:
068: /**
069: * get the current (first) instance of an AppletClassLoader on the
070: * execution stack. Returns null if a call to checkPermission with
071: * java.security.AllPermission does not result in a SecurityException,
072: * or if no AppletClassLoader is found.
073: */
074:
075: private static AllPermission allPermission;
076:
077: private AppletClassLoader currentAppletClassLoader() {
078: try {
079: if (allPermission == null) {
080: allPermission = new AllPermission();
081: }
082: checkPermission(allPermission);
083: } catch (SecurityException se) {
084: ClassLoader loader;
085: Class[] context = getClassContext();
086: for (int i = 0; i < context.length; i++) {
087: loader = context[i].getClassLoader();
088: if (loader instanceof AppletClassLoader) {
089: return (AppletClassLoader) loader;
090: }
091: }
092: // if that fails, try the context class loader
093: loader = Thread.currentThread().getContextClassLoader();
094: if (loader instanceof AppletClassLoader) {
095: return (AppletClassLoader) loader;
096: }
097: }
098: // no AppletClassLoader found, or we have AllPermission
099: return (AppletClassLoader) null;
100: }
101:
102: /**
103: * Returns true if this threadgroup is in the applet's own thread
104: * group. This will return false if there is no current applet class
105: * loader.
106: */
107: protected boolean inThreadGroup(ThreadGroup g) {
108: if (currentAppletClassLoader() == null)
109: return false;
110: else
111: return getThreadGroup().parentOf(g);
112: }
113:
114: /**
115: * Returns true of the threadgroup of thread is in the applet's
116: * own threadgroup.
117: */
118: protected boolean inThreadGroup(Thread thread) {
119: return inThreadGroup(thread.getThreadGroup());
120: }
121:
122: /**
123: * Applets are not allowed to manipulate threads outside
124: * applet thread groups.
125: */
126: public synchronized void checkAccess(Thread t) {
127: if (!inThreadGroup(t)) {
128: if (threadPermission == null)
129: threadPermission = new RuntimePermission("modifyThread");
130: checkPermission(threadPermission);
131: }
132: }
133:
134: private static RuntimePermission threadPermission;
135: private static RuntimePermission threadGroupPermission;
136: private boolean inThreadGroupCheck = false;
137:
138: /**
139: * Applets are not allowed to manipulate thread groups outside
140: * applet thread groups.
141: */
142: public synchronized void checkAccess(ThreadGroup g) {
143: if (inThreadGroupCheck) {
144: // if we are in a recursive check, it is because
145: // inThreadGroup is calling appletLoader.getThreadGroup
146: // in that case, only do the super check, as appletLoader
147: // has a begin/endPrivileged
148: if (threadGroupPermission == null)
149: threadGroupPermission = new RuntimePermission(
150: "modifyThreadGroup");
151: checkPermission(threadGroupPermission);
152: } else {
153: try {
154: inThreadGroupCheck = true;
155: if (!inThreadGroup(g)) {
156: if (threadGroupPermission == null)
157: threadGroupPermission = new RuntimePermission(
158: "modifyThreadGroup");
159: checkPermission(threadGroupPermission);
160: }
161: } finally {
162: inThreadGroupCheck = false;
163: }
164: }
165: }
166:
167: /**
168: * Throws a <code>SecurityException</code> if the
169: * calling thread is not allowed to access the package specified by
170: * the argument.
171: * <p>
172: * This method is used by the <code>loadClass</code> method of class
173: * loaders.
174: * <p>
175: * The <code>checkPackageAccess</code> method for class
176: * <code>SecurityManager</code> calls
177: * <code>checkPermission</code> with the
178: * <code>RuntimePermission("accessClassInPackage."+pkg)</code>
179: * permission.
180: *
181: * @param pkg the package name.
182: * @exception SecurityException if the caller does not have
183: * permission to access the specified package.
184: * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
185: */
186: public void checkPackageAccess(final String pkgname) {
187: // first see if the VM-wide policy allows access to this package
188: super .checkPackageAccess(pkgname);
189: final boolean[] check = { false };
190: AccessController.doPrivileged(new PrivilegedAction() {
191: public Object run() {
192: int i;
193: String pkg = pkgname;
194: do {
195: String prop = "package.restrict.access." + pkg;
196: if (Boolean.getBoolean(prop)) {
197: check[0] = true;
198: break;
199: }
200: if ((i = pkg.lastIndexOf('.')) != -1) {
201: pkg = pkg.substring(0, i);
202: }
203: } while (i != -1);
204: return null;
205: }
206: });
207: if (check[0])
208: checkPermission(new java.lang.RuntimePermission(
209: "accessClassInPackage." + pkgname));
210: }
211:
212: /**
213: * Tests if a client can get access to the AWT event queue.
214: * <p>
215: * This method calls <code>checkPermission</code> with the
216: * <code>AWTPermission("accessEventQueue")</code> permission.
217: *
218: * @since JDK1.1
219: * @exception SecurityException if the caller does not have
220: * permission to accesss the AWT event queue.
221: */
222: public void checkAwtEventQueueAccess() {
223: AppContext appContext = AppContext.getAppContext();
224: if ((appContext == mainAppContext)
225: && (currentAppletClassLoader() != null)) {
226: // If we're about to allow access to the main EventQueue,
227: // and anything untrusted is on the class context stack,
228: // disallow access.
229: super .checkAwtEventQueueAccess();
230: }
231: } // checkAwtEventQueueAccess()
232:
233: /**
234: * Returns the thread group of the applet. We consult the classloader
235: * if there is one.
236: */
237: public ThreadGroup getThreadGroup() {
238: /* If any applet code is on the execution stack, we return
239: that applet's ThreadGroup. Otherwise, we use the default
240: behavior. */
241: AppletClassLoader appletLoader = currentAppletClassLoader();
242: return (appletLoader == null) ? super .getThreadGroup()
243: : appletLoader.getThreadGroup();
244: }
245:
246: /**
247: * Get the AppContext corresponding to the current context.
248: * The default implementation returns null, but this method
249: * may be overridden by various SecurityManagers
250: * (e.g. AppletSecurity) to index AppContext objects by the
251: * calling context.
252: *
253: * @return the AppContext corresponding to the current context.
254: * @see sun.awt.AppContext
255: * @see java.lang.SecurityManager
256: * @since JDK1.2.1
257: */
258: public AppContext getAppContext() {
259: AppletClassLoader appletLoader = currentAppletClassLoader();
260: return (appletLoader == null) ? null : appletLoader
261: .getAppContext();
262: }
263: } // class AppletSecurity
|