PageRenderTime 80ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

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

#
Java | 1463 lines | 755 code | 137 blank | 571 comment | 190 complexity | bdae7787bf6da21397edc486bfd2b170 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause-No-Nuclear-License-2014, LGPL-3.0, LGPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (c) 1999, 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 com.sun.security.auth;
  26. import java.io.*;
  27. import java.lang.RuntimePermission;
  28. import java.lang.reflect.*;
  29. import java.net.MalformedURLException;
  30. import java.net.URL;
  31. import java.util.*;
  32. import java.security.AccessController;
  33. import java.security.CodeSource;
  34. import java.security.KeyStore;
  35. import java.security.KeyStoreException;
  36. import java.security.Permission;
  37. import java.security.Permissions;
  38. import java.security.PermissionCollection;
  39. import java.security.Principal;
  40. import java.security.UnresolvedPermission;
  41. import java.security.Security;
  42. import java.security.cert.Certificate;
  43. import java.security.cert.X509Certificate;
  44. import javax.security.auth.Subject;
  45. import javax.security.auth.PrivateCredentialPermission;
  46. import sun.security.util.PropertyExpander;
  47. /**
  48. * This class represents a default implementation for
  49. * <code>javax.security.auth.Policy</code>.
  50. *
  51. * <p> This object stores the policy for entire Java runtime,
  52. * and is the amalgamation of multiple static policy
  53. * configurations that resides in files.
  54. * The algorithm for locating the policy file(s) and reading their
  55. * information into this <code>Policy</code> object is:
  56. *
  57. * <ol>
  58. * <li>
  59. * Loop through the <code>java.security.Security</code> properties,
  60. * <i>auth.policy.url.1</i>, <i>auth.policy.url.2</i>, ...,
  61. * <i>auth.policy.url.X</i>". These properties are set
  62. * in the Java security properties file, which is located in the file named
  63. * &lt;JAVA_HOME&gt;/lib/security/java.security.
  64. * &lt;JAVA_HOME&gt; refers to the value of the java.home system property,
  65. * and specifies the directory where the JRE is installed.
  66. * Each property value specifies a <code>URL</code> pointing to a
  67. * policy file to be loaded. Read in and load each policy.
  68. *
  69. * <li>
  70. * The <code>java.lang.System</code> property <i>java.security.auth.policy</i>
  71. * may also be set to a <code>URL</code> pointing to another policy file
  72. * (which is the case when a user uses the -D switch at runtime).
  73. * If this property is defined, and its use is allowed by the
  74. * security property file (the Security property,
  75. * <i>policy.allowSystemProperty</i> is set to <i>true</i>),
  76. * also load that policy.
  77. *
  78. * <li>
  79. * If the <i>java.security.auth.policy</i> property is defined using
  80. * "==" (rather than "="), then ignore all other specified
  81. * policies and only load this policy.
  82. * </ol>
  83. *
  84. * Each policy file consists of one or more grant entries, each of
  85. * which consists of a number of permission entries.
  86. *
  87. * <pre>
  88. * grant signedBy "<b>alias</b>", codeBase "<b>URL</b>",
  89. * principal <b>principalClass</b> "<b>principalName</b>",
  90. * principal <b>principalClass</b> "<b>principalName</b>",
  91. * ... {
  92. *
  93. * permission <b>Type</b> "<b>name</b> "<b>action</b>",
  94. * signedBy "<b>alias</b>";
  95. * permission <b>Type</b> "<b>name</b> "<b>action</b>",
  96. * signedBy "<b>alias</b>";
  97. * ....
  98. * };
  99. * </pre>
  100. *
  101. * All non-bold items above must appear as is (although case
  102. * doesn't matter and some are optional, as noted below).
  103. * Italicized items represent variable values.
  104. *
  105. * <p> A grant entry must begin with the word <code>grant</code>.
  106. * The <code>signedBy</code> and <code>codeBase</code>
  107. * name/value pairs are optional.
  108. * If they are not present, then any signer (including unsigned code)
  109. * will match, and any codeBase will match. Note that the
  110. * <code>principal</code> name/value pair is not optional.
  111. * This <code>Policy</code> implementation only permits
  112. * Principal-based grant entries. Note that the <i>principalClass</i>
  113. * may be set to the wildcard value, *, which allows it to match
  114. * any <code>Principal</code> class. In addition, the <i>principalName</i>
  115. * may also be set to the wildcard value, *, allowing it to match
  116. * any <code>Principal</code> name. When setting the <i>principalName</i>
  117. * to the *, do not surround the * with quotes.
  118. *
  119. * <p> A permission entry must begin with the word <code>permission</code>.
  120. * The word <code><i>Type</i></code> in the template above is
  121. * a specific permission type, such as <code>java.io.FilePermission</code>
  122. * or <code>java.lang.RuntimePermission</code>.
  123. *
  124. * <p> The "<i>action</i>" is required for
  125. * many permission types, such as <code>java.io.FilePermission</code>
  126. * (where it specifies what type of file access that is permitted).
  127. * It is not required for categories such as
  128. * <code>java.lang.RuntimePermission</code>
  129. * where it is not necessary - you either have the
  130. * permission specified by the <code>"<i>name</i>"</code>
  131. * value following the type name or you don't.
  132. *
  133. * <p> The <code>signedBy</code> name/value pair for a permission entry
  134. * is optional. If present, it indicates a signed permission. That is,
  135. * the permission class itself must be signed by the given alias in
  136. * order for it to be granted. For example,
  137. * suppose you have the following grant entry:
  138. *
  139. * <pre>
  140. * grant principal foo.com.Principal "Duke" {
  141. * permission Foo "foobar", signedBy "FooSoft";
  142. * }
  143. * </pre>
  144. *
  145. * <p> Then this permission of type <i>Foo</i> is granted if the
  146. * <code>Foo.class</code> permission has been signed by the
  147. * "FooSoft" alias, or if <code>Foo.class</code> is a
  148. * system class (i.e., is found on the CLASSPATH).
  149. *
  150. * <p> Items that appear in an entry must appear in the specified order
  151. * (<code>permission</code>, <i>Type</i>, "<i>name</i>", and
  152. * "<i>action</i>"). An entry is terminated with a semicolon.
  153. *
  154. * <p> Case is unimportant for the identifiers (<code>permission</code>,
  155. * <code>signedBy</code>, <code>codeBase</code>, etc.) but is
  156. * significant for the <i>Type</i>
  157. * or for any string that is passed in as a value. <p>
  158. *
  159. * <p> An example of two entries in a policy configuration file is
  160. * <pre>
  161. * // if the code is comes from "foo.com" and is running as "Duke",
  162. * // grant it read/write to all files in /tmp.
  163. *
  164. * grant codeBase "foo.com", principal foo.com.Principal "Duke" {
  165. * permission java.io.FilePermission "/tmp/*", "read,write";
  166. * };
  167. *
  168. * // grant any code running as "Duke" permission to read
  169. * // the "java.vendor" Property.
  170. *
  171. * grant principal foo.com.Principal "Duke" {
  172. * permission java.util.PropertyPermission "java.vendor";
  173. * </pre>
  174. *
  175. * <p> This <code>Policy</code> implementation supports
  176. * special handling for PrivateCredentialPermissions.
  177. * If a grant entry is configured with a
  178. * <code>PrivateCredentialPermission</code>,
  179. * and the "Principal Class/Principal Name" for that
  180. * <code>PrivateCredentialPermission</code> is "self",
  181. * then the entry grants the specified <code>Subject</code> permission to
  182. * access its own private Credential. For example,
  183. * the following grants the <code>Subject</code> "Duke"
  184. * access to its own a.b.Credential.
  185. *
  186. * <pre>
  187. * grant principal foo.com.Principal "Duke" {
  188. * permission javax.security.auth.PrivateCredentialPermission
  189. * "a.b.Credential self",
  190. * "read";
  191. * };
  192. * </pre>
  193. *
  194. * The following grants the <code>Subject</code> "Duke"
  195. * access to all of its own private Credentials:
  196. *
  197. * <pre>
  198. * grant principal foo.com.Principal "Duke" {
  199. * permission javax.security.auth.PrivateCredentialPermission
  200. * "* self",
  201. * "read";
  202. * };
  203. * </pre>
  204. *
  205. * The following grants all Subjects authenticated as a
  206. * <code>SolarisPrincipal</code> (regardless of their respective names)
  207. * permission to access their own private Credentials:
  208. *
  209. * <pre>
  210. * grant principal com.sun.security.auth.SolarisPrincipal * {
  211. * permission javax.security.auth.PrivateCredentialPermission
  212. * "* self",
  213. * "read";
  214. * };
  215. * </pre>
  216. *
  217. * The following grants all Subjects permission to access their own
  218. * private Credentials:
  219. *
  220. * <pre>
  221. * grant principal * * {
  222. * permission javax.security.auth.PrivateCredentialPermission
  223. * "* self",
  224. * "read";
  225. * };
  226. * </pre>
  227. * @deprecated As of JDK&nbsp;1.4, replaced by
  228. * <code>sun.security.provider.PolicyFile</code>.
  229. * This class is entirely deprecated.
  230. *
  231. * @see java.security.CodeSource
  232. * @see java.security.Permissions
  233. * @see java.security.ProtectionDomain
  234. */
  235. @Deprecated
  236. public class PolicyFile extends javax.security.auth.Policy {
  237. static final java.util.ResourceBundle rb =
  238. java.security.AccessController.doPrivileged
  239. (new java.security.PrivilegedAction<java.util.ResourceBundle>() {
  240. public java.util.ResourceBundle run() {
  241. return (java.util.ResourceBundle.getBundle
  242. ("sun.security.util.AuthResources"));
  243. }
  244. });
  245. // needs to be package private
  246. private static final sun.security.util.Debug debug =
  247. sun.security.util.Debug.getInstance("policy", "\t[Auth Policy]");
  248. private static final String AUTH_POLICY = "java.security.auth.policy";
  249. private static final String SECURITY_MANAGER = "java.security.manager";
  250. private static final String AUTH_POLICY_URL = "auth.policy.url.";
  251. private Vector<PolicyEntry> policyEntries;
  252. private Hashtable aliasMapping;
  253. private boolean initialized = false;
  254. private boolean expandProperties = true;
  255. private boolean ignoreIdentityScope = true;
  256. // for use with the reflection API
  257. private static final Class[] PARAMS = { String.class, String.class};
  258. /**
  259. * Initializes the Policy object and reads the default policy
  260. * configuration file(s) into the Policy object.
  261. */
  262. public PolicyFile() {
  263. // initialize Policy if either the AUTH_POLICY or
  264. // SECURITY_MANAGER properties are set
  265. String prop = System.getProperty(AUTH_POLICY);
  266. if (prop == null) {
  267. prop = System.getProperty(SECURITY_MANAGER);
  268. }
  269. if (prop != null)
  270. init();
  271. }
  272. private synchronized void init() {
  273. if (initialized)
  274. return;
  275. policyEntries = new Vector<PolicyEntry>();
  276. aliasMapping = new Hashtable(11);
  277. initPolicyFile();
  278. initialized = true;
  279. }
  280. /**
  281. * Refreshes the policy object by re-reading all the policy files.
  282. *
  283. * <p>
  284. *
  285. * @exception SecurityException if the caller doesn't have permission
  286. * to refresh the <code>Policy</code>.
  287. */
  288. public synchronized void refresh()
  289. {
  290. java.lang.SecurityManager sm = System.getSecurityManager();
  291. if (sm != null) {
  292. sm.checkPermission(new javax.security.auth.AuthPermission
  293. ("refreshPolicy"));
  294. }
  295. // XXX
  296. //
  297. // 1) if code instantiates PolicyFile directly, then it will need
  298. // all the permissions required for the PolicyFile initialization
  299. // 2) if code calls Policy.getPolicy, then it simply needs
  300. // AuthPermission(getPolicy), and the javax.security.auth.Policy
  301. // implementation instantiates PolicyFile in a doPrivileged block
  302. // 3) if after instantiating a Policy (either via #1 or #2),
  303. // code calls refresh, it simply needs
  304. // AuthPermission(refreshPolicy). then PolicyFile wraps
  305. // the refresh in a doPrivileged block.
  306. initialized = false;
  307. java.security.AccessController.doPrivileged
  308. (new java.security.PrivilegedAction<Void>() {
  309. public Void run() {
  310. init();
  311. return null;
  312. }
  313. });
  314. }
  315. private KeyStore initKeyStore(URL policyUrl, String keyStoreName,
  316. String keyStoreType) {
  317. if (keyStoreName != null) {
  318. try {
  319. /*
  320. * location of keystore is specified as absolute URL in policy
  321. * file, or is relative to URL of policy file
  322. */
  323. URL keyStoreUrl = null;
  324. try {
  325. keyStoreUrl = new URL(keyStoreName);
  326. // absolute URL
  327. } catch (java.net.MalformedURLException e) {
  328. // relative URL
  329. keyStoreUrl = new URL(policyUrl, keyStoreName);
  330. }
  331. if (debug != null) {
  332. debug.println("reading keystore"+keyStoreUrl);
  333. }
  334. InputStream inStream =
  335. new BufferedInputStream(getInputStream(keyStoreUrl));
  336. KeyStore ks;
  337. if (keyStoreType != null)
  338. ks = KeyStore.getInstance(keyStoreType);
  339. else
  340. ks = KeyStore.getInstance(KeyStore.getDefaultType());
  341. ks.load(inStream, null);
  342. inStream.close();
  343. return ks;
  344. } catch (Exception e) {
  345. // ignore, treat it like we have no keystore
  346. if (debug != null) {
  347. e.printStackTrace();
  348. }
  349. return null;
  350. }
  351. }
  352. return null;
  353. }
  354. private void initPolicyFile() {
  355. String prop = Security.getProperty("policy.expandProperties");
  356. if (prop != null) expandProperties = prop.equalsIgnoreCase("true");
  357. String iscp = Security.getProperty("policy.ignoreIdentityScope");
  358. if (iscp != null) ignoreIdentityScope = iscp.equalsIgnoreCase("true");
  359. String allowSys = Security.getProperty("policy.allowSystemProperty");
  360. if ((allowSys!=null) && allowSys.equalsIgnoreCase("true")) {
  361. String extra_policy = System.getProperty(AUTH_POLICY);
  362. if (extra_policy != null) {
  363. boolean overrideAll = false;
  364. if (extra_policy.startsWith("=")) {
  365. overrideAll = true;
  366. extra_policy = extra_policy.substring(1);
  367. }
  368. try {
  369. extra_policy = PropertyExpander.expand(extra_policy);
  370. URL policyURL;;
  371. File policyFile = new File(extra_policy);
  372. if (policyFile.exists()) {
  373. policyURL =
  374. new URL("file:" + policyFile.getCanonicalPath());
  375. } else {
  376. policyURL = new URL(extra_policy);
  377. }
  378. if (debug != null)
  379. debug.println("reading "+policyURL);
  380. init(policyURL);
  381. } catch (Exception e) {
  382. // ignore.
  383. if (debug != null) {
  384. debug.println("caught exception: "+e);
  385. }
  386. }
  387. if (overrideAll) {
  388. if (debug != null) {
  389. debug.println("overriding other policies!");
  390. }
  391. return;
  392. }
  393. }
  394. }
  395. int n = 1;
  396. boolean loaded_one = false;
  397. String policy_url;
  398. while ((policy_url = Security.getProperty(AUTH_POLICY_URL+n)) != null) {
  399. try {
  400. policy_url = PropertyExpander.expand(policy_url).replace
  401. (File.separatorChar, '/');
  402. if (debug != null)
  403. debug.println("reading "+policy_url);
  404. init(new URL(policy_url));
  405. loaded_one = true;
  406. } catch (Exception e) {
  407. if (debug != null) {
  408. debug.println("error reading policy "+e);
  409. e.printStackTrace();
  410. }
  411. // ignore that policy
  412. }
  413. n++;
  414. }
  415. if (loaded_one == false) {
  416. // do not load a static policy
  417. }
  418. }
  419. /**
  420. * Checks public key. If it is marked as trusted in
  421. * the identity database, add it to the policy
  422. * with the AllPermission.
  423. */
  424. private boolean checkForTrustedIdentity(final Certificate cert) {
  425. // XXX JAAS has no way to access the SUN package.
  426. // we'll add this back in when JAAS goes into core.
  427. return false;
  428. }
  429. /**
  430. * Reads a policy configuration into the Policy object using a
  431. * Reader object.
  432. *
  433. * @param policyFile the policy Reader object.
  434. */
  435. private void init(URL policy) {
  436. PolicyParser pp = new PolicyParser(expandProperties);
  437. try {
  438. InputStreamReader isr
  439. = new InputStreamReader(getInputStream(policy));
  440. pp.read(isr);
  441. isr.close();
  442. KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(),
  443. pp.getKeyStoreType());
  444. Enumeration<PolicyParser.GrantEntry> enum_ = pp.grantElements();
  445. while (enum_.hasMoreElements()) {
  446. PolicyParser.GrantEntry ge = enum_.nextElement();
  447. addGrantEntry(ge, keyStore);
  448. }
  449. } catch (PolicyParser.ParsingException pe) {
  450. System.err.println(AUTH_POLICY +
  451. rb.getString(".error.parsing.") + policy);
  452. System.err.println(AUTH_POLICY +
  453. rb.getString("COLON") +
  454. pe.getMessage());
  455. if (debug != null)
  456. pe.printStackTrace();
  457. } catch (Exception e) {
  458. if (debug != null) {
  459. debug.println("error parsing "+policy);
  460. debug.println(e.toString());
  461. e.printStackTrace();
  462. }
  463. }
  464. }
  465. /*
  466. * Fast path reading from file urls in order to avoid calling
  467. * FileURLConnection.connect() which can be quite slow the first time
  468. * it is called. We really should clean up FileURLConnection so that
  469. * this is not a problem but in the meantime this fix helps reduce
  470. * start up time noticeably for the new launcher. -- DAC
  471. */
  472. private InputStream getInputStream(URL url) throws IOException {
  473. if ("file".equals(url.getProtocol())) {
  474. String path = url.getFile().replace('/', File.separatorChar);
  475. return new FileInputStream(path);
  476. } else {
  477. return url.openStream();
  478. }
  479. }
  480. /**
  481. * Given a PermissionEntry, create a codeSource.
  482. *
  483. * @return null if signedBy alias is not recognized
  484. */
  485. CodeSource getCodeSource(PolicyParser.GrantEntry ge, KeyStore keyStore)
  486. throws java.net.MalformedURLException
  487. {
  488. Certificate[] certs = null;
  489. if (ge.signedBy != null) {
  490. certs = getCertificates(keyStore, ge.signedBy);
  491. if (certs == null) {
  492. // we don't have a key for this alias,
  493. // just return
  494. if (debug != null) {
  495. debug.println(" no certs for alias " +
  496. ge.signedBy + ", ignoring.");
  497. }
  498. return null;
  499. }
  500. }
  501. URL location;
  502. if (ge.codeBase != null)
  503. location = new URL(ge.codeBase);
  504. else
  505. location = null;
  506. if (ge.principals == null || ge.principals.size() == 0) {
  507. return (canonicalizeCodebase
  508. (new CodeSource(location, certs),
  509. false));
  510. } else {
  511. return (canonicalizeCodebase
  512. (new SubjectCodeSource(null, ge.principals, location, certs),
  513. false));
  514. }
  515. }
  516. /**
  517. * Add one policy entry to the vector.
  518. */
  519. private void addGrantEntry(PolicyParser.GrantEntry ge,
  520. KeyStore keyStore) {
  521. if (debug != null) {
  522. debug.println("Adding policy entry: ");
  523. debug.println(" signedBy " + ge.signedBy);
  524. debug.println(" codeBase " + ge.codeBase);
  525. if (ge.principals != null && ge.principals.size() > 0) {
  526. ListIterator<PolicyParser.PrincipalEntry> li =
  527. ge.principals.listIterator();
  528. while (li.hasNext()) {
  529. PolicyParser.PrincipalEntry pppe = li.next();
  530. debug.println(" " + pppe.principalClass +
  531. " " + pppe.principalName);
  532. }
  533. }
  534. debug.println();
  535. }
  536. try {
  537. CodeSource codesource = getCodeSource(ge, keyStore);
  538. // skip if signedBy alias was unknown...
  539. if (codesource == null) return;
  540. PolicyEntry entry = new PolicyEntry(codesource);
  541. Enumeration<PolicyParser.PermissionEntry> enum_ =
  542. ge.permissionElements();
  543. while (enum_.hasMoreElements()) {
  544. PolicyParser.PermissionEntry pe = enum_.nextElement();
  545. try {
  546. // XXX special case PrivateCredentialPermission-SELF
  547. Permission perm;
  548. if (pe.permission.equals
  549. ("javax.security.auth.PrivateCredentialPermission") &&
  550. pe.name.endsWith(" self")) {
  551. perm = getInstance(pe.permission,
  552. pe.name + " \"self\"",
  553. pe.action);
  554. } else {
  555. perm = getInstance(pe.permission,
  556. pe.name,
  557. pe.action);
  558. }
  559. entry.add(perm);
  560. if (debug != null) {
  561. debug.println(" "+perm);
  562. }
  563. } catch (ClassNotFoundException cnfe) {
  564. Certificate certs[];
  565. if (pe.signedBy != null)
  566. certs = getCertificates(keyStore, pe.signedBy);
  567. else
  568. certs = null;
  569. // only add if we had no signer or we had a
  570. // a signer and found the keys for it.
  571. if (certs != null || pe.signedBy == null) {
  572. Permission perm = new UnresolvedPermission(
  573. pe.permission,
  574. pe.name,
  575. pe.action,
  576. certs);
  577. entry.add(perm);
  578. if (debug != null) {
  579. debug.println(" "+perm);
  580. }
  581. }
  582. } catch (java.lang.reflect.InvocationTargetException ite) {
  583. System.err.println
  584. (AUTH_POLICY +
  585. rb.getString(".error.adding.Permission.") +
  586. pe.permission +
  587. rb.getString("SPACE") +
  588. ite.getTargetException());
  589. } catch (Exception e) {
  590. System.err.println
  591. (AUTH_POLICY +
  592. rb.getString(".error.adding.Permission.") +
  593. pe.permission +
  594. rb.getString("SPACE") +
  595. e);
  596. }
  597. }
  598. policyEntries.addElement(entry);
  599. } catch (Exception e) {
  600. System.err.println
  601. (AUTH_POLICY +
  602. rb.getString(".error.adding.Entry.") +
  603. ge +
  604. rb.getString("SPACE") +
  605. e);
  606. }
  607. if (debug != null)
  608. debug.println();
  609. }
  610. /**
  611. * Returns a new Permission object of the given Type. The Permission is
  612. * created by getting the
  613. * Class object using the <code>Class.forName</code> method, and using
  614. * the reflection API to invoke the (String name, String actions)
  615. * constructor on the
  616. * object.
  617. *
  618. * @param type the type of Permission being created.
  619. * @param name the name of the Permission being created.
  620. * @param actions the actions of the Permission being created.
  621. *
  622. * @exception ClassNotFoundException if the particular Permission
  623. * class could not be found.
  624. *
  625. * @exception IllegalAccessException if the class or initializer is
  626. * not accessible.
  627. *
  628. * @exception InstantiationException if getInstance tries to
  629. * instantiate an abstract class or an interface, or if the
  630. * instantiation fails for some other reason.
  631. *
  632. * @exception NoSuchMethodException if the (String, String) constructor
  633. * is not found.
  634. *
  635. * @exception InvocationTargetException if the underlying Permission
  636. * constructor throws an exception.
  637. *
  638. */
  639. private static final Permission getInstance(String type,
  640. String name,
  641. String actions)
  642. throws ClassNotFoundException,
  643. InstantiationException,
  644. IllegalAccessException,
  645. NoSuchMethodException,
  646. InvocationTargetException
  647. {
  648. //XXX we might want to keep a hash of created factories...
  649. Class pc = Class.forName(type);
  650. Constructor c = pc.getConstructor(PARAMS);
  651. return (Permission) c.newInstance(new Object[] { name, actions });
  652. }
  653. /**
  654. * Fetch all certs associated with this alias.
  655. */
  656. Certificate[] getCertificates(
  657. KeyStore keyStore, String aliases) {
  658. Vector<Certificate> vcerts = null;
  659. StringTokenizer st = new StringTokenizer(aliases, ",");
  660. int n = 0;
  661. while (st.hasMoreTokens()) {
  662. String alias = st.nextToken().trim();
  663. n++;
  664. Certificate cert = null;
  665. //See if this alias's cert has already been cached
  666. cert = (Certificate) aliasMapping.get(alias);
  667. if (cert == null && keyStore != null) {
  668. try {
  669. cert = keyStore.getCertificate(alias);
  670. } catch (KeyStoreException kse) {
  671. // never happens, because keystore has already been loaded
  672. // when we call this
  673. }
  674. if (cert != null) {
  675. aliasMapping.put(alias, cert);
  676. aliasMapping.put(cert, alias);
  677. }
  678. }
  679. if (cert != null) {
  680. if (vcerts == null)
  681. vcerts = new Vector<Certificate>();
  682. vcerts.addElement(cert);
  683. }
  684. }
  685. // make sure n == vcerts.size, since we are doing a logical *and*
  686. if (vcerts != null && n == vcerts.size()) {
  687. Certificate[] certs = new Certificate[vcerts.size()];
  688. vcerts.copyInto(certs);
  689. return certs;
  690. } else {
  691. return null;
  692. }
  693. }
  694. /**
  695. * Enumerate all the entries in the global policy object.
  696. * This method is used by policy admin tools. The tools
  697. * should use the Enumeration methods on the returned object
  698. * to fetch the elements sequentially.
  699. */
  700. private final synchronized Enumeration<PolicyEntry> elements(){
  701. return policyEntries.elements();
  702. }
  703. /**
  704. * Examines this <code>Policy</code> and returns the Permissions granted
  705. * to the specified <code>Subject</code> and <code>CodeSource</code>.
  706. *
  707. * <p> Permissions for a particular <i>grant</i> entry are returned
  708. * if the <code>CodeSource</code> constructed using the codebase and
  709. * signedby values specified in the entry <code>implies</code>
  710. * the <code>CodeSource</code> provided to this method, and if the
  711. * <code>Subject</code> provided to this method contains all of the
  712. * Principals specified in the entry.
  713. *
  714. * <p> The <code>Subject</code> provided to this method contains all
  715. * of the Principals specified in the entry if, for each
  716. * <code>Principal</code>, "P1", specified in the <i>grant</i> entry
  717. * one of the following two conditions is met:
  718. *
  719. * <p>
  720. * <ol>
  721. * <li> the <code>Subject</code> has a
  722. * <code>Principal</code>, "P2", where
  723. * <code>P2.getClass().getName()</code> equals the
  724. * P1's class name, and where
  725. * <code>P2.getName()</code> equals the P1's name.
  726. *
  727. * <li> P1 implements
  728. * <code>com.sun.security.auth.PrincipalComparator</code>,
  729. * and <code>P1.implies</code> the provided <code>Subject</code>.
  730. * </ol>
  731. *
  732. * <p> Note that this <code>Policy</code> implementation has
  733. * special handling for PrivateCredentialPermissions.
  734. * When this method encounters a <code>PrivateCredentialPermission</code>
  735. * which specifies "self" as the <code>Principal</code> class and name,
  736. * it does not add that <code>Permission</code> to the returned
  737. * <code>PermissionCollection</code>. Instead, it builds
  738. * a new <code>PrivateCredentialPermission</code>
  739. * for each <code>Principal</code> associated with the provided
  740. * <code>Subject</code>. Each new <code>PrivateCredentialPermission</code>
  741. * contains the same Credential class as specified in the
  742. * originally granted permission, as well as the Class and name
  743. * for the respective <code>Principal</code>.
  744. *
  745. * <p>
  746. *
  747. * @param subject the Permissions granted to this <code>Subject</code>
  748. * and the additionally provided <code>CodeSource</code>
  749. * are returned. <p>
  750. *
  751. * @param codesource the Permissions granted to this <code>CodeSource</code>
  752. * and the additionally provided <code>Subject</code>
  753. * are returned.
  754. *
  755. * @return the Permissions granted to the provided <code>Subject</code>
  756. * <code>CodeSource</code>.
  757. */
  758. public PermissionCollection getPermissions(final Subject subject,
  759. final CodeSource codesource) {
  760. // XXX when JAAS goes into the JDK core,
  761. // we can remove this method and simply
  762. // rely on the getPermissions variant that takes a codesource,
  763. // which no one can use at this point in time.
  764. // at that time, we can also make SubjectCodeSource a public
  765. // class.
  766. // XXX
  767. //
  768. // 1) if code instantiates PolicyFile directly, then it will need
  769. // all the permissions required for the PolicyFile initialization
  770. // 2) if code calls Policy.getPolicy, then it simply needs
  771. // AuthPermission(getPolicy), and the javax.security.auth.Policy
  772. // implementation instantiates PolicyFile in a doPrivileged block
  773. // 3) if after instantiating a Policy (either via #1 or #2),
  774. // code calls getPermissions, PolicyFile wraps the call
  775. // in a doPrivileged block.
  776. return java.security.AccessController.doPrivileged
  777. (new java.security.PrivilegedAction<PermissionCollection>() {
  778. public PermissionCollection run() {
  779. SubjectCodeSource scs = new SubjectCodeSource
  780. (subject,
  781. null,
  782. codesource == null ? null : codesource.getLocation(),
  783. codesource == null ? null : codesource.getCertificates());
  784. if (initialized)
  785. return getPermissions(new Permissions(), scs);
  786. else
  787. return new PolicyPermissions(PolicyFile.this, scs);
  788. }
  789. });
  790. }
  791. /**
  792. * Examines the global policy for the specified CodeSource, and
  793. * creates a PermissionCollection object with
  794. * the set of permissions for that principal's protection domain.
  795. *
  796. * @param CodeSource the codesource associated with the caller.
  797. * This encapsulates the original location of the code (where the code
  798. * came from) and the public key(s) of its signer.
  799. *
  800. * @return the set of permissions according to the policy.
  801. */
  802. PermissionCollection getPermissions(CodeSource codesource) {
  803. if (initialized)
  804. return getPermissions(new Permissions(), codesource);
  805. else
  806. return new PolicyPermissions(this, codesource);
  807. }
  808. /**
  809. * Examines the global policy for the specified CodeSource, and
  810. * creates a PermissionCollection object with
  811. * the set of permissions for that principal's protection domain.
  812. *
  813. * @param permissions the permissions to populate
  814. * @param codesource the codesource associated with the caller.
  815. * This encapsulates the original location of the code (where the code
  816. * came from) and the public key(s) of its signer.
  817. *
  818. * @return the set of permissions according to the policy.
  819. */
  820. Permissions getPermissions(final Permissions perms,
  821. final CodeSource cs)
  822. {
  823. if (!initialized) {
  824. init();
  825. }
  826. final CodeSource codesource[] = {null};
  827. codesource[0] = canonicalizeCodebase(cs, true);
  828. if (debug != null) {
  829. debug.println("evaluate("+codesource[0]+")\n");
  830. }
  831. // needs to be in a begin/endPrivileged block because
  832. // codesource.implies calls URL.equals which does an
  833. // InetAddress lookup
  834. for (int i = 0; i < policyEntries.size(); i++) {
  835. PolicyEntry entry = policyEntries.elementAt(i);
  836. if (debug != null) {
  837. debug.println("PolicyFile CodeSource implies: " +
  838. entry.codesource.toString() + "\n\n" +
  839. "\t" + codesource[0].toString() + "\n\n");
  840. }
  841. if (entry.codesource.implies(codesource[0])) {
  842. for (int j = 0; j < entry.permissions.size(); j++) {
  843. Permission p = entry.permissions.elementAt(j);
  844. if (debug != null) {
  845. debug.println(" granting " + p);
  846. }
  847. if (!addSelfPermissions(p, entry.codesource,
  848. codesource[0], perms)) {
  849. // we could check for duplicates
  850. // before adding new permissions,
  851. // but the SubjectDomainCombiner
  852. // already checks for duplicates later
  853. perms.add(p);
  854. }
  855. }
  856. }
  857. }
  858. // now see if any of the keys are trusted ids.
  859. if (!ignoreIdentityScope) {
  860. Certificate certs[] = codesource[0].getCertificates();
  861. if (certs != null) {
  862. for (int k=0; k < certs.length; k++) {
  863. if ((aliasMapping.get(certs[k]) == null) &&
  864. checkForTrustedIdentity(certs[k])) {
  865. // checkForTrustedIdentity added it
  866. // to the policy for us. next time
  867. // around we'll find it. This time
  868. // around we need to add it.
  869. perms.add(new java.security.AllPermission());
  870. }
  871. }
  872. }
  873. }
  874. return perms;
  875. }
  876. /**
  877. * Returns true if 'Self' permissions were added to the provided
  878. * 'perms', and false otherwise.
  879. *
  880. * <p>
  881. *
  882. * @param p check to see if this Permission is a "SELF"
  883. * PrivateCredentialPermission. <p>
  884. *
  885. * @param entryCs the codesource for the Policy entry.
  886. *
  887. * @param accCs the codesource for from the current AccessControlContext.
  888. *
  889. * @param perms the PermissionCollection where the individual
  890. * PrivateCredentialPermissions will be added.
  891. */
  892. private boolean addSelfPermissions(final Permission p,
  893. CodeSource entryCs,
  894. CodeSource accCs,
  895. Permissions perms) {
  896. if (!(p instanceof PrivateCredentialPermission))
  897. return false;
  898. if (!(entryCs instanceof SubjectCodeSource))
  899. return false;
  900. PrivateCredentialPermission pcp = (PrivateCredentialPermission)p;
  901. SubjectCodeSource scs = (SubjectCodeSource)entryCs;
  902. // see if it is a SELF permission
  903. String[][] pPrincipals = pcp.getPrincipals();
  904. if (pPrincipals.length <= 0 ||
  905. !pPrincipals[0][0].equalsIgnoreCase("self") ||
  906. !pPrincipals[0][1].equalsIgnoreCase("self")) {
  907. // regular PrivateCredentialPermission
  908. return false;
  909. } else {
  910. // granted a SELF permission - create a
  911. // PrivateCredentialPermission for each
  912. // of the Policy entry's CodeSource Principals
  913. if (scs.getPrincipals() == null) {
  914. // XXX SubjectCodeSource has no Subject???
  915. return true;
  916. }
  917. ListIterator<PolicyParser.PrincipalEntry> pli =
  918. scs.getPrincipals().listIterator();
  919. while (pli.hasNext()) {
  920. PolicyParser.PrincipalEntry principal = pli.next();
  921. // XXX
  922. // if the Policy entry's Principal does not contain a
  923. // WILDCARD for the Principal name, then a
  924. // new PrivateCredentialPermission is created
  925. // for the Principal listed in the Policy entry.
  926. // if the Policy entry's Principal contains a WILDCARD
  927. // for the Principal name, then a new
  928. // PrivateCredentialPermission is created
  929. // for each Principal associated with the Subject
  930. // in the current ACC.
  931. String[][] principalInfo = getPrincipalInfo
  932. (principal, accCs);
  933. for (int i = 0; i < principalInfo.length; i++) {
  934. // here's the new PrivateCredentialPermission
  935. PrivateCredentialPermission newPcp =
  936. new PrivateCredentialPermission
  937. (pcp.getCredentialClass() +
  938. " " +
  939. principalInfo[i][0] +
  940. " " +
  941. "\"" + principalInfo[i][1] + "\"",
  942. "read");
  943. if (debug != null) {
  944. debug.println("adding SELF permission: " +
  945. newPcp.toString());
  946. }
  947. perms.add(newPcp);
  948. }
  949. }
  950. }
  951. return true;
  952. }
  953. /**
  954. * return the principal class/name pair in the 2D array.
  955. * array[x][y]: x corresponds to the array length.
  956. * if (y == 0), it's the principal class.
  957. * if (y == 1), it's the principal name.
  958. */
  959. private String[][] getPrincipalInfo
  960. (PolicyParser.PrincipalEntry principal,
  961. final CodeSource accCs) {
  962. // there are 3 possibilities:
  963. // 1) the entry's Principal class and name are not wildcarded
  964. // 2) the entry's Principal name is wildcarded only
  965. // 3) the entry's Principal class and name are wildcarded
  966. if (!principal.principalClass.equals
  967. (PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
  968. !principal.principalName.equals
  969. (PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
  970. // build a PrivateCredentialPermission for the principal
  971. // from the Policy entry
  972. String[][] info = new String[1][2];
  973. info[0][0] = principal.principalClass;
  974. info[0][1] = principal.principalName;
  975. return info;
  976. } else if (!principal.principalClass.equals
  977. (PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
  978. principal.principalName.equals
  979. (PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
  980. // build a PrivateCredentialPermission for all
  981. // the Subject's principals that are instances of principalClass
  982. // the accCs is guaranteed to be a SubjectCodeSource
  983. // because the earlier CodeSource.implies succeeded
  984. SubjectCodeSource scs = (SubjectCodeSource)accCs;
  985. Set<Principal> principalSet = null;
  986. try {
  987. Class pClass = Class.forName(principal.principalClass, false,
  988. ClassLoader.getSystemClassLoader());
  989. principalSet = scs.getSubject().getPrincipals(pClass);
  990. } catch (Exception e) {
  991. if (debug != null) {
  992. debug.println("problem finding Principal Class " +
  993. "when expanding SELF permission: " +
  994. e.toString());
  995. }
  996. }
  997. if (principalSet == null) {
  998. // error
  999. return new String[0][0];
  1000. }
  1001. String[][] info = new String[principalSet.size()][2];
  1002. java.util.Iterator<Principal> pIterator = principalSet.iterator();
  1003. int i = 0;
  1004. while (pIterator.hasNext()) {
  1005. Principal p = pIterator.next();
  1006. info[i][0] = p.getClass().getName();
  1007. info[i][1] = p.getName();
  1008. i++;
  1009. }
  1010. return info;
  1011. } else {
  1012. // build a PrivateCredentialPermission for every
  1013. // one of the current Subject's principals
  1014. // the accCs is guaranteed to be a SubjectCodeSource
  1015. // because the earlier CodeSource.implies succeeded
  1016. SubjectCodeSource scs = (SubjectCodeSource)accCs;
  1017. Set<Principal> principalSet = scs.getSubject().getPrincipals();
  1018. String[][] info = new String[principalSet.size()][2];
  1019. java.util.Iterator<Principal> pIterator = principalSet.iterator();
  1020. int i = 0;
  1021. while (pIterator.hasNext()) {
  1022. Principal p = pIterator.next();
  1023. info[i][0] = p.getClass().getName();
  1024. info[i][1] = p.getName();
  1025. i++;
  1026. }
  1027. return info;
  1028. }
  1029. }
  1030. /*
  1031. * Returns the signer certificates from the list of certificates associated
  1032. * with the given code source.
  1033. *
  1034. * The signer certificates are those certificates that were used to verify
  1035. * signed code originating from the codesource location.
  1036. *
  1037. * This method assumes that in the given code source, each signer
  1038. * certificate is followed by its supporting certificate chain
  1039. * (which may be empty), and that the signer certificate and its
  1040. * supporting certificate chain are ordered bottom-to-top (i.e., with the
  1041. * signer certificate first and the (root) certificate authority last).
  1042. */
  1043. Certificate[] getSignerCertificates(CodeSource cs) {
  1044. Certificate[] certs = null;
  1045. if ((certs = cs.getCertificates()) == null)
  1046. return null;
  1047. for (int i=0; i<certs.length; i++) {
  1048. if (!(certs[i] instanceof X509Certificate))
  1049. return cs.getCertificates();
  1050. }
  1051. // Do we have to do anything?
  1052. int i = 0;
  1053. int count = 0;
  1054. while (i < certs.length) {
  1055. count++;
  1056. while (((i+1) < certs.length)
  1057. && ((X509Certificate)certs[i]).getIssuerDN().equals(
  1058. ((X509Certificate)certs[i+1]).getSubjectDN())) {
  1059. i++;
  1060. }
  1061. i++;
  1062. }
  1063. if (count == certs.length)
  1064. // Done
  1065. return certs;
  1066. ArrayList<Certificate> userCertList = new ArrayList<>();
  1067. i = 0;
  1068. while (i < certs.length) {
  1069. userCertList.add(certs[i]);
  1070. while (((i+1) < certs.length)
  1071. && ((X509Certificate)certs[i]).getIssuerDN().equals(
  1072. ((X509Certificate)certs[i+1]).getSubjectDN())) {
  1073. i++;
  1074. }
  1075. i++;
  1076. }
  1077. Certificate[] userCerts = new Certificate[userCertList.size()];
  1078. userCertList.toArray(userCerts);
  1079. return userCerts;
  1080. }
  1081. private CodeSource canonicalizeCodebase(CodeSource cs,
  1082. boolean extractSignerCerts) {
  1083. CodeSource canonCs = cs;
  1084. if (cs.getLocation() != null &&
  1085. cs.getLocation().getProtocol().equalsIgnoreCase("file")) {
  1086. try {
  1087. String path = cs.getLocation().getFile().replace
  1088. ('/',
  1089. File.separatorChar);
  1090. URL csUrl = null;
  1091. if (path.endsWith("*")) {
  1092. // remove trailing '*' because it causes canonicalization
  1093. // to fail on win32
  1094. path = path.substring(0, path.length()-1);
  1095. boolean appendFileSep = false;
  1096. if (path.endsWith(File.separator))
  1097. appendFileSep = true;
  1098. if (path.equals("")) {
  1099. path = System.getProperty("user.dir");
  1100. }
  1101. File f = new File(path);
  1102. path = f.getCanonicalPath();
  1103. StringBuffer sb = new StringBuffer(path);
  1104. // reappend '*' to canonicalized filename (note that
  1105. // canonicalization may have removed trailing file
  1106. // separator, so we have to check for that, too)
  1107. if (!path.endsWith(File.separator) &&
  1108. (appendFileSep || f.isDirectory()))
  1109. sb.append(File.separatorChar);
  1110. sb.append('*');
  1111. path = sb.toString();
  1112. } else {
  1113. path = new File(path).getCanonicalPath();
  1114. }
  1115. csUrl = new File(path).toURL();
  1116. if (cs instanceof SubjectCodeSource) {
  1117. SubjectCodeSource scs = (SubjectCodeSource)cs;
  1118. if (extractSignerCerts) {
  1119. canonCs = new SubjectCodeSource
  1120. (scs.getSubject(),
  1121. scs.getPrincipals(),
  1122. csUrl,
  1123. getSignerCertificates(scs));
  1124. } else {
  1125. canonCs = new SubjectCodeSource
  1126. (scs.getSubject(),
  1127. scs.getPrincipals(),
  1128. csUrl,
  1129. scs.getCertificates());
  1130. }
  1131. } else {
  1132. if (extractSignerCerts) {
  1133. canonCs = new CodeSource(csUrl,
  1134. getSignerCertificates(cs));
  1135. } else {
  1136. canonCs = new CodeSource(csUrl,
  1137. cs.getCertificates());
  1138. }
  1139. }
  1140. } catch (IOException ioe) {
  1141. // leave codesource as it is, unless we have to extract its
  1142. // signer certificates
  1143. if (extractSignerCerts) {
  1144. if (!(cs instanceof SubjectCodeSource)) {
  1145. canonCs = new CodeSource(cs.getLocation(),
  1146. getSignerCertificates(cs));
  1147. } else {
  1148. SubjectCodeSource scs = (SubjectCodeSource)cs;
  1149. canonCs = new SubjectCodeSource(scs.getSubject(),
  1150. scs.getPrincipals(),
  1151. scs.getLocation(),
  1152. getSignerCertificates(scs));

Large files files are truncated, but you can click here to view the full file