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