• 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 import org.apache.harmony.security.internal.nls.Messages;
29 
30 //FIXME: move this class under umbrella of protected packages -
31 // see lib/java.security: property 'package.access',
32 // so only trusted classes like Thread and AccessController will
33 // have an access to this class.
34 // This is to remove dependency on VMStack, to reduce number
35 // of VM2API-dependent classes.
36 
37 /**
38  * The class is used to perform an exchange of information between
39  * java.lang.Thread and java.security.AccessController.<br>
40  * The data to exchange is inherited contexts for the Thread-s.
41  *
42  */
43 public final class SecurityUtils {
44 
45     // A map used to store inherited contexts.<br>
46     // A thread is used as a key for the map and AccessControlContext
47     // passed to the putContext is used as a value.
48     private static final WeakHashMap<Thread, AccessControlContext> ACC_CACHE = new WeakHashMap<Thread, AccessControlContext>();
49 
50     /**
51      * This method to be invoked in the Thread's constructor. The first argument
52      * (thread) must be Thread's this and the second must be a snapshot of the
53      * current AccessControlContext:
54      * <p>
55      * <code>
56      * Thread() {<br>
57      * SecurityUtils.putContext(this,AccessController.getContext());<br>
58      *  ...do the stuff you need...<br>
59      * }<br>
60      * </code>
61      *
62      * The method throws SecurityException if the method is called more than
63      * once for a given thread. The first call to <code>putContext</code> is
64      * always performed in the Thread's constructor so this effectively means
65      * that no one can replace the snapshot taken.
66      *
67      * @throws SecurityException if a context for the passed
68      *     <code>thread</code> already exists in the map.
69      * @throws NullPointerException if thread is null
70      * @throws Error if context is null AND if null context is already stored
71      *     in the map
72      */
putContext(Thread thread, AccessControlContext context)73     public static void putContext(Thread thread, AccessControlContext context)
74             throws SecurityException {
75         if (thread == null) {
76             throw new NullPointerException(Messages.getString("security.140")); //$NON-NLS-1$
77         }
78         synchronized (ACC_CACHE) {
79             if (ACC_CACHE.containsKey(thread)) {
80                 throw new SecurityException(Messages.getString("security.141")); //$NON-NLS-1$
81             }
82             if (context == null) {
83                 // this only allowed once - for the very first thread.
84                 if (ACC_CACHE.containsValue(null)) {
85                     throw new Error(Messages.getString("security.142")); //$NON-NLS-1$
86                 }
87             }
88             ACC_CACHE.put(thread, context);
89         }
90     }
91 
92     /**
93      * Returns the AccessControlContext stored for a given thread.<br>
94      * The method may return null - for the very first thread created
95      * by the VM which does not have inherited context.<br>
96      * It may also return null if no Thread found in the map - that seems
97      * possible during VM startup process.
98      */
getContext(Thread thread)99     public static AccessControlContext getContext(Thread thread)
100             throws SecurityException {
101 
102         // ~fixme: see 'fixme' at the top of the file
103         /*
104          Class cl = VMStack.getCallerClass(0);
105          if (cl != AccessController.class) {
106          throw new SecurityException("You ["+cl+"] do not have access to this resource.");
107          }
108          */
109 
110         synchronized (ACC_CACHE) {
111             return ACC_CACHE.get(thread);
112         }
113     }
114 }
115