+Date: Tue, 31 Mar 2020 16:58:31 +0100
+Subject: [PATCH 1/6] Javax Servlet API
+
+---
+ dist/pom.xml | 2 +-
+ pom.xml | 4 +-
+ server/pom.xml | 8 ++-
+ .../webserver/HttpServletRequestImpl.java | 54 +++++++++++++++++++
+ .../webserver/HttpServletResponseImpl.java | 26 ++++++++-
+ .../webserver/ServletOutputStreamImpl.java | 5 ++
+ 6 files changed, 94 insertions(+), 5 deletions(-)
+
+diff --git a/dist/pom.xml b/dist/pom.xml
+index 67aded6..590f750 100644
+--- a/dist/pom.xml
++++ b/dist/pom.xml
+@@ -59,7 +59,7 @@
+
+
+ javax.servlet
+- servlet-api
++ javax.servlet-api
+
+
+ org.apache.xmlrpc
+diff --git a/pom.xml b/pom.xml
+index 3933da5..5e18625 100644
+--- a/pom.xml
++++ b/pom.xml
+@@ -344,8 +344,8 @@
+
+
+ javax.servlet
+- servlet-api
+- 2.4
++ javax.servlet-api
++ 3.1.0
+ provided
+
+
+diff --git a/server/pom.xml b/server/pom.xml
+index 0d09544..6cbc6e7 100644
+--- a/server/pom.xml
++++ b/server/pom.xml
+@@ -67,6 +67,12 @@
+
+ commons-logging
+ commons-logging
++
++
++ javax.servlet
++ servlet-api
++
++
+
+
+ org.apache.xmlrpc
+@@ -81,7 +87,7 @@
+
+
+ javax.servlet
+- servlet-api
++ javax.servlet-api
+
+
+ commons-httpclient
+diff --git a/server/src/main/java/org/apache/xmlrpc/webserver/HttpServletRequestImpl.java b/server/src/main/java/org/apache/xmlrpc/webserver/HttpServletRequestImpl.java
+index 3dc7e43..19b14a2 100644
+--- a/server/src/main/java/org/apache/xmlrpc/webserver/HttpServletRequestImpl.java
++++ b/server/src/main/java/org/apache/xmlrpc/webserver/HttpServletRequestImpl.java
+@@ -31,6 +31,7 @@ import java.net.URLDecoder;
+ import java.security.Principal;
+ import java.util.ArrayList;
+ import java.util.Collections;
++import java.util.Collection;
+ import java.util.Enumeration;
+ import java.util.HashMap;
+ import java.util.Iterator;
+@@ -39,10 +40,20 @@ import java.util.Locale;
+ import java.util.Map;
+ import java.util.StringTokenizer;
+
++import javax.servlet.ReadListener;
+ import javax.servlet.RequestDispatcher;
++import javax.servlet.ServletException;
+ import javax.servlet.ServletInputStream;
++import javax.servlet.DispatcherType;
++import javax.servlet.AsyncContext;
++import javax.servlet.ServletContext;
++import javax.servlet.ServletRequest;
++import javax.servlet.ServletResponse;
+ import javax.servlet.http.Cookie;
++import javax.servlet.http.HttpUpgradeHandler;
++import javax.servlet.http.Part;
+ import javax.servlet.http.HttpServletRequest;
++import javax.servlet.http.HttpServletResponse;
+ import javax.servlet.http.HttpSession;
+
+ import org.apache.xmlrpc.common.XmlRpcStreamConfig;
+@@ -66,6 +77,7 @@ public class HttpServletRequestImpl implements HttpServletRequest {
+ private String queryString;
+ private String httpVersion;
+ private final Map headers = new HashMap();
++ private final Map parts = new HashMap();
+ private final Map attributes = new HashMap();
+ private Map parameters;
+ private String characterEncoding;
+@@ -97,6 +109,18 @@ public class HttpServletRequestImpl implements HttpServletRequest {
+ }
+ return c;
+ }
++
++ public boolean isFinished() {
++ return contentBytesRemaining == 0;
++ }
++
++ public boolean isReady() {
++ return true;
++ }
++
++ public void setReadListener(ReadListener arg0) {
++ throw new IllegalStateException("Not implemented.");
++ }
+ };
+ }
+
+@@ -227,6 +251,12 @@ public class HttpServletRequestImpl implements HttpServletRequest {
+ return Collections.enumeration(list);
+ }
+
++ public Part getPart(String name) { throw new IllegalStateException("Not implemented"); }
++
++ public Collection getParts() { throw new IllegalStateException("Not implemented"); }
++
++ public boolean authenticate (HttpServletResponse response) { throw new IllegalStateException("Not implemented"); }
++
+ public int getIntHeader(String pHeader) {
+ String s = getHeader(pHeader);
+ return s == null ? -1 : Integer.parseInt(s);
+@@ -242,6 +272,10 @@ public class HttpServletRequestImpl implements HttpServletRequest {
+
+ public String getRemoteUser() { throw new IllegalStateException("Not implemented"); }
+
++ public void login(String username, String password) { throw new IllegalStateException("Not implemented"); }
++
++ public void logout() { throw new IllegalStateException("Not implemented"); }
++
+ public String getRequestURI() { return uri; }
+
+ public StringBuffer getRequestURL() {
+@@ -280,6 +314,20 @@ public class HttpServletRequestImpl implements HttpServletRequest {
+ return sb;
+ }
+
++ public AsyncContext getAsyncContext() { throw new IllegalStateException("Not implemented"); }
++
++ public boolean isAsyncSupported() { return false; }
++
++ public boolean isAsyncStarted() { return false; }
++
++ public ServletContext getServletContext() { throw new IllegalStateException("Not implemented"); }
++
++ public AsyncContext startAsync(ServletRequest req, ServletResponse resp) { throw new IllegalStateException("Not implemented"); }
++
++ public AsyncContext startAsync() { throw new IllegalStateException("Not implemented"); }
++
++ public DispatcherType getDispatcherType() { throw new IllegalStateException("Not implemented"); }
++
+ public String getRequestedSessionId() { throw new IllegalStateException("Not implemented"); }
+
+ public String getServletPath() { return uri; }
+@@ -544,4 +592,10 @@ public class HttpServletRequestImpl implements HttpServletRequest {
+ }
+
+ protected String getHttpVersion() { return httpVersion; }
++
++ public long getContentLengthLong() { throw new IllegalStateException("Not implemented."); }
++
++ public String changeSessionId() { throw new IllegalStateException("Not implemented."); }
++
++ public HttpUpgradeHandler upgrade(Class arg0) { throw new IllegalStateException("Not implemented."); }
+ }
+diff --git a/server/src/main/java/org/apache/xmlrpc/webserver/HttpServletResponseImpl.java b/server/src/main/java/org/apache/xmlrpc/webserver/HttpServletResponseImpl.java
+index 6ba7018..5319dcf 100644
+--- a/server/src/main/java/org/apache/xmlrpc/webserver/HttpServletResponseImpl.java
++++ b/server/src/main/java/org/apache/xmlrpc/webserver/HttpServletResponseImpl.java
+@@ -29,6 +29,8 @@ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Locale;
+ import java.util.Map;
++import java.util.Collection;
++import java.util.Collections;
+ import java.util.StringTokenizer;
+
+ import javax.servlet.ServletOutputStream;
+@@ -84,7 +86,7 @@ public class HttpServletResponseImpl implements HttpServletResponse {
+ }
+ }
+
+- private String getHeader(String pHeader) {
++ public String getHeader(String pHeader) {
+ String key = pHeader.toLowerCase();
+ Object o = headers.get(key);
+ if (o == null) {
+@@ -101,6 +103,26 @@ public class HttpServletResponseImpl implements HttpServletResponse {
+ }
+ }
+
++ public Collection getHeaderNames() {
++ return headers.keySet();
++ }
++
++ public Collection getHeaders(String pHeader) {
++ String key = pHeader.toLowerCase();
++ Object o = headers.get(key);
++ List list;
++ if (o instanceof List) {
++ list = (List) o;
++ } else {
++ list = Collections.singletonList(o);
++ }
++ return list;
++ }
++
++ public int getStatus() {
++ return status;
++ }
++
+ public void addIntHeader(String pHeader, int pValue) {
+ addHeader(pHeader, Integer.toString(pValue));
+ }
+@@ -465,4 +487,6 @@ public class HttpServletResponseImpl implements HttpServletResponse {
+ sb.append("\r\n");
+ return sb.toString();
+ }
++
++ public void setContentLengthLong(long arg0) { throw new IllegalStateException("Not implemented."); }
+ }
+diff --git a/server/src/main/java/org/apache/xmlrpc/webserver/ServletOutputStreamImpl.java b/server/src/main/java/org/apache/xmlrpc/webserver/ServletOutputStreamImpl.java
+index c2a53b1..86dbbb4 100644
+--- a/server/src/main/java/org/apache/xmlrpc/webserver/ServletOutputStreamImpl.java
++++ b/server/src/main/java/org/apache/xmlrpc/webserver/ServletOutputStreamImpl.java
+@@ -22,6 +22,7 @@ import java.io.IOException;
+ import java.io.OutputStream;
+
+ import javax.servlet.ServletOutputStream;
++import javax.servlet.WriteListener;
+
+
+ /** Default implementation of a servlet output stream.
+@@ -99,4 +100,8 @@ class ServletOutputStreamImpl extends ServletOutputStream {
+ boolean isCommitted() {
+ return committed;
+ }
++
++ public boolean isReady() { return true; }
++
++ public void setWriteListener(WriteListener arg0) { throw new IllegalStateException("Not implemented."); }
+ }
+--
+2.26.0.rc2
+
diff --git a/0002-Add-OSGi-metadata.patch b/0002-Add-OSGi-metadata.patch
new file mode 100644
index 0000000..b3e4c77
--- /dev/null
+++ b/0002-Add-OSGi-metadata.patch
@@ -0,0 +1,74 @@
+From 56ed627f9d69a9c065aab02e8f7d07524d4fa315 Mon Sep 17 00:00:00 2001
+From: Mat Booth
+Date: Tue, 31 Mar 2020 17:00:03 +0100
+Subject: [PATCH 2/6] Add OSGi metadata
+
+---
+ client/pom.xml | 11 +++++++++++
+ common/pom.xml | 10 ++++++++++
+ server/pom.xml | 6 ++++++
+ 3 files changed, 27 insertions(+)
+
+diff --git a/client/pom.xml b/client/pom.xml
+index e588657..f31b2d2 100644
+--- a/client/pom.xml
++++ b/client/pom.xml
+@@ -48,6 +48,17 @@
+ org.apache
+ Apache Software Foundation
+ ${project.version}
++ 2
++ %Bundle-Name
++ plugin
++ org.apache.xmlrpc
++ ${project.version}
++ org.apache.xmlrpc.common
++ org.apache.xmlrpc, org.apache.xmlrpc.client, org.apache.xmlrpc.client.util
++ javax.xml.namespace, javax.xml.parsers, org.apache.commons.httpclient, org.apache.commons.httpclient.auth, org.apache.commons.httpclient.methods, org.apache.commons.httpclient.params, org.apache.commons.logging, org.apache.ws.commons.serialize, org.apache.ws.commons.util, org.w3c.dom, org.xml.sax, org.xml.sax.helpers
++ J2SE-1.4, CDC-1.0/Foundation-1.0, J2SE-1.3
++ dependent
++ %Bundle-Vendor.0
+
+
+
+diff --git a/common/pom.xml b/common/pom.xml
+index 5058d50..7a5bf49 100644
+--- a/common/pom.xml
++++ b/common/pom.xml
+@@ -48,6 +48,16 @@
+ org.apache
+ Apache Software Foundation
+ ${project.version}
++ 2
++ %Bundle-Name
++ plugin
++ org.apache.xmlrpc.common
++ ${project.version}
++ org.apache.xmlrpc, org.apache.xmlrpc.common, org.apache.xmlrpc.jaxb, org.apache.xmlrpc.parser, org.apache.xmlrpc.serializer, org.apache.xmlrpc.util
++ javax.xml.namespace, javax.xml.parsers, org.apache.commons.httpclient, org.apache.commons.httpclient.auth, org.apache.commons.httpclient.methods, org.apache.commons.httpclient.params, org.apache.commons.logging, org.apache.ws.commons.serialize, org.apache.ws.commons.util, org.w3c.dom, org.xml.sax, org.xml.sax.helpers
++ J2SE-1.4, CDC-1.0/Foundation-1.0, J2SE-1.3
++ dependent
++ %Bundle-Vendor.0
+
+
+
+diff --git a/server/pom.xml b/server/pom.xml
+index 6cbc6e7..4c90e50 100644
+--- a/server/pom.xml
++++ b/server/pom.xml
+@@ -48,6 +48,12 @@
+ org.apache
+ Apache Software Foundation
+ ${project.version}
++ 1
++ %Bundle-Name
++ org.apache.xmlrpc.server
++ ${project.version}
++ org.apache.xmlrpc.common
++ org.apache.xmlrpc.server,org.apache.xmlrpc.webserver
+
+
+
+--
+2.26.0.rc2
+
diff --git a/0003-disallow-deserialization-of-ex-serializable-tags.patch b/0003-disallow-deserialization-of-ex-serializable-tags.patch
new file mode 100644
index 0000000..0b568c7
--- /dev/null
+++ b/0003-disallow-deserialization-of-ex-serializable-tags.patch
@@ -0,0 +1,71 @@
+From febe70f7ca78926660a7d11607a35f663165322a Mon Sep 17 00:00:00 2001
+From: Mat Booth
+Date: Tue, 31 Mar 2020 17:01:29 +0100
+Subject: [PATCH 3/6] disallow deserialization of ex serializable tags
+
+---
+ .../xmlrpc/parser/SerializableParser.java | 8 ++++++
+ .../java/org/apache/xmlrpc/test/BaseTest.java | 28 -------------------
+ 2 files changed, 8 insertions(+), 28 deletions(-)
+
+diff --git a/common/src/main/java/org/apache/xmlrpc/parser/SerializableParser.java b/common/src/main/java/org/apache/xmlrpc/parser/SerializableParser.java
+index 18f25ac..c8bb7ed 100644
+--- a/common/src/main/java/org/apache/xmlrpc/parser/SerializableParser.java
++++ b/common/src/main/java/org/apache/xmlrpc/parser/SerializableParser.java
+@@ -29,6 +29,14 @@ import org.apache.xmlrpc.XmlRpcException;
+ */
+ public class SerializableParser extends ByteArrayParser {
+ public Object getResult() throws XmlRpcException {
++ if (!"1".equals(System.getProperty("org.apache.xmlrpc.allowInsecureDeserialization"))) {
++ throw new UnsupportedOperationException(
++ "Deserialization of ex:serializable objects is vulnerable to " +
++ "remote execution attacks and is disabled by default. " +
++ "If you are sure the source data is trusted, you can enable " +
++ "it by setting org.apache.xmlrpc.allowInsecureDeserialization " +
++ "JVM property to 1");
++ }
+ try {
+ byte[] res = (byte[]) super.getResult();
+ ByteArrayInputStream bais = new ByteArrayInputStream(res);
+diff --git a/server/src/test/java/org/apache/xmlrpc/test/BaseTest.java b/server/src/test/java/org/apache/xmlrpc/test/BaseTest.java
+index 16699a6..6ad4b5e 100644
+--- a/server/src/test/java/org/apache/xmlrpc/test/BaseTest.java
++++ b/server/src/test/java/org/apache/xmlrpc/test/BaseTest.java
+@@ -805,34 +805,6 @@ public class BaseTest extends XmlRpcTestCase {
+ assertTrue(ok);
+ }
+
+- /** Test, whether we can invoke a method, passing an instance of
+- * {@link java.io.Serializable} as a parameter.
+- * @throws Exception The test failed.
+- */
+- public void testSerializableParam() throws Exception {
+- for (int i = 0; i < providers.length; i++) {
+- testSerializableParam(providers[i]);
+- }
+- }
+-
+- private void testSerializableParam(ClientProvider pProvider) throws Exception {
+- final String methodName = "Remote.serializableParam";
+- Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+- cal.set(2005, 5, 23, 8, 4, 0);
+- cal.set(Calendar.MILLISECOND, 5);
+- final Object[] params = new Object[]{new Remote.CalendarWrapper(cal)};
+- final XmlRpcClient client = pProvider.getClient();
+- Object result = client.execute(getExConfig(pProvider), methodName, params);
+- assertEquals(new Long(cal.getTime().getTime()), result);
+- boolean ok = false;
+- try {
+- client.execute(getConfig(pProvider), methodName, params);
+- } catch (XmlRpcExtensionException e) {
+- ok = true;
+- }
+- assertTrue(ok);
+- }
+-
+ /** Tests, whether we can invoke a method, passing an instance of
+ * {@link Calendar} as a parameter.
+ * @throws Exception The test failed.
+--
+2.26.0.rc2
+
diff --git a/0004-disallow-loading-external-dtd.patch b/0004-disallow-loading-external-dtd.patch
new file mode 100644
index 0000000..f522b77
--- /dev/null
+++ b/0004-disallow-loading-external-dtd.patch
@@ -0,0 +1,30 @@
+From 2c16d38ab18039327b2575f61c3035683f16cd7d Mon Sep 17 00:00:00 2001
+From: Mat Booth
+Date: Tue, 31 Mar 2020 17:02:12 +0100
+Subject: [PATCH 4/6] disallow loading external dtd
+
+---
+ .../src/main/java/org/apache/xmlrpc/util/SAXParsers.java | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/common/src/main/java/org/apache/xmlrpc/util/SAXParsers.java b/common/src/main/java/org/apache/xmlrpc/util/SAXParsers.java
+index b1034e7..49ef5de 100644
+--- a/common/src/main/java/org/apache/xmlrpc/util/SAXParsers.java
++++ b/common/src/main/java/org/apache/xmlrpc/util/SAXParsers.java
+@@ -48,6 +48,13 @@ public class SAXParsers {
+ } catch (org.xml.sax.SAXException e) {
+ // Ignore it
+ }
++ try {
++ spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
++ } catch (javax.xml.parsers.ParserConfigurationException e) {
++ // Ignore it
++ } catch (org.xml.sax.SAXException e) {
++ // Ignore it
++ }
+ }
+
+ /** Creates a new instance of {@link XMLReader}.
+--
+2.26.0.rc2
+
diff --git a/0005-Remove-dep-on-ancient-commons-httpclient.patch b/0005-Remove-dep-on-ancient-commons-httpclient.patch
new file mode 100644
index 0000000..1629c5a
--- /dev/null
+++ b/0005-Remove-dep-on-ancient-commons-httpclient.patch
@@ -0,0 +1,466 @@
+From 77f696a95873c6bd8cac9254579838db556044a6 Mon Sep 17 00:00:00 2001
+From: Mat Booth
+Date: Tue, 31 Mar 2020 17:18:53 +0100
+Subject: [PATCH 5/6] Remove dep on ancient commons httpclient
+
+---
+ client/pom.xml | 4 -
+ .../xmlrpc/client/XmlRpcCommonsTransport.java | 262 ------------------
+ .../client/XmlRpcCommonsTransportFactory.java | 66 -----
+ pom.xml | 6 -
+ server/pom.xml | 5 -
+ .../apache/xmlrpc/test/CommonsProvider.java | 41 ---
+ .../apache/xmlrpc/test/XmlRpcTestCase.java | 1 -
+ 7 files changed, 385 deletions(-)
+ delete mode 100644 client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java
+ delete mode 100644 client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransportFactory.java
+ delete mode 100644 server/src/test/java/org/apache/xmlrpc/test/CommonsProvider.java
+
+diff --git a/client/pom.xml b/client/pom.xml
+index f31b2d2..b78ede0 100644
+--- a/client/pom.xml
++++ b/client/pom.xml
+@@ -72,9 +72,5 @@
+ xmlrpc-common
+ 3.1.3
+
+-
+- commons-httpclient
+- commons-httpclient
+-
+
+
+diff --git a/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java b/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java
+deleted file mode 100644
+index 1e60ceb..0000000
+--- a/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java
++++ /dev/null
+@@ -1,262 +0,0 @@
+-/*
+- * Licensed to the Apache Software Foundation (ASF) under one
+- * or more contributor license agreements. See the NOTICE file
+- * distributed with this work for additional information
+- * regarding copyright ownership. The ASF licenses this file
+- * to you under the Apache License, Version 2.0 (the
+- * "License"); you may not use this file except in compliance
+- * with the License. You may obtain a copy of the License at
+- *
+- * http://www.apache.org/licenses/LICENSE-2.0
+- *
+- * Unless required by applicable law or agreed to in writing,
+- * software distributed under the License is distributed on an
+- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+- * KIND, either express or implied. See the License for the
+- * specific language governing permissions and limitations
+- * under the License.
+- */
+-package org.apache.xmlrpc.client;
+-
+-import java.io.BufferedOutputStream;
+-import java.io.FilterOutputStream;
+-import java.io.IOException;
+-import java.io.InputStream;
+-import java.io.OutputStream;
+-
+-import org.apache.commons.httpclient.Credentials;
+-import org.apache.commons.httpclient.Header;
+-import org.apache.commons.httpclient.HttpClient;
+-import org.apache.commons.httpclient.HttpException;
+-import org.apache.commons.httpclient.HttpMethod;
+-import org.apache.commons.httpclient.HttpStatus;
+-import org.apache.commons.httpclient.HttpVersion;
+-import org.apache.commons.httpclient.URI;
+-import org.apache.commons.httpclient.URIException;
+-import org.apache.commons.httpclient.UsernamePasswordCredentials;
+-import org.apache.commons.httpclient.auth.AuthScope;
+-import org.apache.commons.httpclient.methods.PostMethod;
+-import org.apache.commons.httpclient.methods.RequestEntity;
+-import org.apache.commons.httpclient.params.HttpMethodParams;
+-import org.apache.xmlrpc.XmlRpcException;
+-import org.apache.xmlrpc.XmlRpcRequest;
+-import org.apache.xmlrpc.common.XmlRpcStreamConfig;
+-import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig;
+-import org.apache.xmlrpc.util.HttpUtil;
+-import org.apache.xmlrpc.util.XmlRpcIOException;
+-import org.xml.sax.SAXException;
+-
+-
+-/** An HTTP transport factory, which is based on the Jakarta Commons
+- * HTTP Client.
+- */
+-public class XmlRpcCommonsTransport extends XmlRpcHttpTransport {
+- /**
+- * Maximum number of allowed redirects.
+- */
+- private static final int MAX_REDIRECT_ATTEMPTS = 100;
+-
+- protected final HttpClient client;
+- private static final String userAgent = USER_AGENT + " (Jakarta Commons httpclient Transport)";
+- protected PostMethod method;
+- private int contentLength = -1;
+- private XmlRpcHttpClientConfig config;
+-
+- /** Creates a new instance.
+- * @param pFactory The factory, which created this transport.
+- */
+- public XmlRpcCommonsTransport(XmlRpcCommonsTransportFactory pFactory) {
+- super(pFactory.getClient(), userAgent);
+- HttpClient httpClient = pFactory.getHttpClient();
+- if (httpClient == null) {
+- httpClient = newHttpClient();
+- }
+- client = httpClient;
+- }
+-
+- protected void setContentLength(int pLength) {
+- contentLength = pLength;
+- }
+-
+- protected HttpClient newHttpClient() {
+- return new HttpClient();
+- }
+-
+- protected void initHttpHeaders(XmlRpcRequest pRequest) throws XmlRpcClientException {
+- config = (XmlRpcHttpClientConfig) pRequest.getConfig();
+- method = newPostMethod(config);
+- super.initHttpHeaders(pRequest);
+-
+- if (config.getConnectionTimeout() != 0)
+- client.getHttpConnectionManager().getParams().setConnectionTimeout(config.getConnectionTimeout());
+-
+- if (config.getReplyTimeout() != 0)
+- client.getHttpConnectionManager().getParams().setSoTimeout(config.getReplyTimeout());
+-
+- method.getParams().setVersion(HttpVersion.HTTP_1_1);
+- }
+-
+- protected PostMethod newPostMethod(XmlRpcHttpClientConfig pConfig) {
+- return new PostMethod(pConfig.getServerURL().toString());
+- }
+-
+- protected void setRequestHeader(String pHeader, String pValue) {
+- method.setRequestHeader(new Header(pHeader, pValue));
+- }
+-
+- protected boolean isResponseGzipCompressed() {
+- Header h = method.getResponseHeader( "Content-Encoding" );
+- if (h == null) {
+- return false;
+- } else {
+- return HttpUtil.isUsingGzipEncoding(h.getValue());
+- }
+- }
+-
+- protected InputStream getInputStream() throws XmlRpcException {
+- try {
+- checkStatus(method);
+- return method.getResponseBodyAsStream();
+- } catch (HttpException e) {
+- throw new XmlRpcClientException("Error in HTTP transport: " + e.getMessage(), e);
+- } catch (IOException e) {
+- throw new XmlRpcClientException("I/O error in server communication: " + e.getMessage(), e);
+- }
+- }
+-
+- protected void setCredentials(XmlRpcHttpClientConfig pConfig) throws XmlRpcClientException {
+- String userName = pConfig.getBasicUserName();
+- if (userName != null) {
+- String enc = pConfig.getBasicEncoding();
+- if (enc == null) {
+- enc = XmlRpcStreamConfig.UTF8_ENCODING;
+- }
+- client.getParams().setParameter(HttpMethodParams.CREDENTIAL_CHARSET, enc);
+- Credentials creds = new UsernamePasswordCredentials(userName, pConfig.getBasicPassword());
+- AuthScope scope = new AuthScope(null, AuthScope.ANY_PORT, null, AuthScope.ANY_SCHEME);
+- client.getState().setCredentials(scope, creds);
+- client.getParams().setAuthenticationPreemptive(true);
+- }
+- }
+-
+- protected void close() throws XmlRpcClientException {
+- method.releaseConnection();
+- }
+-
+- protected boolean isResponseGzipCompressed(XmlRpcStreamRequestConfig pConfig) {
+- Header h = method.getResponseHeader( "Content-Encoding" );
+- if (h == null) {
+- return false;
+- } else {
+- return HttpUtil.isUsingGzipEncoding(h.getValue());
+- }
+- }
+-
+- protected boolean isRedirectRequired() {
+- switch (method.getStatusCode()) {
+- case HttpStatus.SC_MOVED_TEMPORARILY:
+- case HttpStatus.SC_MOVED_PERMANENTLY:
+- case HttpStatus.SC_SEE_OTHER:
+- case HttpStatus.SC_TEMPORARY_REDIRECT:
+- return true;
+- default:
+- return false;
+- }
+- }
+-
+- protected void resetClientForRedirect()
+- throws XmlRpcException {
+- //get the location header to find out where to redirect to
+- Header locationHeader = method.getResponseHeader("location");
+- if (locationHeader == null) {
+- throw new XmlRpcException("Invalid redirect: Missing location header");
+- }
+- String location = locationHeader.getValue();
+-
+- URI redirectUri = null;
+- URI currentUri = null;
+- try {
+- currentUri = method.getURI();
+- String charset = currentUri.getProtocolCharset();
+- redirectUri = new URI(location, true, charset);
+- method.setURI(redirectUri);
+- } catch (URIException ex) {
+- throw new XmlRpcException(ex.getMessage(), ex);
+- }
+-
+- //And finally invalidate the actual authentication scheme
+- method.getHostAuthState().invalidate();
+- }
+-
+- protected void writeRequest(final ReqWriter pWriter) throws XmlRpcException {
+- method.setRequestEntity(new RequestEntity(){
+- public boolean isRepeatable() { return true; }
+- public void writeRequest(OutputStream pOut) throws IOException {
+- try {
+- /* Make sure, that the socket is not closed by replacing it with our
+- * own BufferedOutputStream.
+- */
+- OutputStream ostream;
+- if (isUsingByteArrayOutput(config)) {
+- // No need to buffer the output.
+- ostream = new FilterOutputStream(pOut){
+- public void close() throws IOException {
+- flush();
+- }
+- };
+- } else {
+- ostream = new BufferedOutputStream(pOut){
+- public void close() throws IOException {
+- flush();
+- }
+- };
+- }
+- pWriter.write(ostream);
+- } catch (XmlRpcException e) {
+- throw new XmlRpcIOException(e);
+- } catch (SAXException e) {
+- throw new XmlRpcIOException(e);
+- }
+- }
+- public long getContentLength() { return contentLength; }
+- public String getContentType() { return "text/xml"; }
+- });
+- try {
+- int redirectAttempts = 0;
+- for (;;) {
+- client.executeMethod(method);
+- if (!isRedirectRequired()) {
+- break;
+- }
+- if (redirectAttempts++ > MAX_REDIRECT_ATTEMPTS) {
+- throw new XmlRpcException("Too many redirects.");
+- }
+- resetClientForRedirect();
+- }
+- } catch (XmlRpcIOException e) {
+- Throwable t = e.getLinkedException();
+- if (t instanceof XmlRpcException) {
+- throw (XmlRpcException) t;
+- } else {
+- throw new XmlRpcException("Unexpected exception: " + t.getMessage(), t);
+- }
+- } catch (IOException e) {
+- throw new XmlRpcException("I/O error while communicating with HTTP server: " + e.getMessage(), e);
+- }
+- }
+-
+- /**
+- * Check the status of the HTTP request and throw an XmlRpcHttpTransportException if it
+- * indicates that there is an error.
+- * @param pMethod the method that has been executed
+- * @throws XmlRpcHttpTransportException if the status of the method indicates that there is an error.
+- */
+- private void checkStatus(HttpMethod pMethod) throws XmlRpcHttpTransportException {
+- final int status = pMethod.getStatusCode();
+-
+- // All status codes except SC_OK are handled as errors. Perhaps some should require special handling (e.g., SC_UNAUTHORIZED)
+- if (status < 200 || status > 299) {
+- throw new XmlRpcHttpTransportException(status, pMethod.getStatusText());
+- }
+- }
+-}
+diff --git a/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransportFactory.java b/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransportFactory.java
+deleted file mode 100644
+index 630d5b4..0000000
+--- a/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransportFactory.java
++++ /dev/null
+@@ -1,66 +0,0 @@
+-/*
+- * Licensed to the Apache Software Foundation (ASF) under one
+- * or more contributor license agreements. See the NOTICE file
+- * distributed with this work for additional information
+- * regarding copyright ownership. The ASF licenses this file
+- * to you under the Apache License, Version 2.0 (the
+- * "License"); you may not use this file except in compliance
+- * with the License. You may obtain a copy of the License at
+- *
+- * http://www.apache.org/licenses/LICENSE-2.0
+- *
+- * Unless required by applicable law or agreed to in writing,
+- * software distributed under the License is distributed on an
+- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+- * KIND, either express or implied. See the License for the
+- * specific language governing permissions and limitations
+- * under the License.
+- */
+-package org.apache.xmlrpc.client;
+-
+-import org.apache.commons.httpclient.HttpClient;
+-
+-
+-/** An HTTP transport factory, which is based on the Jakarta Commons
+- * HTTP Client.
+- */
+-public class XmlRpcCommonsTransportFactory extends XmlRpcTransportFactoryImpl {
+- private HttpClient httpClient;
+-
+- /** Creates a new instance.
+- * @param pClient The client, which is controlling the factory.
+- */
+- public XmlRpcCommonsTransportFactory(XmlRpcClient pClient) {
+- super(pClient);
+- }
+-
+- public XmlRpcTransport getTransport() {
+- return new XmlRpcCommonsTransport(this);
+- }
+-
+- /**
+- * Sets the factories {@link HttpClient}. By default, a new instance
+- * of {@link HttpClient} is created for any request.
+- * Reusing the {@link HttpClient} is required, if you want to preserve
+- * some state between requests. This applies, in particular, if you want
+- * to use cookies: In that case, create an instance of {@link HttpClient},
+- * give it to the factory, and use {@link HttpClient#getState()} to
+- * read or set cookies.
+- */
+- public void setHttpClient(HttpClient pHttpClient) {
+- httpClient = pHttpClient;
+- }
+-
+- /**
+- *
Returns the factories {@link HttpClient}. By default, a new instance
+- * of {@link HttpClient} is created for any request.
+- * Reusing the {@link HttpClient} is required, if you want to preserve
+- * some state between requests. This applies, in particular, if you want
+- * to use cookies: In that case, create an instance of {@link HttpClient},
+- * give it to the factory, and use {@link HttpClient#getState()} to
+- * read or set cookies.
+- */
+- public HttpClient getHttpClient() {
+- return httpClient;
+- }
+-}
+diff --git a/pom.xml b/pom.xml
+index 5e18625..55cc6a8 100644
+--- a/pom.xml
++++ b/pom.xml
+@@ -321,12 +321,6 @@
+
+
+
+-
+- commons-httpclient
+- commons-httpclient
+- 3.0.1
+- provided
+-
+
+ commons-logging
+ commons-logging
+diff --git a/server/pom.xml b/server/pom.xml
+index 4c90e50..84234ff 100644
+--- a/server/pom.xml
++++ b/server/pom.xml
+@@ -95,10 +95,5 @@
+ javax.servlet
+ javax.servlet-api
+
+-
+- commons-httpclient
+- commons-httpclient
+- test
+-
+
+
+diff --git a/server/src/test/java/org/apache/xmlrpc/test/CommonsProvider.java b/server/src/test/java/org/apache/xmlrpc/test/CommonsProvider.java
+deleted file mode 100644
+index 2551a59..0000000
+--- a/server/src/test/java/org/apache/xmlrpc/test/CommonsProvider.java
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/*
+- * Licensed to the Apache Software Foundation (ASF) under one
+- * or more contributor license agreements. See the NOTICE file
+- * distributed with this work for additional information
+- * regarding copyright ownership. The ASF licenses this file
+- * to you under the Apache License, Version 2.0 (the
+- * "License"); you may not use this file except in compliance
+- * with the License. You may obtain a copy of the License at
+- *
+- * http://www.apache.org/licenses/LICENSE-2.0
+- *
+- * Unless required by applicable law or agreed to in writing,
+- * software distributed under the License is distributed on an
+- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+- * KIND, either express or implied. See the License for the
+- * specific language governing permissions and limitations
+- * under the License.
+- */
+-package org.apache.xmlrpc.test;
+-
+-import org.apache.xmlrpc.client.XmlRpcClient;
+-import org.apache.xmlrpc.client.XmlRpcCommonsTransportFactory;
+-import org.apache.xmlrpc.client.XmlRpcTransportFactory;
+-import org.apache.xmlrpc.server.XmlRpcHandlerMapping;
+-
+-
+-/** Provider for testing the
+- * {@link org.apache.xmlrpc.client.XmlRpcCommonsTransport}.
+- */
+-public class CommonsProvider extends WebServerProvider {
+- /** Creates a new instance.
+- * @param pMapping The test servers handler mapping.
+- */
+- public CommonsProvider(XmlRpcHandlerMapping pMapping) {
+- super(pMapping, true);
+- }
+-
+- protected XmlRpcTransportFactory getTransportFactory(XmlRpcClient pClient) {
+- return new XmlRpcCommonsTransportFactory(pClient);
+- }
+-}
+diff --git a/server/src/test/java/org/apache/xmlrpc/test/XmlRpcTestCase.java b/server/src/test/java/org/apache/xmlrpc/test/XmlRpcTestCase.java
+index a9d1fbf..de06406 100644
+--- a/server/src/test/java/org/apache/xmlrpc/test/XmlRpcTestCase.java
++++ b/server/src/test/java/org/apache/xmlrpc/test/XmlRpcTestCase.java
+@@ -75,7 +75,6 @@ public abstract class XmlRpcTestCase extends TestCase {
+ // new LiteTransportProvider(mapping, false), Doesn't support HTTP/1.1
+ new SunHttpTransportProvider(pMapping, true),
+ new SunHttpTransportProvider(pMapping, false),
+- new CommonsProvider(pMapping),
+ new ServletWebServerProvider(pMapping, true),
+ new ServletWebServerProvider(pMapping, false)
+ };
+--
+2.26.0.rc2
+
diff --git a/0006-Fix-for-CVE-2019-17570.patch b/0006-Fix-for-CVE-2019-17570.patch
new file mode 100644
index 0000000..8a93dc5
--- /dev/null
+++ b/0006-Fix-for-CVE-2019-17570.patch
@@ -0,0 +1,52 @@
+From 1594395df534d60133d98884c9d9f5eb92d0652e Mon Sep 17 00:00:00 2001
+From: Mat Booth
+Date: Wed, 1 Apr 2020 10:21:03 +0100
+Subject: [PATCH 6/6] Fix for CVE-2019-17570
+
+Deserialization of server-side exception from faultCause in XMLRPC error response
+---
+ .../xmlrpc/parser/XmlRpcResponseParser.java | 28 ++++++++++---------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/common/src/main/java/org/apache/xmlrpc/parser/XmlRpcResponseParser.java b/common/src/main/java/org/apache/xmlrpc/parser/XmlRpcResponseParser.java
+index 087572b..f1b2427 100644
+--- a/common/src/main/java/org/apache/xmlrpc/parser/XmlRpcResponseParser.java
++++ b/common/src/main/java/org/apache/xmlrpc/parser/XmlRpcResponseParser.java
+@@ -69,19 +69,21 @@ public class XmlRpcResponseParser extends RecursiveTypeParserImpl {
+ getDocumentLocator());
+ }
+ errorMessage = (String) map.get("faultString");
+- Object exception = map.get("faultCause");
+- if (exception != null) {
+- try {
+- byte[] bytes = (byte[]) exception;
+- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+- ObjectInputStream ois = new ObjectInputStream(bais);
+- errorCause = (Throwable) ois.readObject();
+- ois.close();
+- bais.close();
+- } catch (Throwable t) {
+- // Ignore me
+- }
+- }
++ if (((XmlRpcStreamRequestConfig)cfg).isEnabledForExceptions()) {
++ Object exception = map.get("faultCause");
++ if (exception != null) {
++ try {
++ byte[] bytes = (byte[]) exception;
++ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
++ ObjectInputStream ois = new ObjectInputStream(bais);
++ errorCause = (Throwable) ois.readObject();
++ ois.close();
++ bais.close();
++ } catch (Throwable t) {
++ // Ignore me
++ }
++ }
++ }
+ }
+ }
+
+--
+2.26.0.rc2
+
diff --git a/dead.package b/dead.package
deleted file mode 100644
index 5204a84..0000000
--- a/dead.package
+++ /dev/null
@@ -1 +0,0 @@
-Orphaned for 6+ weeks
diff --git a/sources b/sources
new file mode 100644
index 0000000..f4bbd2c
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+f7817485fa6a6a500c49ec9515d1f3b9 apache-xmlrpc-3.1.3-src.tar.bz2
diff --git a/xmlrpc.spec b/xmlrpc.spec
new file mode 100644
index 0000000..a2cb5e6
--- /dev/null
+++ b/xmlrpc.spec
@@ -0,0 +1,175 @@
+Name: xmlrpc
+Version: 3.1.3
+Release: 24%{?dist}
+Epoch: 1
+Summary: Java XML-RPC implementation
+License: ASL 2.0
+URL: https://ws.apache.org/xmlrpc/
+BuildArch: noarch
+
+Source0: https://archive.apache.org/dist/ws/xmlrpc/sources/apache-xmlrpc-%{version}-src.tar.bz2
+
+# Fix build against modern servlet API by implementing missing interfaces
+Patch0: 0001-Javax-Servlet-API.patch
+# Add OSGi metadata so that xmlrpc can be used in OSGi runtimes
+Patch1: 0002-Add-OSGi-metadata.patch
+# CVE-2016-5003 - Disallow deserialization of tags by default
+Patch2: 0003-disallow-deserialization-of-ex-serializable-tags.patch
+# CVE-2016-5002 - isallow loading of external DTD
+Patch3: 0004-disallow-loading-external-dtd.patch
+# Jakarta Commons HttpClient is obsolete and should not be used, one of the other
+# provider implementations should by used instead by clients of xmlrpc
+Patch4: 0005-Remove-dep-on-ancient-commons-httpclient.patch
+# CVE-2019-17570 - Deserialization of server-side exception from faultCause in XMLRPC error response
+Patch5: 0006-Fix-for-CVE-2019-17570.patch
+
+BuildRequires: maven-local
+BuildRequires: mvn(commons-logging:commons-logging)
+BuildRequires: mvn(javax.servlet:javax.servlet-api)
+BuildRequires: mvn(junit:junit)
+BuildRequires: mvn(org.apache:apache:pom:)
+BuildRequires: mvn(org.apache.ws.commons.util:ws-commons-util)
+
+
+%description
+Apache XML-RPC is a Java implementation of XML-RPC, a popular protocol
+that uses XML over HTTP to implement remote procedure calls.
+
+%package javadoc
+Summary: Javadoc for %{name}
+
+%description javadoc
+Javadoc for %{name}.
+
+%package common
+Summary: Common classes for XML-RPC client and server implementations
+
+%description common
+%{summary}.
+
+%package client
+Summary: XML-RPC client implementation
+
+%description client
+%{summary}.
+
+%package server
+Summary: XML-RPC server implementation
+
+%description server
+%{summary}.
+
+%prep
+%setup -q -n apache-%{name}-%{version}-src
+
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+
+sed -i 's/\r//' LICENSE.txt
+
+%pom_disable_module dist
+%pom_remove_dep jaxme:jaxmeapi common
+%pom_add_dep junit:junit:3.8.1:test
+
+%mvn_file :{*} @1
+%mvn_package :*-common %{name}
+
+%build
+# ignore test failure because server part needs network
+%mvn_build -s -- -Dmaven.test.failure.ignore=true
+
+%install
+%mvn_install
+
+%files common -f .mfiles-%{name}
+%license LICENSE.txt NOTICE.txt
+
+%files client -f .mfiles-%{name}-client
+
+%files server -f .mfiles-%{name}-server
+
+%files javadoc -f .mfiles-javadoc
+%license LICENSE.txt NOTICE.txt
+
+%changelog
+* Wed Apr 01 2020 Mat Booth - 1:3.1.3-24
+- Add patch for CVE-2019-17570
+
+* Tue Mar 31 2020 Mat Booth - 1:3.1.3-23
+- Modernise spec file and remove dep on ancient Jakarta Commons httpclient implementation
+
+* Sun Feb 03 2019 Fedora Release Engineering - 1:3.1.3-22
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
+
+* Sat Jul 14 2018 Fedora Release Engineering - 1:3.1.3-21
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Fri May 18 2018 Michael Simacek - 1:3.1.3-20
+- Disallow deserialization of tags by default
+- Resolves CVE-2016-5003
+- Disallow loading of external DTD
+- Resolves CVE-2016-5002
+
+* Fri Feb 09 2018 Fedora Release Engineering - 1:3.1.3-19
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Thu Jul 27 2017 Fedora Release Engineering - 1:3.1.3-18
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Mon Jun 12 2017 Troy Dawson - 1:3.1.3-17
+- Add junit to pom deps. Was originally supplied by ws-commons-util (#1460767)
+
+* Sat Feb 11 2017 Fedora Release Engineering - 1:3.1.3-16
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Thu Jan 12 2017 Igor Gnatenko - 1:3.1.3-15
+- Rebuild for readline 7.x
+
+* Fri Feb 05 2016 Fedora Release Engineering - 1:3.1.3-14
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Fri Jun 19 2015 Fedora Release Engineering - 1:3.1.3-13
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Fri Feb 13 2015 gil cattaneo 1:3.1.3-12
+- introduce license macro
+
+* Thu Jul 10 2014 Sami Wagiaalla - 1:3.1.3-11
+- Add OSGi info for xmlrpc-server jar.
+- export o.a.xmlrpc from xmlrpc-client jar.
+
+* Mon Jun 16 2014 Mikolaj Izdebski - 1:3.1.3-10
+- Use servlet 3.1.0 API
+
+* Sun Jun 08 2014 Fedora Release Engineering - 1:3.1.3-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Tue Mar 04 2014 Stanislav Ochotnicky - 1:3.1.3-8
+- Use Requires: java-headless rebuild (#1067528)
+
+* Sun Aug 04 2013 Fedora Release Engineering - 1:3.1.3-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Fri Jun 14 2013 Mikolaj Izdebski - 1:3.1.3-6
+- Update to current packaging guidelines
+
+* Fri May 17 2013 Alexander Kurtakov 1:3.1.3-5
+- Remove javax.xml.bind from osgi imports - it's part of the JVM now.
+- Drop the ws-jaxme dependency for the same reason.
+
+* Fri Feb 15 2013 Fedora Release Engineering - 1:3.1.3-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Wed Feb 06 2013 Java SIG - 1:3.1.3-3
+- Update for https://fedoraproject.org/wiki/Fedora_19_Maven_Rebuild
+- Replace maven BuildRequires with maven-local
+
+* Sat Oct 20 2012 Peter Robinson 3.1.3-2
+- xmlrpc v2 had an Epoch so we need one here. Add it back
+
+* Fri Sep 14 2012 Alexander Kurtakov 3.1.3-1
+- First release of version 3.x package