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.equalsIgnoreCase(accessAny)) { 233 return null; 234 } 235 236 String protocol; 237 if (systemId.indexOf(":")==-1) { 238 protocol = "file"; 239 } else { 240 URL url = new URL(systemId); 241 protocol = url.getProtocol(); 242 if (protocol.equalsIgnoreCase("jar")) { 243 String path = url.getPath(); 244 protocol = path.substring(0, path.indexOf(":")); 245 } 246 } 247 248 if (isProtocolAllowed(protocol, allowedProtocols)) { 249 //access allowed 250 return null; 251 } else { 252 return protocol; 253 } 254 } 255 256 /** 257 * Check if the protocol is in the allowed list of protocols. The check 258 * is case-insensitive while ignoring whitespaces. 259 * 260 * @param protocol a protocol 261 * @param allowedProtocols a list of allowed protocols 262 * @return true if the protocol is in the list 263 */ 264 private static boolean isProtocolAllowed(String protocol, String allowedProtocols) { 265 String temp[] = allowedProtocols.split(","); 266 for (String t : temp) { 267 t = t.trim(); 268 if (t.equalsIgnoreCase(protocol)) { 269 return true; 270 } 271 } 272 return false; 273 } 274 275 /** 276 * Read from $java.home/lib/jaxp.properties for the specified property 277 * 278 * @param propertyId the Id of the property 279 * @return the value of the property 280 */ 281 public static String getDefaultAccessProperty(String sysPropertyId, String defaultVal) { 282 String accessExternal = SecuritySupport.getSystemProperty(sysPropertyId); 283 if (accessExternal == null) { 284 accessExternal = readJAXPProperty(sysPropertyId); 285 if (accessExternal == null) { 286 accessExternal = defaultVal; 287 } 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 }