History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/applet/AppletSecurity.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/applet/AppletSecurity.java+371−0
@@ -0,0 +1,371 @@
1+/*
2+ * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.applet;
27+
28+import java.io.File;
29+import java.io.FilePermission;
30+import java.io.IOException;
31+import java.io.FileDescriptor;
32+import java.net.URL;
33+import java.net.URLClassLoader;
34+import java.net.InetAddress;
35+import java.net.UnknownHostException;
36+import java.net.SocketPermission;
37+import java.util.Enumeration;
38+import java.util.Iterator;
39+import java.util.HashSet;
40+import java.util.StringTokenizer;
41+import java.security.*;
42+import java.lang.reflect.*;
43+import sun.awt.AWTSecurityManager;
44+import sun.awt.AppContext;
45+import sun.security.provider.*;
46+import sun.security.util.SecurityConstants;
47+
48+
49+/**
50+ * This class defines an applet security policy
51+ *
52+ */
53+public
54+class AppletSecurity extends AWTSecurityManager {
55+ private AppContext mainAppContext;
56+
57+ //URLClassLoader.acc
58+ private static Field facc = null;
59+
60+ //AccessControlContext.context;
61+ private static Field fcontext = null;
62+
63+ static {
64+ try {
65+ facc = URLClassLoader.class.getDeclaredField("acc");
66+ facc.setAccessible(true);
67+ fcontext = AccessControlContext.class.getDeclaredField("context");
68+ fcontext.setAccessible(true);
69+ } catch (NoSuchFieldException e) {
70+ throw new UnsupportedOperationException(e);
71+ }
72+ }
73+
74+
75+ /**
76+ * Construct and initialize.
77+ */
78+ public AppletSecurity() {
79+ reset();
80+ mainAppContext = AppContext.getAppContext();
81+ }
82+
83+ // Cache to store known restricted packages
84+ private HashSet restrictedPackages = new HashSet();
85+
86+ /**
87+ * Reset from Properties
88+ */
89+ public void reset()
90+ {
91+ // Clear cache
92+ restrictedPackages.clear();
93+
94+ AccessController.doPrivileged(new PrivilegedAction() {
95+ public Object run()
96+ {
97+ // Enumerate system properties
98+ Enumeration e = System.getProperties().propertyNames();
99+
100+ while (e.hasMoreElements())
101+ {
102+ String name = (String) e.nextElement();
103+
104+ if (name != null && name.startsWith("package.restrict.access."))
105+ {
106+ String value = System.getProperty(name);
107+
108+ if (value != null && value.equalsIgnoreCase("true"))
109+ {
110+ String pkg = name.substring(24);
111+
112+ // Cache restricted packages
113+ restrictedPackages.add(pkg);
114+ }
115+ }
116+ }
117+ return null;
118+ }
119+ });
120+ }
121+
122+ /**
123+ * get the current (first) instance of an AppletClassLoader on the stack.
124+ */
125+ private AppletClassLoader currentAppletClassLoader()
126+ {
127+ // try currentClassLoader first
128+ ClassLoader loader = currentClassLoader();
129+
130+ if ((loader == null) || (loader instanceof AppletClassLoader))
131+ return (AppletClassLoader)loader;
132+
133+ // if that fails, get all the classes on the stack and check them.
134+ Class[] context = getClassContext();
135+ for (int i = 0; i < context.length; i++) {
136+ loader = context[i].getClassLoader();
137+ if (loader instanceof AppletClassLoader)
138+ return (AppletClassLoader)loader;
139+ }
140+
141+ /*
142+ * fix bug # 6433620 the logic here is : try to find URLClassLoader from
143+ * class context, check its AccessControlContext to see if
144+ * AppletClassLoader is in stack when it's created. for this kind of
145+ * URLClassLoader, return the AppContext assocated with the
146+ * AppletClassLoader.
147+ */
148+ for (int i = 0; i < context.length; i++) {
149+ final ClassLoader currentLoader = context[i].getClassLoader();
150+
151+ if (currentLoader instanceof URLClassLoader) {
152+ loader = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
153+ public Object run() {
154+
155+ AccessControlContext acc = null;
156+ ProtectionDomain[] pds = null;
157+
158+ try {
159+ acc = (AccessControlContext) facc.get(currentLoader);
160+ if (acc == null) {
161+ return null;
162+ }
163+
164+ pds = (ProtectionDomain[]) fcontext.get(acc);
165+ if (pds == null) {
166+ return null;
167+ }
168+ } catch (Exception e) {
169+ throw new UnsupportedOperationException(e);
170+ }
171+
172+ for (int i=0; i<pds.length; i++) {
173+ ClassLoader cl = pds[i].getClassLoader();
174+
175+ if (cl instanceof AppletClassLoader) {
176+ return cl;
177+ }
178+ }
179+
180+ return null;
181+ }
182+ });
183+
184+ if (loader != null) {
185+ return (AppletClassLoader) loader;
186+ }
187+ }
188+ }
189+
190+ // if that fails, try the context class loader
191+ loader = Thread.currentThread().getContextClassLoader();
192+ if (loader instanceof AppletClassLoader)
193+ return (AppletClassLoader)loader;
194+
195+ // no AppletClassLoaders on the stack
196+ return (AppletClassLoader)null;
197+ }
198+
199+ /**
200+ * Returns true if this threadgroup is in the applet's own thread
201+ * group. This will return false if there is no current class
202+ * loader.
203+ */
204+ protected boolean inThreadGroup(ThreadGroup g) {
205+ if (currentAppletClassLoader() == null)
206+ return false;
207+ else
208+ return getThreadGroup().parentOf(g);
209+ }
210+
211+ /**
212+ * Returns true of the threadgroup of thread is in the applet's
213+ * own threadgroup.
214+ */
215+ protected boolean inThreadGroup(Thread thread) {
216+ return inThreadGroup(thread.getThreadGroup());
217+ }
218+
219+ /**
220+ * Applets are not allowed to manipulate threads outside
221+ * applet thread groups. However a terminated thread no longer belongs
222+ * to any group.
223+ */
224+ public void checkAccess(Thread t) {
225+ /* When multiple applets is reloaded simultaneously, there will be
226+ * multiple invocations to this method from plugin's SecurityManager.
227+ * This method should not be synchronized to avoid deadlock when
228+ * a page with multiple applets is reloaded
229+ */
230+ if ((t.getState() != Thread.State.TERMINATED) && !inThreadGroup(t)) {
231+ checkPermission(SecurityConstants.MODIFY_THREAD_PERMISSION);
232+ }
233+ }
234+
235+ private boolean inThreadGroupCheck = false;
236+
237+ /**
238+ * Applets are not allowed to manipulate thread groups outside
239+ * applet thread groups.
240+ */
241+ public synchronized void checkAccess(ThreadGroup g) {
242+ if (inThreadGroupCheck) {
243+ // if we are in a recursive check, it is because
244+ // inThreadGroup is calling appletLoader.getThreadGroup
245+ // in that case, only do the super check, as appletLoader
246+ // has a begin/endPrivileged
247+ checkPermission(SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
248+ } else {
249+ try {
250+ inThreadGroupCheck = true;
251+ if (!inThreadGroup(g)) {
252+ checkPermission(SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
253+ }
254+ } finally {
255+ inThreadGroupCheck = false;
256+ }
257+ }
258+ }
259+
260+
261+ /**
262+ * Throws a <code>SecurityException</code> if the
263+ * calling thread is not allowed to access the package specified by
264+ * the argument.
265+ * <p>
266+ * This method is used by the <code>loadClass</code> method of class
267+ * loaders.
268+ * <p>
269+ * The <code>checkPackageAccess</code> method for class
270+ * <code>SecurityManager</code> calls
271+ * <code>checkPermission</code> with the
272+ * <code>RuntimePermission("accessClassInPackage."+pkg)</code>
273+ * permission.
274+ *
275+ * @param pkg the package name.
276+ * @exception SecurityException if the caller does not have
277+ * permission to access the specified package.
278+ * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
279+ */
280+ public void checkPackageAccess(final String pkgname) {
281+
282+ // first see if the VM-wide policy allows access to this package
283+ super.checkPackageAccess(pkgname);
284+
285+ // now check the list of restricted packages
286+ for (Iterator iter = restrictedPackages.iterator(); iter.hasNext();)
287+ {
288+ String pkg = (String) iter.next();
289+
290+ // Prevent matching "sun" and "sunir" even if they
291+ // starts with similar beginning characters
292+ //
293+ if (pkgname.equals(pkg) || pkgname.startsWith(pkg + "."))
294+ {
295+ checkPermission(new java.lang.RuntimePermission
296+ ("accessClassInPackage." + pkgname));
297+ }
298+ }
299+ }
300+
301+ /**
302+ * Tests if a client can get access to the AWT event queue.
303+ * <p>
304+ * This method calls <code>checkPermission</code> with the
305+ * <code>AWTPermission("accessEventQueue")</code> permission.
306+ *
307+ * @since JDK1.1
308+ * @exception SecurityException if the caller does not have
309+ * permission to accesss the AWT event queue.
310+ */
311+ public void checkAwtEventQueueAccess() {
312+ AppContext appContext = AppContext.getAppContext();
313+ AppletClassLoader appletClassLoader = currentAppletClassLoader();
314+
315+ if ((appContext == mainAppContext) && (appletClassLoader != null)) {
316+ // If we're about to allow access to the main EventQueue,
317+ // and anything untrusted is on the class context stack,
318+ // disallow access.
319+ super.checkAwtEventQueueAccess();
320+ }
321+ } // checkAwtEventQueueAccess()
322+
323+ /**
324+ * Returns the thread group of the applet. We consult the classloader
325+ * if there is one.
326+ */
327+ public ThreadGroup getThreadGroup() {
328+ /* If any applet code is on the execution stack, we return
329+ that applet's ThreadGroup. Otherwise, we use the default
330+ behavior. */
331+ AppletClassLoader appletLoader = currentAppletClassLoader();
332+ ThreadGroup loaderGroup = (appletLoader == null) ? null
333+ : appletLoader.getThreadGroup();
334+ if (loaderGroup != null) {
335+ return loaderGroup;
336+ } else {
337+ return super.getThreadGroup();
338+ }
339+ } // getThreadGroup()
340+
341+ /**
342+ * Get the AppContext corresponding to the current context.
343+ * The default implementation returns null, but this method
344+ * may be overridden by various SecurityManagers
345+ * (e.g. AppletSecurity) to index AppContext objects by the
346+ * calling context.
347+ *
348+ * @return the AppContext corresponding to the current context.
349+ * @see sun.awt.AppContext
350+ * @see java.lang.SecurityManager
351+ * @since JDK1.2.1
352+ */
353+ public AppContext getAppContext() {
354+ AppletClassLoader appletLoader = currentAppletClassLoader();
355+
356+ if (appletLoader == null) {
357+ return null;
358+ } else {
359+ AppContext context = appletLoader.getAppContext();
360+
361+ // context == null when some thread in applet thread group
362+ // has not been destroyed in AppContext.dispose()
363+ if (context == null) {
364+ throw new SecurityException("Applet classloader has invalid AppContext");
365+ }
366+
367+ return context;
368+ }
369+ }
370+
371+} // class AppletSecurity