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