< prev index next >

src/java.base/share/classes/sun/security/provider/PolicyFile.java

Print this page


   1 /*
   2  * Copyright (c) 1997, 2013, 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


 261 
 262     private static final String NONE = "NONE";
 263     private static final String P11KEYSTORE = "PKCS11";
 264 
 265     private static final String SELF = "${{self}}";
 266     private static final String X500PRINCIPAL =
 267                         "javax.security.auth.x500.X500Principal";
 268     private static final String POLICY = "java.security.policy";
 269     private static final String SECURITY_MANAGER = "java.security.manager";
 270     private static final String POLICY_URL = "policy.url.";
 271     private static final String AUTH_POLICY = "java.security.auth.policy";
 272     private static final String AUTH_POLICY_URL = "auth.policy.url.";
 273 
 274     private static final int DEFAULT_CACHE_SIZE = 1;
 275 
 276     // contains the policy grant entries, PD cache, and alias mapping
 277     private AtomicReference<PolicyInfo> policyInfo = new AtomicReference<>();
 278     private boolean constructed = false;
 279 
 280     private boolean expandProperties = true;
 281     private boolean ignoreIdentityScope = true;
 282     private boolean allowSystemProperties = true;
 283     private boolean notUtf8 = false;
 284     private URL url;
 285 
 286     // for use with the reflection API
 287 
 288     private static final Class<?>[] PARAMS0 = { };
 289     private static final Class<?>[] PARAMS1 = { String.class };
 290     private static final Class<?>[] PARAMS2 = { String.class, String.class };
 291 
 292     /**
 293      * Initializes the Policy object and reads the default policy
 294      * configuration file(s) into the Policy object.
 295      */
 296     public PolicyFile() {
 297         init((URL)null);
 298     }
 299 
 300     /**
 301      * Initializes the Policy object and reads the default policy


 398      *
 399      *   grant signedBy "Duke" {
 400      *          permission java.io.FilePermission "/tmp/*", "read,write";
 401      *   };
 402      *
 403      *   // grant everyone the following permission
 404      *
 405      *   grant {
 406      *     permission java.util.PropertyPermission "java.vendor";
 407      *   };
 408      *  </pre>
 409      */
 410     private void init(URL url) {
 411         // Properties are set once for each init(); ignore changes between
 412         // between diff invocations of initPolicyFile(policy, url, info).
 413         String numCacheStr =
 414           AccessController.doPrivileged(new PrivilegedAction<String>() {
 415             public String run() {
 416                 expandProperties = "true".equalsIgnoreCase
 417                     (Security.getProperty("policy.expandProperties"));
 418                 ignoreIdentityScope = "true".equalsIgnoreCase
 419                     (Security.getProperty("policy.ignoreIdentityScope"));
 420                 allowSystemProperties = "true".equalsIgnoreCase
 421                     (Security.getProperty("policy.allowSystemProperty"));
 422                 notUtf8 = "false".equalsIgnoreCase
 423                     (System.getProperty("sun.security.policy.utf8"));
 424                 return System.getProperty("sun.security.policy.numcaches");
 425             }});
 426 
 427         int numCaches;
 428         if (numCacheStr != null) {
 429             try {
 430                 numCaches = Integer.parseInt(numCacheStr);
 431             } catch (NumberFormatException e) {
 432                 numCaches = DEFAULT_CACHE_SIZE;
 433             }
 434         } else {
 435             numCaches = DEFAULT_CACHE_SIZE;
 436         }
 437         // System.out.println("number caches=" + numCaches);
 438         PolicyInfo newInfo = new PolicyInfo(numCaches);
 439         initPolicyFile(newInfo, url);


1189 
1190         CodeSource canonCodeSource = AccessController.doPrivileged(
1191             new java.security.PrivilegedAction<CodeSource>(){
1192                 public CodeSource run() {
1193                     return canonicalizeCodebase(cs, true);
1194                 }
1195             });
1196 
1197         return getPermissions(perms, canonCodeSource, null);
1198     }
1199 
1200     private Permissions getPermissions(Permissions perms,
1201                                        final CodeSource cs,
1202                                        Principal[] principals) {
1203         PolicyInfo pi = policyInfo.get();
1204 
1205         for (PolicyEntry entry : pi.policyEntries) {
1206             addPermissions(perms, cs, principals, entry);
1207         }
1208 
1209         // Go through policyEntries gotten from identity db; sync required
1210         // because checkForTrustedIdentity (below) might update list
1211         synchronized (pi.identityPolicyEntries) {
1212             for (PolicyEntry entry : pi.identityPolicyEntries) {
1213                 addPermissions(perms, cs, principals, entry);
1214             }
1215         }
1216 
1217         // now see if any of the keys are trusted ids.
1218         if (!ignoreIdentityScope) {
1219             Certificate certs[] = cs.getCertificates();
1220             if (certs != null) {
1221                 for (int k=0; k < certs.length; k++) {
1222                     Object idMap = pi.aliasMapping.get(certs[k]);
1223                     if (idMap == null &&
1224                         checkForTrustedIdentity(certs[k], pi)) {
1225                         // checkForTrustedIdentity added it
1226                         // to the policy for us. next time
1227                         // around we'll find it. This time
1228                         // around we need to add it.
1229                         perms.add(SecurityConstants.ALL_PERMISSION);
1230                     }
1231                 }
1232             }
1233         }
1234         return perms;
1235     }
1236 
1237     private void addPermissions(Permissions perms,
1238         final CodeSource cs,
1239         Principal[] principals,
1240         final PolicyEntry entry) {
1241 
1242         if (debug != null) {
1243             debug.println("evaluate codesources:\n" +
1244                 "\tPolicy CodeSource: " + entry.getCodeSource() + "\n" +
1245                 "\tActive CodeSource: " + cs);
1246         }
1247 
1248         // check to see if the CodeSource implies
1249         Boolean imp = AccessController.doPrivileged
1250             (new PrivilegedAction<Boolean>() {
1251             public Boolean run() {
1252                 return entry.getCodeSource().implies(cs);
1253             }


1603         } else {
1604 
1605             // build an info array for every
1606             // one of the current Domain's principals
1607 
1608             String[][] info = new String[pdp.length][2];
1609 
1610             for (int i = 0; i < pdp.length; i++) {
1611                 info[i][0] = pdp[i].getClass().getName();
1612                 info[i][1] = pdp[i].getName();
1613             }
1614             return info;
1615         }
1616     }
1617 
1618     /*
1619      * Returns the signer certificates from the list of certificates
1620      * associated with the given code source.
1621      *
1622      * The signer certificates are those certificates that were used
1623      * to verifysigned code originating from the codesource location.
1624      *
1625      * This method assumes that in the given code source, each signer
1626      * certificate is followed by its supporting certificate chain
1627      * (which may be empty), and that the signer certificate and its
1628      * supporting certificate chain are ordered bottom-to-top
1629      * (i.e., with the signer certificate first and the (root) certificate
1630      * authority last).
1631      */
1632     protected Certificate[] getSignerCertificates(CodeSource cs) {
1633         Certificate[] certs = null;
1634         if ((certs = cs.getCertificates()) == null)
1635             return null;
1636         for (int i=0; i<certs.length; i++) {
1637             if (!(certs[i] instanceof X509Certificate))
1638                 return cs.getCertificates();
1639         }
1640 
1641         // Do we have to do anything?
1642         int i = 0;
1643         int count = 0;


1900             if (debug != null) {
1901                 debug.println("  -- No certificate for '" +
1902                                 alias +
1903                                 "' - ignoring entry");
1904             }
1905             return null;
1906         } else {
1907             X509Certificate x509Cert = (X509Certificate)cert;
1908 
1909             // 4702543:  X500 names with an EmailAddress
1910             // were encoded incorrectly.  create new
1911             // X500Principal name with correct encoding
1912 
1913             X500Principal p = new X500Principal
1914                 (x509Cert.getSubjectX500Principal().toString());
1915             return p.getName();
1916         }
1917     }
1918 
1919     /**
1920      * Checks public key. If it is marked as trusted in
1921      * the identity database, add it to the policy
1922      * with the AllPermission.
1923      */
1924     private boolean checkForTrustedIdentity(final Certificate cert,
1925         PolicyInfo myInfo)
1926     {
1927         return false;
1928     }
1929 
1930     /**
1931      * Each entry in the policy configuration file is represented by a
1932      * PolicyEntry object.  <p>
1933      *
1934      * A PolicyEntry is a (CodeSource,Permission) pair.  The
1935      * CodeSource contains the (URL, PublicKey) that together identify
1936      * where the Java bytecodes come from and who (if anyone) signed
1937      * them.  The URL could refer to localhost.  The URL could also be
1938      * null, meaning that this policy entry is given to all comers, as
1939      * long as they match the signer field.  The signer could be null,
1940      * meaning the code is not signed. <p>
1941      *
1942      * The Permission contains the (Type, Name, Action) triplet. <p>
1943      *
1944      * For now, the Policy object retrieves the public key from the
1945      * X.509 certificate on disk that corresponds to the signedBy
1946      * alias specified in the Policy config file.  For reasons of
1947      * efficiency, the Policy object keeps a hashtable of certs already
1948      * read in.  This could be replaced by a secure internal key
1949      * store.
1950      *


2265          * Returns a string describing this SelfPermission.  The convention
2266          * is to specify the class name, the permission name, and the actions,
2267          * in the following format: '(unresolved "ClassName" "name" "actions")'.
2268          *
2269          * @return information about this SelfPermission.
2270          */
2271         @Override public String toString() {
2272             return "(SelfPermission " + type + " " + name + " " + actions + ")";
2273         }
2274     }
2275 
2276     /**
2277      * holds policy information that we need to synch on
2278      */
2279     private static class PolicyInfo {
2280         private static final boolean verbose = false;
2281 
2282         // Stores grant entries in the policy
2283         final List<PolicyEntry> policyEntries;
2284 
2285         // Stores grant entries gotten from identity database
2286         // Use separate lists to avoid sync on policyEntries
2287         final List<PolicyEntry> identityPolicyEntries;
2288 
2289         // Maps aliases to certs
2290         final Map<Object, Object> aliasMapping;
2291 
2292         // Maps ProtectionDomain to PermissionCollection
2293         private final ProtectionDomainCache[] pdMapping;
2294         private java.util.Random random;
2295 
2296         PolicyInfo(int numCaches) {
2297             policyEntries = new ArrayList<>();
2298             identityPolicyEntries =
2299                 Collections.synchronizedList(new ArrayList<PolicyEntry>(2));
2300             aliasMapping = Collections.synchronizedMap(new HashMap<>(11));
2301 
2302             pdMapping = new ProtectionDomainCache[numCaches];
2303             JavaSecurityProtectionDomainAccess jspda
2304                 = SharedSecrets.getJavaSecurityProtectionDomainAccess();
2305             for (int i = 0; i < numCaches; i++) {
2306                 pdMapping[i] = jspda.getProtectionDomainCache();
2307             }
2308             if (numCaches > 1) {
2309                 random = new java.util.Random();
2310             }
2311         }
2312         ProtectionDomainCache getPdMapping() {
2313             if (pdMapping.length == 1) {
2314                 return pdMapping[0];
2315             } else {
2316                 int i = java.lang.Math.abs(random.nextInt() % pdMapping.length);
2317                 return pdMapping[i];
2318             }
2319         }
   1 /*
   2  * Copyright (c) 1997, 2015, 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


 261 
 262     private static final String NONE = "NONE";
 263     private static final String P11KEYSTORE = "PKCS11";
 264 
 265     private static final String SELF = "${{self}}";
 266     private static final String X500PRINCIPAL =
 267                         "javax.security.auth.x500.X500Principal";
 268     private static final String POLICY = "java.security.policy";
 269     private static final String SECURITY_MANAGER = "java.security.manager";
 270     private static final String POLICY_URL = "policy.url.";
 271     private static final String AUTH_POLICY = "java.security.auth.policy";
 272     private static final String AUTH_POLICY_URL = "auth.policy.url.";
 273 
 274     private static final int DEFAULT_CACHE_SIZE = 1;
 275 
 276     // contains the policy grant entries, PD cache, and alias mapping
 277     private AtomicReference<PolicyInfo> policyInfo = new AtomicReference<>();
 278     private boolean constructed = false;
 279 
 280     private boolean expandProperties = true;

 281     private boolean allowSystemProperties = true;
 282     private boolean notUtf8 = false;
 283     private URL url;
 284 
 285     // for use with the reflection API
 286 
 287     private static final Class<?>[] PARAMS0 = { };
 288     private static final Class<?>[] PARAMS1 = { String.class };
 289     private static final Class<?>[] PARAMS2 = { String.class, String.class };
 290 
 291     /**
 292      * Initializes the Policy object and reads the default policy
 293      * configuration file(s) into the Policy object.
 294      */
 295     public PolicyFile() {
 296         init((URL)null);
 297     }
 298 
 299     /**
 300      * Initializes the Policy object and reads the default policy


 397      *
 398      *   grant signedBy "Duke" {
 399      *          permission java.io.FilePermission "/tmp/*", "read,write";
 400      *   };
 401      *
 402      *   // grant everyone the following permission
 403      *
 404      *   grant {
 405      *     permission java.util.PropertyPermission "java.vendor";
 406      *   };
 407      *  </pre>
 408      */
 409     private void init(URL url) {
 410         // Properties are set once for each init(); ignore changes between
 411         // between diff invocations of initPolicyFile(policy, url, info).
 412         String numCacheStr =
 413           AccessController.doPrivileged(new PrivilegedAction<String>() {
 414             public String run() {
 415                 expandProperties = "true".equalsIgnoreCase
 416                     (Security.getProperty("policy.expandProperties"));


 417                 allowSystemProperties = "true".equalsIgnoreCase
 418                     (Security.getProperty("policy.allowSystemProperty"));
 419                 notUtf8 = "false".equalsIgnoreCase
 420                     (System.getProperty("sun.security.policy.utf8"));
 421                 return System.getProperty("sun.security.policy.numcaches");
 422             }});
 423 
 424         int numCaches;
 425         if (numCacheStr != null) {
 426             try {
 427                 numCaches = Integer.parseInt(numCacheStr);
 428             } catch (NumberFormatException e) {
 429                 numCaches = DEFAULT_CACHE_SIZE;
 430             }
 431         } else {
 432             numCaches = DEFAULT_CACHE_SIZE;
 433         }
 434         // System.out.println("number caches=" + numCaches);
 435         PolicyInfo newInfo = new PolicyInfo(numCaches);
 436         initPolicyFile(newInfo, url);


1186 
1187         CodeSource canonCodeSource = AccessController.doPrivileged(
1188             new java.security.PrivilegedAction<CodeSource>(){
1189                 public CodeSource run() {
1190                     return canonicalizeCodebase(cs, true);
1191                 }
1192             });
1193 
1194         return getPermissions(perms, canonCodeSource, null);
1195     }
1196 
1197     private Permissions getPermissions(Permissions perms,
1198                                        final CodeSource cs,
1199                                        Principal[] principals) {
1200         PolicyInfo pi = policyInfo.get();
1201 
1202         for (PolicyEntry entry : pi.policyEntries) {
1203             addPermissions(perms, cs, principals, entry);
1204         }
1205 

























1206         return perms;
1207     }
1208 
1209     private void addPermissions(Permissions perms,
1210         final CodeSource cs,
1211         Principal[] principals,
1212         final PolicyEntry entry) {
1213 
1214         if (debug != null) {
1215             debug.println("evaluate codesources:\n" +
1216                 "\tPolicy CodeSource: " + entry.getCodeSource() + "\n" +
1217                 "\tActive CodeSource: " + cs);
1218         }
1219 
1220         // check to see if the CodeSource implies
1221         Boolean imp = AccessController.doPrivileged
1222             (new PrivilegedAction<Boolean>() {
1223             public Boolean run() {
1224                 return entry.getCodeSource().implies(cs);
1225             }


1575         } else {
1576 
1577             // build an info array for every
1578             // one of the current Domain's principals
1579 
1580             String[][] info = new String[pdp.length][2];
1581 
1582             for (int i = 0; i < pdp.length; i++) {
1583                 info[i][0] = pdp[i].getClass().getName();
1584                 info[i][1] = pdp[i].getName();
1585             }
1586             return info;
1587         }
1588     }
1589 
1590     /*
1591      * Returns the signer certificates from the list of certificates
1592      * associated with the given code source.
1593      *
1594      * The signer certificates are those certificates that were used
1595      * to verify signed code originating from the codesource location.
1596      *
1597      * This method assumes that in the given code source, each signer
1598      * certificate is followed by its supporting certificate chain
1599      * (which may be empty), and that the signer certificate and its
1600      * supporting certificate chain are ordered bottom-to-top
1601      * (i.e., with the signer certificate first and the (root) certificate
1602      * authority last).
1603      */
1604     protected Certificate[] getSignerCertificates(CodeSource cs) {
1605         Certificate[] certs = null;
1606         if ((certs = cs.getCertificates()) == null)
1607             return null;
1608         for (int i=0; i<certs.length; i++) {
1609             if (!(certs[i] instanceof X509Certificate))
1610                 return cs.getCertificates();
1611         }
1612 
1613         // Do we have to do anything?
1614         int i = 0;
1615         int count = 0;


1872             if (debug != null) {
1873                 debug.println("  -- No certificate for '" +
1874                                 alias +
1875                                 "' - ignoring entry");
1876             }
1877             return null;
1878         } else {
1879             X509Certificate x509Cert = (X509Certificate)cert;
1880 
1881             // 4702543:  X500 names with an EmailAddress
1882             // were encoded incorrectly.  create new
1883             // X500Principal name with correct encoding
1884 
1885             X500Principal p = new X500Principal
1886                 (x509Cert.getSubjectX500Principal().toString());
1887             return p.getName();
1888         }
1889     }
1890 
1891     /**











1892      * Each entry in the policy configuration file is represented by a
1893      * PolicyEntry object.  <p>
1894      *
1895      * A PolicyEntry is a (CodeSource,Permission) pair.  The
1896      * CodeSource contains the (URL, PublicKey) that together identify
1897      * where the Java bytecodes come from and who (if anyone) signed
1898      * them.  The URL could refer to localhost.  The URL could also be
1899      * null, meaning that this policy entry is given to all comers, as
1900      * long as they match the signer field.  The signer could be null,
1901      * meaning the code is not signed. <p>
1902      *
1903      * The Permission contains the (Type, Name, Action) triplet. <p>
1904      *
1905      * For now, the Policy object retrieves the public key from the
1906      * X.509 certificate on disk that corresponds to the signedBy
1907      * alias specified in the Policy config file.  For reasons of
1908      * efficiency, the Policy object keeps a hashtable of certs already
1909      * read in.  This could be replaced by a secure internal key
1910      * store.
1911      *


2226          * Returns a string describing this SelfPermission.  The convention
2227          * is to specify the class name, the permission name, and the actions,
2228          * in the following format: '(unresolved "ClassName" "name" "actions")'.
2229          *
2230          * @return information about this SelfPermission.
2231          */
2232         @Override public String toString() {
2233             return "(SelfPermission " + type + " " + name + " " + actions + ")";
2234         }
2235     }
2236 
2237     /**
2238      * holds policy information that we need to synch on
2239      */
2240     private static class PolicyInfo {
2241         private static final boolean verbose = false;
2242 
2243         // Stores grant entries in the policy
2244         final List<PolicyEntry> policyEntries;
2245 




2246         // Maps aliases to certs
2247         final Map<Object, Object> aliasMapping;
2248 
2249         // Maps ProtectionDomain to PermissionCollection
2250         private final ProtectionDomainCache[] pdMapping;
2251         private java.util.Random random;
2252 
2253         PolicyInfo(int numCaches) {
2254             policyEntries = new ArrayList<>();


2255             aliasMapping = Collections.synchronizedMap(new HashMap<>(11));
2256 
2257             pdMapping = new ProtectionDomainCache[numCaches];
2258             JavaSecurityProtectionDomainAccess jspda
2259                 = SharedSecrets.getJavaSecurityProtectionDomainAccess();
2260             for (int i = 0; i < numCaches; i++) {
2261                 pdMapping[i] = jspda.getProtectionDomainCache();
2262             }
2263             if (numCaches > 1) {
2264                 random = new java.util.Random();
2265             }
2266         }
2267         ProtectionDomainCache getPdMapping() {
2268             if (pdMapping.length == 1) {
2269                 return pdMapping[0];
2270             } else {
2271                 int i = java.lang.Math.abs(random.nextInt() % pdMapping.length);
2272                 return pdMapping[i];
2273             }
2274         }
< prev index next >