• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 /**
19 * @author Alexander V. Astapchuk
20 * @version $Revision$
21 */
22 
23 package org.apache.harmony.security.fortress;
24 
25 import java.security.AccessControlContext;
26 import java.util.WeakHashMap;
27 
28 //FIXME: move this class under umbrella of protected packages -
29 // see lib/java.security: property 'package.access',
30 // so only trusted classes like Thread and AccessController will
31 // have an access to this class.
32 // This is to remove dependency on VMStack, to reduce number
33 // of VM2API-dependent classes.
34 
35 /**
36  * The class is used to perform an exchange of information between
37  * java.lang.Thread and java.security.AccessController.<br>
38  * The data to exchange is inherited contexts for the Thread-s.
39  *
40  */
41 public final class SecurityUtils {
42 
43     // A map used to store inherited contexts.<br>
44     // A thread is used as a key for the map and AccessControlContext
45     // passed to the putContext is used as a value.
46     private static final WeakHashMap<Thread, AccessControlContext> ACC_CACHE = new WeakHashMap<Thread, AccessControlContext>();
47 
48     /**
49      * This method to be invoked in the Thread's constructor. The first argument
50      * (thread) must be Thread's this and the second must be a snapshot of the
51      * current AccessControlContext:
52      * <p>
53      * <code>
54      * Thread() {<br>
55      * SecurityUtils.putContext(this,AccessController.getContext());<br>
56      *  ...do the stuff you need...<br>
57      * }<br>
58      * </code>
59      *
60      * The method throws SecurityException if the method is called more than
61      * once for a given thread. The first call to <code>putContext</code> is
62      * always performed in the Thread's constructor so this effectively means
63      * that no one can replace the snapshot taken.
64      *
65      * @throws SecurityException if a context for the passed
66      *     <code>thread</code> already exists in the map.
67      * @throws NullPointerException if thread is null
68      * @throws Error if context is null AND if null context is already stored
69      *     in the map
70      */
putContext(Thread thread, AccessControlContext context)71     public static void putContext(Thread thread, AccessControlContext context)
72             throws SecurityException {
73         if (thread == null) {
74             throw new NullPointerException();
75         }
76         synchronized (ACC_CACHE) {
77             if (ACC_CACHE.containsKey(thread)) {
78                 throw new SecurityException("You can not modify this map");
79             }
80             if (context == null) {
81                 // this only allowed once - for the very first thread.
82                 if (ACC_CACHE.containsValue(null)) {
83                     throw new Error("null context may be stored only once");
84                 }
85             }
86             ACC_CACHE.put(thread, context);
87         }
88     }
89 
90     /**
91      * Returns the AccessControlContext stored for a given thread.<br>
92      * The method may return null - for the very first thread created
93      * by the VM which does not have inherited context.<br>
94      * It may also return null if no Thread found in the map - that seems
95      * possible during VM startup process.
96      */
getContext(Thread thread)97     public static AccessControlContext getContext(Thread thread)
98             throws SecurityException {
99 
100         // ~fixme: see 'fixme' at the top of the file
101         /*
102          Class cl = VMStack.getCallerClass(0);
103          if (cl != AccessController.class) {
104          throw new SecurityException("You ["+cl+"] do not have access to this resource.");
105          }
106          */
107 
108         synchronized (ACC_CACHE) {
109             return ACC_CACHE.get(thread);
110         }
111     }
112 }
113