KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > framework > internal > core > FrameworkSecurityManager


1 /*******************************************************************************
2  * Copyright (c) 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.osgi.framework.internal.core;
13
14 import java.security.*;
15 import java.util.*;
16 import org.osgi.service.condpermadmin.Condition;
17
18 /**
19  *
20  * This security manager implements the ConditionalPermission processing for
21  * OSGi. It is to be used with ConditionalPermissionAdmin.
22  *
23  */

24 public class FrameworkSecurityManager extends SecurityManager JavaDoc {
25     /*
26      * This is super goofy, but we need to make sure that the CheckContext and
27      * CheckPermissionAction classes load early. Otherwise, we run into problems later.
28      */

29     static {
30         Class JavaDoc c;
31         c = CheckPermissionAction.class;
32         c = CheckContext.class;
33         c.getName(); // to prevent compiler warnings
34
}
35
36     static class CheckContext {
37         // A non zero depth indicates that we are doing a recursive permission check.
38
ArrayList depthCondSets = new ArrayList(2);
39         ArrayList accs = new ArrayList(2);
40         ArrayList CondClassSet;
41
42         public int getDepth() {
43             return depthCondSets.size() - 1;
44         }
45     }
46
47     /**
48      * Adds an array of Condition[] for a ProtectionDomain.
49      *
50      * @param condSet the array of Condition[] for the ProtectionDomain.
51      * @return true if the condSet was added. false if this is a recursive check
52      * and ConditionalPermissions cannot be used.
53      */

54     boolean addConditionsForDomain(Condition condSet[][]) {
55         CheckContext cc = (CheckContext) localCheckContext.get();
56         if (cc == null) {
57             // We are being invoked in a weird way. Perhaps the ProtectionDomain is
58
// getting invoked directly.
59
return false;
60         }
61         Vector condSets = (Vector) cc.depthCondSets.get(cc.getDepth());
62         if (condSets == null) {
63             condSets = new Vector(2);
64             cc.depthCondSets.set(cc.getDepth(), condSets);
65         }
66         condSets.add(condSet);
67         return true;
68     }
69
70     ThreadLocal JavaDoc localCheckContext = new ThreadLocal JavaDoc();
71
72     static class CheckPermissionAction implements PrivilegedAction {
73         Permission perm;
74         Object JavaDoc context;
75         FrameworkSecurityManager fsm;
76
77         CheckPermissionAction(FrameworkSecurityManager fsm, Permission perm, Object JavaDoc context) {
78             this.fsm = fsm;
79             this.perm = perm;
80             this.context = context;
81         }
82
83         public Object JavaDoc run() {
84             fsm.internalCheckPermission(perm, context);
85             return null;
86         }
87     }
88
89     public void checkPermission(Permission perm, Object JavaDoc context) {
90         AccessController.doPrivileged(new CheckPermissionAction(this, perm, context));
91     }
92
93     /**
94      * Gets the AccessControlContext currently being evaluated by
95      * the SecurityManager.
96      *
97      * @return the AccessControlContext currently being evaluated by the SecurityManager, or
98      * null if no AccessControlContext is being evaluted. Note: this method will
99      * return null if the permission check is being done directly on the AccessControlContext
100      * rather than the SecurityManager.
101      */

102     public AccessControlContext getContextToBeChecked() {
103         CheckContext cc = (CheckContext) localCheckContext.get();
104         if (cc != null && cc.accs != null && !cc.accs.isEmpty())
105             return (AccessControlContext) cc.accs.get(cc.accs.size()-1);
106         return null;
107     }
108     
109     public void internalCheckPermission(Permission perm, Object JavaDoc context) {
110         AccessControlContext acc = (AccessControlContext) context;
111         CheckContext cc = (CheckContext) localCheckContext.get();
112         if (cc == null) {
113             cc = new CheckContext();
114             localCheckContext.set(cc);
115         }
116         cc.depthCondSets.add(null); // initialize postponed condition set to null
117
cc.accs.add(acc);
118         try {
119             acc.checkPermission(perm);
120             // We want to pop the first set of postponed conditions and process them
121
Vector remainingSets = (Vector) cc.depthCondSets.get(cc.getDepth());
122             if (remainingSets != null) {
123                 /*
124                  * In this bit of code we have to try every possible combination
125                  * of conditional permissions that still need to be evaluated. We
126                  * do this using recursion to keep track of the different
127                  * combinations we have tried. The top call will setup the different
128                  * combinations for the first protection domain with unevaluated
129                  * conditions. The final call will actually evaluate the condition.
130                  * If a good combination is found, it will immediately bubble
131                  * up.
132                  */

133                 Hashtable condContextDict = new Hashtable(2);
134                 // The remainder we will process recursively.
135
Condition conds[][] = (Condition[][]) remainingSets.remove(0);
136                 for (int i = 0; i < conds.length; i++)
137                     if (recursiveCheck(remainingSets, conds[i], null, condContextDict, cc))
138                         return; // found a pass return without SecurityException
139
throw new SecurityException JavaDoc("Conditions not satisfied"); //$NON-NLS-1$
140
}
141         } finally {
142             cc.depthCondSets.remove(cc.getDepth());
143             cc.accs.remove(cc.accs.size()-1);
144         }
145     }
146
147     /**
148      * Checks that at least one combination of the Condition[] in the Vector can
149      * be satisfied along with the passed array of Conditions.
150      *
151      * @param remainingSets the Vector of Condition[][] to check.
152      * @param conditions the conditions that must be satisfied.
153      * @param condDict a dictionary that will be filled with the Conditions to
154      * check.
155      * @param condContextDict a Dictionary of Dictionaries that will be passed
156      * to Condition.isSatisfied when performing repeated check.
157      * @param cc the CheckContext
158      * @return true if a successful combination was found.
159      */

160     private boolean recursiveCheck(Vector remainingSets, Condition[] conditions, Hashtable condDict, Hashtable condContextDict, CheckContext cc) {
161         // clone condDict and clone each Vector in the condDict
162
if (condDict == null) {
163             condDict = new Hashtable(2);
164         } else {
165             Hashtable copyCondDict = new Hashtable(2);
166             for (Enumeration keys = condDict.keys(); keys.hasMoreElements();) {
167                 Object JavaDoc key = keys.nextElement();
168                 copyCondDict.put(key, ((Vector) condDict.get(key)).clone());
169             }
170             condDict = copyCondDict;
171         }
172         for (int i = 0; i < conditions.length; i++) {
173             if (conditions[i] == null)
174                 continue;
175             Vector condList = (Vector) condDict.get(conditions[i].getClass());
176             if (condList == null) {
177                 condList = new Vector();
178                 condDict.put(conditions[i].getClass(), condList);
179             }
180             condList.add(conditions[i]);
181         }
182         if (remainingSets.size() > 0) {
183             Condition conds[][] = (Condition[][]) remainingSets.get(0);
184             Vector newSets = (Vector) remainingSets.clone();
185             newSets.remove(0);
186             for (int i = 0; i < conds.length; i++)
187                 if (recursiveCheck(newSets, conds[i], condDict, condContextDict, cc))
188                     return true;
189             return false;
190         }
191         Enumeration keys = condDict.keys();
192         while (keys.hasMoreElements()) {
193             Class JavaDoc key = (Class JavaDoc) keys.nextElement();
194             Vector conds = (Vector) condDict.get(key);
195             if (conds.size() == 0)
196                 continue; // This should never happen since we only add to the condDict if there is a condition
197
Condition condArray[] = (Condition[]) conds.toArray(new Condition[conds.size()]);
198             Dictionary context = (Dictionary) condContextDict.get(key);
199             if (context == null) {
200                 context = new Hashtable(2);
201                 condContextDict.put(key, context);
202             }
203             if (cc.CondClassSet == null)
204                 cc.CondClassSet = new ArrayList(2);
205             if (cc.CondClassSet.contains(condArray[0].getClass()))
206                 return false; // doing recursion into same condition class
207
cc.CondClassSet.add(condArray[0].getClass());
208             try {
209                 if (!condArray[0].isSatisfied(condArray, context))
210                     return false;
211             } finally {
212                 cc.CondClassSet.remove(condArray[0].getClass());
213             }
214         }
215         return true;
216     }
217
218     public void checkPermission(Permission perm) {
219         checkPermission(perm, getSecurityContext());
220     }
221
222     public Object JavaDoc getSecurityContext() {
223         return AccessController.getContext();
224     }
225 }
226
Popular Tags