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/security/provider/PolicyFile.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/provider/PolicyFile.java+2437−0
@@ -0,0 +1,2437 @@
1+/*
2+ * Copyright (c) 1997, 2011, 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.security.provider;
27+
28+import java.io.*;
29+import java.lang.RuntimePermission;
30+import java.lang.reflect.*;
31+import java.lang.ref.*;
32+import java.net.MalformedURLException;
33+import java.net.URL;
34+import java.net.URI;
35+import java.util.*;
36+import java.util.Enumeration;
37+import java.util.Hashtable;
38+import java.util.List;
39+import java.util.StringTokenizer;
40+import java.util.PropertyPermission;
41+import java.util.ArrayList;
42+import java.util.ListIterator;
43+import java.util.WeakHashMap;
44+import java.text.MessageFormat;
45+import com.sun.security.auth.PrincipalComparator;
46+import java.security.*;
47+import java.security.cert.Certificate;
48+import java.security.cert.X509Certificate;
49+import javax.security.auth.PrivateCredentialPermission;
50+import javax.security.auth.Subject;
51+import javax.security.auth.x500.X500Principal;
52+import java.io.FilePermission;
53+import java.net.SocketPermission;
54+import java.net.NetPermission;
55+import java.util.PropertyPermission;
56+import java.util.concurrent.atomic.AtomicReference;
57+/*
58+import javax.security.auth.AuthPermission;
59+import javax.security.auth.kerberos.ServicePermission;
60+import javax.security.auth.kerberos.DelegationPermission;
61+import java.io.SerializablePermission;
62+import java.util.logging.LoggingPermission;
63+import java.sql.SQLPermission;
64+import java.lang.reflect.ReflectPermission;
65+import javax.sound.sampled.AudioPermission;
66+import javax.net.ssl.SSLPermission;
67+*/
68+import sun.misc.JavaSecurityProtectionDomainAccess;
69+import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
70+import sun.misc.SharedSecrets;
71+import sun.security.util.Password;
72+import sun.security.util.PolicyUtil;
73+import sun.security.util.PropertyExpander;
74+import sun.security.util.Debug;
75+import sun.security.util.ResourcesMgr;
76+import sun.security.util.SecurityConstants;
77+import sun.net.www.ParseUtil;
78+
79+/**
80+ * This class represents a default implementation for
81+ * <code>java.security.Policy</code>.
82+ *
83+ * Note:
84+ * For backward compatibility with JAAS 1.0 it loads
85+ * both java.auth.policy and java.policy. However it
86+ * is recommended that java.auth.policy be not used
87+ * and the java.policy contain all grant entries including
88+ * that contain principal-based entries.
89+ *
90+ *
91+ * <p> This object stores the policy for entire Java runtime,
92+ * and is the amalgamation of multiple static policy
93+ * configurations that resides in files.
94+ * The algorithm for locating the policy file(s) and reading their
95+ * information into this <code>Policy</code> object is:
96+ *
97+ * <ol>
98+ * <li>
99+ * Loop through the <code>java.security.Security</code> properties,
100+ * <i>policy.url.1</i>, <i>policy.url.2</i>, ...,
101+ * <i>policy.url.X</i>" and
102+ * <i>auth.policy.url.1</i>, <i>auth.policy.url.2</i>, ...,
103+ * <i>auth.policy.url.X</i>". These properties are set
104+ * in the Java security properties file, which is located in the file named
105+ * &lt;JAVA_HOME&gt;/lib/security/java.security.
106+ * &lt;JAVA_HOME&gt; refers to the value of the java.home system property,
107+ * and specifies the directory where the JRE is installed.
108+ * Each property value specifies a <code>URL</code> pointing to a
109+ * policy file to be loaded. Read in and load each policy.
110+ *
111+ * <i>auth.policy.url</i> is supported only for backward compatibility.
112+ *
113+ * <li>
114+ * The <code>java.lang.System</code> property <i>java.security.policy</i>
115+ * may also be set to a <code>URL</code> pointing to another policy file
116+ * (which is the case when a user uses the -D switch at runtime).
117+ * If this property is defined, and its use is allowed by the
118+ * security property file (the Security property,
119+ * <i>policy.allowSystemProperty</i> is set to <i>true</i>),
120+ * also load that policy.
121+ *
122+ * <li>
123+ * The <code>java.lang.System</code> property
124+ * <i>java.security.auth.policy</i> may also be set to a
125+ * <code>URL</code> pointing to another policy file
126+ * (which is the case when a user uses the -D switch at runtime).
127+ * If this property is defined, and its use is allowed by the
128+ * security property file (the Security property,
129+ * <i>policy.allowSystemProperty</i> is set to <i>true</i>),
130+ * also load that policy.
131+ *
132+ * <i>java.security.auth.policy</i> is supported only for backward
133+ * compatibility.
134+ *
135+ * If the <i>java.security.policy</i> or
136+ * <i>java.security.auth.policy</i> property is defined using
137+ * "==" (rather than "="), then ignore all other specified
138+ * policies and only load this policy.
139+ * </ol>
140+ *
141+ * Each policy file consists of one or more grant entries, each of
142+ * which consists of a number of permission entries.
143+ *
144+ * <pre>
145+ * grant signedBy "<b>alias</b>", codeBase "<b>URL</b>",
146+ * principal <b>principalClass</b> "<b>principalName</b>",
147+ * principal <b>principalClass</b> "<b>principalName</b>",
148+ * ... {
149+ *
150+ * permission <b>Type</b> "<b>name</b> "<b>action</b>",
151+ * signedBy "<b>alias</b>";
152+ * permission <b>Type</b> "<b>name</b> "<b>action</b>",
153+ * signedBy "<b>alias</b>";
154+ * ....
155+ * };
156+ * </pre>
157+ *
158+ * All non-bold items above must appear as is (although case
159+ * doesn't matter and some are optional, as noted below).
160+ * principal entries are optional and need not be present.
161+ * Italicized items represent variable values.
162+ *
163+ * <p> A grant entry must begin with the word <code>grant</code>.
164+ * The <code>signedBy</code>,<code>codeBase</code> and <code>principal</code>
165+ * name/value pairs are optional.
166+ * If they are not present, then any signer (including unsigned code)
167+ * will match, and any codeBase will match.
168+ * Note that the <i>principalClass</i>
169+ * may be set to the wildcard value, *, which allows it to match
170+ * any <code>Principal</code> class. In addition, the <i>principalName</i>
171+ * may also be set to the wildcard value, *, allowing it to match
172+ * any <code>Principal</code> name. When setting the <i>principalName</i>
173+ * to the *, do not surround the * with quotes.
174+ *
175+ * <p> A permission entry must begin with the word <code>permission</code>.
176+ * The word <code><i>Type</i></code> in the template above is
177+ * a specific permission type, such as <code>java.io.FilePermission</code>
178+ * or <code>java.lang.RuntimePermission</code>.
179+ *
180+ * <p> The "<i>action</i>" is required for
181+ * many permission types, such as <code>java.io.FilePermission</code>
182+ * (where it specifies what type of file access that is permitted).
183+ * It is not required for categories such as
184+ * <code>java.lang.RuntimePermission</code>
185+ * where it is not necessary - you either have the
186+ * permission specified by the <code>"<i>name</i>"</code>
187+ * value following the type name or you don't.
188+ *
189+ * <p> The <code>signedBy</code> name/value pair for a permission entry
190+ * is optional. If present, it indicates a signed permission. That is,
191+ * the permission class itself must be signed by the given alias in
192+ * order for it to be granted. For example,
193+ * suppose you have the following grant entry:
194+ *
195+ * <pre>
196+ * grant principal foo.com.Principal "Duke" {
197+ * permission Foo "foobar", signedBy "FooSoft";
198+ * }
199+ * </pre>
200+ *
201+ * <p> Then this permission of type <i>Foo</i> is granted if the
202+ * <code>Foo.class</code> permission has been signed by the
203+ * "FooSoft" alias, or if XXX <code>Foo.class</code> is a
204+ * system class (i.e., is found on the CLASSPATH).
205+ *
206+ *
207+ * <p> Items that appear in an entry must appear in the specified order
208+ * (<code>permission</code>, <i>Type</i>, "<i>name</i>", and
209+ * "<i>action</i>"). An entry is terminated with a semicolon.
210+ *
211+ * <p> Case is unimportant for the identifiers (<code>permission</code>,
212+ * <code>signedBy</code>, <code>codeBase</code>, etc.) but is
213+ * significant for the <i>Type</i>
214+ * or for any string that is passed in as a value. <p>
215+ *
216+ * <p> An example of two entries in a policy configuration file is
217+ * <pre>
218+ * // if the code is comes from "foo.com" and is running as "Duke",
219+ * // grant it read/write to all files in /tmp.
220+ *
221+ * grant codeBase "foo.com", principal foo.com.Principal "Duke" {
222+ * permission java.io.FilePermission "/tmp/*", "read,write";
223+ * };
224+ *
225+ * // grant any code running as "Duke" permission to read
226+ * // the "java.vendor" Property.
227+ *
228+ * grant principal foo.com.Principal "Duke" {
229+ * permission java.util.PropertyPermission "java.vendor";
230+ *
231+ *
232+ * </pre>
233+ * This Policy implementation supports special handling of any
234+ * permission that contains the string, "<b>${{self}}</b>", as part of
235+ * its target name. When such a permission is evaluated
236+ * (such as during a security check), <b>${{self}}</b> is replaced
237+ * with one or more Principal class/name pairs. The exact
238+ * replacement performed depends upon the contents of the
239+ * grant clause to which the permission belongs.
240+ *<p>
241+ *
242+ * If the grant clause does not contain any principal information,
243+ * the permission will be ignored (permissions containing
244+ * <b>${{self}}</b> in their target names are only valid in the context
245+ * of a principal-based grant clause). For example, BarPermission
246+ * will always be ignored in the following grant clause:
247+ *
248+ *<pre>
249+ * grant codebase "www.foo.com", signedby "duke" {
250+ * permission BarPermission "... ${{self}} ...";
251+ * };
252+ *</pre>
253+ *
254+ * If the grant clause contains principal information, <b>${{self}}</b>
255+ * will be replaced with that same principal information.
256+ * For example, <b>${{self}}</b> in BarPermission will be replaced by
257+ * <b>javax.security.auth.x500.X500Principal "cn=Duke"</b>
258+ * in the following grant clause:
259+ *
260+ * <pre>
261+ * grant principal javax.security.auth.x500.X500Principal "cn=Duke" {
262+ * permission BarPermission "... ${{self}} ...";
263+ * };
264+ * </pre>
265+ *
266+ * If there is a comma-separated list of principals in the grant
267+ * clause, then <b>${{self}}</b> will be replaced by the same
268+ * comma-separated list or principals.
269+ * In the case where both the principal class and name are
270+ * wildcarded in the grant clause, <b>${{self}}</b> is replaced
271+ * with all the principals associated with the <code>Subject</code>
272+ * in the current <code>AccessControlContext</code>.
273+ *
274+ *
275+ * <p> For PrivateCredentialPermissions, you can also use "<b>self</b>"
276+ * instead of "<b>${{self}}</b>". However the use of "<b>self</b>" is
277+ * deprecated in favour of "<b>${{self}}</b>".
278+ *
279+ * @see java.security.CodeSource
280+ * @see java.security.Permissions
281+ * @see java.security.ProtectionDomain
282+ */
283+public class PolicyFile extends java.security.Policy {
284+
285+ private static final Debug debug = Debug.getInstance("policy");
286+
287+ private static final String NONE = "NONE";
288+ private static final String P11KEYSTORE = "PKCS11";
289+
290+ private static final String SELF = "${{self}}";
291+ private static final String X500PRINCIPAL =
292+ "javax.security.auth.x500.X500Principal";
293+ private static final String POLICY = "java.security.policy";
294+ private static final String SECURITY_MANAGER = "java.security.manager";
295+ private static final String POLICY_URL = "policy.url.";
296+ private static final String AUTH_POLICY = "java.security.auth.policy";
297+ private static final String AUTH_POLICY_URL = "auth.policy.url.";
298+
299+ private static final int DEFAULT_CACHE_SIZE = 1;
300+
301+ // contains the policy grant entries, PD cache, and alias mapping
302+ private AtomicReference<PolicyInfo> policyInfo = new AtomicReference<>();
303+ private boolean constructed = false;
304+
305+ private boolean expandProperties = true;
306+ private boolean ignoreIdentityScope = true;
307+ private boolean allowSystemProperties = true;
308+ private boolean notUtf8 = false;
309+ private URL url;
310+
311+ // for use with the reflection API
312+
313+ private static final Class[] PARAMS0 = { };
314+ private static final Class[] PARAMS1 = { String.class };
315+ private static final Class[] PARAMS2 = { String.class, String.class };
316+
317+ /**
318+ * Initializes the Policy object and reads the default policy
319+ * configuration file(s) into the Policy object.
320+ */
321+ public PolicyFile() {
322+ init((URL)null);
323+ }
324+
325+ /**
326+ * Initializes the Policy object and reads the default policy
327+ * from the specified URL only.
328+ */
329+ public PolicyFile(URL url) {
330+ this.url = url;
331+ init(url);
332+ }
333+
334+ /**
335+ * Initializes the Policy object and reads the default policy
336+ * configuration file(s) into the Policy object.
337+ *
338+ * The algorithm for locating the policy file(s) and reading their
339+ * information into the Policy object is:
340+ * <pre>
341+ * loop through the Security Properties named "policy.url.1",
342+ * ""policy.url.2", "auth.policy.url.1", "auth.policy.url.2" etc, until
343+ * you don't find one. Each of these specify a policy file.
344+ *
345+ * if none of these could be loaded, use a builtin static policy
346+ * equivalent to the default lib/security/java.policy file.
347+ *
348+ * if the system property "java.policy" or "java.auth.policy" is defined
349+ * (which is the
350+ * case when the user uses the -D switch at runtime), and
351+ * its use is allowed by the security property file,
352+ * also load it.
353+ * </pre>
354+ *
355+ * Each policy file consists of one or more grant entries, each of
356+ * which consists of a number of permission entries.
357+ * <pre>
358+ * grant signedBy "<i>alias</i>", codeBase "<i>URL</i>" {
359+ * permission <i>Type</i> "<i>name</i>", "<i>action</i>",
360+ * signedBy "<i>alias</i>";
361+ * ....
362+ * permission <i>Type</i> "<i>name</i>", "<i>action</i>",
363+ * signedBy "<i>alias</i>";
364+ * };
365+ *
366+ * </pre>
367+ *
368+ * All non-italicized items above must appear as is (although case
369+ * doesn't matter and some are optional, as noted below).
370+ * Italicized items represent variable values.
371+ *
372+ * <p> A grant entry must begin with the word <code>grant</code>.
373+ * The <code>signedBy</code> and <code>codeBase</code> name/value
374+ * pairs are optional.
375+ * If they are not present, then any signer (including unsigned code)
376+ * will match, and any codeBase will match.
377+ *
378+ * <p> A permission entry must begin with the word <code>permission</code>.
379+ * The word <code><i>Type</i></code> in the template above would actually
380+ * be a specific permission type, such as
381+ * <code>java.io.FilePermission</code> or
382+ * <code>java.lang.RuntimePermission</code>.
383+ *
384+ * <p>The "<i>action</i>" is required for
385+ * many permission types, such as <code>java.io.FilePermission</code>
386+ * (where it specifies what type of file access is permitted).
387+ * It is not required for categories such as
388+ * <code>java.lang.RuntimePermission</code>
389+ * where it is not necessary - you either have the
390+ * permission specified by the <code>"<i>name</i>"</code>
391+ * value following the type name or you don't.
392+ *
393+ * <p>The <code>signedBy</code> name/value pair for a permission entry
394+ * is optional. If present, it indicates a signed permission. That is,
395+ * the permission class itself must be signed by the given alias in
396+ * order for it to be granted. For example,
397+ * suppose you have the following grant entry:
398+ *
399+ * <pre>
400+ * grant {
401+ * permission Foo "foobar", signedBy "FooSoft";
402+ * }
403+ * </pre>
404+ *
405+ * <p>Then this permission of type <i>Foo</i> is granted if the
406+ * <code>Foo.class</code> permission has been signed by the
407+ * "FooSoft" alias, or if <code>Foo.class</code> is a
408+ * system class (i.e., is found on the CLASSPATH).
409+ *
410+ * <p>Items that appear in an entry must appear in the specified order
411+ * (<code>permission</code>, <i>Type</i>, "<i>name</i>", and
412+ * "<i>action</i>"). An entry is terminated with a semicolon.
413+ *
414+ * <p>Case is unimportant for the identifiers (<code>permission</code>,
415+ * <code>signedBy</code>, <code>codeBase</code>, etc.) but is
416+ * significant for the <i>Type</i>
417+ * or for any string that is passed in as a value. <p>
418+ *
419+ * <p>An example of two entries in a policy configuration file is
420+ * <pre>
421+ * // if the code is signed by "Duke", grant it read/write to all
422+ * // files in /tmp.
423+ *
424+ * grant signedBy "Duke" {
425+ * permission java.io.FilePermission "/tmp/*", "read,write";
426+ * };
427+ * <p>
428+ * // grant everyone the following permission
429+ *
430+ * grant {
431+ * permission java.util.PropertyPermission "java.vendor";
432+ * };
433+ * </pre>
434+ */
435+ private void init(URL url) {
436+ // Properties are set once for each init(); ignore changes between
437+ // between diff invocations of initPolicyFile(policy, url, info).
438+ String numCacheStr =
439+ AccessController.doPrivileged(new PrivilegedAction<String>() {
440+ public String run() {
441+ expandProperties = "true".equalsIgnoreCase
442+ (Security.getProperty("policy.expandProperties"));
443+ ignoreIdentityScope = "true".equalsIgnoreCase
444+ (Security.getProperty("policy.ignoreIdentityScope"));
445+ allowSystemProperties = "true".equalsIgnoreCase
446+ (Security.getProperty("policy.allowSystemProperty"));
447+ notUtf8 = "false".equalsIgnoreCase
448+ (System.getProperty("sun.security.policy.utf8"));
449+ return System.getProperty("sun.security.policy.numcaches");
450+ }});
451+
452+ int numCaches;
453+ if (numCacheStr != null) {
454+ try {
455+ numCaches = Integer.parseInt(numCacheStr);
456+ } catch (NumberFormatException e) {
457+ numCaches = DEFAULT_CACHE_SIZE;
458+ }
459+ } else {
460+ numCaches = DEFAULT_CACHE_SIZE;
461+ }
462+ // System.out.println("number caches=" + numCaches);
463+ PolicyInfo newInfo = new PolicyInfo(numCaches);
464+ initPolicyFile(newInfo, url);
465+ policyInfo.set(newInfo);
466+ }
467+
468+ private void initPolicyFile(final PolicyInfo newInfo, final URL url) {
469+
470+ if (url != null) {
471+
472+ /**
473+ * If the caller specified a URL via Policy.getInstance,
474+ * we only read from that URL
475+ */
476+
477+ if (debug != null) {
478+ debug.println("reading "+url);
479+ }
480+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
481+ public Void run() {
482+ if (init(url, newInfo) == false) {
483+ // use static policy if all else fails
484+ initStaticPolicy(newInfo);
485+ }
486+ return null;
487+ }
488+ });
489+
490+ } else {
491+
492+ /**
493+ * Caller did not specify URL via Policy.getInstance.
494+ * Read from URLs listed in the java.security properties file.
495+ *
496+ * We call initPolicyFile with POLICY , POLICY_URL and then
497+ * call it with AUTH_POLICY and AUTH_POLICY_URL
498+ * So first we will process the JAVA standard policy
499+ * and then process the JAVA AUTH Policy.
500+ * This is for backward compatibility as well as to handle
501+ * cases where the user has a single unified policyfile
502+ * with both java policy entries and auth entries
503+ */
504+
505+ boolean loaded_one = initPolicyFile(POLICY, POLICY_URL, newInfo);
506+ // To maintain strict backward compatibility
507+ // we load the static policy only if POLICY load failed
508+ if (!loaded_one) {
509+ // use static policy if all else fails
510+ initStaticPolicy(newInfo);
511+ }
512+
513+ initPolicyFile(AUTH_POLICY, AUTH_POLICY_URL, newInfo);
514+ }
515+ }
516+
517+ private boolean initPolicyFile(final String propname, final String urlname,
518+ final PolicyInfo newInfo) {
519+ Boolean loadedPolicy =
520+ AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
521+ public Boolean run() {
522+ boolean loaded_policy = false;
523+
524+ if (allowSystemProperties) {
525+ String extra_policy = System.getProperty(propname);
526+ if (extra_policy != null) {
527+ boolean overrideAll = false;
528+ if (extra_policy.startsWith("=")) {
529+ overrideAll = true;
530+ extra_policy = extra_policy.substring(1);
531+ }
532+ try {
533+ extra_policy =
534+ PropertyExpander.expand(extra_policy);
535+ URL policyURL;
536+
537+ File policyFile = new File(extra_policy);
538+ if (policyFile.exists()) {
539+ policyURL = ParseUtil.fileToEncodedURL
540+ (new File(policyFile.getCanonicalPath()));
541+ } else {
542+ policyURL = new URL(extra_policy);
543+ }
544+ if (debug != null)
545+ debug.println("reading "+policyURL);
546+ if (init(policyURL, newInfo))
547+ loaded_policy = true;
548+ } catch (Exception e) {
549+ // ignore.
550+ if (debug != null) {
551+ debug.println("caught exception: "+e);
552+ }
553+ }
554+ if (overrideAll) {
555+ if (debug != null) {
556+ debug.println("overriding other policies!");
557+ }
558+ return Boolean.valueOf(loaded_policy);
559+ }
560+ }
561+ }
562+
563+ int n = 1;
564+ String policy_uri;
565+
566+ while ((policy_uri = Security.getProperty(urlname+n)) != null) {
567+ try {
568+ URL policy_url = null;
569+ String expanded_uri = PropertyExpander.expand
570+ (policy_uri).replace(File.separatorChar, '/');
571+
572+ if (policy_uri.startsWith("file:${java.home}/") ||
573+ policy_uri.startsWith("file:${user.home}/")) {
574+
575+ // this special case accommodates
576+ // the situation java.home/user.home
577+ // expand to a single slash, resulting in
578+ // a file://foo URI
579+ policy_url = new File
580+ (expanded_uri.substring(5)).toURI().toURL();
581+ } else {
582+ policy_url = new URI(expanded_uri).toURL();
583+ }
584+
585+ if (debug != null)
586+ debug.println("reading "+policy_url);
587+ if (init(policy_url, newInfo))
588+ loaded_policy = true;
589+ } catch (Exception e) {
590+ if (debug != null) {
591+ debug.println("error reading policy "+e);
592+ e.printStackTrace();
593+ }
594+ // ignore that policy
595+ }
596+ n++;
597+ }
598+ return Boolean.valueOf(loaded_policy);
599+ }
600+ });
601+
602+ return loadedPolicy.booleanValue();
603+ }
604+
605+ /**
606+ * Reads a policy configuration into the Policy object using a
607+ * Reader object.
608+ *
609+ * @param policyFile the policy Reader object.
610+ */
611+ private boolean init(URL policy, PolicyInfo newInfo) {
612+ boolean success = false;
613+ PolicyParser pp = new PolicyParser(expandProperties);
614+ InputStreamReader isr = null;
615+ try {
616+
617+ // read in policy using UTF-8 by default
618+ //
619+ // check non-standard system property to see if
620+ // the default encoding should be used instead
621+
622+ if (notUtf8) {
623+ isr = new InputStreamReader
624+ (PolicyUtil.getInputStream(policy));
625+ } else {
626+ isr = new InputStreamReader
627+ (PolicyUtil.getInputStream(policy), "UTF-8");
628+ }
629+
630+ pp.read(isr);
631+
632+ KeyStore keyStore = null;
633+ try {
634+ keyStore = PolicyUtil.getKeyStore
635+ (policy,
636+ pp.getKeyStoreUrl(),
637+ pp.getKeyStoreType(),
638+ pp.getKeyStoreProvider(),
639+ pp.getStorePassURL(),
640+ debug);
641+ } catch (Exception e) {
642+ // ignore, treat it like we have no keystore
643+ if (debug != null) {
644+ e.printStackTrace();
645+ }
646+ }
647+
648+ Enumeration<PolicyParser.GrantEntry> enum_ = pp.grantElements();
649+ while (enum_.hasMoreElements()) {
650+ PolicyParser.GrantEntry ge = enum_.nextElement();
651+ addGrantEntry(ge, keyStore, newInfo);
652+ }
653+ } catch (PolicyParser.ParsingException pe) {
654+ MessageFormat form = new MessageFormat(ResourcesMgr.getString
655+ (POLICY + ".error.parsing.policy.message"));
656+ Object[] source = {policy, pe.getLocalizedMessage()};
657+ System.err.println(form.format(source));
658+ if (debug != null)
659+ pe.printStackTrace();
660+
661+ } catch (Exception e) {
662+ if (debug != null) {
663+ debug.println("error parsing "+policy);
664+ debug.println(e.toString());
665+ e.printStackTrace();
666+ }
667+ } finally {
668+ if (isr != null) {
669+ try {
670+ isr.close();
671+ success = true;
672+ } catch (IOException e) {
673+ // ignore the exception
674+ }
675+ } else {
676+ success = true;
677+ }
678+ }
679+
680+ return success;
681+ }
682+
683+ private void initStaticPolicy(final PolicyInfo newInfo) {
684+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
685+ public Void run() {
686+ PolicyEntry pe = new PolicyEntry(new CodeSource(null,
687+ (Certificate[]) null));
688+ pe.add(SecurityConstants.LOCAL_LISTEN_PERMISSION);
689+ pe.add(new PropertyPermission("java.version",
690+ SecurityConstants.PROPERTY_READ_ACTION));
691+ pe.add(new PropertyPermission("java.vendor",
692+ SecurityConstants.PROPERTY_READ_ACTION));
693+ pe.add(new PropertyPermission("java.vendor.url",
694+ SecurityConstants.PROPERTY_READ_ACTION));
695+ pe.add(new PropertyPermission("java.class.version",
696+ SecurityConstants.PROPERTY_READ_ACTION));
697+ pe.add(new PropertyPermission("os.name",
698+ SecurityConstants.PROPERTY_READ_ACTION));
699+ pe.add(new PropertyPermission("os.version",
700+ SecurityConstants.PROPERTY_READ_ACTION));
701+ pe.add(new PropertyPermission("os.arch",
702+ SecurityConstants.PROPERTY_READ_ACTION));
703+ pe.add(new PropertyPermission("file.separator",
704+ SecurityConstants.PROPERTY_READ_ACTION));
705+ pe.add(new PropertyPermission("path.separator",
706+ SecurityConstants.PROPERTY_READ_ACTION));
707+ pe.add(new PropertyPermission("line.separator",
708+ SecurityConstants.PROPERTY_READ_ACTION));
709+ pe.add(new PropertyPermission
710+ ("java.specification.version",
711+ SecurityConstants.PROPERTY_READ_ACTION));
712+ pe.add(new PropertyPermission
713+ ("java.specification.vendor",
714+ SecurityConstants.PROPERTY_READ_ACTION));
715+ pe.add(new PropertyPermission
716+ ("java.specification.name",
717+ SecurityConstants.PROPERTY_READ_ACTION));
718+ pe.add(new PropertyPermission
719+ ("java.vm.specification.version",
720+ SecurityConstants.PROPERTY_READ_ACTION));
721+ pe.add(new PropertyPermission
722+ ("java.vm.specification.vendor",
723+ SecurityConstants.PROPERTY_READ_ACTION));
724+ pe.add(new PropertyPermission
725+ ("java.vm.specification.name",
726+ SecurityConstants.PROPERTY_READ_ACTION));
727+ pe.add(new PropertyPermission("java.vm.version",
728+ SecurityConstants.PROPERTY_READ_ACTION));
729+ pe.add(new PropertyPermission("java.vm.vendor",
730+ SecurityConstants.PROPERTY_READ_ACTION));
731+ pe.add(new PropertyPermission("java.vm.name",
732+ SecurityConstants.PROPERTY_READ_ACTION));
733+
734+ // No need to sync because noone has access to newInfo yet
735+ newInfo.policyEntries.add(pe);
736+
737+ // Add AllPermissions for standard extensions
738+ String[] extCodebases = PolicyParser.parseExtDirs(
739+ PolicyParser.EXTDIRS_EXPANSION, 0);
740+ if (extCodebases != null && extCodebases.length > 0) {
741+ for (int i = 0; i < extCodebases.length; i++) {
742+ try {
743+ pe = new PolicyEntry(canonicalizeCodebase(
744+ new CodeSource(new URL(extCodebases[i]),
745+ (Certificate[]) null), false ));
746+ pe.add(SecurityConstants.ALL_PERMISSION);
747+
748+ // No need to sync because noone has access to
749+ // newInfo yet
750+ newInfo.policyEntries.add(pe);
751+ } catch (Exception e) {
752+ // this is probably bad (though not dangerous).
753+ // What should we do?
754+ }
755+ }
756+ }
757+ return null;
758+ }
759+ });
760+ }
761+
762+ /**
763+ * Given a GrantEntry, create a codeSource.
764+ *
765+ * @return null if signedBy alias is not recognized
766+ */
767+ private CodeSource getCodeSource(PolicyParser.GrantEntry ge, KeyStore keyStore,
768+ PolicyInfo newInfo) throws java.net.MalformedURLException
769+ {
770+ Certificate[] certs = null;
771+ if (ge.signedBy != null) {
772+ certs = getCertificates(keyStore, ge.signedBy, newInfo);
773+ if (certs == null) {
774+ // we don't have a key for this alias,
775+ // just return
776+ if (debug != null) {
777+ debug.println(" -- No certs for alias '" +
778+ ge.signedBy + "' - ignoring entry");
779+ }
780+ return null;
781+ }
782+ }
783+
784+ URL location;
785+
786+ if (ge.codeBase != null)
787+ location = new URL(ge.codeBase);
788+ else
789+ location = null;
790+
791+ return (canonicalizeCodebase(new CodeSource(location, certs),false));
792+ }
793+
794+ /**
795+ * Add one policy entry to the list.
796+ */
797+ private void addGrantEntry(PolicyParser.GrantEntry ge,
798+ KeyStore keyStore, PolicyInfo newInfo) {
799+
800+ if (debug != null) {
801+ debug.println("Adding policy entry: ");
802+ debug.println(" signedBy " + ge.signedBy);
803+ debug.println(" codeBase " + ge.codeBase);
804+ if (ge.principals != null && ge.principals.size() > 0) {
805+ ListIterator<PolicyParser.PrincipalEntry> li =
806+ ge.principals.listIterator();
807+ while (li.hasNext()) {
808+ PolicyParser.PrincipalEntry pppe = li.next();
809+ debug.println(" " + pppe.toString());
810+ }
811+ }
812+ }
813+
814+ try {
815+ CodeSource codesource = getCodeSource(ge, keyStore, newInfo);
816+ // skip if signedBy alias was unknown...
817+ if (codesource == null) return;
818+
819+ // perform keystore alias principal replacement.
820+ // for example, if alias resolves to X509 certificate,
821+ // replace principal with: <X500Principal class> <SubjectDN>
822+ // -- skip if alias is unknown
823+ if (replacePrincipals(ge.principals, keyStore) == false)
824+ return;
825+ PolicyEntry entry = new PolicyEntry(codesource, ge.principals);
826+ Enumeration<PolicyParser.PermissionEntry> enum_ =
827+ ge.permissionElements();
828+ while (enum_.hasMoreElements()) {
829+ PolicyParser.PermissionEntry pe = enum_.nextElement();
830+
831+ try {
832+ // perform ${{ ... }} expansions within permission name
833+ expandPermissionName(pe, keyStore);
834+
835+ // XXX special case PrivateCredentialPermission-SELF
836+ Permission perm;
837+ if (pe.permission.equals
838+ ("javax.security.auth.PrivateCredentialPermission") &&
839+ pe.name.endsWith(" self")) {
840+ pe.name = pe.name.substring(0, pe.name.indexOf("self"))
841+ + SELF;
842+ }
843+ // check for self
844+ if (pe.name != null && pe.name.indexOf(SELF) != -1) {
845+ // Create a "SelfPermission" , it could be an
846+ // an unresolved permission which will be resolved
847+ // when implies is called
848+ // Add it to entry
849+ Certificate certs[];
850+ if (pe.signedBy != null) {
851+ certs = getCertificates(keyStore,
852+ pe.signedBy,
853+ newInfo);
854+ } else {
855+ certs = null;
856+ }
857+ perm = new SelfPermission(pe.permission,
858+ pe.name,
859+ pe.action,
860+ certs);
861+ } else {
862+ perm = getInstance(pe.permission,
863+ pe.name,
864+ pe.action);
865+ }
866+ entry.add(perm);
867+ if (debug != null) {
868+ debug.println(" "+perm);
869+ }
870+ } catch (ClassNotFoundException cnfe) {
871+ Certificate certs[];
872+ if (pe.signedBy != null) {
873+ certs = getCertificates(keyStore,
874+ pe.signedBy,
875+ newInfo);
876+ } else {
877+ certs = null;
878+ }
879+
880+ // only add if we had no signer or we had a
881+ // a signer and found the keys for it.
882+ if (certs != null || pe.signedBy == null) {
883+ Permission perm = new UnresolvedPermission(
884+ pe.permission,
885+ pe.name,
886+ pe.action,
887+ certs);
888+ entry.add(perm);
889+ if (debug != null) {
890+ debug.println(" "+perm);
891+ }
892+ }
893+ } catch (java.lang.reflect.InvocationTargetException ite) {
894+ MessageFormat form = new MessageFormat
895+ (ResourcesMgr.getString
896+ (POLICY +
897+ ".error.adding.Permission.perm.message"));
898+ Object[] source = {pe.permission,
899+ ite.getTargetException().toString()};
900+ System.err.println(form.format(source));
901+ } catch (Exception e) {
902+ MessageFormat form = new MessageFormat
903+ (ResourcesMgr.getString
904+ (POLICY +
905+ ".error.adding.Permission.perm.message"));
906+ Object[] source = {pe.permission,
907+ e.toString()};
908+ System.err.println(form.format(source));
909+ }
910+ }
911+
912+ // No need to sync because noone has access to newInfo yet
913+ newInfo.policyEntries.add(entry);
914+ } catch (Exception e) {
915+ MessageFormat form = new MessageFormat(ResourcesMgr.getString
916+ (POLICY
917+ + ".error.adding.Entry.message"));
918+ Object[] source = {e.toString()};
919+ System.err.println(form.format(source));
920+ }
921+ if (debug != null)
922+ debug.println();
923+ }
924+
925+ /**
926+ * Returns a new Permission object of the given Type. The Permission is
927+ * created by getting the
928+ * Class object using the <code>Class.forName</code> method, and using
929+ * the reflection API to invoke the (String name, String actions)
930+ * constructor on the
931+ * object.
932+ *
933+ * @param type the type of Permission being created.
934+ * @param name the name of the Permission being created.
935+ * @param actions the actions of the Permission being created.
936+ *
937+ * @exception ClassNotFoundException if the particular Permission
938+ * class could not be found.
939+ *
940+ * @exception IllegalAccessException if the class or initializer is
941+ * not accessible.
942+ *
943+ * @exception InstantiationException if getInstance tries to
944+ * instantiate an abstract class or an interface, or if the
945+ * instantiation fails for some other reason.
946+ *
947+ * @exception NoSuchMethodException if the (String, String) constructor
948+ * is not found.
949+ *
950+ * @exception InvocationTargetException if the underlying Permission
951+ * constructor throws an exception.
952+ *
953+ */
954+
955+ private static final Permission getInstance(String type,
956+ String name,
957+ String actions)
958+ throws ClassNotFoundException,
959+ InstantiationException,
960+ IllegalAccessException,
961+ NoSuchMethodException,
962+ InvocationTargetException
963+ {
964+ //XXX we might want to keep a hash of created factories...
965+ Class<?> pc = Class.forName(type);
966+ Permission answer = getKnownInstance(pc, name, actions);
967+ if (answer != null) {
968+ return answer;
969+ }
970+
971+ if (name == null && actions == null) {
972+ try {
973+ Constructor<?> c = pc.getConstructor(PARAMS0);
974+ return (Permission) c.newInstance(new Object[] {});
975+ } catch (NoSuchMethodException ne) {
976+ try {
977+ Constructor<?> c = pc.getConstructor(PARAMS1);
978+ return (Permission) c.newInstance(
979+ new Object[] { name});
980+ } catch (NoSuchMethodException ne1 ) {
981+ Constructor<?> c = pc.getConstructor(PARAMS2);
982+ return (Permission) c.newInstance(
983+ new Object[] { name, actions });
984+ }
985+ }
986+ } else {
987+ if (name != null && actions == null) {
988+ try {
989+ Constructor<?> c = pc.getConstructor(PARAMS1);
990+ return (Permission) c.newInstance(new Object[] { name});
991+ } catch (NoSuchMethodException ne) {
992+ Constructor<?> c = pc.getConstructor(PARAMS2);
993+ return (Permission) c.newInstance(
994+ new Object[] { name, actions });
995+ }
996+ } else {
997+ Constructor<?> c = pc.getConstructor(PARAMS2);
998+ return (Permission) c.newInstance(
999+ new Object[] { name, actions });
1000+ }
1001+ }
1002+ }
1003+
1004+ /**
1005+ * Creates one of the well-known permissions directly instead of
1006+ * via reflection. Keep list short to not penalize non-JDK-defined
1007+ * permissions.
1008+ */
1009+ private static final Permission getKnownInstance(Class claz,
1010+ String name, String actions) {
1011+ // XXX shorten list to most popular ones?
1012+ if (claz.equals(FilePermission.class)) {
1013+ return new FilePermission(name, actions);
1014+ } else if (claz.equals(SocketPermission.class)) {
1015+ return new SocketPermission(name, actions);
1016+ } else if (claz.equals(RuntimePermission.class)) {
1017+ return new RuntimePermission(name, actions);
1018+ } else if (claz.equals(PropertyPermission.class)) {
1019+ return new PropertyPermission(name, actions);
1020+ } else if (claz.equals(NetPermission.class)) {
1021+ return new NetPermission(name, actions);
1022+ } else if (claz.equals(AllPermission.class)) {
1023+ return SecurityConstants.ALL_PERMISSION;
1024+/*
1025+ } else if (claz.equals(ReflectPermission.class)) {
1026+ return new ReflectPermission(name, actions);
1027+ } else if (claz.equals(SecurityPermission.class)) {
1028+ return new SecurityPermission(name, actions);
1029+ } else if (claz.equals(PrivateCredentialPermission.class)) {
1030+ return new PrivateCredentialPermission(name, actions);
1031+ } else if (claz.equals(AuthPermission.class)) {
1032+ return new AuthPermission(name, actions);
1033+ } else if (claz.equals(ServicePermission.class)) {
1034+ return new ServicePermission(name, actions);
1035+ } else if (claz.equals(DelegationPermission.class)) {
1036+ return new DelegationPermission(name, actions);
1037+ } else if (claz.equals(SerializablePermission.class)) {
1038+ return new SerializablePermission(name, actions);
1039+ } else if (claz.equals(AudioPermission.class)) {
1040+ return new AudioPermission(name, actions);
1041+ } else if (claz.equals(SSLPermission.class)) {
1042+ return new SSLPermission(name, actions);
1043+ } else if (claz.equals(LoggingPermission.class)) {
1044+ return new LoggingPermission(name, actions);
1045+ } else if (claz.equals(SQLPermission.class)) {
1046+ return new SQLPermission(name, actions);
1047+*/
1048+ } else {
1049+ return null;
1050+ }
1051+ }
1052+
1053+ /**
1054+ * Fetch all certs associated with this alias.
1055+ */
1056+ private Certificate[] getCertificates
1057+ (KeyStore keyStore, String aliases, PolicyInfo newInfo) {
1058+
1059+ List<Certificate> vcerts = null;
1060+
1061+ StringTokenizer st = new StringTokenizer(aliases, ",");
1062+ int n = 0;
1063+
1064+ while (st.hasMoreTokens()) {
1065+ String alias = st.nextToken().trim();
1066+ n++;
1067+ Certificate cert = null;
1068+ // See if this alias's cert has already been cached
1069+ synchronized (newInfo.aliasMapping) {
1070+ cert = (Certificate)newInfo.aliasMapping.get(alias);
1071+
1072+ if (cert == null && keyStore != null) {
1073+
1074+ try {
1075+ cert = keyStore.getCertificate(alias);
1076+ } catch (KeyStoreException kse) {
1077+ // never happens, because keystore has already been loaded
1078+ // when we call this
1079+ }
1080+ if (cert != null) {
1081+ newInfo.aliasMapping.put(alias, cert);
1082+ newInfo.aliasMapping.put(cert, alias);
1083+ }
1084+ }
1085+ }
1086+
1087+ if (cert != null) {
1088+ if (vcerts == null)
1089+ vcerts = new ArrayList<Certificate>();
1090+ vcerts.add(cert);
1091+ }
1092+ }
1093+
1094+ // make sure n == vcerts.size, since we are doing a logical *and*
1095+ if (vcerts != null && n == vcerts.size()) {
1096+ Certificate[] certs = new Certificate[vcerts.size()];
1097+ vcerts.toArray(certs);
1098+ return certs;
1099+ } else {
1100+ return null;
1101+ }
1102+ }
1103+
1104+ /**
1105+ * Refreshes the policy object by re-reading all the policy files.
1106+ */
1107+ @Override public void refresh() {
1108+ init(url);
1109+ }
1110+
1111+ /**
1112+ * Evaluates the the global policy for the permissions granted to
1113+ * the ProtectionDomain and tests whether the permission is
1114+ * granted.
1115+ *
1116+ * @param domain the ProtectionDomain to test
1117+ * @param permission the Permission object to be tested for implication.
1118+ *
1119+ * @return true if "permission" is a proper subset of a permission
1120+ * granted to this ProtectionDomain.
1121+ *
1122+ * @see java.security.ProtectionDomain
1123+ */
1124+ @Override
1125+ public boolean implies(ProtectionDomain pd, Permission p) {
1126+ PolicyInfo pi = policyInfo.get();
1127+ ProtectionDomainCache pdMap = pi.getPdMapping();
1128+
1129+ PermissionCollection pc = pdMap.get(pd);
1130+
1131+ if (pc != null) {
1132+ return pc.implies(p);
1133+ }
1134+
1135+ pc = getPermissions(pd);
1136+ if (pc == null) {
1137+ return false;
1138+ }
1139+
1140+ // cache mapping of protection domain to its PermissionCollection
1141+ pdMap.put(pd, pc);
1142+ return pc.implies(p);
1143+ }
1144+
1145+ /**
1146+ * Examines this <code>Policy</code> and returns the permissions granted
1147+ * to the specified <code>ProtectionDomain</code>. This includes
1148+ * the permissions currently associated with the domain as well
1149+ * as the policy permissions granted to the domain's
1150+ * CodeSource, ClassLoader, and Principals.
1151+ *
1152+ * <p> Note that this <code>Policy</code> implementation has
1153+ * special handling for PrivateCredentialPermissions.
1154+ * When this method encounters a <code>PrivateCredentialPermission</code>
1155+ * which specifies "self" as the <code>Principal</code> class and name,
1156+ * it does not add that <code>Permission</code> to the returned
1157+ * <code>PermissionCollection</code>. Instead, it builds
1158+ * a new <code>PrivateCredentialPermission</code>
1159+ * for each <code>Principal</code> associated with the provided
1160+ * <code>Subject</code>. Each new <code>PrivateCredentialPermission</code>
1161+ * contains the same Credential class as specified in the
1162+ * originally granted permission, as well as the Class and name
1163+ * for the respective <code>Principal</code>.
1164+ *
1165+ * <p>
1166+ *
1167+ * @param domain the Permissions granted to this
1168+ * <code>ProtectionDomain</code> are returned.
1169+ *
1170+ * @return the Permissions granted to the provided
1171+ * <code>ProtectionDomain</code>.
1172+ */
1173+ @Override
1174+ public PermissionCollection getPermissions(ProtectionDomain domain) {
1175+ Permissions perms = new Permissions();
1176+
1177+ if (domain == null)
1178+ return perms;
1179+
1180+ // first get policy perms
1181+ getPermissions(perms, domain);
1182+
1183+ // add static perms
1184+ // - adding static perms after policy perms is necessary
1185+ // to avoid a regression for 4301064
1186+ PermissionCollection pc = domain.getPermissions();
1187+ if (pc != null) {
1188+ synchronized (pc) {
1189+ Enumeration<Permission> e = pc.elements();
1190+ while (e.hasMoreElements()) {
1191+ perms.add(e.nextElement());
1192+ }
1193+ }
1194+ }
1195+
1196+ return perms;
1197+ }
1198+
1199+ /**
1200+ * Examines this Policy and creates a PermissionCollection object with
1201+ * the set of permissions for the specified CodeSource.
1202+ *
1203+ * @param CodeSource the codesource associated with the caller.
1204+ * This encapsulates the original location of the code (where the code
1205+ * came from) and the public key(s) of its signer.
1206+ *
1207+ * @return the set of permissions according to the policy.
1208+ */
1209+ @Override
1210+ public PermissionCollection getPermissions(CodeSource codesource) {
1211+ return getPermissions(new Permissions(), codesource);
1212+ }
1213+
1214+ /**
1215+ * Examines the global policy and returns the provided Permissions
1216+ * object with additional permissions granted to the specified
1217+ * ProtectionDomain.
1218+ *
1219+ * @param perm the Permissions to populate
1220+ * @param pd the ProtectionDomain associated with the caller.
1221+ *
1222+ * @return the set of Permissions according to the policy.
1223+ */
1224+ private PermissionCollection getPermissions(Permissions perms,
1225+ ProtectionDomain pd ) {
1226+ if (debug != null) {
1227+ debug.println("getPermissions:\n\t" + printPD(pd));
1228+ }
1229+
1230+ final CodeSource cs = pd.getCodeSource();
1231+ if (cs == null)
1232+ return perms;
1233+
1234+ CodeSource canonCodeSource = AccessController.doPrivileged(
1235+ new java.security.PrivilegedAction<CodeSource>(){
1236+ public CodeSource run() {
1237+ return canonicalizeCodebase(cs, true);
1238+ }
1239+ });
1240+ return getPermissions(perms, canonCodeSource, pd.getPrincipals());
1241+ }
1242+
1243+ /**
1244+ * Examines the global policy and returns the provided Permissions
1245+ * object with additional permissions granted to the specified
1246+ * CodeSource.
1247+ *
1248+ * @param permissions the permissions to populate
1249+ * @param codesource the codesource associated with the caller.
1250+ * This encapsulates the original location of the code (where the code
1251+ * came from) and the public key(s) of its signer.
1252+ *
1253+ * @return the set of permissions according to the policy.
1254+ */
1255+ private PermissionCollection getPermissions(Permissions perms,
1256+ final CodeSource cs) {
1257+
1258+ CodeSource canonCodeSource = AccessController.doPrivileged(
1259+ new java.security.PrivilegedAction<CodeSource>(){
1260+ public CodeSource run() {
1261+ return canonicalizeCodebase(cs, true);
1262+ }
1263+ });
1264+
1265+ return getPermissions(perms, canonCodeSource, null);
1266+ }
1267+
1268+ private Permissions getPermissions(Permissions perms,
1269+ final CodeSource cs,
1270+ Principal[] principals) {
1271+ PolicyInfo pi = policyInfo.get();
1272+
1273+ for (PolicyEntry entry : pi.policyEntries) {
1274+ addPermissions(perms, cs, principals, entry);
1275+ }
1276+
1277+ // Go through policyEntries gotten from identity db; sync required
1278+ // because checkForTrustedIdentity (below) might update list
1279+ synchronized (pi.identityPolicyEntries) {
1280+ for (PolicyEntry entry : pi.identityPolicyEntries) {
1281+ addPermissions(perms, cs, principals, entry);
1282+ }
1283+ }
1284+
1285+ // now see if any of the keys are trusted ids.
1286+ if (!ignoreIdentityScope) {
1287+ Certificate certs[] = cs.getCertificates();
1288+ if (certs != null) {
1289+ for (int k=0; k < certs.length; k++) {
1290+ Object idMap = pi.aliasMapping.get(certs[k]);
1291+ if (idMap == null &&
1292+ checkForTrustedIdentity(certs[k], pi)) {
1293+ // checkForTrustedIdentity added it
1294+ // to the policy for us. next time
1295+ // around we'll find it. This time
1296+ // around we need to add it.
1297+ perms.add(SecurityConstants.ALL_PERMISSION);
1298+ }
1299+ }
1300+ }
1301+ }
1302+ return perms;
1303+ }
1304+
1305+ private void addPermissions(Permissions perms,
1306+ final CodeSource cs,
1307+ Principal[] principals,
1308+ final PolicyEntry entry) {
1309+
1310+ if (debug != null) {
1311+ debug.println("evaluate codesources:\n" +
1312+ "\tPolicy CodeSource: " + entry.getCodeSource() + "\n" +
1313+ "\tActive CodeSource: " + cs);
1314+ }
1315+
1316+ // check to see if the CodeSource implies
1317+ Boolean imp = AccessController.doPrivileged
1318+ (new PrivilegedAction<Boolean>() {
1319+ public Boolean run() {
1320+ return new Boolean(entry.getCodeSource().implies(cs));
1321+ }
1322+ });
1323+ if (!imp.booleanValue()) {
1324+ if (debug != null) {
1325+ debug.println("evaluation (codesource) failed");
1326+ }
1327+
1328+ // CodeSource does not imply - return and try next policy entry
1329+ return;
1330+ }
1331+
1332+ // check to see if the Principals imply
1333+
1334+ List<PolicyParser.PrincipalEntry> entryPs = entry.getPrincipals();
1335+ if (debug != null) {
1336+ ArrayList<PolicyParser.PrincipalEntry> accPs = new ArrayList<>();
1337+ if (principals != null) {
1338+ for (int i = 0; i < principals.length; i++) {
1339+ accPs.add(new PolicyParser.PrincipalEntry
1340+ (principals[i].getClass().getName(),
1341+ principals[i].getName()));
1342+ }
1343+ }
1344+ debug.println("evaluate principals:\n" +
1345+ "\tPolicy Principals: " + entryPs + "\n" +
1346+ "\tActive Principals: " + accPs);
1347+ }
1348+
1349+ if (entryPs == null || entryPs.size() == 0) {
1350+
1351+ // policy entry has no principals -
1352+ // add perms regardless of principals in current ACC
1353+
1354+ addPerms(perms, principals, entry);
1355+ if (debug != null) {
1356+ debug.println("evaluation (codesource/principals) passed");
1357+ }
1358+ return;
1359+
1360+ } else if (principals == null || principals.length == 0) {
1361+
1362+ // current thread has no principals but this policy entry
1363+ // has principals - perms are not added
1364+
1365+ if (debug != null) {
1366+ debug.println("evaluation (principals) failed");
1367+ }
1368+ return;
1369+ }
1370+
1371+ // current thread has principals and this policy entry
1372+ // has principals. see if policy entry principals match
1373+ // principals in current ACC
1374+
1375+ for (int i = 0; i < entryPs.size(); i++) {
1376+ PolicyParser.PrincipalEntry pppe = entryPs.get(i);
1377+
1378+ // see if principal entry is a PrincipalComparator
1379+
1380+ try {
1381+ Class<?> pClass = Class.forName
1382+ (pppe.principalClass,
1383+ true,
1384+ Thread.currentThread().getContextClassLoader());
1385+
1386+ if (!PrincipalComparator.class.isAssignableFrom(pClass)) {
1387+
1388+ // common case - dealing with regular Principal class.
1389+ // see if policy entry principal is in current ACC
1390+
1391+ if (!checkEntryPs(principals, pppe)) {
1392+ if (debug != null) {
1393+ debug.println("evaluation (principals) failed");
1394+ }
1395+
1396+ // policy entry principal not in current ACC -
1397+ // immediately return and go to next policy entry
1398+ return;
1399+ }
1400+
1401+ } else {
1402+
1403+ // dealing with a PrincipalComparator
1404+
1405+ Constructor<?> c = pClass.getConstructor(PARAMS1);
1406+ PrincipalComparator pc = (PrincipalComparator)c.newInstance
1407+ (new Object[] { pppe.principalName });
1408+
1409+ if (debug != null) {
1410+ debug.println("found PrincipalComparator " +
1411+ pc.getClass().getName());
1412+ }
1413+
1414+ // check if the PrincipalComparator
1415+ // implies the current thread's principals
1416+
1417+ Set<Principal> pSet = new HashSet<>(principals.length);
1418+ for (int j = 0; j < principals.length; j++) {
1419+ pSet.add(principals[j]);
1420+ }
1421+ Subject subject = new Subject(true,
1422+ pSet,
1423+ Collections.EMPTY_SET,
1424+ Collections.EMPTY_SET);
1425+
1426+ if (!pc.implies(subject)) {
1427+ if (debug != null) {
1428+ debug.println
1429+ ("evaluation (principal comparator) failed");
1430+ }
1431+
1432+ // policy principal does not imply the current Subject -
1433+ // immediately return and go to next policy entry
1434+ return;
1435+ }
1436+ }
1437+ } catch (Exception e) {
1438+ // fall back to regular principal comparison.
1439+ // see if policy entry principal is in current ACC
1440+
1441+ if (debug != null) {
1442+ e.printStackTrace();
1443+ }
1444+
1445+ if (!checkEntryPs(principals, pppe)) {
1446+ if (debug != null) {
1447+ debug.println("evaluation (principals) failed");
1448+ }
1449+
1450+ // policy entry principal not in current ACC -
1451+ // immediately return and go to next policy entry
1452+ return;
1453+ }
1454+ }
1455+
1456+ // either the principal information matched,
1457+ // or the PrincipalComparator.implies succeeded.
1458+ // continue loop and test the next policy principal
1459+ }
1460+
1461+ // all policy entry principals were found in the current ACC -
1462+ // grant the policy permissions
1463+
1464+ if (debug != null) {
1465+ debug.println("evaluation (codesource/principals) passed");
1466+ }
1467+ addPerms(perms, principals, entry);
1468+ }
1469+
1470+ private void addPerms(Permissions perms,
1471+ Principal[] accPs,
1472+ PolicyEntry entry) {
1473+ for (int i = 0; i < entry.permissions.size(); i++) {
1474+ Permission p = entry.permissions.get(i);
1475+ if (debug != null) {
1476+ debug.println(" granting " + p);
1477+ }
1478+
1479+ if (p instanceof SelfPermission) {
1480+ // handle "SELF" permissions
1481+ expandSelf((SelfPermission)p,
1482+ entry.getPrincipals(),
1483+ accPs,
1484+ perms);
1485+ } else {
1486+ perms.add(p);
1487+ }
1488+ }
1489+ }
1490+
1491+ /**
1492+ * This method returns, true, if the principal in the policy entry,
1493+ * pppe, is part of the current thread's principal array, pList.
1494+ * This method also returns, true, if the policy entry's principal
1495+ * is appropriately wildcarded.
1496+ *
1497+ * Note that the provided <i>pppe</i> argument may have
1498+ * wildcards (*) for both the <code>Principal</code> class and name.
1499+ *
1500+ * @param pList an array of principals from the current thread's
1501+ * AccessControlContext.
1502+ *
1503+ * @param pppe a Principal specified in a policy grant entry.
1504+ *
1505+ * @return true if the current thread's pList "contains" the
1506+ * principal in the policy entry, pppe. This method
1507+ * also returns true if the policy entry's principal
1508+ * appropriately wildcarded.
1509+ */
1510+ private boolean checkEntryPs(Principal[] pList,
1511+ PolicyParser.PrincipalEntry pppe) {
1512+
1513+ for (int i = 0; i < pList.length; i++) {
1514+
1515+ if (pppe.principalClass.equals
1516+ (PolicyParser.PrincipalEntry.WILDCARD_CLASS) ||
1517+ pppe.principalClass.equals
1518+ (pList[i].getClass().getName())) {
1519+
1520+ if (pppe.principalName.equals
1521+ (PolicyParser.PrincipalEntry.WILDCARD_NAME) ||
1522+ pppe.principalName.equals
1523+ (pList[i].getName())) {
1524+
1525+ return true;
1526+ }
1527+ }
1528+ }
1529+ return false;
1530+ }
1531+
1532+ /**
1533+ * <p>
1534+ *
1535+ * @param sp the SelfPermission that needs to be expanded <p>
1536+ *
1537+ * @param entryPs list of principals for the Policy entry.
1538+ *
1539+ * @param pdp Principal array from the current ProtectionDomain.
1540+ *
1541+ * @param perms the PermissionCollection where the individual
1542+ * Permissions will be added after expansion.
1543+ */
1544+
1545+ private void expandSelf(SelfPermission sp,
1546+ List<PolicyParser.PrincipalEntry> entryPs,
1547+ Principal[] pdp,
1548+ Permissions perms) {
1549+
1550+ if (entryPs == null || entryPs.size() == 0) {
1551+ // No principals in the grant to substitute
1552+ if (debug != null) {
1553+ debug.println("Ignoring permission "
1554+ + sp.getSelfType()
1555+ + " with target name ("
1556+ + sp.getSelfName() + "). "
1557+ + "No Principal(s) specified "
1558+ + "in the grant clause. "
1559+ + "SELF-based target names are "
1560+ + "only valid in the context "
1561+ + "of a Principal-based grant entry."
1562+ );
1563+ }
1564+ return;
1565+ }
1566+ int startIndex = 0;
1567+ int v;
1568+ StringBuilder sb = new StringBuilder();
1569+ while ((v = sp.getSelfName().indexOf(SELF, startIndex)) != -1) {
1570+
1571+ // add non-SELF string
1572+ sb.append(sp.getSelfName().substring(startIndex, v));
1573+
1574+ // expand SELF
1575+ ListIterator<PolicyParser.PrincipalEntry> pli =
1576+ entryPs.listIterator();
1577+ while (pli.hasNext()) {
1578+ PolicyParser.PrincipalEntry pppe = pli.next();
1579+ String[][] principalInfo = getPrincipalInfo(pppe,pdp);
1580+ for (int i = 0; i < principalInfo.length; i++) {
1581+ if (i != 0) {
1582+ sb.append(", ");
1583+ }
1584+ sb.append(principalInfo[i][0] + " " +
1585+ "\"" + principalInfo[i][1] + "\"");
1586+ }
1587+ if (pli.hasNext()) {
1588+ sb.append(", ");
1589+ }
1590+ }
1591+ startIndex = v + SELF.length();
1592+ }
1593+ // add remaining string (might be the entire string)
1594+ sb.append(sp.getSelfName().substring(startIndex));
1595+
1596+ if (debug != null) {
1597+ debug.println(" expanded:\n\t" + sp.getSelfName()
1598+ + "\n into:\n\t" + sb.toString());
1599+ }
1600+ try {
1601+ // first try to instantiate the permission
1602+ perms.add(getInstance(sp.getSelfType(),
1603+ sb.toString(),
1604+ sp.getSelfActions()));
1605+ } catch (ClassNotFoundException cnfe) {
1606+ // ok, the permission is not in the bootclasspath.
1607+ // before we add an UnresolvedPermission, check to see
1608+ // whether this perm already belongs to the collection.
1609+ // if so, use that perm's ClassLoader to create a new
1610+ // one.
1611+ Class<?> pc = null;
1612+ synchronized (perms) {
1613+ Enumeration<Permission> e = perms.elements();
1614+ while (e.hasMoreElements()) {
1615+ Permission pElement = e.nextElement();
1616+ if (pElement.getClass().getName().equals(sp.getSelfType())) {
1617+ pc = pElement.getClass();
1618+ break;
1619+ }
1620+ }
1621+ }
1622+ if (pc == null) {
1623+ // create an UnresolvedPermission
1624+ perms.add(new UnresolvedPermission(sp.getSelfType(),
1625+ sb.toString(),
1626+ sp.getSelfActions(),
1627+ sp.getCerts()));
1628+ } else {
1629+ try {
1630+ // we found an instantiated permission.
1631+ // use its class loader to instantiate a new permission.
1632+ Constructor<?> c;
1633+ // name parameter can not be null
1634+ if (sp.getSelfActions() == null) {
1635+ try {
1636+ c = pc.getConstructor(PARAMS1);
1637+ perms.add((Permission)c.newInstance
1638+ (new Object[] {sb.toString()}));
1639+ } catch (NoSuchMethodException ne) {
1640+ c = pc.getConstructor(PARAMS2);
1641+ perms.add((Permission)c.newInstance
1642+ (new Object[] {sb.toString(),
1643+ sp.getSelfActions() }));
1644+ }
1645+ } else {
1646+ c = pc.getConstructor(PARAMS2);
1647+ perms.add((Permission)c.newInstance
1648+ (new Object[] {sb.toString(),
1649+ sp.getSelfActions()}));
1650+ }
1651+ } catch (Exception nme) {
1652+ if (debug != null) {
1653+ debug.println("self entry expansion " +
1654+ " instantiation failed: "
1655+ + nme.toString());
1656+ }
1657+ }
1658+ }
1659+ } catch (Exception e) {
1660+ if (debug != null) {
1661+ debug.println(e.toString());
1662+ }
1663+ }
1664+ }
1665+
1666+ /**
1667+ * return the principal class/name pair in the 2D array.
1668+ * array[x][y]: x corresponds to the array length.
1669+ * if (y == 0), it's the principal class.
1670+ * if (y == 1), it's the principal name.
1671+ */
1672+ private String[][] getPrincipalInfo
1673+ (PolicyParser.PrincipalEntry pe, Principal[] pdp) {
1674+
1675+ // there are 3 possibilities:
1676+ // 1) the entry's Principal class and name are not wildcarded
1677+ // 2) the entry's Principal name is wildcarded only
1678+ // 3) the entry's Principal class and name are wildcarded
1679+
1680+ if (!pe.principalClass.equals
1681+ (PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
1682+ !pe.principalName.equals
1683+ (PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
1684+
1685+ // build an info array for the principal
1686+ // from the Policy entry
1687+ String[][] info = new String[1][2];
1688+ info[0][0] = pe.principalClass;
1689+ info[0][1] = pe.principalName;
1690+ return info;
1691+
1692+ } else if (!pe.principalClass.equals
1693+ (PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
1694+ pe.principalName.equals
1695+ (PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
1696+
1697+ // build an info array for every principal
1698+ // in the current domain which has a principal class
1699+ // that is equal to policy entry principal class name
1700+ List<Principal> plist = new ArrayList<>();
1701+ for (int i = 0; i < pdp.length; i++) {
1702+ if(pe.principalClass.equals(pdp[i].getClass().getName()))
1703+ plist.add(pdp[i]);
1704+ }
1705+ String[][] info = new String[plist.size()][2];
1706+ int i = 0;
1707+ java.util.Iterator<Principal> pIterator = plist.iterator();
1708+ while (pIterator.hasNext()) {
1709+ Principal p = pIterator.next();
1710+ info[i][0] = p.getClass().getName();
1711+ info[i][1] = p.getName();
1712+ i++;
1713+ }
1714+ return info;
1715+
1716+ } else {
1717+
1718+ // build an info array for every
1719+ // one of the current Domain's principals
1720+
1721+ String[][] info = new String[pdp.length][2];
1722+
1723+ for (int i = 0; i < pdp.length; i++) {
1724+ info[i][0] = pdp[i].getClass().getName();
1725+ info[i][1] = pdp[i].getName();
1726+ }
1727+ return info;
1728+ }
1729+ }
1730+
1731+ /*
1732+ * Returns the signer certificates from the list of certificates
1733+ * associated with the given code source.
1734+ *
1735+ * The signer certificates are those certificates that were used
1736+ * to verifysigned code originating from the codesource location.
1737+ *
1738+ * This method assumes that in the given code source, each signer
1739+ * certificate is followed by its supporting certificate chain
1740+ * (which may be empty), and that the signer certificate and its
1741+ * supporting certificate chain are ordered bottom-to-top
1742+ * (i.e., with the signer certificate first and the (root) certificate
1743+ * authority last).
1744+ */
1745+ protected Certificate[] getSignerCertificates(CodeSource cs) {
1746+ Certificate[] certs = null;
1747+ if ((certs = cs.getCertificates()) == null)
1748+ return null;
1749+ for (int i=0; i<certs.length; i++) {
1750+ if (!(certs[i] instanceof X509Certificate))
1751+ return cs.getCertificates();
1752+ }
1753+
1754+ // Do we have to do anything?
1755+ int i = 0;
1756+ int count = 0;
1757+ while (i < certs.length) {
1758+ count++;
1759+ while (((i+1) < certs.length)
1760+ && ((X509Certificate)certs[i]).getIssuerDN().equals(
1761+ ((X509Certificate)certs[i+1]).getSubjectDN())) {
1762+ i++;
1763+ }
1764+ i++;
1765+ }
1766+ if (count == certs.length)
1767+ // Done
1768+ return certs;
1769+
1770+ ArrayList<Certificate> userCertList = new ArrayList<>();
1771+ i = 0;
1772+ while (i < certs.length) {
1773+ userCertList.add(certs[i]);
1774+ while (((i+1) < certs.length)
1775+ && ((X509Certificate)certs[i]).getIssuerDN().equals(
1776+ ((X509Certificate)certs[i+1]).getSubjectDN())) {
1777+ i++;
1778+ }
1779+ i++;
1780+ }
1781+ Certificate[] userCerts = new Certificate[userCertList.size()];
1782+ userCertList.toArray(userCerts);
1783+ return userCerts;
1784+ }
1785+
1786+ private CodeSource canonicalizeCodebase(CodeSource cs,
1787+ boolean extractSignerCerts) {
1788+
1789+ String path = null;
1790+
1791+ CodeSource canonCs = cs;
1792+ URL u = cs.getLocation();
1793+ if (u != null) {
1794+ if (u.getProtocol().equals("jar")) {
1795+ // unwrap url embedded inside jar url
1796+ String spec = u.getFile();
1797+ int separator = spec.indexOf("!/");
1798+ if (separator != -1) {
1799+ try {
1800+ u = new URL(spec.substring(0, separator));
1801+ } catch (MalformedURLException e) {
1802+ // Fail silently. In this case, url stays what
1803+ // it was above
1804+ }
1805+ }
1806+ }
1807+ if (u.getProtocol().equals("file")) {
1808+ boolean isLocalFile = false;
1809+ String host = u.getHost();
1810+ isLocalFile = (host == null || host.equals("") ||
1811+ host.equals("~") || host.equalsIgnoreCase("localhost"));
1812+
1813+ if (isLocalFile) {
1814+ path = u.getFile().replace('/', File.separatorChar);
1815+ path = ParseUtil.decode(path);
1816+ }
1817+ }
1818+ }
1819+
1820+ if (path != null) {
1821+ try {
1822+ URL csUrl = null;
1823+ path = canonPath(path);
1824+ csUrl = ParseUtil.fileToEncodedURL(new File(path));
1825+
1826+ if (extractSignerCerts) {
1827+ canonCs = new CodeSource(csUrl,
1828+ getSignerCertificates(cs));
1829+ } else {
1830+ canonCs = new CodeSource(csUrl,
1831+ cs.getCertificates());
1832+ }
1833+ } catch (IOException ioe) {
1834+ // leave codesource as it is, unless we have to extract its
1835+ // signer certificates
1836+ if (extractSignerCerts) {
1837+ canonCs = new CodeSource(cs.getLocation(),
1838+ getSignerCertificates(cs));
1839+ }
1840+ }
1841+ } else {
1842+ if (extractSignerCerts) {
1843+ canonCs = new CodeSource(cs.getLocation(),
1844+ getSignerCertificates(cs));
1845+ }
1846+ }
1847+ return canonCs;
1848+ }
1849+
1850+ // Wrapper to return a canonical path that avoids calling getCanonicalPath()
1851+ // with paths that are intended to match all entries in the directory
1852+ private static String canonPath(String path) throws IOException {
1853+ if (path.endsWith("*")) {
1854+ path = path.substring(0, path.length()-1) + "-";
1855+ path = new File(path).getCanonicalPath();
1856+ return path.substring(0, path.length()-1) + "*";
1857+ } else {
1858+ return new File(path).getCanonicalPath();
1859+ }
1860+ }
1861+
1862+ private String printPD(ProtectionDomain pd) {
1863+ Principal[] principals = pd.getPrincipals();
1864+ String pals = "<no principals>";
1865+ if (principals != null && principals.length > 0) {
1866+ StringBuilder palBuf = new StringBuilder("(principals ");
1867+ for (int i = 0; i < principals.length; i++) {
1868+ palBuf.append(principals[i].getClass().getName() +
1869+ " \"" + principals[i].getName() +
1870+ "\"");
1871+ if (i < principals.length-1)
1872+ palBuf.append(", ");
1873+ else
1874+ palBuf.append(")");
1875+ }
1876+ pals = palBuf.toString();
1877+ }
1878+ return "PD CodeSource: "
1879+ + pd.getCodeSource()
1880+ +"\n\t" + "PD ClassLoader: "
1881+ + pd.getClassLoader()
1882+ +"\n\t" + "PD Principals: "
1883+ + pals;
1884+ }
1885+
1886+ /**
1887+ * return true if no replacement was performed,
1888+ * or if replacement succeeded.
1889+ */
1890+ private boolean replacePrincipals(
1891+ List<PolicyParser.PrincipalEntry> principals, KeyStore keystore) {
1892+
1893+ if (principals == null || principals.size() == 0 || keystore == null)
1894+ return true;
1895+
1896+ ListIterator<PolicyParser.PrincipalEntry> i = principals.listIterator();
1897+ while (i.hasNext()) {
1898+ PolicyParser.PrincipalEntry pppe = i.next();
1899+ if (pppe.principalClass.equals(PolicyParser.REPLACE_NAME)) {
1900+
1901+ // perform replacement
1902+ // (only X509 replacement is possible now)
1903+ String name;
1904+ if ((name = getDN(pppe.principalName, keystore)) == null) {
1905+ return false;
1906+ }
1907+
1908+ if (debug != null) {
1909+ debug.println(" Replacing \"" +
1910+ pppe.principalName +
1911+ "\" with " +
1912+ X500PRINCIPAL + "/\"" +
1913+ name +
1914+ "\"");
1915+ }
1916+
1917+ pppe.principalClass = X500PRINCIPAL;
1918+ pppe.principalName = name;
1919+ }
1920+ }
1921+ // return true if no replacement was performed,
1922+ // or if replacement succeeded
1923+ return true;
1924+ }
1925+
1926+ private void expandPermissionName(PolicyParser.PermissionEntry pe,
1927+ KeyStore keystore) throws Exception {
1928+ // short cut the common case
1929+ if (pe.name == null || pe.name.indexOf("${{", 0) == -1) {
1930+ return;
1931+ }
1932+
1933+ int startIndex = 0;
1934+ int b, e;
1935+ StringBuilder sb = new StringBuilder();
1936+ while ((b = pe.name.indexOf("${{", startIndex)) != -1) {
1937+ e = pe.name.indexOf("}}", b);
1938+ if (e < 1) {
1939+ break;
1940+ }
1941+ sb.append(pe.name.substring(startIndex, b));
1942+
1943+ // get the value in ${{...}}
1944+ String value = pe.name.substring(b+3, e);
1945+
1946+ // parse up to the first ':'
1947+ int colonIndex;
1948+ String prefix = value;
1949+ String suffix;
1950+ if ((colonIndex = value.indexOf(":")) != -1) {
1951+ prefix = value.substring(0, colonIndex);
1952+ }
1953+
1954+ // handle different prefix possibilities
1955+ if (prefix.equalsIgnoreCase("self")) {
1956+ // do nothing - handled later
1957+ sb.append(pe.name.substring(b, e+2));
1958+ startIndex = e+2;
1959+ continue;
1960+ } else if (prefix.equalsIgnoreCase("alias")) {
1961+ // get the suffix and perform keystore alias replacement
1962+ if (colonIndex == -1) {
1963+ MessageFormat form = new MessageFormat
1964+ (ResourcesMgr.getString
1965+ ("alias.name.not.provided.pe.name."));
1966+ Object[] source = {pe.name};
1967+ throw new Exception(form.format(source));
1968+ }
1969+ suffix = value.substring(colonIndex+1);
1970+ if ((suffix = getDN(suffix, keystore)) == null) {
1971+ MessageFormat form = new MessageFormat
1972+ (ResourcesMgr.getString
1973+ ("unable.to.perform.substitution.on.alias.suffix"));
1974+ Object[] source = {value.substring(colonIndex+1)};
1975+ throw new Exception(form.format(source));
1976+ }
1977+
1978+ sb.append(X500PRINCIPAL + " \"" + suffix + "\"");
1979+ startIndex = e+2;
1980+ } else {
1981+ MessageFormat form = new MessageFormat
1982+ (ResourcesMgr.getString
1983+ ("substitution.value.prefix.unsupported"));
1984+ Object[] source = {prefix};
1985+ throw new Exception(form.format(source));
1986+ }
1987+ }
1988+
1989+ // copy the rest of the value
1990+ sb.append(pe.name.substring(startIndex));
1991+
1992+ // replace the name with expanded value
1993+ if (debug != null) {
1994+ debug.println(" Permission name expanded from:\n\t" +
1995+ pe.name + "\nto\n\t" + sb.toString());
1996+ }
1997+ pe.name = sb.toString();
1998+ }
1999+
2000+ private String getDN(String alias, KeyStore keystore) {
2001+ Certificate cert = null;
2002+ try {
2003+ cert = keystore.getCertificate(alias);
2004+ } catch (Exception e) {
2005+ if (debug != null) {
2006+ debug.println(" Error retrieving certificate for '" +
2007+ alias +
2008+ "': " +
2009+ e.toString());
2010+ }
2011+ return null;
2012+ }
2013+
2014+ if (cert == null || !(cert instanceof X509Certificate)) {
2015+ if (debug != null) {
2016+ debug.println(" -- No certificate for '" +
2017+ alias +
2018+ "' - ignoring entry");
2019+ }
2020+ return null;
2021+ } else {
2022+ X509Certificate x509Cert = (X509Certificate)cert;
2023+
2024+ // 4702543: X500 names with an EmailAddress
2025+ // were encoded incorrectly. create new
2026+ // X500Principal name with correct encoding
2027+
2028+ X500Principal p = new X500Principal
2029+ (x509Cert.getSubjectX500Principal().toString());
2030+ return p.getName();
2031+ }
2032+ }
2033+
2034+ /**
2035+ * Checks public key. If it is marked as trusted in
2036+ * the identity database, add it to the policy
2037+ * with the AllPermission.
2038+ */
2039+ private boolean checkForTrustedIdentity(final Certificate cert,
2040+ PolicyInfo myInfo)
2041+ {
2042+ return false;
2043+ }
2044+
2045+ /**
2046+ * Each entry in the policy configuration file is represented by a
2047+ * PolicyEntry object. <p>
2048+ *
2049+ * A PolicyEntry is a (CodeSource,Permission) pair. The
2050+ * CodeSource contains the (URL, PublicKey) that together identify
2051+ * where the Java bytecodes come from and who (if anyone) signed
2052+ * them. The URL could refer to localhost. The URL could also be
2053+ * null, meaning that this policy entry is given to all comers, as
2054+ * long as they match the signer field. The signer could be null,
2055+ * meaning the code is not signed. <p>
2056+ *
2057+ * The Permission contains the (Type, Name, Action) triplet. <p>
2058+ *
2059+ * For now, the Policy object retrieves the public key from the
2060+ * X.509 certificate on disk that corresponds to the signedBy
2061+ * alias specified in the Policy config file. For reasons of
2062+ * efficiency, the Policy object keeps a hashtable of certs already
2063+ * read in. This could be replaced by a secure internal key
2064+ * store.
2065+ *
2066+ * <p>
2067+ * For example, the entry
2068+ * <pre>
2069+ * permission java.io.File "/tmp", "read,write",
2070+ * signedBy "Duke";
2071+ * </pre>
2072+ * is represented internally
2073+ * <pre>
2074+ *
2075+ * FilePermission f = new FilePermission("/tmp", "read,write");
2076+ * PublicKey p = publickeys.get("Duke");
2077+ * URL u = InetAddress.getLocalHost();
2078+ * CodeBase c = new CodeBase( p, u );
2079+ * pe = new PolicyEntry(f, c);
2080+ * </pre>
2081+ *
2082+ * @author Marianne Mueller
2083+ * @author Roland Schemers
2084+ * @see java.security.CodeSource
2085+ * @see java.security.Policy
2086+ * @see java.security.Permissions
2087+ * @see java.security.ProtectionDomain
2088+ */
2089+ private static class PolicyEntry {
2090+
2091+ private final CodeSource codesource;
2092+ final List<Permission> permissions;
2093+ private final List<PolicyParser.PrincipalEntry> principals;
2094+
2095+ /**
2096+ * Given a Permission and a CodeSource, create a policy entry.
2097+ *
2098+ * XXX Decide if/how to add validity fields and "purpose" fields to
2099+ * XXX policy entries
2100+ *
2101+ * @param cs the CodeSource, which encapsulates the URL and the
2102+ * public key
2103+ * attributes from the policy config file. Validity checks
2104+ * are performed on the public key before PolicyEntry is
2105+ * called.
2106+ *
2107+ */
2108+ PolicyEntry(CodeSource cs, List<PolicyParser.PrincipalEntry> principals)
2109+ {
2110+ this.codesource = cs;
2111+ this.permissions = new ArrayList<Permission>();
2112+ this.principals = principals; // can be null
2113+ }
2114+
2115+ PolicyEntry(CodeSource cs)
2116+ {
2117+ this(cs, null);
2118+ }
2119+
2120+ List<PolicyParser.PrincipalEntry> getPrincipals() {
2121+ return principals; // can be null
2122+ }
2123+
2124+ /**
2125+ * add a Permission object to this entry.
2126+ * No need to sync add op because perms are added to entry only
2127+ * while entry is being initialized
2128+ */
2129+ void add(Permission p) {
2130+ permissions.add(p);
2131+ }
2132+
2133+ /**
2134+ * Return the CodeSource for this policy entry
2135+ */
2136+ CodeSource getCodeSource() {
2137+ return codesource;
2138+ }
2139+
2140+ @Override public String toString(){
2141+ StringBuilder sb = new StringBuilder();
2142+ sb.append(ResourcesMgr.getString("LPARAM"));
2143+ sb.append(getCodeSource());
2144+ sb.append("\n");
2145+ for (int j = 0; j < permissions.size(); j++) {
2146+ Permission p = permissions.get(j);
2147+ sb.append(ResourcesMgr.getString("SPACE"));
2148+ sb.append(ResourcesMgr.getString("SPACE"));
2149+ sb.append(p);
2150+ sb.append(ResourcesMgr.getString("NEWLINE"));
2151+ }
2152+ sb.append(ResourcesMgr.getString("RPARAM"));
2153+ sb.append(ResourcesMgr.getString("NEWLINE"));
2154+ return sb.toString();
2155+ }
2156+ }
2157+
2158+ private static class SelfPermission extends Permission {
2159+
2160+ private static final long serialVersionUID = -8315562579967246806L;
2161+
2162+ /**
2163+ * The class name of the Permission class that will be
2164+ * created when this self permission is expanded .
2165+ *
2166+ * @serial
2167+ */
2168+ private String type;
2169+
2170+ /**
2171+ * The permission name.
2172+ *
2173+ * @serial
2174+ */
2175+ private String name;
2176+
2177+ /**
2178+ * The actions of the permission.
2179+ *
2180+ * @serial
2181+ */
2182+ private String actions;
2183+
2184+ /**
2185+ * The certs of the permission.
2186+ *
2187+ * @serial
2188+ */
2189+ private Certificate certs[];
2190+
2191+ /**
2192+ * Creates a new SelfPermission containing the permission
2193+ * information needed later to expand the self
2194+ * @param type the class name of the Permission class that will be
2195+ * created when this permission is expanded and if necessary resolved.
2196+ * @param name the name of the permission.
2197+ * @param actions the actions of the permission.
2198+ * @param certs the certificates the permission's class was signed with.
2199+ * This is a list of certificate chains, where each chain is composed of
2200+ * a signer certificate and optionally its supporting certificate chain.
2201+ * Each chain is ordered bottom-to-top (i.e., with the signer
2202+ * certificate first and the (root) certificate authority last).
2203+ */
2204+ public SelfPermission(String type, String name, String actions,
2205+ Certificate certs[])
2206+ {
2207+ super(type);
2208+ if (type == null) {
2209+ throw new NullPointerException
2210+ (ResourcesMgr.getString("type.can.t.be.null"));
2211+ }
2212+ this.type = type;
2213+ this.name = name;
2214+ this.actions = actions;
2215+ if (certs != null) {
2216+ // Extract the signer certs from the list of certificates.
2217+ for (int i=0; i<certs.length; i++) {
2218+ if (!(certs[i] instanceof X509Certificate)) {
2219+ // there is no concept of signer certs, so we store the
2220+ // entire cert array
2221+ this.certs = certs.clone();
2222+ break;
2223+ }
2224+ }
2225+
2226+ if (this.certs == null) {
2227+ // Go through the list of certs and see if all the certs are
2228+ // signer certs.
2229+ int i = 0;
2230+ int count = 0;
2231+ while (i < certs.length) {
2232+ count++;
2233+ while (((i+1) < certs.length) &&
2234+ ((X509Certificate)certs[i]).getIssuerDN().equals(
2235+ ((X509Certificate)certs[i+1]).getSubjectDN())) {
2236+ i++;
2237+ }
2238+ i++;
2239+ }
2240+ if (count == certs.length) {
2241+ // All the certs are signer certs, so we store the
2242+ // entire array
2243+ this.certs = certs.clone();
2244+ }
2245+
2246+ if (this.certs == null) {
2247+ // extract the signer certs
2248+ ArrayList<Certificate> signerCerts =
2249+ new ArrayList<>();
2250+ i = 0;
2251+ while (i < certs.length) {
2252+ signerCerts.add(certs[i]);
2253+ while (((i+1) < certs.length) &&
2254+ ((X509Certificate)certs[i]).getIssuerDN().equals(
2255+ ((X509Certificate)certs[i+1]).getSubjectDN())) {
2256+ i++;
2257+ }
2258+ i++;
2259+ }
2260+ this.certs = new Certificate[signerCerts.size()];
2261+ signerCerts.toArray(this.certs);
2262+ }
2263+ }
2264+ }
2265+ }
2266+
2267+ /**
2268+ * This method always returns false for SelfPermission permissions.
2269+ * That is, an SelfPermission never considered to
2270+ * imply another permission.
2271+ *
2272+ * @param p the permission to check against.
2273+ *
2274+ * @return false.
2275+ */
2276+ @Override public boolean implies(Permission p) {
2277+ return false;
2278+ }
2279+
2280+ /**
2281+ * Checks two SelfPermission objects for equality.
2282+ *
2283+ * Checks that <i>obj</i> is an SelfPermission, and has
2284+ * the same type (class) name, permission name, actions, and
2285+ * certificates as this object.
2286+ *
2287+ * @param obj the object we are testing for equality with this object.
2288+ *
2289+ * @return true if obj is an SelfPermission, and has the same
2290+ * type (class) name, permission name, actions, and
2291+ * certificates as this object.
2292+ */
2293+ @Override public boolean equals(Object obj) {
2294+ if (obj == this)
2295+ return true;
2296+
2297+ if (! (obj instanceof SelfPermission))
2298+ return false;
2299+ SelfPermission that = (SelfPermission) obj;
2300+
2301+ if (!(this.type.equals(that.type) &&
2302+ this.name.equals(that.name) &&
2303+ this.actions.equals(that.actions)))
2304+ return false;
2305+
2306+ if (this.certs.length != that.certs.length)
2307+ return false;
2308+
2309+ int i,j;
2310+ boolean match;
2311+
2312+ for (i = 0; i < this.certs.length; i++) {
2313+ match = false;
2314+ for (j = 0; j < that.certs.length; j++) {
2315+ if (this.certs[i].equals(that.certs[j])) {
2316+ match = true;
2317+ break;
2318+ }
2319+ }
2320+ if (!match) return false;
2321+ }
2322+
2323+ for (i = 0; i < that.certs.length; i++) {
2324+ match = false;
2325+ for (j = 0; j < this.certs.length; j++) {
2326+ if (that.certs[i].equals(this.certs[j])) {
2327+ match = true;
2328+ break;
2329+ }
2330+ }
2331+ if (!match) return false;
2332+ }
2333+ return true;
2334+ }
2335+
2336+ /**
2337+ * Returns the hash code value for this object.
2338+ *
2339+ * @return a hash code value for this object.
2340+ */
2341+ @Override public int hashCode() {
2342+ int hash = type.hashCode();
2343+ if (name != null)
2344+ hash ^= name.hashCode();
2345+ if (actions != null)
2346+ hash ^= actions.hashCode();
2347+ return hash;
2348+ }
2349+
2350+ /**
2351+ * Returns the canonical string representation of the actions,
2352+ * which currently is the empty string "", since there are no actions
2353+ * for an SelfPermission. That is, the actions for the
2354+ * permission that will be created when this SelfPermission
2355+ * is resolved may be non-null, but an SelfPermission
2356+ * itself is never considered to have any actions.
2357+ *
2358+ * @return the empty string "".
2359+ */
2360+ @Override public String getActions() {
2361+ return "";
2362+ }
2363+
2364+ public String getSelfType() {
2365+ return type;
2366+ }
2367+
2368+ public String getSelfName() {
2369+ return name;
2370+ }
2371+
2372+ public String getSelfActions() {
2373+ return actions;
2374+ }
2375+
2376+ public Certificate[] getCerts() {
2377+ return certs;
2378+ }
2379+
2380+ /**
2381+ * Returns a string describing this SelfPermission. The convention
2382+ * is to specify the class name, the permission name, and the actions,
2383+ * in the following format: '(unresolved "ClassName" "name" "actions")'.
2384+ *
2385+ * @return information about this SelfPermission.
2386+ */
2387+ @Override public String toString() {
2388+ return "(SelfPermission " + type + " " + name + " " + actions + ")";
2389+ }
2390+ }
2391+
2392+ /**
2393+ * holds policy information that we need to synch on
2394+ */
2395+ private static class PolicyInfo {
2396+ private static final boolean verbose = false;
2397+
2398+ // Stores grant entries in the policy
2399+ final List<PolicyEntry> policyEntries;
2400+
2401+ // Stores grant entries gotten from identity database
2402+ // Use separate lists to avoid sync on policyEntries
2403+ final List<PolicyEntry> identityPolicyEntries;
2404+
2405+ // Maps aliases to certs
2406+ final Map aliasMapping;
2407+
2408+ // Maps ProtectionDomain to PermissionCollection
2409+ private final ProtectionDomainCache[] pdMapping;
2410+ private java.util.Random random;
2411+
2412+ PolicyInfo(int numCaches) {
2413+ policyEntries = new ArrayList<PolicyEntry>();
2414+ identityPolicyEntries =
2415+ Collections.synchronizedList(new ArrayList<PolicyEntry>(2));
2416+ aliasMapping = Collections.synchronizedMap(new HashMap(11));
2417+
2418+ pdMapping = new ProtectionDomainCache[numCaches];
2419+ JavaSecurityProtectionDomainAccess jspda
2420+ = SharedSecrets.getJavaSecurityProtectionDomainAccess();
2421+ for (int i = 0; i < numCaches; i++) {
2422+ pdMapping[i] = jspda.getProtectionDomainCache();
2423+ }
2424+ if (numCaches > 1) {
2425+ random = new java.util.Random();
2426+ }
2427+ }
2428+ ProtectionDomainCache getPdMapping() {
2429+ if (pdMapping.length == 1) {
2430+ return pdMapping[0];
2431+ } else {
2432+ int i = java.lang.Math.abs(random.nextInt() % pdMapping.length);
2433+ return pdMapping[i];
2434+ }
2435+ }
2436+ }
2437+}