diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6de88cd --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +xmlrpc-2.0.1-src.tar.gz +/apache-xmlrpc-3.1.3-src.tar.bz2 diff --git a/.project b/.project new file mode 100644 index 0000000..d3cdf74 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + xmlrpc + + + + + + org.eclipse.linuxtools.rpm.rpmlint.rpmlintBuilder + + + + + + org.eclipse.linuxtools.rpm.rpmlint.rpmlintNature + + diff --git a/0001-Javax-Servlet-API.patch b/0001-Javax-Servlet-API.patch new file mode 100644 index 0000000..c6a4f93 --- /dev/null +++ b/0001-Javax-Servlet-API.patch @@ -0,0 +1,264 @@ +From a552fe2cd20c9804d9abcbf5f99533ed9c495fe7 Mon Sep 17 00:00:00 2001 +From: Mat Booth +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