src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java
changeset 47312 d4f959806fe9
parent 47311 ff631a3cadbc
child 47313 eb28be8f935d
equal deleted inserted replaced
47311:ff631a3cadbc 47312:d4f959806fe9
     1 /*
       
     2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  */
       
     4 /*
       
     5  * Licensed to the Apache Software Foundation (ASF) under one or more
       
     6  * contributor license agreements.  See the NOTICE file distributed with
       
     7  * this work for additional information regarding copyright ownership.
       
     8  * The ASF licenses this file to You under the Apache License, Version 2.0
       
     9  * (the "License"); you may not use this file except in compliance with
       
    10  * the License.  You may obtain a copy of the License at
       
    11  *
       
    12  *      http://www.apache.org/licenses/LICENSE-2.0
       
    13  *
       
    14  * Unless required by applicable law or agreed to in writing, software
       
    15  * distributed under the License is distributed on an "AS IS" BASIS,
       
    16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    17  * See the License for the specific language governing permissions and
       
    18  * limitations under the License.
       
    19  */
       
    20 
       
    21 package com.sun.org.apache.xalan.internal.utils;
       
    22 
       
    23 import java.io.File;
       
    24 import java.io.FileInputStream;
       
    25 import java.io.FileNotFoundException;
       
    26 import java.io.IOException;
       
    27 import java.io.InputStream;
       
    28 import java.net.URL;
       
    29 
       
    30 import java.security.AccessController;
       
    31 import java.security.PrivilegedAction;
       
    32 import java.security.PrivilegedActionException;
       
    33 import java.security.PrivilegedExceptionAction;
       
    34 import java.util.ListResourceBundle;
       
    35 import java.util.Locale;
       
    36 import java.util.MissingResourceException;
       
    37 import java.util.ResourceBundle;
       
    38 import java.util.Properties;
       
    39 
       
    40 /**
       
    41  * This class is duplicated for each subpackage so keep it in sync. It is
       
    42  * package private and therefore is not exposed as part of any API.
       
    43  *
       
    44  * @xerces.internal
       
    45  */
       
    46 public final class SecuritySupport {
       
    47 
       
    48     private static final SecuritySupport securitySupport = new SecuritySupport();
       
    49 
       
    50     /**
       
    51      * Return an instance of this class.
       
    52      */
       
    53     public static SecuritySupport getInstance() {
       
    54         return securitySupport;
       
    55     }
       
    56 
       
    57     public static ClassLoader getContextClassLoader() {
       
    58         return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
       
    59             public Object run() {
       
    60                 ClassLoader cl = null;
       
    61                 try {
       
    62                     cl = Thread.currentThread().getContextClassLoader();
       
    63                 } catch (SecurityException ex) {
       
    64                 }
       
    65                 return cl;
       
    66             }
       
    67         });
       
    68     }
       
    69 
       
    70     static ClassLoader getSystemClassLoader() {
       
    71         return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
       
    72             public Object run() {
       
    73                 ClassLoader cl = null;
       
    74                 try {
       
    75                     cl = ClassLoader.getSystemClassLoader();
       
    76                 } catch (SecurityException ex) {
       
    77                 }
       
    78                 return cl;
       
    79             }
       
    80         });
       
    81     }
       
    82 
       
    83     static ClassLoader getParentClassLoader(final ClassLoader cl) {
       
    84         return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
       
    85             public Object run() {
       
    86                 ClassLoader parent = null;
       
    87                 try {
       
    88                     parent = cl.getParent();
       
    89                 } catch (SecurityException ex) {
       
    90                 }
       
    91 
       
    92                 // eliminate loops in case of the boot
       
    93                 // ClassLoader returning itself as a parent
       
    94                 return (parent == cl) ? null : parent;
       
    95             }
       
    96         });
       
    97     }
       
    98 
       
    99     public static String getSystemProperty(final String propName) {
       
   100         return (String) AccessController.doPrivileged(new PrivilegedAction() {
       
   101             public Object run() {
       
   102                 return System.getProperty(propName);
       
   103             }
       
   104         });
       
   105     }
       
   106 
       
   107     public static String getSystemProperty(final String propName, final String def) {
       
   108         return (String) AccessController.doPrivileged(new PrivilegedAction() {
       
   109             public Object run() {
       
   110                 return System.getProperty(propName, def);
       
   111             }
       
   112         });
       
   113     }
       
   114 
       
   115     static FileInputStream getFileInputStream(final File file)
       
   116             throws FileNotFoundException {
       
   117         try {
       
   118             return (FileInputStream) AccessController.doPrivileged(new PrivilegedExceptionAction() {
       
   119                 public Object run() throws FileNotFoundException {
       
   120                     return new FileInputStream(file);
       
   121                 }
       
   122             });
       
   123         } catch (PrivilegedActionException e) {
       
   124             throw (FileNotFoundException)e.getException();
       
   125         }
       
   126     }
       
   127 
       
   128     public static InputStream getResourceAsStream(final String name) {
       
   129         return (InputStream) AccessController.doPrivileged(new PrivilegedAction() {
       
   130             public Object run() {
       
   131                 return SecuritySupport.class.getResourceAsStream("/"+name);
       
   132             }
       
   133         });
       
   134     }
       
   135 
       
   136     /**
       
   137      * Gets a resource bundle using the specified base name, the default locale, and the caller's class loader.
       
   138      * @param bundle the base name of the resource bundle, a fully qualified class name
       
   139      * @return a resource bundle for the given base name and the default locale
       
   140      */
       
   141     public static ListResourceBundle getResourceBundle(String bundle) {
       
   142         return getResourceBundle(bundle, Locale.getDefault());
       
   143     }
       
   144 
       
   145     /**
       
   146      * Gets a resource bundle using the specified base name and locale, and the caller's class loader.
       
   147      * @param bundle the base name of the resource bundle, a fully qualified class name
       
   148      * @param locale the locale for which a resource bundle is desired
       
   149      * @return a resource bundle for the given base name and locale
       
   150      */
       
   151     public static ListResourceBundle getResourceBundle(final String bundle, final Locale locale) {
       
   152         return AccessController.doPrivileged(new PrivilegedAction<ListResourceBundle>() {
       
   153             public ListResourceBundle run() {
       
   154                 try {
       
   155                     return (ListResourceBundle)ResourceBundle.getBundle(bundle, locale);
       
   156                 } catch (MissingResourceException e) {
       
   157                     try {
       
   158                         return (ListResourceBundle)ResourceBundle.getBundle(bundle, new Locale("en", "US"));
       
   159                     } catch (MissingResourceException e2) {
       
   160                         throw new MissingResourceException(
       
   161                                 "Could not load any resource bundle by " + bundle, bundle, "");
       
   162                     }
       
   163                 }
       
   164             }
       
   165         });
       
   166     }
       
   167 
       
   168     public static boolean getFileExists(final File f) {
       
   169         return ((Boolean) AccessController.doPrivileged(new PrivilegedAction() {
       
   170                     public Object run() {
       
   171                         return f.exists() ? Boolean.TRUE : Boolean.FALSE;
       
   172                     }
       
   173                 })).booleanValue();
       
   174     }
       
   175 
       
   176     static long getLastModified(final File f) {
       
   177         return ((Long) AccessController.doPrivileged(new PrivilegedAction() {
       
   178                     public Object run() {
       
   179                         return f.lastModified();
       
   180                     }
       
   181                 })).longValue();
       
   182     }
       
   183 
       
   184     /**
       
   185      * Strip off path from an URI
       
   186      *
       
   187      * @param uri an URI with full path
       
   188      * @return the file name only
       
   189      */
       
   190     public static String sanitizePath(String uri) {
       
   191         if (uri == null) {
       
   192             return "";
       
   193         }
       
   194         int i = uri.lastIndexOf("/");
       
   195         if (i > 0) {
       
   196             return uri.substring(i+1, uri.length());
       
   197         }
       
   198         return "";
       
   199     }
       
   200 
       
   201     /**
       
   202      * Check the protocol used in the systemId against allowed protocols
       
   203      *
       
   204      * @param systemId the Id of the URI
       
   205      * @param allowedProtocols a list of allowed protocols separated by comma
       
   206      * @param accessAny keyword to indicate allowing any protocol
       
   207      * @return the name of the protocol if rejected, null otherwise
       
   208      */
       
   209     public static String checkAccess(String systemId, String allowedProtocols, String accessAny) throws IOException {
       
   210         if (systemId == null || (allowedProtocols != null &&
       
   211                 allowedProtocols.equalsIgnoreCase(accessAny))) {
       
   212             return null;
       
   213         }
       
   214 
       
   215         String protocol;
       
   216         if (systemId.indexOf(":")==-1) {
       
   217             protocol = "file";
       
   218         } else {
       
   219             URL url = new URL(systemId);
       
   220             protocol = url.getProtocol();
       
   221             if (protocol.equalsIgnoreCase("jar")) {
       
   222                 String path = url.getPath();
       
   223                 protocol = path.substring(0, path.indexOf(":"));
       
   224             } else if (protocol.equalsIgnoreCase("jrt")) {
       
   225                 // if the systemId is "jrt" then allow access if "file" allowed
       
   226                 protocol = "file";
       
   227             }
       
   228         }
       
   229 
       
   230         if (isProtocolAllowed(protocol, allowedProtocols)) {
       
   231             //access allowed
       
   232             return null;
       
   233         } else {
       
   234             return protocol;
       
   235         }
       
   236     }
       
   237 
       
   238     /**
       
   239      * Check if the protocol is in the allowed list of protocols. The check
       
   240      * is case-insensitive while ignoring whitespaces.
       
   241      *
       
   242      * @param protocol a protocol
       
   243      * @param allowedProtocols a list of allowed protocols
       
   244      * @return true if the protocol is in the list
       
   245      */
       
   246     private static boolean isProtocolAllowed(String protocol, String allowedProtocols) {
       
   247          if (allowedProtocols == null) {
       
   248              return false;
       
   249          }
       
   250          String temp[] = allowedProtocols.split(",");
       
   251          for (String t : temp) {
       
   252              t = t.trim();
       
   253              if (t.equalsIgnoreCase(protocol)) {
       
   254                  return true;
       
   255              }
       
   256          }
       
   257          return false;
       
   258      }
       
   259 
       
   260     /**
       
   261      * Read JAXP system property in this order: system property,
       
   262      * $java.home/conf/jaxp.properties if the system property is not specified
       
   263      *
       
   264      * @param propertyId the Id of the property
       
   265      * @return the value of the property
       
   266      */
       
   267     public static String getJAXPSystemProperty(String sysPropertyId) {
       
   268         String accessExternal = getSystemProperty(sysPropertyId);
       
   269         if (accessExternal == null) {
       
   270             accessExternal = readJAXPProperty(sysPropertyId);
       
   271         }
       
   272         return accessExternal;
       
   273     }
       
   274 
       
   275     /**
       
   276      * Read from $java.home/conf/jaxp.properties for the specified property
       
   277      * The program
       
   278      *
       
   279      * @param propertyId the Id of the property
       
   280      * @return the value of the property
       
   281      */
       
   282     static String readJAXPProperty(String propertyId) {
       
   283         String value = null;
       
   284         InputStream is = null;
       
   285         try {
       
   286             if (firstTime) {
       
   287                 synchronized (cacheProps) {
       
   288                     if (firstTime) {
       
   289                         String configFile = getSystemProperty("java.home") + File.separator +
       
   290                             "conf" + File.separator + "jaxp.properties";
       
   291                         File f = new File(configFile);
       
   292                         if (getFileExists(f)) {
       
   293                             is = getFileInputStream(f);
       
   294                             cacheProps.load(is);
       
   295                         }
       
   296                         firstTime = false;
       
   297                     }
       
   298                 }
       
   299             }
       
   300             value = cacheProps.getProperty(propertyId);
       
   301 
       
   302         }
       
   303         catch (Exception ex) {}
       
   304         finally {
       
   305             if (is != null) {
       
   306                 try {
       
   307                     is.close();
       
   308                 } catch (IOException ex) {}
       
   309             }
       
   310         }
       
   311 
       
   312         return value;
       
   313     }
       
   314 
       
   315     /**
       
   316      * Cache for properties in java.home/conf/jaxp.properties
       
   317      */
       
   318     static final Properties cacheProps = new Properties();
       
   319 
       
   320     /**
       
   321      * Flag indicating if the program has tried reading java.home/conf/jaxp.properties
       
   322      */
       
   323     static volatile boolean firstTime = true;
       
   324 
       
   325     private SecuritySupport () {}
       
   326 }