PageRenderTime 32ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/java-1.7.0-openjdk/openjdk/jdk/src/share/classes/sun/security/provider/PolicyFile.java

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