From 3c1dba6f11cd5f463d6dbf3e09ab924dbb6528b0 Mon Sep 17 00:00:00 2001 From: Johannes Faltermeier Date: Wed, 24 Mar 2021 11:37:50 +0100 Subject: [PATCH] TCI - Disallow serializable * exceptions for file uploads Change-Id: I05ecf35e8722bee6b6ef68287ba199291e88e0f5 --- .../xmlrpc/util/EObjectTypeFactory.java | 8 +++ .../util/FileTransferInformationParser.java | 54 +++++++++++++++++++ .../FileTransferInformationSerializer.java | 50 +++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/FileTransferInformationParser.java create mode 100644 bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/FileTransferInformationSerializer.java diff --git a/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/EObjectTypeFactory.java b/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/EObjectTypeFactory.java index 0cd935f91..410b5015e 100644 --- a/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/EObjectTypeFactory.java +++ b/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/EObjectTypeFactory.java @@ -18,6 +18,8 @@ import org.apache.xmlrpc.parser.TypeParser; import org.apache.xmlrpc.serializer.TypeSerializer; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.emfstore.internal.server.filetransfer.FileChunk; +import org.eclipse.emf.emfstore.internal.server.filetransfer.FileTransferInformation; import org.xml.sax.SAXException; /** @@ -46,6 +48,9 @@ public TypeParser getParser(XmlRpcStreamConfig pConfig, NamespaceContextImpl pCo if (EObjectSerializer.EOBJECT_TAG.equals(pLocalName)) { return new EObjectDeserializer(); } + if (FileTransferInformationSerializer.FTI_TAG.equals(pLocalName)) { + return new FileTransferInformationParser(); + } final TypeParser parser = super.getParser(pConfig, pContext, pURI, pLocalName); if (parser instanceof org.apache.xmlrpc.parser.SerializableParser) { throw new IllegalArgumentException("A SerializableParser is not supported"); //$NON-NLS-1$ @@ -61,6 +66,9 @@ public TypeSerializer getSerializer(XmlRpcStreamConfig pConfig, Object pObject) if (pObject instanceof EObject) { return new EObjectSerializer(); } + if (pObject instanceof FileTransferInformation || pObject instanceof FileChunk) { + return new FileTransferInformationSerializer(); + } return super.getSerializer(pConfig, pObject); } diff --git a/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/FileTransferInformationParser.java b/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/FileTransferInformationParser.java new file mode 100644 index 000000000..0615cf207 --- /dev/null +++ b/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/FileTransferInformationParser.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2011-2021 EclipseSource Muenchen GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Johannes Faltermeier - initial API and implementation + ******************************************************************************/ +package org.eclipse.emf.emfstore.internal.server.connection.xmlrpc.util; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; + +import org.apache.xmlrpc.XmlRpcException; +import org.apache.xmlrpc.parser.ByteArrayParser; +import org.eclipse.emf.emfstore.internal.server.filetransfer.FileChunk; +import org.eclipse.emf.emfstore.internal.server.filetransfer.FileTransferInformation; + +public class FileTransferInformationParser extends ByteArrayParser { + @Override + public Object getResult() throws XmlRpcException { + try { + final byte[] res = (byte[]) super.getResult(); + final ByteArrayInputStream bais = new ByteArrayInputStream(res); + final ObjectInputStream ois = new ObjectInputStream(bais) { + @Override + protected java.lang.Class resolveClass(java.io.ObjectStreamClass desc) + throws IOException, ClassNotFoundException { + final Class resolveClass = super.resolveClass(desc); + if (resolveClass == FileTransferInformation.class) { + return resolveClass; + } + if (resolveClass == FileChunk.class) { + return resolveClass; + } + if (resolveClass == byte[].class) { + // needed because of byte array inputstream usage above + return resolveClass; + } + throw new IllegalArgumentException("Deserialzation is not supported"); //$NON-NLS-1$ + } + }; + return ois.readObject(); + } catch (final IOException e) { + throw new XmlRpcException("Failed to read result object: " + e.getMessage(), e); //$NON-NLS-1$ + } catch (final ClassNotFoundException e) { + throw new XmlRpcException("Failed to load class for result object: " + e.getMessage(), e); //$NON-NLS-1$ + } + } +} diff --git a/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/FileTransferInformationSerializer.java b/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/FileTransferInformationSerializer.java new file mode 100644 index 000000000..6e4759eaa --- /dev/null +++ b/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/connection/xmlrpc/util/FileTransferInformationSerializer.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2011-2021 EclipseSource Muenchen GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Johannes Faltermeier - initial API and implementation + ******************************************************************************/ +package org.eclipse.emf.emfstore.internal.server.connection.xmlrpc.util; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +import org.apache.ws.commons.util.Base64; +import org.apache.ws.commons.util.Base64.Encoder; +import org.apache.ws.commons.util.Base64.EncoderOutputStream; +import org.apache.xmlrpc.serializer.TypeSerializerImpl; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +public class FileTransferInformationSerializer extends TypeSerializerImpl { + /** + * Tag name of a base64 value. + */ + public static final String FTI_TAG = "filetransferinformation"; //$NON-NLS-1$ + private static final String EX_FTI_TAG = "ex:" + FTI_TAG; //$NON-NLS-1$ + + public void write(final ContentHandler pHandler, Object pObject) throws SAXException { + pHandler.startElement("", VALUE_TAG, VALUE_TAG, ZERO_ATTRIBUTES); //$NON-NLS-1$ + pHandler.startElement("", FTI_TAG, EX_FTI_TAG, ZERO_ATTRIBUTES); //$NON-NLS-1$ + final char[] buffer = new char[1024]; + final Encoder encoder = new Base64.SAXEncoder(buffer, 0, null, pHandler); + try { + final OutputStream ostream = new EncoderOutputStream(encoder); + final ObjectOutputStream oos = new ObjectOutputStream(ostream); + oos.writeObject(pObject); + oos.close(); + } catch (final Base64.SAXIOException e) { + throw e.getSAXException(); + } catch (final IOException e) { + throw new SAXException(e); + } + pHandler.endElement("", FTI_TAG, EX_FTI_TAG); //$NON-NLS-1$ + pHandler.endElement("", VALUE_TAG, VALUE_TAG); //$NON-NLS-1$ + } +} \ No newline at end of file