82 private final static String LEXICAL_HANDLER_PROPERTY = |
82 private final static String LEXICAL_HANDLER_PROPERTY = |
83 "http://xml.org/sax/properties/lexical-handler"; |
83 "http://xml.org/sax/properties/lexical-handler"; |
84 |
84 |
85 private static final Logger LOGGER = Logger.getLogger(XmlUtil.class.getName()); |
85 private static final Logger LOGGER = Logger.getLogger(XmlUtil.class.getName()); |
86 |
86 |
87 private static boolean globalSecureXmlProcessingEnabled; |
87 private static boolean XML_SECURITY_DISABLED; |
88 |
88 |
89 static { |
89 static { |
90 String disableSecureXmlProcessing = System.getProperty("disableSecureXmlProcessing"); |
90 String disableXmlSecurity = System.getProperty("com.sun.xml.internal.ws.disableXmlSecurity"); |
91 globalSecureXmlProcessingEnabled = disableSecureXmlProcessing == null || !Boolean.valueOf(disableSecureXmlProcessing); |
91 XML_SECURITY_DISABLED = disableXmlSecurity == null || !Boolean.valueOf(disableXmlSecurity); |
92 } |
92 } |
93 |
93 |
94 public static String getPrefix(String s) { |
94 public static String getPrefix(String s) { |
95 int i = s.indexOf(':'); |
95 int i = s.indexOf(':'); |
96 if (i == -1) |
96 if (i == -1) |
362 } |
362 } |
363 |
363 |
364 public static DocumentBuilderFactory newDocumentBuilderFactory(boolean secureXmlProcessing) { |
364 public static DocumentBuilderFactory newDocumentBuilderFactory(boolean secureXmlProcessing) { |
365 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
365 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
366 try { |
366 try { |
367 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, checkGlobalOverride(secureXmlProcessing)); |
367 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, isXMLSecurityDisabled(secureXmlProcessing)); |
368 } catch (ParserConfigurationException e) { |
368 } catch (ParserConfigurationException e) { |
369 LOGGER.log(Level.WARNING, "Factory [{}] doesn't support secure xml processing!", new Object[] { factory.getClass().getName() } ); |
369 LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[] { factory.getClass().getName() } ); |
370 } |
370 } |
371 return factory; |
371 return factory; |
372 } |
372 } |
373 |
373 |
374 public static TransformerFactory newTransformerFactory(boolean secureXmlProcessingEnabled) { |
374 public static TransformerFactory newTransformerFactory(boolean secureXmlProcessingEnabled) { |
375 TransformerFactory factory = TransformerFactory.newInstance(); |
375 TransformerFactory factory = TransformerFactory.newInstance(); |
376 try { |
376 try { |
377 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, checkGlobalOverride(secureXmlProcessingEnabled)); |
377 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, isXMLSecurityDisabled(secureXmlProcessingEnabled)); |
378 } catch (TransformerConfigurationException e) { |
378 } catch (TransformerConfigurationException e) { |
379 LOGGER.log(Level.WARNING, "Factory [{}] doesn't support secure xml processing!", new Object[]{factory.getClass().getName()}); |
379 LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[]{factory.getClass().getName()}); |
380 } |
380 } |
381 return factory; |
381 return factory; |
382 } |
382 } |
383 |
383 |
384 public static TransformerFactory newTransformerFactory() { |
384 public static TransformerFactory newTransformerFactory() { |
386 } |
386 } |
387 |
387 |
388 public static SAXParserFactory newSAXParserFactory(boolean secureXmlProcessingEnabled) { |
388 public static SAXParserFactory newSAXParserFactory(boolean secureXmlProcessingEnabled) { |
389 SAXParserFactory factory = SAXParserFactory.newInstance(); |
389 SAXParserFactory factory = SAXParserFactory.newInstance(); |
390 try { |
390 try { |
391 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, checkGlobalOverride(secureXmlProcessingEnabled)); |
391 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, isXMLSecurityDisabled(secureXmlProcessingEnabled)); |
392 } catch (Exception e) { |
392 } catch (Exception e) { |
393 LOGGER.log(Level.WARNING, "Factory [{}] doesn't support secure xml processing!", new Object[]{factory.getClass().getName()}); |
393 LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[]{factory.getClass().getName()}); |
394 } |
394 } |
395 return factory; |
395 return factory; |
396 } |
396 } |
397 |
397 |
398 public static XPathFactory newXPathFactory(boolean secureXmlProcessingEnabled) { |
398 public static XPathFactory newXPathFactory(boolean secureXmlProcessingEnabled) { |
399 XPathFactory factory = XPathFactory.newInstance(); |
399 XPathFactory factory = XPathFactory.newInstance(); |
400 try { |
400 try { |
401 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, checkGlobalOverride(secureXmlProcessingEnabled)); |
401 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, isXMLSecurityDisabled(secureXmlProcessingEnabled)); |
402 } catch (XPathFactoryConfigurationException e) { |
402 } catch (XPathFactoryConfigurationException e) { |
403 LOGGER.log(Level.WARNING, "Factory [{}] doesn't support secure xml processing!", new Object[] { factory.getClass().getName() } ); |
403 LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[] { factory.getClass().getName() } ); |
404 } |
404 } |
405 return factory; |
405 return factory; |
406 } |
406 } |
407 |
407 |
408 public static XMLInputFactory newXMLInputFactory(boolean secureXmlProcessingEnabled) { |
408 public static XMLInputFactory newXMLInputFactory(boolean secureXmlProcessingEnabled) { |
409 XMLInputFactory factory = XMLInputFactory.newInstance(); |
409 XMLInputFactory factory = XMLInputFactory.newInstance(); |
410 if (checkGlobalOverride(secureXmlProcessingEnabled)) { |
410 if (isXMLSecurityDisabled(secureXmlProcessingEnabled)) { |
411 // TODO-Miran: are those apppropriate defaults? |
411 // TODO-Miran: are those apppropriate defaults? |
412 factory.setProperty(XMLInputFactory.SUPPORT_DTD, false); |
412 factory.setProperty(XMLInputFactory.SUPPORT_DTD, false); |
413 factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); |
413 factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); |
414 } |
414 } |
415 return factory; |
415 return factory; |
416 } |
416 } |
417 |
417 |
418 private static boolean checkGlobalOverride(boolean localSecureXmlProcessingEnabled) { |
418 private static boolean isXMLSecurityDisabled(boolean runtimeDisabled) { |
419 return globalSecureXmlProcessingEnabled && localSecureXmlProcessingEnabled; |
419 return XML_SECURITY_DISABLED || runtimeDisabled; |
420 } |
420 } |
421 |
421 |
422 public static SchemaFactory allowFileAccess(SchemaFactory sf, boolean disableSecureProcessing) { |
422 public static SchemaFactory allowExternalAccess(SchemaFactory sf, String value, boolean disableSecureProcessing) { |
423 |
423 |
424 // if feature secure processing enabled, nothing to do, file is allowed, |
424 // if xml security (feature secure processing) disabled, nothing to do, no restrictions applied |
425 // or user is able to control access by standard JAXP mechanisms |
425 if (isXMLSecurityDisabled(disableSecureProcessing)) { |
426 if (checkGlobalOverride(disableSecureProcessing)) { |
426 if (LOGGER.isLoggable(Level.FINE)) { |
|
427 LOGGER.log(Level.FINE, "Xml Security disabled, no JAXP xsd external access configuration necessary."); |
|
428 } |
427 return sf; |
429 return sf; |
428 } |
430 } |
429 |
431 |
430 try { |
432 if (System.getProperty("javax.xml.accessExternalSchema") != null) { |
431 sf.setProperty(ACCESS_EXTERNAL_SCHEMA, "file"); |
433 if (LOGGER.isLoggable(Level.FINE)) { |
432 LOGGER.log(Level.FINE, "Property \"{}\" is supported and has been successfully set by used JAXP implementation.", new Object[]{ACCESS_EXTERNAL_SCHEMA}); |
434 LOGGER.log(Level.FINE, "Detected explicitly JAXP configuration, no JAXP xsd external access configuration necessary."); |
|
435 } |
|
436 return sf; |
|
437 } |
|
438 |
|
439 try { |
|
440 sf.setProperty(ACCESS_EXTERNAL_SCHEMA, value); |
|
441 if (LOGGER.isLoggable(Level.FINE)) { |
|
442 LOGGER.log(Level.FINE, "Property \"{0}\" is supported and has been successfully set by used JAXP implementation.", new Object[]{ACCESS_EXTERNAL_SCHEMA}); |
|
443 } |
433 } catch (SAXException ignored) { |
444 } catch (SAXException ignored) { |
434 // depending on JDK/SAX implementation used |
445 // nothing to do; support depends on version JDK or SAX implementation |
435 LOGGER.log(Level.CONFIG, "Property \"{}\" is not supported by used JAXP implementation.", new Object[]{ACCESS_EXTERNAL_SCHEMA}); |
446 if (LOGGER.isLoggable(Level.CONFIG)) { |
|
447 LOGGER.log(Level.CONFIG, "Property \"{0}\" is not supported by used JAXP implementation.", new Object[]{ACCESS_EXTERNAL_SCHEMA}); |
|
448 } |
436 } |
449 } |
437 return sf; |
450 return sf; |
438 } |
451 } |
|
452 |
439 } |
453 } |