24 package com.sun.org.apache.xalan.internal.utils; |
24 package com.sun.org.apache.xalan.internal.utils; |
25 |
25 |
26 import java.io.File; |
26 import java.io.File; |
27 import java.io.FileInputStream; |
27 import java.io.FileInputStream; |
28 import java.io.FileNotFoundException; |
28 import java.io.FileNotFoundException; |
|
29 import java.io.IOException; |
29 import java.io.InputStream; |
30 import java.io.InputStream; |
|
31 import java.net.URL; |
30 |
32 |
31 import java.security.AccessController; |
33 import java.security.AccessController; |
32 import java.security.PrivilegedAction; |
34 import java.security.PrivilegedAction; |
33 import java.security.PrivilegedActionException; |
35 import java.security.PrivilegedActionException; |
34 import java.security.PrivilegedExceptionAction; |
36 import java.security.PrivilegedExceptionAction; |
35 import java.util.ListResourceBundle; |
37 import java.util.ListResourceBundle; |
36 import java.util.Locale; |
38 import java.util.Locale; |
37 import java.util.MissingResourceException; |
39 import java.util.MissingResourceException; |
38 import java.util.ResourceBundle; |
40 import java.util.ResourceBundle; |
|
41 import java.util.Properties; |
39 |
42 |
40 /** |
43 /** |
41 * This class is duplicated for each subpackage so keep it in sync. It is |
44 * 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. |
45 * package private and therefore is not exposed as part of any API. |
43 * |
46 * |
198 return new Long(f.lastModified()); |
201 return new Long(f.lastModified()); |
199 } |
202 } |
200 })).longValue(); |
203 })).longValue(); |
201 } |
204 } |
202 |
205 |
203 |
206 /** |
204 private SecuritySupport() { |
207 * Strip off path from an URI |
205 } |
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 () {} |
206 } |
343 } |