From 00c6a153edd9251605e5e71aa24adc0f8ac8a065 Mon Sep 17 00:00:00 2001 From: Ondrej Dubaj Date: Tue, 28 Jul 2020 14:56:48 +0200 Subject: [PATCH 1/5] Fixed XXE vulnerability (CVE-2020-13692) --- fix-XXE-vulnerability.patch | 715 ++++++++++++++++++++++++++++++++++++ postgresql-jdbc.spec | 8 +- 2 files changed, 722 insertions(+), 1 deletion(-) create mode 100644 fix-XXE-vulnerability.patch diff --git a/fix-XXE-vulnerability.patch b/fix-XXE-vulnerability.patch new file mode 100644 index 0000000..4b12fc2 --- /dev/null +++ b/fix-XXE-vulnerability.patch @@ -0,0 +1,715 @@ +From 0bbff72847caabbc3a7dd897a848c5bf460f4999 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Tue, 28 Jul 2020 14:52:25 +0200 +Subject: [PATCH] Fix for XXE vulnerability + +by defaulting to disabling external access and doc types. The +legacy insecure behavior can be restored via the new connection property xmlFactoryFactory +with a value of LEGACY_INSECURE. Alternatively, a custom class name can be specified that +implements org.postgresql.xml.PGXmlFactoryFactory and takes a no argument constructor. + +* refactor: Clean up whitespace in existing PgSQLXMLTest +* fix: Fix XXE vulnerability in PgSQLXML by disabling external access and doctypes +* fix: Add missing getter and setter for XML_FACTORY_FACTORY to BasicDataSource +--- + .../main/java/org/postgresql/PGProperty.java | 11 ++ + .../org/postgresql/core/BaseConnection.java | 9 ++ + .../postgresql/ds/common/BaseDataSource.java | 8 + + .../org/postgresql/jdbc/PgConnection.java | 40 +++++ + .../java/org/postgresql/jdbc/PgSQLXML.java | 43 +++--- + .../xml/DefaultPGXmlFactoryFactory.java | 140 ++++++++++++++++++ + .../xml/EmptyStringEntityResolver.java | 23 +++ + .../LegacyInsecurePGXmlFactoryFactory.java | 57 +++++++ + .../org/postgresql/xml/NullErrorHandler.java | 25 ++++ + .../postgresql/xml/PGXmlFactoryFactory.java | 30 ++++ + .../org/postgresql/jdbc/PgSQLXMLTest.java | 80 +++++++++- + 11 files changed, 437 insertions(+), 29 deletions(-) + create mode 100644 pgjdbc/src/main/java/org/postgresql/xml/DefaultPGXmlFactoryFactory.java + create mode 100644 pgjdbc/src/main/java/org/postgresql/xml/EmptyStringEntityResolver.java + create mode 100644 pgjdbc/src/main/java/org/postgresql/xml/LegacyInsecurePGXmlFactoryFactory.java + create mode 100644 pgjdbc/src/main/java/org/postgresql/xml/NullErrorHandler.java + create mode 100644 pgjdbc/src/main/java/org/postgresql/xml/PGXmlFactoryFactory.java + +diff --git a/pgjdbc/src/main/java/org/postgresql/PGProperty.java b/pgjdbc/src/main/java/org/postgresql/PGProperty.java +index 4901889..538b244 100644 +--- a/pgjdbc/src/main/java/org/postgresql/PGProperty.java ++++ b/pgjdbc/src/main/java/org/postgresql/PGProperty.java +@@ -661,6 +661,17 @@ public enum PGProperty { + "false", + "Use SPNEGO in SSPI authentication requests"), + ++ /** ++ * Factory class to instantiate factories for XML processing. ++ * The default factory disables external entity processing. ++ * Legacy behavior with external entity processing can be enabled by specifying a value of LEGACY_INSECURE. ++ * Or specify a custom class that implements {@code org.postgresql.xml.PGXmlFactoryFactory}. ++ */ ++ XML_FACTORY_FACTORY( ++ "xmlFactoryFactory", ++ "", ++ "Factory class to instantiate factories for XML processing"), ++ + ; + + private final String name; +diff --git a/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java b/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java +index 2dbba96..56fb4b8 100644 +--- a/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java ++++ b/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java +@@ -10,6 +10,7 @@ import org.postgresql.PGProperty; + import org.postgresql.jdbc.FieldMetadata; + import org.postgresql.jdbc.TimestampUtils; + import org.postgresql.util.LruCache; ++import org.postgresql.xml.PGXmlFactoryFactory; + + import java.sql.Connection; + import java.sql.ResultSet; +@@ -212,4 +213,12 @@ public interface BaseConnection extends PGConnection, Connection { + * @see PGProperty#READ_ONLY_MODE + */ + boolean hintReadOnly(); ++ ++ /** ++ * Retrieve the factory to instantiate XML processing factories. ++ * ++ * @return The factory to use to instantiate XML processing factories ++ * @throws SQLException if the class cannot be found or instantiated. ++ */ ++ PGXmlFactoryFactory getXmlFactoryFactory() throws SQLException; + } +diff --git a/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java b/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java +index f6e0fa7..5053b32 100644 +--- a/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java ++++ b/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java +@@ -1525,6 +1525,14 @@ public abstract class BaseDataSource implements CommonDataSource, Referenceable + } + //#endif + ++ public String getXmlFactoryFactory() { ++ return PGProperty.XML_FACTORY_FACTORY.get(properties); ++ } ++ ++ public void setXmlFactoryFactory(String xmlFactoryFactory) { ++ PGProperty.XML_FACTORY_FACTORY.set(properties, xmlFactoryFactory); ++ } ++ + /* + * Alias methods below, these are to help with ease-of-use with other database tools / frameworks + * which expect normal java bean getters / setters to exist for the property names. +diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java +index 72e9639..18d5638 100644 +--- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java ++++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java +@@ -37,6 +37,9 @@ import org.postgresql.util.PGBinaryObject; + import org.postgresql.util.PGobject; + import org.postgresql.util.PSQLException; + import org.postgresql.util.PSQLState; ++import org.postgresql.xml.DefaultPGXmlFactoryFactory; ++import org.postgresql.xml.LegacyInsecurePGXmlFactoryFactory; ++import org.postgresql.xml.PGXmlFactoryFactory; + + import java.io.IOException; + import java.sql.Array; +@@ -156,6 +159,9 @@ public class PgConnection implements BaseConnection { + + private final LruCache fieldMetadataCache; + ++ private final String xmlFactoryFactoryClass; ++ private PGXmlFactoryFactory xmlFactoryFactory; ++ + final CachedQuery borrowQuery(String sql) throws SQLException { + return queryExecutor.borrowQuery(sql); + } +@@ -311,6 +317,8 @@ public class PgConnection implements BaseConnection { + false); + + replicationConnection = PGProperty.REPLICATION.get(info) != null; ++ ++ xmlFactoryFactoryClass = PGProperty.XML_FACTORY_FACTORY.get(info); + } + + private static ReadOnlyBehavior getReadOnlyBehavior(String property) { +@@ -1823,4 +1831,36 @@ public class PgConnection implements BaseConnection { + return queryExecutor.getParameterStatus(parameterName); + } + ++ @Override ++ public PGXmlFactoryFactory getXmlFactoryFactory() throws SQLException { ++ if (xmlFactoryFactory == null) { ++ if (xmlFactoryFactoryClass == null || xmlFactoryFactoryClass.equals("")) { ++ xmlFactoryFactory = DefaultPGXmlFactoryFactory.INSTANCE; ++ } else if (xmlFactoryFactoryClass.equals("LEGACY_INSECURE")) { ++ xmlFactoryFactory = LegacyInsecurePGXmlFactoryFactory.INSTANCE; ++ } else { ++ Class clazz; ++ try { ++ clazz = Class.forName(xmlFactoryFactoryClass); ++ } catch (ClassNotFoundException ex) { ++ throw new PSQLException( ++ GT.tr("Could not instantiate xmlFactoryFactory: {0}", xmlFactoryFactoryClass), ++ PSQLState.INVALID_PARAMETER_VALUE, ex); ++ } ++ if (!clazz.isAssignableFrom(PGXmlFactoryFactory.class)) { ++ throw new PSQLException( ++ GT.tr("Connection property xmlFactoryFactory must implement PGXmlFactoryFactory: {0}", xmlFactoryFactoryClass), ++ PSQLState.INVALID_PARAMETER_VALUE); ++ } ++ try { ++ xmlFactoryFactory = (PGXmlFactoryFactory) clazz.newInstance(); ++ } catch (Exception ex) { ++ throw new PSQLException( ++ GT.tr("Could not instantiate xmlFactoryFactory: {0}", xmlFactoryFactoryClass), ++ PSQLState.INVALID_PARAMETER_VALUE, ex); ++ } ++ } ++ } ++ return xmlFactoryFactory; ++ } + } +diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgSQLXML.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgSQLXML.java +index 919df06..c928b7b 100644 +--- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgSQLXML.java ++++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgSQLXML.java +@@ -9,10 +9,11 @@ import org.postgresql.core.BaseConnection; + import org.postgresql.util.GT; + import org.postgresql.util.PSQLException; + import org.postgresql.util.PSQLState; ++import org.postgresql.xml.DefaultPGXmlFactoryFactory; ++import org.postgresql.xml.PGXmlFactoryFactory; + +-import org.xml.sax.ErrorHandler; + import org.xml.sax.InputSource; +-import org.xml.sax.SAXParseException; ++import org.xml.sax.XMLReader; + + import java.io.ByteArrayInputStream; + import java.io.ByteArrayOutputStream; +@@ -27,7 +28,6 @@ import java.sql.SQLException; + import java.sql.SQLXML; + + import javax.xml.parsers.DocumentBuilder; +-import javax.xml.parsers.DocumentBuilderFactory; + import javax.xml.stream.XMLInputFactory; + import javax.xml.stream.XMLOutputFactory; + import javax.xml.stream.XMLStreamException; +@@ -77,6 +77,13 @@ public class PgSQLXML implements SQLXML { + this.freed = false; + } + ++ private PGXmlFactoryFactory getXmlFactoryFactory() throws SQLException { ++ if (conn != null) { ++ return conn.getXmlFactoryFactory(); ++ } ++ return DefaultPGXmlFactoryFactory.INSTANCE; ++ } ++ + @Override + public synchronized void free() { + freed = true; +@@ -132,18 +139,17 @@ public class PgSQLXML implements SQLXML { + + try { + if (sourceClass == null || DOMSource.class.equals(sourceClass)) { +- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); +- DocumentBuilder builder = factory.newDocumentBuilder(); +- builder.setErrorHandler(new NonPrintingErrorHandler()); ++ DocumentBuilder builder = getXmlFactoryFactory().newDocumentBuilder(); + InputSource input = new InputSource(new StringReader(data)); + return (T) new DOMSource(builder.parse(input)); + } else if (SAXSource.class.equals(sourceClass)) { ++ XMLReader reader = getXmlFactoryFactory().createXMLReader(); + InputSource is = new InputSource(new StringReader(data)); +- return (T) new SAXSource(is); ++ return (T) new SAXSource(reader, is); + } else if (StreamSource.class.equals(sourceClass)) { + return (T) new StreamSource(new StringReader(data)); + } else if (StAXSource.class.equals(sourceClass)) { +- XMLInputFactory xif = XMLInputFactory.newInstance(); ++ XMLInputFactory xif = getXmlFactoryFactory().newXMLInputFactory(); + XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(data)); + return (T) new StAXSource(xsr); + } +@@ -191,8 +197,7 @@ public class PgSQLXML implements SQLXML { + return (T) domResult; + } else if (SAXResult.class.equals(resultClass)) { + try { +- SAXTransformerFactory transformerFactory = +- (SAXTransformerFactory) SAXTransformerFactory.newInstance(); ++ SAXTransformerFactory transformerFactory = getXmlFactoryFactory().newSAXTransformerFactory(); + TransformerHandler transformerHandler = transformerFactory.newTransformerHandler(); + stringWriter = new StringWriter(); + transformerHandler.setResult(new StreamResult(stringWriter)); +@@ -209,7 +214,7 @@ public class PgSQLXML implements SQLXML { + } else if (StAXResult.class.equals(resultClass)) { + stringWriter = new StringWriter(); + try { +- XMLOutputFactory xof = XMLOutputFactory.newInstance(); ++ XMLOutputFactory xof = getXmlFactoryFactory().newXMLOutputFactory(); + XMLStreamWriter xsw = xof.createXMLStreamWriter(stringWriter); + active = true; + return (T) new StAXResult(xsw); +@@ -272,7 +277,7 @@ public class PgSQLXML implements SQLXML { + // and use the identify transform to get it into a + // friendlier result format. + try { +- TransformerFactory factory = TransformerFactory.newInstance(); ++ TransformerFactory factory = getXmlFactoryFactory().newTransformerFactory(); + Transformer transformer = factory.newTransformer(); + DOMSource domSource = new DOMSource(domResult.getNode()); + StringWriter stringWriter = new StringWriter(); +@@ -298,19 +303,5 @@ public class PgSQLXML implements SQLXML { + } + initialized = true; + } +- +- // Don't clutter System.err with errors the user can't silence. +- // If something bad really happens an exception will be thrown. +- static class NonPrintingErrorHandler implements ErrorHandler { +- public void error(SAXParseException e) { +- } +- +- public void fatalError(SAXParseException e) { +- } +- +- public void warning(SAXParseException e) { +- } +- } +- + } + +diff --git a/pgjdbc/src/main/java/org/postgresql/xml/DefaultPGXmlFactoryFactory.java b/pgjdbc/src/main/java/org/postgresql/xml/DefaultPGXmlFactoryFactory.java +new file mode 100644 +index 0000000..7334935 +--- /dev/null ++++ b/pgjdbc/src/main/java/org/postgresql/xml/DefaultPGXmlFactoryFactory.java +@@ -0,0 +1,140 @@ ++/* ++ * Copyright (c) 2020, PostgreSQL Global Development Group ++ * See the LICENSE file in the project root for more information. ++ */ ++ ++package org.postgresql.xml; ++ ++import org.xml.sax.SAXException; ++import org.xml.sax.XMLReader; ++import org.xml.sax.helpers.XMLReaderFactory; ++ ++import javax.xml.XMLConstants; ++import javax.xml.parsers.DocumentBuilder; ++import javax.xml.parsers.DocumentBuilderFactory; ++import javax.xml.parsers.ParserConfigurationException; ++import javax.xml.stream.XMLInputFactory; ++import javax.xml.stream.XMLOutputFactory; ++import javax.xml.transform.TransformerFactory; ++import javax.xml.transform.sax.SAXTransformerFactory; ++ ++/** ++ * Default implementation of PGXmlFactoryFactory that configures each factory per OWASP recommendations. ++ * ++ * @see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html ++ */ ++public class DefaultPGXmlFactoryFactory implements PGXmlFactoryFactory { ++ public static final DefaultPGXmlFactoryFactory INSTANCE = new DefaultPGXmlFactoryFactory(); ++ ++ private DefaultPGXmlFactoryFactory() { ++ } ++ ++ private DocumentBuilderFactory getDocumentBuilderFactory() { ++ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); ++ setFactoryProperties(factory); ++ factory.setXIncludeAware(false); ++ factory.setExpandEntityReferences(false); ++ return factory; ++ } ++ ++ @Override ++ public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { ++ DocumentBuilder builder = getDocumentBuilderFactory().newDocumentBuilder(); ++ builder.setEntityResolver(EmptyStringEntityResolver.INSTANCE); ++ builder.setErrorHandler(NullErrorHandler.INSTANCE); ++ return builder; ++ } ++ ++ @Override ++ public TransformerFactory newTransformerFactory() { ++ TransformerFactory factory = TransformerFactory.newInstance(); ++ setFactoryProperties(factory); ++ return factory; ++ } ++ ++ @Override ++ public SAXTransformerFactory newSAXTransformerFactory() { ++ SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); ++ setFactoryProperties(factory); ++ return factory; ++ } ++ ++ @Override ++ public XMLInputFactory newXMLInputFactory() { ++ XMLInputFactory factory = XMLInputFactory.newInstance(); ++ setPropertyQuietly(factory, XMLInputFactory.SUPPORT_DTD, false); ++ setPropertyQuietly(factory, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); ++ return factory; ++ } ++ ++ @Override ++ public XMLOutputFactory newXMLOutputFactory() { ++ XMLOutputFactory factory = XMLOutputFactory.newInstance(); ++ return factory; ++ } ++ ++ @Override ++ public XMLReader createXMLReader() throws SAXException { ++ XMLReader factory = XMLReaderFactory.createXMLReader(); ++ setFeatureQuietly(factory, "http://apache.org/xml/features/disallow-doctype-decl", true); ++ setFeatureQuietly(factory, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false); ++ setFeatureQuietly(factory, "http://xml.org/sax/features/external-general-entities", false); ++ setFeatureQuietly(factory, "http://xml.org/sax/features/external-parameter-entities", false); ++ factory.setErrorHandler(NullErrorHandler.INSTANCE); ++ return factory; ++ } ++ ++ private static void setFeatureQuietly(Object factory, String name, boolean value) { ++ try { ++ if (factory instanceof DocumentBuilderFactory) { ++ ((DocumentBuilderFactory) factory).setFeature(name, value); ++ } else if (factory instanceof TransformerFactory) { ++ ((TransformerFactory) factory).setFeature(name, value); ++ } else if (factory instanceof XMLReader) { ++ ((XMLReader) factory).setFeature(name, value); ++ } else { ++ throw new Error("Invalid factory class: " + factory.getClass()); ++ } ++ return; ++ } catch (Exception ignore) { ++ } ++ } ++ ++ private static void setAttributeQuietly(Object factory, String name, Object value) { ++ try { ++ if (factory instanceof DocumentBuilderFactory) { ++ ((DocumentBuilderFactory) factory).setAttribute(name, value); ++ } else if (factory instanceof TransformerFactory) { ++ ((TransformerFactory) factory).setAttribute(name, value); ++ } else { ++ throw new Error("Invalid factory class: " + factory.getClass()); ++ } ++ } catch (Exception ignore) { ++ } ++ } ++ ++ private static void setFactoryProperties(Object factory) { ++ setFeatureQuietly(factory, XMLConstants.FEATURE_SECURE_PROCESSING, true); ++ setFeatureQuietly(factory, "http://apache.org/xml/features/disallow-doctype-decl", true); ++ setFeatureQuietly(factory, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false); ++ setFeatureQuietly(factory, "http://xml.org/sax/features/external-general-entities", false); ++ setFeatureQuietly(factory, "http://xml.org/sax/features/external-parameter-entities", false); ++ // Values from XMLConstants inlined for JDK 1.6 compatibility ++ setAttributeQuietly(factory, "http://javax.xml.XMLConstants/property/accessExternalDTD", ""); ++ setAttributeQuietly(factory, "http://javax.xml.XMLConstants/property/accessExternalSchema", ""); ++ setAttributeQuietly(factory, "http://javax.xml.XMLConstants/property/accessExternalStylesheet", ""); ++ } ++ ++ private static void setPropertyQuietly(Object factory, String name, Object value) { ++ try { ++ if (factory instanceof XMLReader) { ++ ((XMLReader) factory).setProperty(name, value); ++ } else if (factory instanceof XMLInputFactory) { ++ ((XMLInputFactory) factory).setProperty(name, value); ++ } else { ++ throw new Error("Invalid factory class: " + factory.getClass()); ++ } ++ } catch (Exception ignore) { ++ } ++ } ++} +\ No newline at end of file +diff --git a/pgjdbc/src/main/java/org/postgresql/xml/EmptyStringEntityResolver.java b/pgjdbc/src/main/java/org/postgresql/xml/EmptyStringEntityResolver.java +new file mode 100644 +index 0000000..39227e0 +--- /dev/null ++++ b/pgjdbc/src/main/java/org/postgresql/xml/EmptyStringEntityResolver.java +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (c) 2020, PostgreSQL Global Development Group ++ * See the LICENSE file in the project root for more information. ++ */ ++ ++package org.postgresql.xml; ++ ++import org.xml.sax.EntityResolver; ++import org.xml.sax.InputSource; ++import org.xml.sax.SAXException; ++ ++import java.io.IOException; ++import java.io.StringReader; ++ ++public class EmptyStringEntityResolver implements EntityResolver { ++ public static final EmptyStringEntityResolver INSTANCE = new EmptyStringEntityResolver(); ++ ++ @Override ++ public InputSource resolveEntity(String publicId, String systemId) ++ throws SAXException, IOException { ++ return new InputSource(new StringReader("")); ++ } ++} +\ No newline at end of file +diff --git a/pgjdbc/src/main/java/org/postgresql/xml/LegacyInsecurePGXmlFactoryFactory.java b/pgjdbc/src/main/java/org/postgresql/xml/LegacyInsecurePGXmlFactoryFactory.java +new file mode 100644 +index 0000000..ed7a66b +--- /dev/null ++++ b/pgjdbc/src/main/java/org/postgresql/xml/LegacyInsecurePGXmlFactoryFactory.java +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (c) 2020, PostgreSQL Global Development Group ++ * See the LICENSE file in the project root for more information. ++ */ ++ ++package org.postgresql.xml; ++ ++import org.xml.sax.SAXException; ++import org.xml.sax.XMLReader; ++import org.xml.sax.helpers.XMLReaderFactory; ++ ++import javax.xml.parsers.DocumentBuilder; ++import javax.xml.parsers.DocumentBuilderFactory; ++import javax.xml.parsers.ParserConfigurationException; ++import javax.xml.stream.XMLInputFactory; ++import javax.xml.stream.XMLOutputFactory; ++import javax.xml.transform.TransformerFactory; ++import javax.xml.transform.sax.SAXTransformerFactory; ++ ++public class LegacyInsecurePGXmlFactoryFactory implements PGXmlFactoryFactory { ++ public static final LegacyInsecurePGXmlFactoryFactory INSTANCE = new LegacyInsecurePGXmlFactoryFactory(); ++ ++ private LegacyInsecurePGXmlFactoryFactory() { ++ } ++ ++ @Override ++ public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { ++ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); ++ builder.setErrorHandler(NullErrorHandler.INSTANCE); ++ return builder; ++ } ++ ++ @Override ++ public TransformerFactory newTransformerFactory() { ++ return TransformerFactory.newInstance(); ++ } ++ ++ @Override ++ public SAXTransformerFactory newSAXTransformerFactory() { ++ return (SAXTransformerFactory) SAXTransformerFactory.newInstance(); ++ } ++ ++ @Override ++ public XMLInputFactory newXMLInputFactory() { ++ return XMLInputFactory.newInstance(); ++ } ++ ++ @Override ++ public XMLOutputFactory newXMLOutputFactory() { ++ return XMLOutputFactory.newInstance(); ++ } ++ ++ @Override ++ public XMLReader createXMLReader() throws SAXException { ++ return XMLReaderFactory.createXMLReader(); ++ } ++} +\ No newline at end of file +diff --git a/pgjdbc/src/main/java/org/postgresql/xml/NullErrorHandler.java b/pgjdbc/src/main/java/org/postgresql/xml/NullErrorHandler.java +new file mode 100644 +index 0000000..ad486c7 +--- /dev/null ++++ b/pgjdbc/src/main/java/org/postgresql/xml/NullErrorHandler.java +@@ -0,0 +1,25 @@ ++/* ++ * Copyright (c) 2020, PostgreSQL Global Development Group ++ * See the LICENSE file in the project root for more information. ++ */ ++ ++package org.postgresql.xml; ++ ++import org.xml.sax.ErrorHandler; ++import org.xml.sax.SAXParseException; ++ ++/** ++ * Error handler that silently suppresses all errors. ++ */ ++public class NullErrorHandler implements ErrorHandler { ++ public static final NullErrorHandler INSTANCE = new NullErrorHandler(); ++ ++ public void error(SAXParseException e) { ++ } ++ ++ public void fatalError(SAXParseException e) { ++ } ++ ++ public void warning(SAXParseException e) { ++ } ++} +\ No newline at end of file +diff --git a/pgjdbc/src/main/java/org/postgresql/xml/PGXmlFactoryFactory.java b/pgjdbc/src/main/java/org/postgresql/xml/PGXmlFactoryFactory.java +new file mode 100644 +index 0000000..4bb98e4 +--- /dev/null ++++ b/pgjdbc/src/main/java/org/postgresql/xml/PGXmlFactoryFactory.java +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (c) 2020, PostgreSQL Global Development Group ++ * See the LICENSE file in the project root for more information. ++ */ ++ ++package org.postgresql.xml; ++ ++import org.xml.sax.SAXException; ++import org.xml.sax.XMLReader; ++ ++import javax.xml.parsers.DocumentBuilder; ++import javax.xml.parsers.ParserConfigurationException; ++import javax.xml.stream.XMLInputFactory; ++import javax.xml.stream.XMLOutputFactory; ++import javax.xml.transform.TransformerFactory; ++import javax.xml.transform.sax.SAXTransformerFactory; ++ ++public interface PGXmlFactoryFactory { ++ DocumentBuilder newDocumentBuilder() throws ParserConfigurationException; ++ ++ TransformerFactory newTransformerFactory(); ++ ++ SAXTransformerFactory newSAXTransformerFactory(); ++ ++ XMLInputFactory newXMLInputFactory(); ++ ++ XMLOutputFactory newXMLOutputFactory(); ++ ++ XMLReader createXMLReader() throws SAXException; ++} +\ No newline at end of file +diff --git a/pgjdbc/src/test/java/org/postgresql/jdbc/PgSQLXMLTest.java b/pgjdbc/src/test/java/org/postgresql/jdbc/PgSQLXMLTest.java +index 53fd56d..49e389c 100644 +--- a/pgjdbc/src/test/java/org/postgresql/jdbc/PgSQLXMLTest.java ++++ b/pgjdbc/src/test/java/org/postgresql/jdbc/PgSQLXMLTest.java +@@ -8,18 +8,36 @@ package org.postgresql.jdbc; + import static org.junit.Assert.assertEquals; + import static org.junit.Assert.assertNotNull; + import static org.junit.Assert.assertTrue; ++import static org.junit.Assert.fail; + ++import org.postgresql.PGProperty; ++import org.postgresql.core.BaseConnection; + import org.postgresql.test.TestUtil; + import org.postgresql.test.jdbc2.BaseTest4; + + import org.junit.Before; + import org.junit.Test; + ++import java.io.StringWriter; + import java.io.Writer; ++import java.sql.Connection; + import java.sql.PreparedStatement; + import java.sql.ResultSet; ++import java.sql.SQLException; + import java.sql.SQLXML; + import java.sql.Statement; ++import java.util.Properties; ++ ++import javax.xml.stream.XMLStreamException; ++import javax.xml.stream.XMLStreamReader; ++import javax.xml.transform.Source; ++import javax.xml.transform.Transformer; ++import javax.xml.transform.TransformerException; ++import javax.xml.transform.TransformerFactory; ++import javax.xml.transform.dom.DOMSource; ++import javax.xml.transform.sax.SAXSource; ++import javax.xml.transform.stax.StAXSource; ++import javax.xml.transform.stream.StreamResult; + + public class PgSQLXMLTest extends BaseTest4 { + +@@ -27,17 +45,17 @@ public class PgSQLXMLTest extends BaseTest4 { + @Before + public void setUp() throws Exception { + super.setUp(); +- TestUtil.createTempTable(con, "xmltab","x xml"); ++ TestUtil.createTempTable(con, "xmltab", "x xml"); + } + + @Test +- public void setCharacterStream() throws Exception { ++ public void setCharacterStream() throws Exception { + String exmplar = "value"; + SQLXML pgSQLXML = con.createSQLXML(); + Writer writer = pgSQLXML.setCharacterStream(); + writer.write(exmplar); + PreparedStatement preparedStatement = con.prepareStatement("insert into xmltab values (?)"); +- preparedStatement.setSQLXML(1,pgSQLXML); ++ preparedStatement.setSQLXML(1, pgSQLXML); + preparedStatement.execute(); + + Statement statement = con.createStatement(); +@@ -47,4 +65,60 @@ public class PgSQLXMLTest extends BaseTest4 { + assertNotNull(result); + assertEquals(exmplar, result.getString()); + } ++ ++ private static final String LICENSE_URL = ++ PgSQLXMLTest.class.getClassLoader().getResource("META-INF/LICENSE").toString(); ++ private static final String XXE_EXAMPLE = ++ "\n" ++ + "]>" ++ + "&xxe;"; ++ ++ @Test ++ public void testLegacyXxe() throws Exception { ++ Properties props = new Properties(); ++ props.setProperty(PGProperty.XML_FACTORY_FACTORY.getName(), "LEGACY_INSECURE"); ++ try (Connection conn = TestUtil.openDB(props)) { ++ BaseConnection baseConn = conn.unwrap(BaseConnection.class); ++ PgSQLXML xml = new PgSQLXML(baseConn, XXE_EXAMPLE); ++ xml.getSource(null); ++ } ++ } ++ ++ private static String sourceToString(Source source) throws TransformerException { ++ StringWriter sw = new StringWriter(); ++ Transformer transformer = TransformerFactory.newInstance().newTransformer(); ++ transformer.transform(source, new StreamResult(sw)); ++ return sw.toString(); ++ } ++ ++ @Test(expected = SQLException.class) ++ public void testGetSourceXxeNull() throws Exception { ++ PgSQLXML xml = new PgSQLXML(null, XXE_EXAMPLE); ++ xml.getSource(null); ++ } ++ ++ @Test(expected = SQLException.class) ++ public void testGetSourceXxeDOMSource() throws Exception { ++ PgSQLXML xml = new PgSQLXML(null, XXE_EXAMPLE); ++ xml.getSource(DOMSource.class); ++ } ++ ++ @Test(expected = TransformerException.class) ++ public void testGetSourceXxeSAXSource() throws Exception { ++ PgSQLXML xml = new PgSQLXML(null, XXE_EXAMPLE); ++ SAXSource source = xml.getSource(SAXSource.class); ++ sourceToString(source); ++ ++ } ++ ++ @Test(expected = XMLStreamException.class) ++ public void testGetSourceXxeStAXSource() throws Exception { ++ PgSQLXML xml = new PgSQLXML(null, XXE_EXAMPLE); ++ StAXSource source = xml.getSource(StAXSource.class); ++ XMLStreamReader reader = source.getXMLStreamReader(); ++ // STAX will not throw XXE error until we actually read the element ++ while (reader.hasNext()) { ++ reader.next(); ++ } ++ } + } +-- +2.26.0 + diff --git a/postgresql-jdbc.spec b/postgresql-jdbc.spec index b1f4b1c..0944291 100644 --- a/postgresql-jdbc.spec +++ b/postgresql-jdbc.spec @@ -55,13 +55,15 @@ Summary: JDBC driver for PostgreSQL Name: postgresql-jdbc Version: 42.2.12 -Release: 1%{?dist} +Release: 2%{?dist} License: BSD URL: http://jdbc.postgresql.org/ Source0: https://github.com/pgjdbc/pgjdbc/archive/REL%{version}/pgjdbc-REL%{version}.tar.gz Provides: pgjdbc = %version-%release +Patch0: fix-XXE-vulnerability.patch + # Upstream moved parent pom.xml into separate project (even though there is only # one dependant project on it?). Let's try to not complicate packaging by # having separate spec file for it, too. @@ -108,6 +110,7 @@ This package contains the API Documentation for %{name}. mv pgjdbc-REL%version/* . mv pgjdbc-parent-poms-REL%parent_ver pgjdbc-parent-poms +%patch0 -p1 # remove any binary libs find -name "*.jar" -or -name "*.class" | xargs rm -f @@ -188,6 +191,9 @@ opts="-f" %changelog +* Fri Jul 24 2020 Ondrej Dubaj - 42.2.12-2 +- fixed XXE vulnerability (CVE-2020-13692) + * Wed May 13 2020 Ondrej Dubaj - 42.2.12-1 - new upstream release + skip javadoc due to jdk-11 From cf9cc28f038d451c4022916b163f0dd3703dbe46 Mon Sep 17 00:00:00 2001 From: Ondrej Dubaj Date: Tue, 28 Jul 2020 15:08:16 +0200 Subject: [PATCH 2/5] Fixed javadoc build problem --- postgresql-jdbc.spec | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/postgresql-jdbc.spec b/postgresql-jdbc.spec index 0944291..e75a51e 100644 --- a/postgresql-jdbc.spec +++ b/postgresql-jdbc.spec @@ -50,7 +50,7 @@ %global parent_poms_builddir ./pgjdbc-parent-poms %global pgjdbc_mvn_options -DwaffleEnabled=false -DosgiEnabled=false \\\ - -DexcludePackageNames=org.postgresql.osgi:org.postgresql.sspi -Dmaven.javadoc.skip=true + -DexcludePackageNames=org.postgresql.osgi:org.postgresql.sspi Summary: JDBC driver for PostgreSQL Name: postgresql-jdbc @@ -174,7 +174,7 @@ EOF opts="-f" %endif -%mvn_build $opts -- %pgjdbc_mvn_options +%mvn_build $opts --xmvn-javadoc -- %pgjdbc_mvn_options %install @@ -186,13 +186,14 @@ opts="-f" %doc README.md -#%files javadoc -f .mfiles-javadoc +%files javadoc -f .mfiles-javadoc %license LICENSE %changelog * Fri Jul 24 2020 Ondrej Dubaj - 42.2.12-2 - fixed XXE vulnerability (CVE-2020-13692) +- fixed javadoc build problem * Wed May 13 2020 Ondrej Dubaj - 42.2.12-1 - new upstream release + skip javadoc due to jdk-11 From 9bb3d5e4b634a7b86ff24e0e09f7ce831776cdf3 Mon Sep 17 00:00:00 2001 From: Ondrej Dubaj Date: Mon, 17 Aug 2020 10:28:42 +0200 Subject: [PATCH 3/5] Rebased to version 42.2.15 --- .gitignore | 1 + fix-XXE-vulnerability.patch | 715 ------------------------------------ postgresql-jdbc.spec | 57 +-- sources | 3 +- 4 files changed, 19 insertions(+), 757 deletions(-) delete mode 100644 fix-XXE-vulnerability.patch diff --git a/.gitignore b/.gitignore index 71f315d..6faa3a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /pgjdbc-REL*.tar.gz /pgjdbc-parent-poms-REL*.tar.gz /pgjdbc-v42.3.0-rc2.tar.gz +/postgresql-42.2.15-jdbc-src.tar.gz diff --git a/fix-XXE-vulnerability.patch b/fix-XXE-vulnerability.patch deleted file mode 100644 index 4b12fc2..0000000 --- a/fix-XXE-vulnerability.patch +++ /dev/null @@ -1,715 +0,0 @@ -From 0bbff72847caabbc3a7dd897a848c5bf460f4999 Mon Sep 17 00:00:00 2001 -From: Ondrej Dubaj -Date: Tue, 28 Jul 2020 14:52:25 +0200 -Subject: [PATCH] Fix for XXE vulnerability - -by defaulting to disabling external access and doc types. The -legacy insecure behavior can be restored via the new connection property xmlFactoryFactory -with a value of LEGACY_INSECURE. Alternatively, a custom class name can be specified that -implements org.postgresql.xml.PGXmlFactoryFactory and takes a no argument constructor. - -* refactor: Clean up whitespace in existing PgSQLXMLTest -* fix: Fix XXE vulnerability in PgSQLXML by disabling external access and doctypes -* fix: Add missing getter and setter for XML_FACTORY_FACTORY to BasicDataSource ---- - .../main/java/org/postgresql/PGProperty.java | 11 ++ - .../org/postgresql/core/BaseConnection.java | 9 ++ - .../postgresql/ds/common/BaseDataSource.java | 8 + - .../org/postgresql/jdbc/PgConnection.java | 40 +++++ - .../java/org/postgresql/jdbc/PgSQLXML.java | 43 +++--- - .../xml/DefaultPGXmlFactoryFactory.java | 140 ++++++++++++++++++ - .../xml/EmptyStringEntityResolver.java | 23 +++ - .../LegacyInsecurePGXmlFactoryFactory.java | 57 +++++++ - .../org/postgresql/xml/NullErrorHandler.java | 25 ++++ - .../postgresql/xml/PGXmlFactoryFactory.java | 30 ++++ - .../org/postgresql/jdbc/PgSQLXMLTest.java | 80 +++++++++- - 11 files changed, 437 insertions(+), 29 deletions(-) - create mode 100644 pgjdbc/src/main/java/org/postgresql/xml/DefaultPGXmlFactoryFactory.java - create mode 100644 pgjdbc/src/main/java/org/postgresql/xml/EmptyStringEntityResolver.java - create mode 100644 pgjdbc/src/main/java/org/postgresql/xml/LegacyInsecurePGXmlFactoryFactory.java - create mode 100644 pgjdbc/src/main/java/org/postgresql/xml/NullErrorHandler.java - create mode 100644 pgjdbc/src/main/java/org/postgresql/xml/PGXmlFactoryFactory.java - -diff --git a/pgjdbc/src/main/java/org/postgresql/PGProperty.java b/pgjdbc/src/main/java/org/postgresql/PGProperty.java -index 4901889..538b244 100644 ---- a/pgjdbc/src/main/java/org/postgresql/PGProperty.java -+++ b/pgjdbc/src/main/java/org/postgresql/PGProperty.java -@@ -661,6 +661,17 @@ public enum PGProperty { - "false", - "Use SPNEGO in SSPI authentication requests"), - -+ /** -+ * Factory class to instantiate factories for XML processing. -+ * The default factory disables external entity processing. -+ * Legacy behavior with external entity processing can be enabled by specifying a value of LEGACY_INSECURE. -+ * Or specify a custom class that implements {@code org.postgresql.xml.PGXmlFactoryFactory}. -+ */ -+ XML_FACTORY_FACTORY( -+ "xmlFactoryFactory", -+ "", -+ "Factory class to instantiate factories for XML processing"), -+ - ; - - private final String name; -diff --git a/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java b/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java -index 2dbba96..56fb4b8 100644 ---- a/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java -+++ b/pgjdbc/src/main/java/org/postgresql/core/BaseConnection.java -@@ -10,6 +10,7 @@ import org.postgresql.PGProperty; - import org.postgresql.jdbc.FieldMetadata; - import org.postgresql.jdbc.TimestampUtils; - import org.postgresql.util.LruCache; -+import org.postgresql.xml.PGXmlFactoryFactory; - - import java.sql.Connection; - import java.sql.ResultSet; -@@ -212,4 +213,12 @@ public interface BaseConnection extends PGConnection, Connection { - * @see PGProperty#READ_ONLY_MODE - */ - boolean hintReadOnly(); -+ -+ /** -+ * Retrieve the factory to instantiate XML processing factories. -+ * -+ * @return The factory to use to instantiate XML processing factories -+ * @throws SQLException if the class cannot be found or instantiated. -+ */ -+ PGXmlFactoryFactory getXmlFactoryFactory() throws SQLException; - } -diff --git a/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java b/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java -index f6e0fa7..5053b32 100644 ---- a/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java -+++ b/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java -@@ -1525,6 +1525,14 @@ public abstract class BaseDataSource implements CommonDataSource, Referenceable - } - //#endif - -+ public String getXmlFactoryFactory() { -+ return PGProperty.XML_FACTORY_FACTORY.get(properties); -+ } -+ -+ public void setXmlFactoryFactory(String xmlFactoryFactory) { -+ PGProperty.XML_FACTORY_FACTORY.set(properties, xmlFactoryFactory); -+ } -+ - /* - * Alias methods below, these are to help with ease-of-use with other database tools / frameworks - * which expect normal java bean getters / setters to exist for the property names. -diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java -index 72e9639..18d5638 100644 ---- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java -+++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java -@@ -37,6 +37,9 @@ import org.postgresql.util.PGBinaryObject; - import org.postgresql.util.PGobject; - import org.postgresql.util.PSQLException; - import org.postgresql.util.PSQLState; -+import org.postgresql.xml.DefaultPGXmlFactoryFactory; -+import org.postgresql.xml.LegacyInsecurePGXmlFactoryFactory; -+import org.postgresql.xml.PGXmlFactoryFactory; - - import java.io.IOException; - import java.sql.Array; -@@ -156,6 +159,9 @@ public class PgConnection implements BaseConnection { - - private final LruCache fieldMetadataCache; - -+ private final String xmlFactoryFactoryClass; -+ private PGXmlFactoryFactory xmlFactoryFactory; -+ - final CachedQuery borrowQuery(String sql) throws SQLException { - return queryExecutor.borrowQuery(sql); - } -@@ -311,6 +317,8 @@ public class PgConnection implements BaseConnection { - false); - - replicationConnection = PGProperty.REPLICATION.get(info) != null; -+ -+ xmlFactoryFactoryClass = PGProperty.XML_FACTORY_FACTORY.get(info); - } - - private static ReadOnlyBehavior getReadOnlyBehavior(String property) { -@@ -1823,4 +1831,36 @@ public class PgConnection implements BaseConnection { - return queryExecutor.getParameterStatus(parameterName); - } - -+ @Override -+ public PGXmlFactoryFactory getXmlFactoryFactory() throws SQLException { -+ if (xmlFactoryFactory == null) { -+ if (xmlFactoryFactoryClass == null || xmlFactoryFactoryClass.equals("")) { -+ xmlFactoryFactory = DefaultPGXmlFactoryFactory.INSTANCE; -+ } else if (xmlFactoryFactoryClass.equals("LEGACY_INSECURE")) { -+ xmlFactoryFactory = LegacyInsecurePGXmlFactoryFactory.INSTANCE; -+ } else { -+ Class clazz; -+ try { -+ clazz = Class.forName(xmlFactoryFactoryClass); -+ } catch (ClassNotFoundException ex) { -+ throw new PSQLException( -+ GT.tr("Could not instantiate xmlFactoryFactory: {0}", xmlFactoryFactoryClass), -+ PSQLState.INVALID_PARAMETER_VALUE, ex); -+ } -+ if (!clazz.isAssignableFrom(PGXmlFactoryFactory.class)) { -+ throw new PSQLException( -+ GT.tr("Connection property xmlFactoryFactory must implement PGXmlFactoryFactory: {0}", xmlFactoryFactoryClass), -+ PSQLState.INVALID_PARAMETER_VALUE); -+ } -+ try { -+ xmlFactoryFactory = (PGXmlFactoryFactory) clazz.newInstance(); -+ } catch (Exception ex) { -+ throw new PSQLException( -+ GT.tr("Could not instantiate xmlFactoryFactory: {0}", xmlFactoryFactoryClass), -+ PSQLState.INVALID_PARAMETER_VALUE, ex); -+ } -+ } -+ } -+ return xmlFactoryFactory; -+ } - } -diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgSQLXML.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgSQLXML.java -index 919df06..c928b7b 100644 ---- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgSQLXML.java -+++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgSQLXML.java -@@ -9,10 +9,11 @@ import org.postgresql.core.BaseConnection; - import org.postgresql.util.GT; - import org.postgresql.util.PSQLException; - import org.postgresql.util.PSQLState; -+import org.postgresql.xml.DefaultPGXmlFactoryFactory; -+import org.postgresql.xml.PGXmlFactoryFactory; - --import org.xml.sax.ErrorHandler; - import org.xml.sax.InputSource; --import org.xml.sax.SAXParseException; -+import org.xml.sax.XMLReader; - - import java.io.ByteArrayInputStream; - import java.io.ByteArrayOutputStream; -@@ -27,7 +28,6 @@ import java.sql.SQLException; - import java.sql.SQLXML; - - import javax.xml.parsers.DocumentBuilder; --import javax.xml.parsers.DocumentBuilderFactory; - import javax.xml.stream.XMLInputFactory; - import javax.xml.stream.XMLOutputFactory; - import javax.xml.stream.XMLStreamException; -@@ -77,6 +77,13 @@ public class PgSQLXML implements SQLXML { - this.freed = false; - } - -+ private PGXmlFactoryFactory getXmlFactoryFactory() throws SQLException { -+ if (conn != null) { -+ return conn.getXmlFactoryFactory(); -+ } -+ return DefaultPGXmlFactoryFactory.INSTANCE; -+ } -+ - @Override - public synchronized void free() { - freed = true; -@@ -132,18 +139,17 @@ public class PgSQLXML implements SQLXML { - - try { - if (sourceClass == null || DOMSource.class.equals(sourceClass)) { -- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); -- DocumentBuilder builder = factory.newDocumentBuilder(); -- builder.setErrorHandler(new NonPrintingErrorHandler()); -+ DocumentBuilder builder = getXmlFactoryFactory().newDocumentBuilder(); - InputSource input = new InputSource(new StringReader(data)); - return (T) new DOMSource(builder.parse(input)); - } else if (SAXSource.class.equals(sourceClass)) { -+ XMLReader reader = getXmlFactoryFactory().createXMLReader(); - InputSource is = new InputSource(new StringReader(data)); -- return (T) new SAXSource(is); -+ return (T) new SAXSource(reader, is); - } else if (StreamSource.class.equals(sourceClass)) { - return (T) new StreamSource(new StringReader(data)); - } else if (StAXSource.class.equals(sourceClass)) { -- XMLInputFactory xif = XMLInputFactory.newInstance(); -+ XMLInputFactory xif = getXmlFactoryFactory().newXMLInputFactory(); - XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(data)); - return (T) new StAXSource(xsr); - } -@@ -191,8 +197,7 @@ public class PgSQLXML implements SQLXML { - return (T) domResult; - } else if (SAXResult.class.equals(resultClass)) { - try { -- SAXTransformerFactory transformerFactory = -- (SAXTransformerFactory) SAXTransformerFactory.newInstance(); -+ SAXTransformerFactory transformerFactory = getXmlFactoryFactory().newSAXTransformerFactory(); - TransformerHandler transformerHandler = transformerFactory.newTransformerHandler(); - stringWriter = new StringWriter(); - transformerHandler.setResult(new StreamResult(stringWriter)); -@@ -209,7 +214,7 @@ public class PgSQLXML implements SQLXML { - } else if (StAXResult.class.equals(resultClass)) { - stringWriter = new StringWriter(); - try { -- XMLOutputFactory xof = XMLOutputFactory.newInstance(); -+ XMLOutputFactory xof = getXmlFactoryFactory().newXMLOutputFactory(); - XMLStreamWriter xsw = xof.createXMLStreamWriter(stringWriter); - active = true; - return (T) new StAXResult(xsw); -@@ -272,7 +277,7 @@ public class PgSQLXML implements SQLXML { - // and use the identify transform to get it into a - // friendlier result format. - try { -- TransformerFactory factory = TransformerFactory.newInstance(); -+ TransformerFactory factory = getXmlFactoryFactory().newTransformerFactory(); - Transformer transformer = factory.newTransformer(); - DOMSource domSource = new DOMSource(domResult.getNode()); - StringWriter stringWriter = new StringWriter(); -@@ -298,19 +303,5 @@ public class PgSQLXML implements SQLXML { - } - initialized = true; - } -- -- // Don't clutter System.err with errors the user can't silence. -- // If something bad really happens an exception will be thrown. -- static class NonPrintingErrorHandler implements ErrorHandler { -- public void error(SAXParseException e) { -- } -- -- public void fatalError(SAXParseException e) { -- } -- -- public void warning(SAXParseException e) { -- } -- } -- - } - -diff --git a/pgjdbc/src/main/java/org/postgresql/xml/DefaultPGXmlFactoryFactory.java b/pgjdbc/src/main/java/org/postgresql/xml/DefaultPGXmlFactoryFactory.java -new file mode 100644 -index 0000000..7334935 ---- /dev/null -+++ b/pgjdbc/src/main/java/org/postgresql/xml/DefaultPGXmlFactoryFactory.java -@@ -0,0 +1,140 @@ -+/* -+ * Copyright (c) 2020, PostgreSQL Global Development Group -+ * See the LICENSE file in the project root for more information. -+ */ -+ -+package org.postgresql.xml; -+ -+import org.xml.sax.SAXException; -+import org.xml.sax.XMLReader; -+import org.xml.sax.helpers.XMLReaderFactory; -+ -+import javax.xml.XMLConstants; -+import javax.xml.parsers.DocumentBuilder; -+import javax.xml.parsers.DocumentBuilderFactory; -+import javax.xml.parsers.ParserConfigurationException; -+import javax.xml.stream.XMLInputFactory; -+import javax.xml.stream.XMLOutputFactory; -+import javax.xml.transform.TransformerFactory; -+import javax.xml.transform.sax.SAXTransformerFactory; -+ -+/** -+ * Default implementation of PGXmlFactoryFactory that configures each factory per OWASP recommendations. -+ * -+ * @see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html -+ */ -+public class DefaultPGXmlFactoryFactory implements PGXmlFactoryFactory { -+ public static final DefaultPGXmlFactoryFactory INSTANCE = new DefaultPGXmlFactoryFactory(); -+ -+ private DefaultPGXmlFactoryFactory() { -+ } -+ -+ private DocumentBuilderFactory getDocumentBuilderFactory() { -+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); -+ setFactoryProperties(factory); -+ factory.setXIncludeAware(false); -+ factory.setExpandEntityReferences(false); -+ return factory; -+ } -+ -+ @Override -+ public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { -+ DocumentBuilder builder = getDocumentBuilderFactory().newDocumentBuilder(); -+ builder.setEntityResolver(EmptyStringEntityResolver.INSTANCE); -+ builder.setErrorHandler(NullErrorHandler.INSTANCE); -+ return builder; -+ } -+ -+ @Override -+ public TransformerFactory newTransformerFactory() { -+ TransformerFactory factory = TransformerFactory.newInstance(); -+ setFactoryProperties(factory); -+ return factory; -+ } -+ -+ @Override -+ public SAXTransformerFactory newSAXTransformerFactory() { -+ SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); -+ setFactoryProperties(factory); -+ return factory; -+ } -+ -+ @Override -+ public XMLInputFactory newXMLInputFactory() { -+ XMLInputFactory factory = XMLInputFactory.newInstance(); -+ setPropertyQuietly(factory, XMLInputFactory.SUPPORT_DTD, false); -+ setPropertyQuietly(factory, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); -+ return factory; -+ } -+ -+ @Override -+ public XMLOutputFactory newXMLOutputFactory() { -+ XMLOutputFactory factory = XMLOutputFactory.newInstance(); -+ return factory; -+ } -+ -+ @Override -+ public XMLReader createXMLReader() throws SAXException { -+ XMLReader factory = XMLReaderFactory.createXMLReader(); -+ setFeatureQuietly(factory, "http://apache.org/xml/features/disallow-doctype-decl", true); -+ setFeatureQuietly(factory, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false); -+ setFeatureQuietly(factory, "http://xml.org/sax/features/external-general-entities", false); -+ setFeatureQuietly(factory, "http://xml.org/sax/features/external-parameter-entities", false); -+ factory.setErrorHandler(NullErrorHandler.INSTANCE); -+ return factory; -+ } -+ -+ private static void setFeatureQuietly(Object factory, String name, boolean value) { -+ try { -+ if (factory instanceof DocumentBuilderFactory) { -+ ((DocumentBuilderFactory) factory).setFeature(name, value); -+ } else if (factory instanceof TransformerFactory) { -+ ((TransformerFactory) factory).setFeature(name, value); -+ } else if (factory instanceof XMLReader) { -+ ((XMLReader) factory).setFeature(name, value); -+ } else { -+ throw new Error("Invalid factory class: " + factory.getClass()); -+ } -+ return; -+ } catch (Exception ignore) { -+ } -+ } -+ -+ private static void setAttributeQuietly(Object factory, String name, Object value) { -+ try { -+ if (factory instanceof DocumentBuilderFactory) { -+ ((DocumentBuilderFactory) factory).setAttribute(name, value); -+ } else if (factory instanceof TransformerFactory) { -+ ((TransformerFactory) factory).setAttribute(name, value); -+ } else { -+ throw new Error("Invalid factory class: " + factory.getClass()); -+ } -+ } catch (Exception ignore) { -+ } -+ } -+ -+ private static void setFactoryProperties(Object factory) { -+ setFeatureQuietly(factory, XMLConstants.FEATURE_SECURE_PROCESSING, true); -+ setFeatureQuietly(factory, "http://apache.org/xml/features/disallow-doctype-decl", true); -+ setFeatureQuietly(factory, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false); -+ setFeatureQuietly(factory, "http://xml.org/sax/features/external-general-entities", false); -+ setFeatureQuietly(factory, "http://xml.org/sax/features/external-parameter-entities", false); -+ // Values from XMLConstants inlined for JDK 1.6 compatibility -+ setAttributeQuietly(factory, "http://javax.xml.XMLConstants/property/accessExternalDTD", ""); -+ setAttributeQuietly(factory, "http://javax.xml.XMLConstants/property/accessExternalSchema", ""); -+ setAttributeQuietly(factory, "http://javax.xml.XMLConstants/property/accessExternalStylesheet", ""); -+ } -+ -+ private static void setPropertyQuietly(Object factory, String name, Object value) { -+ try { -+ if (factory instanceof XMLReader) { -+ ((XMLReader) factory).setProperty(name, value); -+ } else if (factory instanceof XMLInputFactory) { -+ ((XMLInputFactory) factory).setProperty(name, value); -+ } else { -+ throw new Error("Invalid factory class: " + factory.getClass()); -+ } -+ } catch (Exception ignore) { -+ } -+ } -+} -\ No newline at end of file -diff --git a/pgjdbc/src/main/java/org/postgresql/xml/EmptyStringEntityResolver.java b/pgjdbc/src/main/java/org/postgresql/xml/EmptyStringEntityResolver.java -new file mode 100644 -index 0000000..39227e0 ---- /dev/null -+++ b/pgjdbc/src/main/java/org/postgresql/xml/EmptyStringEntityResolver.java -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (c) 2020, PostgreSQL Global Development Group -+ * See the LICENSE file in the project root for more information. -+ */ -+ -+package org.postgresql.xml; -+ -+import org.xml.sax.EntityResolver; -+import org.xml.sax.InputSource; -+import org.xml.sax.SAXException; -+ -+import java.io.IOException; -+import java.io.StringReader; -+ -+public class EmptyStringEntityResolver implements EntityResolver { -+ public static final EmptyStringEntityResolver INSTANCE = new EmptyStringEntityResolver(); -+ -+ @Override -+ public InputSource resolveEntity(String publicId, String systemId) -+ throws SAXException, IOException { -+ return new InputSource(new StringReader("")); -+ } -+} -\ No newline at end of file -diff --git a/pgjdbc/src/main/java/org/postgresql/xml/LegacyInsecurePGXmlFactoryFactory.java b/pgjdbc/src/main/java/org/postgresql/xml/LegacyInsecurePGXmlFactoryFactory.java -new file mode 100644 -index 0000000..ed7a66b ---- /dev/null -+++ b/pgjdbc/src/main/java/org/postgresql/xml/LegacyInsecurePGXmlFactoryFactory.java -@@ -0,0 +1,57 @@ -+/* -+ * Copyright (c) 2020, PostgreSQL Global Development Group -+ * See the LICENSE file in the project root for more information. -+ */ -+ -+package org.postgresql.xml; -+ -+import org.xml.sax.SAXException; -+import org.xml.sax.XMLReader; -+import org.xml.sax.helpers.XMLReaderFactory; -+ -+import javax.xml.parsers.DocumentBuilder; -+import javax.xml.parsers.DocumentBuilderFactory; -+import javax.xml.parsers.ParserConfigurationException; -+import javax.xml.stream.XMLInputFactory; -+import javax.xml.stream.XMLOutputFactory; -+import javax.xml.transform.TransformerFactory; -+import javax.xml.transform.sax.SAXTransformerFactory; -+ -+public class LegacyInsecurePGXmlFactoryFactory implements PGXmlFactoryFactory { -+ public static final LegacyInsecurePGXmlFactoryFactory INSTANCE = new LegacyInsecurePGXmlFactoryFactory(); -+ -+ private LegacyInsecurePGXmlFactoryFactory() { -+ } -+ -+ @Override -+ public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { -+ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); -+ builder.setErrorHandler(NullErrorHandler.INSTANCE); -+ return builder; -+ } -+ -+ @Override -+ public TransformerFactory newTransformerFactory() { -+ return TransformerFactory.newInstance(); -+ } -+ -+ @Override -+ public SAXTransformerFactory newSAXTransformerFactory() { -+ return (SAXTransformerFactory) SAXTransformerFactory.newInstance(); -+ } -+ -+ @Override -+ public XMLInputFactory newXMLInputFactory() { -+ return XMLInputFactory.newInstance(); -+ } -+ -+ @Override -+ public XMLOutputFactory newXMLOutputFactory() { -+ return XMLOutputFactory.newInstance(); -+ } -+ -+ @Override -+ public XMLReader createXMLReader() throws SAXException { -+ return XMLReaderFactory.createXMLReader(); -+ } -+} -\ No newline at end of file -diff --git a/pgjdbc/src/main/java/org/postgresql/xml/NullErrorHandler.java b/pgjdbc/src/main/java/org/postgresql/xml/NullErrorHandler.java -new file mode 100644 -index 0000000..ad486c7 ---- /dev/null -+++ b/pgjdbc/src/main/java/org/postgresql/xml/NullErrorHandler.java -@@ -0,0 +1,25 @@ -+/* -+ * Copyright (c) 2020, PostgreSQL Global Development Group -+ * See the LICENSE file in the project root for more information. -+ */ -+ -+package org.postgresql.xml; -+ -+import org.xml.sax.ErrorHandler; -+import org.xml.sax.SAXParseException; -+ -+/** -+ * Error handler that silently suppresses all errors. -+ */ -+public class NullErrorHandler implements ErrorHandler { -+ public static final NullErrorHandler INSTANCE = new NullErrorHandler(); -+ -+ public void error(SAXParseException e) { -+ } -+ -+ public void fatalError(SAXParseException e) { -+ } -+ -+ public void warning(SAXParseException e) { -+ } -+} -\ No newline at end of file -diff --git a/pgjdbc/src/main/java/org/postgresql/xml/PGXmlFactoryFactory.java b/pgjdbc/src/main/java/org/postgresql/xml/PGXmlFactoryFactory.java -new file mode 100644 -index 0000000..4bb98e4 ---- /dev/null -+++ b/pgjdbc/src/main/java/org/postgresql/xml/PGXmlFactoryFactory.java -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (c) 2020, PostgreSQL Global Development Group -+ * See the LICENSE file in the project root for more information. -+ */ -+ -+package org.postgresql.xml; -+ -+import org.xml.sax.SAXException; -+import org.xml.sax.XMLReader; -+ -+import javax.xml.parsers.DocumentBuilder; -+import javax.xml.parsers.ParserConfigurationException; -+import javax.xml.stream.XMLInputFactory; -+import javax.xml.stream.XMLOutputFactory; -+import javax.xml.transform.TransformerFactory; -+import javax.xml.transform.sax.SAXTransformerFactory; -+ -+public interface PGXmlFactoryFactory { -+ DocumentBuilder newDocumentBuilder() throws ParserConfigurationException; -+ -+ TransformerFactory newTransformerFactory(); -+ -+ SAXTransformerFactory newSAXTransformerFactory(); -+ -+ XMLInputFactory newXMLInputFactory(); -+ -+ XMLOutputFactory newXMLOutputFactory(); -+ -+ XMLReader createXMLReader() throws SAXException; -+} -\ No newline at end of file -diff --git a/pgjdbc/src/test/java/org/postgresql/jdbc/PgSQLXMLTest.java b/pgjdbc/src/test/java/org/postgresql/jdbc/PgSQLXMLTest.java -index 53fd56d..49e389c 100644 ---- a/pgjdbc/src/test/java/org/postgresql/jdbc/PgSQLXMLTest.java -+++ b/pgjdbc/src/test/java/org/postgresql/jdbc/PgSQLXMLTest.java -@@ -8,18 +8,36 @@ package org.postgresql.jdbc; - import static org.junit.Assert.assertEquals; - import static org.junit.Assert.assertNotNull; - import static org.junit.Assert.assertTrue; -+import static org.junit.Assert.fail; - -+import org.postgresql.PGProperty; -+import org.postgresql.core.BaseConnection; - import org.postgresql.test.TestUtil; - import org.postgresql.test.jdbc2.BaseTest4; - - import org.junit.Before; - import org.junit.Test; - -+import java.io.StringWriter; - import java.io.Writer; -+import java.sql.Connection; - import java.sql.PreparedStatement; - import java.sql.ResultSet; -+import java.sql.SQLException; - import java.sql.SQLXML; - import java.sql.Statement; -+import java.util.Properties; -+ -+import javax.xml.stream.XMLStreamException; -+import javax.xml.stream.XMLStreamReader; -+import javax.xml.transform.Source; -+import javax.xml.transform.Transformer; -+import javax.xml.transform.TransformerException; -+import javax.xml.transform.TransformerFactory; -+import javax.xml.transform.dom.DOMSource; -+import javax.xml.transform.sax.SAXSource; -+import javax.xml.transform.stax.StAXSource; -+import javax.xml.transform.stream.StreamResult; - - public class PgSQLXMLTest extends BaseTest4 { - -@@ -27,17 +45,17 @@ public class PgSQLXMLTest extends BaseTest4 { - @Before - public void setUp() throws Exception { - super.setUp(); -- TestUtil.createTempTable(con, "xmltab","x xml"); -+ TestUtil.createTempTable(con, "xmltab", "x xml"); - } - - @Test -- public void setCharacterStream() throws Exception { -+ public void setCharacterStream() throws Exception { - String exmplar = "value"; - SQLXML pgSQLXML = con.createSQLXML(); - Writer writer = pgSQLXML.setCharacterStream(); - writer.write(exmplar); - PreparedStatement preparedStatement = con.prepareStatement("insert into xmltab values (?)"); -- preparedStatement.setSQLXML(1,pgSQLXML); -+ preparedStatement.setSQLXML(1, pgSQLXML); - preparedStatement.execute(); - - Statement statement = con.createStatement(); -@@ -47,4 +65,60 @@ public class PgSQLXMLTest extends BaseTest4 { - assertNotNull(result); - assertEquals(exmplar, result.getString()); - } -+ -+ private static final String LICENSE_URL = -+ PgSQLXMLTest.class.getClassLoader().getResource("META-INF/LICENSE").toString(); -+ private static final String XXE_EXAMPLE = -+ "\n" -+ + "]>" -+ + "&xxe;"; -+ -+ @Test -+ public void testLegacyXxe() throws Exception { -+ Properties props = new Properties(); -+ props.setProperty(PGProperty.XML_FACTORY_FACTORY.getName(), "LEGACY_INSECURE"); -+ try (Connection conn = TestUtil.openDB(props)) { -+ BaseConnection baseConn = conn.unwrap(BaseConnection.class); -+ PgSQLXML xml = new PgSQLXML(baseConn, XXE_EXAMPLE); -+ xml.getSource(null); -+ } -+ } -+ -+ private static String sourceToString(Source source) throws TransformerException { -+ StringWriter sw = new StringWriter(); -+ Transformer transformer = TransformerFactory.newInstance().newTransformer(); -+ transformer.transform(source, new StreamResult(sw)); -+ return sw.toString(); -+ } -+ -+ @Test(expected = SQLException.class) -+ public void testGetSourceXxeNull() throws Exception { -+ PgSQLXML xml = new PgSQLXML(null, XXE_EXAMPLE); -+ xml.getSource(null); -+ } -+ -+ @Test(expected = SQLException.class) -+ public void testGetSourceXxeDOMSource() throws Exception { -+ PgSQLXML xml = new PgSQLXML(null, XXE_EXAMPLE); -+ xml.getSource(DOMSource.class); -+ } -+ -+ @Test(expected = TransformerException.class) -+ public void testGetSourceXxeSAXSource() throws Exception { -+ PgSQLXML xml = new PgSQLXML(null, XXE_EXAMPLE); -+ SAXSource source = xml.getSource(SAXSource.class); -+ sourceToString(source); -+ -+ } -+ -+ @Test(expected = XMLStreamException.class) -+ public void testGetSourceXxeStAXSource() throws Exception { -+ PgSQLXML xml = new PgSQLXML(null, XXE_EXAMPLE); -+ StAXSource source = xml.getSource(StAXSource.class); -+ XMLStreamReader reader = source.getXMLStreamReader(); -+ // STAX will not throw XXE error until we actually read the element -+ while (reader.hasNext()) { -+ reader.next(); -+ } -+ } - } --- -2.26.0 - diff --git a/postgresql-jdbc.spec b/postgresql-jdbc.spec index e75a51e..0210b04 100644 --- a/postgresql-jdbc.spec +++ b/postgresql-jdbc.spec @@ -43,43 +43,35 @@ %{!?runselftest:%global runselftest 1} - %global section devel %global source_path pgjdbc/src/main/java/org/postgresql -%global parent_ver 1.1.6 -%global parent_poms_builddir ./pgjdbc-parent-poms - -%global pgjdbc_mvn_options -DwaffleEnabled=false -DosgiEnabled=false \\\ - -DexcludePackageNames=org.postgresql.osgi:org.postgresql.sspi Summary: JDBC driver for PostgreSQL Name: postgresql-jdbc -Version: 42.2.12 -Release: 2%{?dist} +Version: 42.2.15 +Release: 1%{?dist} License: BSD URL: http://jdbc.postgresql.org/ -Source0: https://github.com/pgjdbc/pgjdbc/archive/REL%{version}/pgjdbc-REL%{version}.tar.gz +Source0: https://repo1.maven.org/maven2/org/postgresql/postgresql/%{version}/postgresql-%{version}-jdbc-src.tar.gz Provides: pgjdbc = %version-%release -Patch0: fix-XXE-vulnerability.patch - -# Upstream moved parent pom.xml into separate project (even though there is only -# one dependant project on it?). Let's try to not complicate packaging by -# having separate spec file for it, too. -Source1: https://github.com/pgjdbc/pgjdbc-parent-poms/archive/REL%parent_ver/pgjdbc-parent-poms-REL%{parent_ver}.tar.gz - BuildArch: noarch BuildRequires: java-devel >= 1.8 BuildRequires: maven-local +BuildRequires: maven-javadoc-plugin BuildRequires: java-comment-preprocessor BuildRequires: maven-enforcer-plugin BuildRequires: maven-plugin-bundle -BuildRequires: maven-plugin-build-helper BuildRequires: classloader-leak-test-framework BuildRequires: mvn(com.ongres.scram:client) BuildRequires: mvn(org.apache.maven.plugins:maven-clean-plugin) +BuildRequires: mvn(org.apache.maven.surefire:surefire-junit-platform) +BuildRequires: mvn(org.junit.jupiter:junit-jupiter-api) +BuildRequires: mvn(org.junit.jupiter:junit-jupiter-engine) +BuildRequires: mvn(org.junit.jupiter:junit-jupiter-params) +BuildRequires: mvn(org.junit.vintage:junit-vintage-engine) %if %runselftest BuildRequires: postgresql-contrib @@ -105,41 +97,23 @@ This package contains the API Documentation for %{name}. %prep -%setup -c -q -a 1 +%setup -c -q -mv pgjdbc-REL%version/* . -mv pgjdbc-parent-poms-REL%parent_ver pgjdbc-parent-poms - -%patch0 -p1 +mv postgresql-%{version}-jdbc-src/* . # remove any binary libs -find -name "*.jar" -or -name "*.class" | xargs rm -f +find -type f \( -name "*.jar" -or -name "*.class" \) | xargs rm -f # Build parent POMs in the same Maven call. -%pom_xpath_inject pom:modules "%parent_poms_builddir" -%pom_xpath_inject pom:parent "pgjdbc-parent-poms/pgjdbc-versions" -%pom_xpath_set pom:relativePath ../pgjdbc-parent-poms/pgjdbc-core-parent pgjdbc -%pom_xpath_remove "pom:plugin[pom:artifactId = 'maven-shade-plugin']" pgjdbc -%pom_remove_plugin :karaf-maven-plugin pgjdbc -%pom_remove_plugin :properties-maven-plugin pgjdbc-parent-poms/pgjdbc-core-parent -%pom_remove_plugin :properties-maven-plugin pgjdbc-parent-poms/pgjdbc-versions - +%pom_xpath_remove "pom:plugin[pom:artifactId = 'maven-shade-plugin']" # compat symlink: requested by dtardon (libreoffice), reverts part of # 0af97ce32de877 commit. %mvn_file org.postgresql:postgresql %{name}/postgresql %{name} postgresql -# Parent POMs should not be installed. -%mvn_package ":*{parent,versions,prevjre}*" __noinstall - # For compat reasons, make Maven artifact available under older coordinates. %mvn_alias org.postgresql:postgresql postgresql:postgresql -# Hack #1! This directory is missing for some reason, it is most probably some -# misunderstanding between maven, maven-compiler-plugin and -# java-comment-preprocessor? Not solved yet. See rhbz#1325060. -mkdir -p pgjdbc/target/generated-sources/annotations - %build # Ideally we would run "sh update-translations.sh" here, but that results @@ -174,7 +148,7 @@ EOF opts="-f" %endif -%mvn_build $opts --xmvn-javadoc -- %pgjdbc_mvn_options +%mvn_build $opts --xmvn-javadoc %install @@ -191,6 +165,9 @@ opts="-f" %changelog +* Fri Jul 24 2020 Ondrej Dubaj - 42.2.15-1 +- rebased to version 42.2.15 + * Fri Jul 24 2020 Ondrej Dubaj - 42.2.12-2 - fixed XXE vulnerability (CVE-2020-13692) - fixed javadoc build problem diff --git a/sources b/sources index 299eea8..fe04bbe 100644 --- a/sources +++ b/sources @@ -1,2 +1 @@ -SHA512 (pgjdbc-REL42.2.12.tar.gz) = 60f93e02e7f6f507e2bec649c6a28c4893a03eca975e9a2755ce9fda4b5bb525adb791359efad1cfb3d0c5d0af036092552c3b6b6a61a98eb1cb93df6e5f4d3f -SHA512 (pgjdbc-parent-poms-REL1.1.6.tar.gz) = 38e34a167744476568220e979bbc4139e43537f693e5e3e969ce58dc79d5b6361e92918d7f235ae9c00786b6997ad6bd98c6b680a6e59c5219da00b8b9b5760d +SHA512 (postgresql-42.2.15-jdbc-src.tar.gz) = 7a9ce733f70638f0dee9fb04103d1f4703e9bd611fc8845e88630a5d8b24659a811fe5e9c0cafea88b98e29da9e1b6f0e5f1af15f26b5f915e40886f120b181d From 0fcbd34cee34c81c66ea752b3a57f18cd9d15dc6 Mon Sep 17 00:00:00 2001 From: Ondrej Dubaj Date: Wed, 26 Aug 2020 07:27:52 +0200 Subject: [PATCH 4/5] Rebased to version 42.2.16 --- .gitignore | 1 + postgresql-jdbc.spec | 5 ++++- sources | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6faa3a4..ead38f8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /pgjdbc-parent-poms-REL*.tar.gz /pgjdbc-v42.3.0-rc2.tar.gz /postgresql-42.2.15-jdbc-src.tar.gz +/postgresql-42.2.16-jdbc-src.tar.gz diff --git a/postgresql-jdbc.spec b/postgresql-jdbc.spec index 0210b04..f74439c 100644 --- a/postgresql-jdbc.spec +++ b/postgresql-jdbc.spec @@ -48,7 +48,7 @@ Summary: JDBC driver for PostgreSQL Name: postgresql-jdbc -Version: 42.2.15 +Version: 42.2.16 Release: 1%{?dist} License: BSD URL: http://jdbc.postgresql.org/ @@ -165,6 +165,9 @@ opts="-f" %changelog +* Wed Aug 26 2020 Ondrej Dubaj - 42.2.16-1 +- rebased to version 42.2.16 + * Fri Jul 24 2020 Ondrej Dubaj - 42.2.15-1 - rebased to version 42.2.15 diff --git a/sources b/sources index fe04bbe..34b3230 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (postgresql-42.2.15-jdbc-src.tar.gz) = 7a9ce733f70638f0dee9fb04103d1f4703e9bd611fc8845e88630a5d8b24659a811fe5e9c0cafea88b98e29da9e1b6f0e5f1af15f26b5f915e40886f120b181d +SHA512 (postgresql-42.2.16-jdbc-src.tar.gz) = 41e8be4f83b01f96ccb1c80f8616087e26f2fc04ecb3a7ea5766632614956b92eb5efed76d448d44a2329f7b76dde0642f670892d58094e9b4fb0fcfbc06119c From 8d064e511ec268f10ab8748264a6a58bf0f3d2b9 Mon Sep 17 00:00:00 2001 From: Ondrej Dubaj Date: Tue, 20 Oct 2020 09:32:12 +0200 Subject: [PATCH 5/5] Rebased to version 42.2.18 --- .gitignore | 1 + postgresql-jdbc.spec | 6 ++++-- sources | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index ead38f8..6256606 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /pgjdbc-v42.3.0-rc2.tar.gz /postgresql-42.2.15-jdbc-src.tar.gz /postgresql-42.2.16-jdbc-src.tar.gz +/postgresql-42.2.18-jdbc-src.tar.gz diff --git a/postgresql-jdbc.spec b/postgresql-jdbc.spec index f74439c..6ecdb3b 100644 --- a/postgresql-jdbc.spec +++ b/postgresql-jdbc.spec @@ -48,7 +48,7 @@ Summary: JDBC driver for PostgreSQL Name: postgresql-jdbc -Version: 42.2.16 +Version: 42.2.18 Release: 1%{?dist} License: BSD URL: http://jdbc.postgresql.org/ @@ -60,7 +60,6 @@ BuildArch: noarch BuildRequires: java-devel >= 1.8 BuildRequires: maven-local BuildRequires: maven-javadoc-plugin -BuildRequires: java-comment-preprocessor BuildRequires: maven-enforcer-plugin BuildRequires: maven-plugin-bundle BuildRequires: classloader-leak-test-framework @@ -165,6 +164,9 @@ opts="-f" %changelog +* Tue Oct 20 2020 Ondrej Dubaj - 42.2.18-1 +- rebase to version 42.2.18 + * Wed Aug 26 2020 Ondrej Dubaj - 42.2.16-1 - rebased to version 42.2.16 diff --git a/sources b/sources index 34b3230..59f962f 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (postgresql-42.2.16-jdbc-src.tar.gz) = 41e8be4f83b01f96ccb1c80f8616087e26f2fc04ecb3a7ea5766632614956b92eb5efed76d448d44a2329f7b76dde0642f670892d58094e9b4fb0fcfbc06119c +SHA512 (postgresql-42.2.18-jdbc-src.tar.gz) = 694458f9b58a1470f0fd2c77870bf73f21818a5112d446ddabb819730616be7e2f038ed132c970ba4285fb4c956c4e8a888b664270eb6493510d1e14d30a4961