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