47 * <p> If no Policy object has been installed in the runtime, a call to |
47 * <p> If no Policy object has been installed in the runtime, a call to |
48 * {@code getPolicy} installs an instance of the default Policy |
48 * {@code getPolicy} installs an instance of the default Policy |
49 * implementation (a default subclass implementation of this abstract class). |
49 * implementation (a default subclass implementation of this abstract class). |
50 * The default Policy implementation can be changed by setting the value |
50 * The default Policy implementation can be changed by setting the value |
51 * of the {@code policy.provider} security property to the fully qualified |
51 * of the {@code policy.provider} security property to the fully qualified |
52 * name of the desired Policy subclass implementation. |
52 * name of the desired Policy subclass implementation. The system class loader |
|
53 * is used to load this class. |
53 * |
54 * |
54 * <p> Application code can directly subclass Policy to provide a custom |
55 * <p> Application code can directly subclass Policy to provide a custom |
55 * implementation. In addition, an instance of a Policy object can be |
56 * implementation. In addition, an instance of a Policy object can be |
56 * constructed by invoking one of the {@code getInstance} factory methods |
57 * constructed by invoking one of the {@code getInstance} factory methods |
57 * with a standard type. The default policy type is "JavaPolicy". |
58 * with a standard type. The default policy type is "JavaPolicy". |
109 private static AtomicReference<PolicyInfo> policy = |
110 private static AtomicReference<PolicyInfo> policy = |
110 new AtomicReference<>(new PolicyInfo(null, false)); |
111 new AtomicReference<>(new PolicyInfo(null, false)); |
111 |
112 |
112 private static final Debug debug = Debug.getInstance("policy"); |
113 private static final Debug debug = Debug.getInstance("policy"); |
113 |
114 |
|
115 // Default policy provider |
|
116 private static final String DEFAULT_POLICY = |
|
117 "sun.security.provider.PolicyFile"; |
|
118 |
114 // Cache mapping ProtectionDomain.Key to PermissionCollection |
119 // Cache mapping ProtectionDomain.Key to PermissionCollection |
115 private WeakHashMap<ProtectionDomain.Key, PermissionCollection> pdMapping; |
120 private WeakHashMap<ProtectionDomain.Key, PermissionCollection> pdMapping; |
116 |
121 |
117 /** package private for AccessControlContext and ProtectionDomain */ |
122 /** package private for AccessControlContext and ProtectionDomain */ |
118 static boolean isSet() |
123 static boolean isSet() |
167 // already initialized |
172 // already initialized |
168 if (pi.initialized == false || pi.policy == null) { |
173 if (pi.initialized == false || pi.policy == null) { |
169 synchronized (Policy.class) { |
174 synchronized (Policy.class) { |
170 PolicyInfo pinfo = policy.get(); |
175 PolicyInfo pinfo = policy.get(); |
171 if (pinfo.policy == null) { |
176 if (pinfo.policy == null) { |
172 String policy_class = AccessController.doPrivileged( |
177 return loadPolicyProvider(); |
173 new PrivilegedAction<>() { |
|
174 public String run() { |
|
175 return Security.getProperty("policy.provider"); |
|
176 } |
|
177 }); |
|
178 if (policy_class == null) { |
|
179 policy_class = "sun.security.provider.PolicyFile"; |
|
180 } |
|
181 |
|
182 try { |
|
183 pinfo = new PolicyInfo( |
|
184 (Policy) Class.forName(policy_class).newInstance(), |
|
185 true); |
|
186 } catch (Exception e) { |
|
187 /* |
|
188 * The policy_class seems to be an extension |
|
189 * so we have to bootstrap loading it via a policy |
|
190 * provider that is on the bootclasspath. |
|
191 * If it loads then shift gears to using the configured |
|
192 * provider. |
|
193 */ |
|
194 |
|
195 // install the bootstrap provider to avoid recursion |
|
196 Policy polFile = new sun.security.provider.PolicyFile(); |
|
197 pinfo = new PolicyInfo(polFile, false); |
|
198 policy.set(pinfo); |
|
199 |
|
200 final String pc = policy_class; |
|
201 Policy pol = AccessController.doPrivileged( |
|
202 new PrivilegedAction<>() { |
|
203 public Policy run() { |
|
204 try { |
|
205 ClassLoader cl = |
|
206 ClassLoader.getSystemClassLoader(); |
|
207 // we want the extension loader |
|
208 ClassLoader extcl = null; |
|
209 while (cl != null) { |
|
210 extcl = cl; |
|
211 cl = cl.getParent(); |
|
212 } |
|
213 return (extcl != null ? (Policy)Class.forName( |
|
214 pc, true, extcl).newInstance() : null); |
|
215 } catch (Exception e) { |
|
216 if (debug != null) { |
|
217 debug.println("policy provider " + |
|
218 pc + |
|
219 " not available"); |
|
220 e.printStackTrace(); |
|
221 } |
|
222 return null; |
|
223 } |
|
224 } |
|
225 }); |
|
226 /* |
|
227 * if it loaded install it as the policy provider. Otherwise |
|
228 * continue to use the system default implementation |
|
229 */ |
|
230 if (pol != null) { |
|
231 pinfo = new PolicyInfo(pol, true); |
|
232 } else { |
|
233 if (debug != null) { |
|
234 debug.println("using sun.security.provider.PolicyFile"); |
|
235 } |
|
236 pinfo = new PolicyInfo(polFile, true); |
|
237 } |
|
238 } |
|
239 policy.set(pinfo); |
|
240 } |
178 } |
241 return pinfo.policy; |
179 return pinfo.policy; |
242 } |
180 } |
243 } |
181 } |
244 return pi.policy; |
182 return pi.policy; |
|
183 } |
|
184 |
|
185 /** |
|
186 * Loads and instantiates a Policy implementation specified by the |
|
187 * policy.provider security property. Note that this method should only |
|
188 * be called by getPolicyNoCheck and from within a synchronized block with |
|
189 * an intrinsic lock on the Policy.class. |
|
190 */ |
|
191 private static Policy loadPolicyProvider() { |
|
192 String policyProvider = |
|
193 AccessController.doPrivileged(new PrivilegedAction<>() { |
|
194 @Override |
|
195 public String run() { |
|
196 return Security.getProperty("policy.provider"); |
|
197 } |
|
198 }); |
|
199 |
|
200 /* |
|
201 * If policy.provider is not set or is set to the default provider, |
|
202 * simply instantiate it and return. |
|
203 */ |
|
204 if (policyProvider == null || policyProvider.isEmpty() || |
|
205 policyProvider.equals(DEFAULT_POLICY)) |
|
206 { |
|
207 Policy polFile = new sun.security.provider.PolicyFile(); |
|
208 policy.set(new PolicyInfo(polFile, true)); |
|
209 return polFile; |
|
210 } |
|
211 |
|
212 /* |
|
213 * Locate, load, and instantiate the policy.provider impl using |
|
214 * the system class loader. While doing so, install the bootstrap |
|
215 * provider to avoid potential recursion. |
|
216 */ |
|
217 Policy polFile = new sun.security.provider.PolicyFile(); |
|
218 policy.set(new PolicyInfo(polFile, false)); |
|
219 |
|
220 Policy pol = AccessController.doPrivileged(new PrivilegedAction<>() { |
|
221 @Override |
|
222 public Policy run() { |
|
223 try { |
|
224 ClassLoader scl = ClassLoader.getSystemClassLoader(); |
|
225 Class<?> c = Class.forName(policyProvider, true, scl); |
|
226 return (Policy)c.newInstance(); |
|
227 } catch (Exception e) { |
|
228 if (debug != null) { |
|
229 debug.println("policy provider " + policyProvider + |
|
230 " not available"); |
|
231 e.printStackTrace(); |
|
232 } |
|
233 return null; |
|
234 } |
|
235 } |
|
236 }); |
|
237 |
|
238 if (pol == null) { |
|
239 // Fallback and use the system default implementation |
|
240 if (debug != null) { |
|
241 debug.println("using " + DEFAULT_POLICY); |
|
242 } |
|
243 pol = polFile; |
|
244 } |
|
245 policy.set(new PolicyInfo(pol, true)); |
|
246 return pol; |
245 } |
247 } |
246 |
248 |
247 /** |
249 /** |
248 * Sets the system-wide Policy object. This method first calls |
250 * Sets the system-wide Policy object. This method first calls |
249 * {@code SecurityManager.checkPermission} with a |
251 * {@code SecurityManager.checkPermission} with a |