< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.provider;
  27 
  28 import java.io.*;
  29 import java.lang.reflect.*;
  30 import java.net.MalformedURLException;
  31 import java.net.URL;
  32 import java.net.URI;

  33 import java.nio.file.Path;
  34 import java.util.*;
  35 import java.security.*;
  36 import java.security.cert.Certificate;
  37 import java.security.cert.X509Certificate;
  38 import javax.security.auth.Subject;
  39 import javax.security.auth.x500.X500Principal;
  40 import java.io.FilePermission;
  41 import java.net.SocketPermission;
  42 import java.net.NetPermission;
  43 import java.util.concurrent.ConcurrentHashMap;
  44 import jdk.internal.access.JavaSecurityAccess;
  45 import static jdk.internal.access.JavaSecurityAccess.ProtectionDomainCache;
  46 import jdk.internal.access.SharedSecrets;
  47 import jdk.internal.util.StaticProperty;
  48 import sun.security.util.*;
  49 import sun.net.www.ParseUtil;
  50 
  51 /**
  52  * This class represents a default Policy implementation for the
  53  * "JavaPolicy" type.
  54  *
  55  * <p> This object stores the policy for the entire Java runtime,
  56  * and is the amalgamation of multiple static policy
  57  * configurations that resides in files.
  58  * The algorithm for locating the policy file(s) and reading their
  59  * information into this <code>Policy</code> object is:
  60  *


 256     private boolean allowSystemProperties = true;
 257     private boolean notUtf8 = false;
 258     private URL url;
 259 
 260     // for use with the reflection API
 261     private static final Class<?>[] PARAMS0 = { };
 262     private static final Class<?>[] PARAMS1 = { String.class };
 263     private static final Class<?>[] PARAMS2 = { String.class, String.class };
 264 
 265     /**
 266      * When a policy file has a syntax error, the exception code may generate
 267      * another permission check and this can cause the policy file to be parsed
 268      * repeatedly, leading to a StackOverflowError or ClassCircularityError.
 269      * To avoid this, this set is populated with policy files that have been
 270      * previously parsed and have syntax errors, so that they can be
 271      * subsequently ignored.
 272      */
 273     private static Set<URL> badPolicyURLs =
 274         Collections.newSetFromMap(new ConcurrentHashMap<URL,Boolean>());
 275 
 276     // The default.policy file
 277     private static final URL DEFAULT_POLICY_URL =
 278         AccessController.doPrivileged(new PrivilegedAction<>() {
 279             @Override
 280             public URL run() {
 281                 String sep = File.separator;
 282                 try {
 283                     return Path.of(StaticProperty.javaHome(),
 284                                      "lib", "security",
 285                                      "default.policy").toUri().toURL();
 286                 } catch (MalformedURLException mue) {
 287                     // should not happen
 288                     throw new Error("Malformed default.policy URL: " + mue);
 289                 }
 290             }
 291         });
 292 
 293     /**
 294      * Initializes the Policy object and reads the default policy
 295      * configuration file(s) into the Policy object.
 296      */
 297     public PolicyFile() {
 298         init((URL)null);
 299     }
 300 
 301     /**
 302      * Initializes the Policy object and reads the default policy
 303      * from the specified URL only.
 304      */
 305     public PolicyFile(URL url) {
 306         this.url = url;
 307         init(url);
 308     }
 309 
 310     /**
 311      * Initializes the Policy object and reads the default policy
 312      * configuration file(s) into the Policy object.


 332 
 333         int numCaches;
 334         if (numCacheStr != null) {
 335             try {
 336                 numCaches = Integer.parseInt(numCacheStr);
 337             } catch (NumberFormatException e) {
 338                 numCaches = DEFAULT_CACHE_SIZE;
 339             }
 340         } else {
 341             numCaches = DEFAULT_CACHE_SIZE;
 342         }
 343         // System.out.println("number caches=" + numCaches);
 344         PolicyInfo newInfo = new PolicyInfo(numCaches);
 345         initPolicyFile(newInfo, url);
 346         policyInfo = newInfo;
 347     }
 348 
 349     private void initPolicyFile(final PolicyInfo newInfo, final URL url) {
 350 
 351         // always load default.policy
 352         if (debug != null) {
 353             debug.println("reading " + DEFAULT_POLICY_URL);
 354         }
 355         AccessController.doPrivileged(new PrivilegedAction<>() {
 356             @Override
 357             public Void run() {
 358                 init(DEFAULT_POLICY_URL, newInfo, true);
 359                 return null;
 360             }
 361         });
 362 
 363         if (url != null) {
 364 
 365             /**
 366              * If the caller specified a URL via Policy.getInstance,
 367              * we only read from default.policy and that URL.
 368              */
 369 
 370             if (debug != null) {
 371                 debug.println("reading " + url);
 372             }
 373             AccessController.doPrivileged(new PrivilegedAction<>() {
 374                 @Override
 375                 public Void run() {
 376                     if (init(url, newInfo, false) == false) {
 377                         // use static policy if all else fails
 378                         initStaticPolicy(newInfo);
 379                     }
 380                     return null;
 381                 }
 382             });
 383 
 384         } else {
 385 
 386             /**
 387              * Caller did not specify URL via Policy.getInstance.
 388              * Read from URLs listed in the java.security properties file.
 389              */
 390 
 391             boolean loaded_one = initPolicyFile(POLICY, POLICY_URL, newInfo);
 392             // To maintain strict backward compatibility
 393             // we load the static policy only if POLICY load failed
 394             if (!loaded_one) {
 395                 // use static policy if all else fails
 396                 initStaticPolicy(newInfo);


 412                         boolean overrideAll = false;
 413                         if (extra_policy.startsWith("=")) {
 414                             overrideAll = true;
 415                             extra_policy = extra_policy.substring(1);
 416                         }
 417                         try {
 418                             extra_policy =
 419                                 PropertyExpander.expand(extra_policy);
 420                             URL policyURL;
 421 
 422                             File policyFile = new File(extra_policy);
 423                             if (policyFile.exists()) {
 424                                 policyURL = ParseUtil.fileToEncodedURL
 425                                     (new File(policyFile.getCanonicalPath()));
 426                             } else {
 427                                 policyURL = new URL(extra_policy);
 428                             }
 429                             if (debug != null) {
 430                                 debug.println("reading "+policyURL);
 431                             }
 432                             if (init(policyURL, newInfo, false)) {
 433                                 loaded_policy = true;
 434                             }
 435                         } catch (Exception e) {
 436                             // ignore.
 437                             if (debug != null) {
 438                                 debug.println("caught exception: "+e);
 439                             }
 440                         }
 441                         if (overrideAll) {
 442                             if (debug != null) {
 443                                 debug.println("overriding other policies!");
 444                             }
 445                             return Boolean.valueOf(loaded_policy);
 446                         }
 447                     }
 448                 }
 449 
 450                 int n = 1;
 451                 String policy_uri;
 452 


 455                         URL policy_url = null;
 456                         String expanded_uri = PropertyExpander.expand
 457                                 (policy_uri).replace(File.separatorChar, '/');
 458 
 459                         if (policy_uri.startsWith("file:${java.home}/") ||
 460                             policy_uri.startsWith("file:${user.home}/")) {
 461 
 462                             // this special case accommodates
 463                             // the situation java.home/user.home
 464                             // expand to a single slash, resulting in
 465                             // a file://foo URI
 466                             policy_url = new File
 467                                 (expanded_uri.substring(5)).toURI().toURL();
 468                         } else {
 469                             policy_url = new URI(expanded_uri).toURL();
 470                         }
 471 
 472                         if (debug != null) {
 473                             debug.println("reading " + policy_url);
 474                         }
 475                         if (init(policy_url, newInfo, false)) {
 476                             loaded_policy = true;
 477                         }
 478                     } catch (Exception e) {
 479                         if (debug != null) {
 480                             debug.println(
 481                                 "Debug info only. Error reading policy " +e);
 482                             e.printStackTrace();
 483                         }
 484                         // ignore that policy
 485                     }
 486                     n++;
 487                 }
 488                 return Boolean.valueOf(loaded_policy);
 489             }
 490         });
 491 
 492         return loadedPolicy;
 493     }
 494 























 495     /**
 496      * Reads a policy configuration into the Policy object using a
 497      * Reader object.
 498      */
 499     private boolean init(URL policy, PolicyInfo newInfo, boolean defPolicy) {
 500 
 501         // skip parsing policy file if it has been previously parsed and
 502         // has syntax errors
 503         if (badPolicyURLs.contains(policy)) {
 504             if (debug != null) {
 505                 debug.println("skipping bad policy file: " + policy);
 506             }
 507             return false;
 508         }
 509 
 510         try (InputStreamReader isr =
 511                  getInputStreamReader(PolicyUtil.getInputStream(policy))) {
 512 
 513             PolicyParser pp = new PolicyParser(expandProperties);
 514             pp.read(isr);
 515 
 516             KeyStore keyStore = null;
 517             try {
 518                 keyStore = PolicyUtil.getKeyStore
 519                                 (policy,
 520                                 pp.getKeyStoreUrl(),
 521                                 pp.getKeyStoreType(),
 522                                 pp.getKeyStoreProvider(),
 523                                 pp.getStorePassURL(),
 524                                 debug);
 525             } catch (Exception e) {
 526                 // ignore, treat it like we have no keystore
 527                 if (debug != null) {
 528                     debug.println("Debug info only. Ignoring exception.");
 529                     e.printStackTrace();
 530                 }
 531             }
 532 
 533             Enumeration<PolicyParser.GrantEntry> enum_ = pp.grantElements();
 534             while (enum_.hasMoreElements()) {
 535                 PolicyParser.GrantEntry ge = enum_.nextElement();
 536                 addGrantEntry(ge, keyStore, newInfo);
 537             }
 538             return true;
 539         } catch (PolicyParser.ParsingException pe) {
 540             if (defPolicy) {
 541                 throw new InternalError("Failed to load default.policy", pe);
 542             }
 543             // record bad policy file to avoid later reparsing it
 544             badPolicyURLs.add(policy);
 545             Object[] source = {policy, pe.getNonlocalizedMessage()};
 546             System.err.println(LocalizedMessage.getNonlocalized
 547                 (POLICY + ".error.parsing.policy.message", source));
 548             if (debug != null) {
 549                 pe.printStackTrace();
 550             }
 551         } catch (Exception e) {
 552             if (defPolicy) {
 553                 throw new InternalError("Failed to load default.policy", e);
 554             }
 555             if (debug != null) {
 556                 debug.println("error parsing "+policy);
 557                 debug.println(e.toString());
 558                 e.printStackTrace();
 559             }
 560         }
 561 
 562         return false;
 563     }
 564 
 565     private InputStreamReader getInputStreamReader(InputStream is)
 566                               throws IOException {
 567         /*
 568          * Read in policy using UTF-8 by default.
 569          *
 570          * Check non-standard system property to see if the default encoding
 571          * should be used instead.
 572          */
 573         return (notUtf8)
 574             ? new InputStreamReader(is)


   1 /*
   2  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.provider;
  27 
  28 import java.io.*;
  29 import java.lang.reflect.*;
  30 import java.net.MalformedURLException;
  31 import java.net.URL;
  32 import java.net.URI;
  33 import java.nio.file.Files;
  34 import java.nio.file.Path;
  35 import java.util.*;
  36 import java.security.*;
  37 import java.security.cert.Certificate;
  38 import java.security.cert.X509Certificate;
  39 import javax.security.auth.Subject;
  40 import javax.security.auth.x500.X500Principal;

  41 import java.net.SocketPermission;
  42 import java.net.NetPermission;
  43 import java.util.concurrent.ConcurrentHashMap;
  44 import jdk.internal.access.JavaSecurityAccess;
  45 import static jdk.internal.access.JavaSecurityAccess.ProtectionDomainCache;
  46 import jdk.internal.access.SharedSecrets;
  47 import jdk.internal.util.StaticProperty;
  48 import sun.security.util.*;
  49 import sun.net.www.ParseUtil;
  50 
  51 /**
  52  * This class represents a default Policy implementation for the
  53  * "JavaPolicy" type.
  54  *
  55  * <p> This object stores the policy for the entire Java runtime,
  56  * and is the amalgamation of multiple static policy
  57  * configurations that resides in files.
  58  * The algorithm for locating the policy file(s) and reading their
  59  * information into this <code>Policy</code> object is:
  60  *


 256     private boolean allowSystemProperties = true;
 257     private boolean notUtf8 = false;
 258     private URL url;
 259 
 260     // for use with the reflection API
 261     private static final Class<?>[] PARAMS0 = { };
 262     private static final Class<?>[] PARAMS1 = { String.class };
 263     private static final Class<?>[] PARAMS2 = { String.class, String.class };
 264 
 265     /**
 266      * When a policy file has a syntax error, the exception code may generate
 267      * another permission check and this can cause the policy file to be parsed
 268      * repeatedly, leading to a StackOverflowError or ClassCircularityError.
 269      * To avoid this, this set is populated with policy files that have been
 270      * previously parsed and have syntax errors, so that they can be
 271      * subsequently ignored.
 272      */
 273     private static Set<URL> badPolicyURLs =
 274         Collections.newSetFromMap(new ConcurrentHashMap<URL,Boolean>());
 275 

















 276     /**
 277      * Initializes the Policy object and reads the default policy
 278      * configuration file(s) into the Policy object.
 279      */
 280     public PolicyFile() {
 281         init((URL)null);
 282     }
 283 
 284     /**
 285      * Initializes the Policy object and reads the default policy
 286      * from the specified URL only.
 287      */
 288     public PolicyFile(URL url) {
 289         this.url = url;
 290         init(url);
 291     }
 292 
 293     /**
 294      * Initializes the Policy object and reads the default policy
 295      * configuration file(s) into the Policy object.


 315 
 316         int numCaches;
 317         if (numCacheStr != null) {
 318             try {
 319                 numCaches = Integer.parseInt(numCacheStr);
 320             } catch (NumberFormatException e) {
 321                 numCaches = DEFAULT_CACHE_SIZE;
 322             }
 323         } else {
 324             numCaches = DEFAULT_CACHE_SIZE;
 325         }
 326         // System.out.println("number caches=" + numCaches);
 327         PolicyInfo newInfo = new PolicyInfo(numCaches);
 328         initPolicyFile(newInfo, url);
 329         policyInfo = newInfo;
 330     }
 331 
 332     private void initPolicyFile(final PolicyInfo newInfo, final URL url) {
 333 
 334         // always load default.policy



 335         AccessController.doPrivileged(new PrivilegedAction<>() {
 336             @Override
 337             public Void run() {
 338                 initDefaultPolicy(newInfo);
 339                 return null;
 340             }
 341         });
 342 
 343         if (url != null) {
 344 
 345             /**
 346              * If the caller specified a URL via Policy.getInstance,
 347              * we only read from default.policy and that URL.
 348              */
 349 
 350             if (debug != null) {
 351                 debug.println("reading " + url);
 352             }
 353             AccessController.doPrivileged(new PrivilegedAction<>() {
 354                 @Override
 355                 public Void run() {
 356                     if (init(url, newInfo) == false) {
 357                         // use static policy if all else fails
 358                         initStaticPolicy(newInfo);
 359                     }
 360                     return null;
 361                 }
 362             });
 363 
 364         } else {
 365 
 366             /**
 367              * Caller did not specify URL via Policy.getInstance.
 368              * Read from URLs listed in the java.security properties file.
 369              */
 370 
 371             boolean loaded_one = initPolicyFile(POLICY, POLICY_URL, newInfo);
 372             // To maintain strict backward compatibility
 373             // we load the static policy only if POLICY load failed
 374             if (!loaded_one) {
 375                 // use static policy if all else fails
 376                 initStaticPolicy(newInfo);


 392                         boolean overrideAll = false;
 393                         if (extra_policy.startsWith("=")) {
 394                             overrideAll = true;
 395                             extra_policy = extra_policy.substring(1);
 396                         }
 397                         try {
 398                             extra_policy =
 399                                 PropertyExpander.expand(extra_policy);
 400                             URL policyURL;
 401 
 402                             File policyFile = new File(extra_policy);
 403                             if (policyFile.exists()) {
 404                                 policyURL = ParseUtil.fileToEncodedURL
 405                                     (new File(policyFile.getCanonicalPath()));
 406                             } else {
 407                                 policyURL = new URL(extra_policy);
 408                             }
 409                             if (debug != null) {
 410                                 debug.println("reading "+policyURL);
 411                             }
 412                             if (init(policyURL, newInfo)) {
 413                                 loaded_policy = true;
 414                             }
 415                         } catch (Exception e) {
 416                             // ignore.
 417                             if (debug != null) {
 418                                 debug.println("caught exception: "+e);
 419                             }
 420                         }
 421                         if (overrideAll) {
 422                             if (debug != null) {
 423                                 debug.println("overriding other policies!");
 424                             }
 425                             return Boolean.valueOf(loaded_policy);
 426                         }
 427                     }
 428                 }
 429 
 430                 int n = 1;
 431                 String policy_uri;
 432 


 435                         URL policy_url = null;
 436                         String expanded_uri = PropertyExpander.expand
 437                                 (policy_uri).replace(File.separatorChar, '/');
 438 
 439                         if (policy_uri.startsWith("file:${java.home}/") ||
 440                             policy_uri.startsWith("file:${user.home}/")) {
 441 
 442                             // this special case accommodates
 443                             // the situation java.home/user.home
 444                             // expand to a single slash, resulting in
 445                             // a file://foo URI
 446                             policy_url = new File
 447                                 (expanded_uri.substring(5)).toURI().toURL();
 448                         } else {
 449                             policy_url = new URI(expanded_uri).toURL();
 450                         }
 451 
 452                         if (debug != null) {
 453                             debug.println("reading " + policy_url);
 454                         }
 455                         if (init(policy_url, newInfo)) {
 456                             loaded_policy = true;
 457                         }
 458                     } catch (Exception e) {
 459                         if (debug != null) {
 460                             debug.println(
 461                                 "Debug info only. Error reading policy " +e);
 462                             e.printStackTrace();
 463                         }
 464                         // ignore that policy
 465                     }
 466                     n++;
 467                 }
 468                 return Boolean.valueOf(loaded_policy);
 469             }
 470         });
 471 
 472         return loadedPolicy;
 473     }
 474 
 475     private void initDefaultPolicy(PolicyInfo newInfo) {
 476         Path defaultPolicy = Path.of(StaticProperty.javaHome(),
 477                                      "lib",
 478                                      "security",
 479                                      "default.policy");
 480         if (debug != null) {
 481             debug.println("reading " + defaultPolicy);
 482         }
 483         try (BufferedReader br = Files.newBufferedReader(defaultPolicy)) {
 484 
 485             PolicyParser pp = new PolicyParser(expandProperties);
 486             pp.read(br);
 487 
 488             Enumeration<PolicyParser.GrantEntry> enum_ = pp.grantElements();
 489             while (enum_.hasMoreElements()) {
 490                 PolicyParser.GrantEntry ge = enum_.nextElement();
 491                 addGrantEntry(ge, null, newInfo);
 492             }
 493         } catch (Exception e) {
 494             throw new InternalError("Failed to load default.policy", e);
 495         }
 496     }
 497 
 498     /**
 499      * Reads a policy configuration into the Policy object using a
 500      * Reader object.
 501      */
 502     private boolean init(URL policy, PolicyInfo newInfo) {
 503 
 504         // skip parsing policy file if it has been previously parsed and
 505         // has syntax errors
 506         if (badPolicyURLs.contains(policy)) {
 507             if (debug != null) {
 508                 debug.println("skipping bad policy file: " + policy);
 509             }
 510             return false;
 511         }
 512 
 513         try (InputStreamReader isr =
 514                  getInputStreamReader(PolicyUtil.getInputStream(policy))) {
 515 
 516             PolicyParser pp = new PolicyParser(expandProperties);
 517             pp.read(isr);
 518 
 519             KeyStore keyStore = null;
 520             try {
 521                 keyStore = PolicyUtil.getKeyStore
 522                                 (policy,
 523                                 pp.getKeyStoreUrl(),
 524                                 pp.getKeyStoreType(),
 525                                 pp.getKeyStoreProvider(),
 526                                 pp.getStorePassURL(),
 527                                 debug);
 528             } catch (Exception e) {
 529                 // ignore, treat it like we have no keystore
 530                 if (debug != null) {
 531                     debug.println("Debug info only. Ignoring exception.");
 532                     e.printStackTrace();
 533                 }
 534             }
 535 
 536             Enumeration<PolicyParser.GrantEntry> enum_ = pp.grantElements();
 537             while (enum_.hasMoreElements()) {
 538                 PolicyParser.GrantEntry ge = enum_.nextElement();
 539                 addGrantEntry(ge, keyStore, newInfo);
 540             }
 541             return true;
 542         } catch (PolicyParser.ParsingException pe) {



 543             // record bad policy file to avoid later reparsing it
 544             badPolicyURLs.add(policy);
 545             Object[] source = {policy, pe.getNonlocalizedMessage()};
 546             System.err.println(LocalizedMessage.getNonlocalized
 547                 (POLICY + ".error.parsing.policy.message", source));
 548             if (debug != null) {
 549                 pe.printStackTrace();
 550             }
 551         } catch (Exception e) {



 552             if (debug != null) {
 553                 debug.println("error parsing "+policy);
 554                 debug.println(e.toString());
 555                 e.printStackTrace();
 556             }
 557         }
 558 
 559         return false;
 560     }
 561 
 562     private InputStreamReader getInputStreamReader(InputStream is)
 563                               throws IOException {
 564         /*
 565          * Read in policy using UTF-8 by default.
 566          *
 567          * Check non-standard system property to see if the default encoding
 568          * should be used instead.
 569          */
 570         return (notUtf8)
 571             ? new InputStreamReader(is)


< prev index next >