# HG changeset patch # User Greg Lewis # Date 1504852632 25200 # Node ID 4626d69ba2c7be777c4e42a07e8ed9388c768dff # Parent 43826bfc7e68338c05879ef6d4bd525755006888# Parent 7a9a6ffac242ea18807df2c5cd47e335d769c87d Merge from main OpenJDK repository diff -r 43826bfc7e68 -r 4626d69ba2c7 .hgtags --- a/.hgtags Sun May 28 21:31:37 2017 -0700 +++ b/.hgtags Thu Sep 07 23:37:12 2017 -0700 @@ -614,3 +614,5 @@ 90c86962aa2e81ecd8d5d79a282f2492447e4c6e jdk7u141-b00 506e24eee4e1887fbfdd77512f830b75e14c5759 jdk7u141-b01 1af82a2d3d16626b8d2f5e633d23c027975406b8 jdk7u141-b02 +1f0dd7a7e0ccaa340db533da400bb83ca1ad3cf2 jdk7u151-b00 +3233576db658552e8933b1cd86f5586507564f44 jdk7u151-b01 diff -r 43826bfc7e68 -r 4626d69ba2c7 src/share/jaxws_classes/com/sun/tools/internal/ws/wscompile/Options.java --- a/src/share/jaxws_classes/com/sun/tools/internal/ws/wscompile/Options.java Sun May 28 21:31:37 2017 -0700 +++ b/src/share/jaxws_classes/com/sun/tools/internal/ws/wscompile/Options.java Thu Sep 07 23:37:12 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,6 +79,15 @@ */ public boolean nocompile; + /** + * If true XML security features when parsing XML documents will be disabled. + * The default value is false. + * + * Boolean + * @since 2.2.9 + */ + public boolean disableXmlSecurity; + public enum Target { V2_0, V2_1, V2_2; @@ -310,6 +319,9 @@ throw new BadCommandLineException(WscompileMessages.WSCOMPILE_NO_SUCH_DIRECTORY(sourceDir.getPath())); } return 2; + } else if (args[i].equals("-disableXmlSecurity")) { + disableXmlSecurity(); + return 1; } else if (args[i].equals("-extension")) { compatibilityMode = EXTENSION; return 1; @@ -326,6 +338,11 @@ return 0; } + // protected method to allow overriding + protected void disableXmlSecurity() { + disableXmlSecurity= true; + } + /** * Obtains an operand and reports an error if it's not there. */ diff -r 43826bfc7e68 -r 4626d69ba2c7 src/share/jaxws_classes/com/sun/tools/internal/ws/wscompile/WsimportOptions.java --- a/src/share/jaxws_classes/com/sun/tools/internal/ws/wscompile/WsimportOptions.java Sun May 28 21:31:37 2017 -0700 +++ b/src/share/jaxws_classes/com/sun/tools/internal/ws/wscompile/WsimportOptions.java Thu Sep 07 23:37:12 2017 -0700 @@ -445,4 +445,10 @@ } } } + + @Override + protected void disableXmlSecurity() { + super.disableXmlSecurity(); + schemaCompiler.getOptions().disableXmlSecurity = true; + } } diff -r 43826bfc7e68 -r 4626d69ba2c7 src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/DOMForest.java --- a/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/DOMForest.java Sun May 28 21:31:37 2017 -0700 +++ b/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/DOMForest.java Thu Sep 07 23:37:12 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,15 +26,12 @@ package com.sun.tools.internal.ws.wsdl.parser; import com.sun.istack.internal.NotNull; -import com.sun.tools.internal.ws.resources.WscompileMessages; -import com.sun.tools.internal.ws.wscompile.AbortException; -import com.sun.tools.internal.ws.wscompile.DefaultAuthenticator; +import com.sun.tools.internal.ws.util.xml.XmlUtil; import com.sun.tools.internal.ws.wscompile.ErrorReceiver; import com.sun.tools.internal.ws.wscompile.WsimportOptions; import com.sun.tools.internal.ws.wsdl.document.schema.SchemaConstants; import com.sun.tools.internal.xjc.reader.internalizer.LocatorTable; import com.sun.xml.internal.bind.marshaller.DataWriter; -import com.sun.xml.internal.ws.util.JAXWSUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; @@ -51,9 +48,6 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXResult; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLSession; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -118,13 +112,13 @@ this.entityResolver = entityResolver; this.errorReceiver = errReceiver; this.logic = logic; + // secure xml processing can be switched off if input requires it + boolean disableXmlSecurity = options == null ? false : options.disableXmlSecurity; + + DocumentBuilderFactory dbf = XmlUtil.newDocumentBuilderFactory(disableXmlSecurity); + this.parserFactory = XmlUtil.newSAXParserFactory(disableXmlSecurity); try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); this.documentBuilder = dbf.newDocumentBuilder(); - - this.parserFactory = SAXParserFactory.newInstance(); - this.parserFactory.setNamespaceAware(true); } catch (ParserConfigurationException e) { throw new AssertionError(e); } @@ -368,7 +362,10 @@ public void dump(OutputStream out) throws IOException { try { // create identity transformer - Transformer it = TransformerFactory.newInstance().newTransformer(); + // secure xml processing can be switched off if input requires it + boolean secureProcessingEnabled = options == null || !options.disableXmlSecurity; + TransformerFactory tf = XmlUtil.newTransformerFactory(secureProcessingEnabled); + Transformer it = tf.newTransformer(); for (Map.Entry e : core.entrySet()) { out.write(("---<< " + e.getKey() + '\n').getBytes()); diff -r 43826bfc7e68 -r 4626d69ba2c7 src/share/jaxws_classes/com/sun/tools/internal/xjc/Options.java --- a/src/share/jaxws_classes/com/sun/tools/internal/xjc/Options.java Sun May 28 21:31:37 2017 -0700 +++ b/src/share/jaxws_classes/com/sun/tools/internal/xjc/Options.java Thu Sep 07 23:37:12 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,6 +104,15 @@ public String encoding; /** + * If true XML security features when parsing XML documents will be disabled. + * The default value is false. + * + * Boolean + * @since 2.2.6 + */ + public boolean disableXmlSecurity; + + /** * Check the source schemas with extra scrutiny. * The exact meaning depends on the schema language. */ @@ -540,6 +549,10 @@ enableIntrospection = true; return 1; } + if (args[i].equals("-disableXmlSecurity")) { + disableXmlSecurity = true; + return 1; + } if (args[i].equals("-contentForWildcard")) { contentForWildcard = true; return 1; diff -r 43826bfc7e68 -r 4626d69ba2c7 src/share/jaxws_classes/com/sun/xml/internal/ws/util/DOMUtil.java --- a/src/share/jaxws_classes/com/sun/xml/internal/ws/util/DOMUtil.java Sun May 28 21:31:37 2017 -0700 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/util/DOMUtil.java Thu Sep 07 23:37:12 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,29 +25,27 @@ package com.sun.xml.internal.ws.util; -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Element; -import org.xml.sax.SAXException; +import com.sun.istack.internal.NotNull; +import com.sun.istack.internal.Nullable; +import com.sun.xml.internal.ws.util.xml.XmlUtil; +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import javax.xml.XMLConstants; -import javax.xml.namespace.NamespaceContext; -import java.io.IOException; -import java.io.InputStream; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.ArrayList; -import com.sun.istack.internal.NotNull; -import com.sun.istack.internal.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** * @author: JAXWS Development Team @@ -63,8 +61,7 @@ synchronized (DOMUtil.class) { if (db == null) { try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); + DocumentBuilderFactory dbf = XmlUtil.newDocumentBuilderFactory(); db = dbf.newDocumentBuilder(); } catch (ParserConfigurationException e) { throw new FactoryConfigurationError(e); @@ -74,28 +71,6 @@ } } - public static Node createDOMNode(InputStream inputStream) { - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(false); - try { - DocumentBuilder builder = dbf.newDocumentBuilder(); - try { - return builder.parse(inputStream); - } catch (SAXException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } catch (IOException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } catch (ParserConfigurationException pce) { - IllegalArgumentException iae = new IllegalArgumentException(pce.getMessage()); - iae.initCause(pce); - throw iae; - } - return null; - } - /** * Traverses a DOM node and writes out on a streaming writer. * @@ -112,6 +87,7 @@ switch (child.getNodeType()) { case Node.PROCESSING_INSTRUCTION_NODE: writer.writeProcessingInstruction(child.getNodeValue()); + break; case Node.DOCUMENT_TYPE_NODE: break; case Node.CDATA_SECTION_NODE: @@ -126,6 +102,7 @@ case Node.ELEMENT_NODE: serializeNode((Element) child, writer); break; + default: break; } } } @@ -222,8 +199,9 @@ for (Node n = e.getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeType() == Node.ELEMENT_NODE) { Element c = (Element) n; - if (c.getLocalName().equals(local) && c.getNamespaceURI().equals(nsUri)) + if (c.getLocalName().equals(local) && c.getNamespaceURI().equals(nsUri)) { return c; + } } } return null; @@ -232,8 +210,11 @@ private static @NotNull String fixNull(@Nullable String s) { - if (s == null) return ""; - else return s; + if (s == null) { + return ""; + } else { + return s; + } } /** diff -r 43826bfc7e68 -r 4626d69ba2c7 src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java --- a/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java Sun May 28 21:31:37 2017 -0700 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java Thu Sep 07 23:37:12 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,13 +40,18 @@ import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.InputSource; +import javax.xml.XMLConstants; import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; +import javax.xml.stream.XMLInputFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; @@ -57,16 +62,22 @@ import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamSource; import javax.xml.ws.WebServiceException; +import javax.xml.xpath.XPathFactory; +import javax.xml.xpath.XPathFactoryConfigurationException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.logging.Logger; /** * @author WS Development Team @@ -75,6 +86,27 @@ private final static String LEXICAL_HANDLER_PROPERTY = "http://xml.org/sax/properties/lexical-handler"; + private static final String DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl"; + + private static final String EXTERNAL_GE = "http://xml.org/sax/features/external-general-entities"; + + private static final String EXTERNAL_PE = "http://xml.org/sax/features/external-parameter-entities"; + + private static final String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; + + private static final Logger LOGGER = Logger.getLogger(XmlUtil.class.getName()); + + private static final String DISABLE_XML_SECURITY = "com.sun.xml.internal.ws.disableXmlSecurity"; + + private static boolean XML_SECURITY_DISABLED = AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Boolean run() { + return Boolean.getBoolean(DISABLE_XML_SECURITY); + } + } + ); + public static String getPrefix(String s) { int i = s.indexOf(':'); if (i == -1) @@ -163,7 +195,7 @@ } public static String getTextForNode(Node node) { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); NodeList children = node.getChildNodes(); if (children.getLength() == 0) @@ -334,15 +366,108 @@ * {@link ErrorHandler} that always treat the error as fatal. */ public static final ErrorHandler DRACONIAN_ERROR_HANDLER = new ErrorHandler() { + @Override public void warning(SAXParseException exception) { } + @Override public void error(SAXParseException exception) throws SAXException { throw exception; } + @Override public void fatalError(SAXParseException exception) throws SAXException { throw exception; } }; + + public static DocumentBuilderFactory newDocumentBuilderFactory() { + return newDocumentBuilderFactory(false); + } + + public static DocumentBuilderFactory newDocumentBuilderFactory(boolean disableSecurity) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING; + try { + boolean securityOn = !isXMLSecurityDisabled(disableSecurity); + factory.setFeature(featureToSet, securityOn); + factory.setNamespaceAware(true); + if (securityOn) { + factory.setExpandEntityReferences(false); + featureToSet = DISALLOW_DOCTYPE_DECL; + factory.setFeature(featureToSet, true); + featureToSet = EXTERNAL_GE; + factory.setFeature(featureToSet, false); + featureToSet = EXTERNAL_PE; + factory.setFeature(featureToSet, false); + featureToSet = LOAD_EXTERNAL_DTD; + factory.setFeature(featureToSet, false); + } + } catch (ParserConfigurationException e) { + LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[] {factory.getClass().getName()} ); + } + return factory; + } + + public static TransformerFactory newTransformerFactory(boolean secureXmlProcessingEnabled) { + TransformerFactory factory = TransformerFactory.newInstance(); + try { + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, isXMLSecurityDisabled(secureXmlProcessingEnabled)); + } catch (TransformerConfigurationException e) { + LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[]{factory.getClass().getName()}); + } + return factory; + } + + public static TransformerFactory newTransformerFactory() { + return newTransformerFactory(true); + } + + public static SAXParserFactory newSAXParserFactory(boolean disableSecurity) { + SAXParserFactory factory = SAXParserFactory.newInstance(); + String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING; + try { + boolean securityOn = !isXMLSecurityDisabled(disableSecurity); + factory.setFeature(featureToSet, securityOn); + factory.setNamespaceAware(true); + if (securityOn) { + featureToSet = DISALLOW_DOCTYPE_DECL; + factory.setFeature(featureToSet, true); + featureToSet = EXTERNAL_GE; + factory.setFeature(featureToSet, false); + featureToSet = EXTERNAL_PE; + factory.setFeature(featureToSet, false); + featureToSet = LOAD_EXTERNAL_DTD; + factory.setFeature(featureToSet, false); + } + } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { + LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[]{factory.getClass().getName()}); + } + return factory; + } + + public static XPathFactory newXPathFactory(boolean secureXmlProcessingEnabled) { + XPathFactory factory = XPathFactory.newInstance(); + try { + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, isXMLSecurityDisabled(secureXmlProcessingEnabled)); + } catch (XPathFactoryConfigurationException e) { + LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[] { factory.getClass().getName() } ); + } + return factory; + } + + public static XMLInputFactory newXMLInputFactory(boolean secureXmlProcessingEnabled) { + XMLInputFactory factory = XMLInputFactory.newInstance(); + if (isXMLSecurityDisabled(secureXmlProcessingEnabled)) { + // TODO-Miran: are those apppropriate defaults? + factory.setProperty(XMLInputFactory.SUPPORT_DTD, false); + factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); + } + return factory; + } + + private static boolean isXMLSecurityDisabled(boolean runtimeDisabled) { + return XML_SECURITY_DISABLED || runtimeDisabled; + } + }